Skip to content

Commit 3f507bd

Browse files
Merge pull request #10 from necryin/examples
Examples
2 parents ea0cb45 + f2cdd18 commit 3f507bd

File tree

2 files changed

+324
-30
lines changed

2 files changed

+324
-30
lines changed

README.md

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,7 @@
2121

2222
Для непосредственного взаимодействия с OpenAPI нужно создать клиента. Клиенты разделены на streaming и rest.
2323

24-
```go
25-
package main
26-
27-
import (
28-
"context"
29-
"log"
30-
"os"
31-
"time"
32-
33-
sdk "github.com/TinkoffCreditSystems/invest-openapi-go-sdk"
34-
)
35-
36-
func main() {
37-
const token = "your_token"
38-
39-
logger := log.New(os.Stdout, "[invest-openapi-go-sdk]", log.LstdFlags)
40-
41-
streamClient, err := sdk.NewStreamingClient(logger, token)
42-
if err != nil {
43-
logger.Fatalln(err)
44-
}
45-
46-
restClient := sdk.NewRestClient(token)
47-
48-
ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
49-
defer cancel()
50-
51-
currencies, err := restClient.Currencies(ctx)
52-
}
53-
```
24+
Примеры использования SDK находятся в директории examples
5425

5526
### У меня есть вопрос
5627

examples/main.go

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"math/rand"
7+
"os"
8+
"time"
9+
10+
sdk "github.com/TinkoffCreditSystems/invest-openapi-go-sdk"
11+
)
12+
13+
const token = "YOUR_TOKEN"
14+
15+
func init() {
16+
rand.Seed(time.Now().UnixNano()) // инициируем Seed рандома для функции requestID
17+
}
18+
19+
func main() {
20+
rest()
21+
sandboxRest()
22+
stream()
23+
}
24+
25+
func stream() {
26+
logger := log.New(os.Stdout, "[invest-openapi-go-sdk]", log.LstdFlags)
27+
28+
client, err := sdk.NewStreamingClient(logger, token)
29+
if err != nil {
30+
log.Fatalln(err)
31+
}
32+
defer client.Close()
33+
34+
// Запускаем цикл обработки входящих событий. Запускаем асинхронно
35+
// Сюда будут приходить сообщения по подпискам после вызова соответствующих методов
36+
// SubscribeInstrumentInfo, SubscribeCandle, SubscribeOrderbook
37+
go func() {
38+
err = client.RunReadLoop(func(event interface{}) error {
39+
logger.Printf("Got event %+v", event)
40+
return nil
41+
})
42+
if err != nil {
43+
log.Fatalln(err)
44+
}
45+
}()
46+
47+
// Подписка на получение событий по инструменту BBG005DXJS36 (TCS)
48+
err = client.SubscribeInstrumentInfo("BBG005DXJS36", requestID())
49+
if err != nil {
50+
log.Fatalln(err)
51+
}
52+
53+
// Подписка на получение свечей по инструменту BBG005DXJS36 (TCS)
54+
err = client.SubscribeCandle("BBG005DXJS36", sdk.CandleInterval5Min, requestID())
55+
if err != nil {
56+
log.Fatalln(err)
57+
}
58+
59+
// Подписка на получения стакана по инструменту BBG005DXJS36 (TCS)
60+
err = client.SubscribeOrderbook("BBG005DXJS36", 10, requestID())
61+
if err != nil {
62+
log.Fatalln(err)
63+
}
64+
65+
// Приложение завершится через 10секунд.
66+
// Tip: В боевом приложении лучше обрабатывать сигналы завершения и работать в бесконечном цикле
67+
time.Sleep(10 * time.Second)
68+
69+
// Отписка от получения событий по инструменту BBG005DXJS36 (TCS)
70+
err = client.UnsubscribeInstrumentInfo("BBG005DXJS36", requestID())
71+
if err != nil {
72+
log.Fatalln(err)
73+
}
74+
75+
// Отписка от получения событий по инструменту BBG005DXJS36 (TCS)
76+
err = client.UnsubscribeCandle("BBG005DXJS36", sdk.CandleInterval5Min, requestID())
77+
if err != nil {
78+
log.Fatalln(err)
79+
}
80+
81+
// Отписка от получения стакана по инструменту BBG005DXJS36 (TCS)
82+
err = client.UnsubscribeOrderbook("BBG005DXJS36", 10, requestID())
83+
if err != nil {
84+
log.Fatalln(err)
85+
}
86+
}
87+
88+
func sandboxRest() {
89+
// Особенность работы в песочнице состоит в том что перед началом работы надо вызвать метод Register
90+
// и выставить установить(нарисовать) себе активов в портфеле методами SetCurrencyBalance (валютные активы) и
91+
// SetPositionsBalance (НЕ валютные активы)
92+
// Обнулить портфель можно методом Clear
93+
// Все остальные методы rest клиента так же доступны в песочнице
94+
client := sdk.NewSandboxRestClient(token)
95+
96+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
97+
defer cancel()
98+
99+
// Регистрация в песочнице
100+
err := client.Register(ctx)
101+
if err != nil {
102+
log.Fatalln(err)
103+
}
104+
105+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
106+
defer cancel()
107+
108+
// Рисуем себе 100500 рублей в портфеле песочницы
109+
err = client.SetCurrencyBalance(ctx, sdk.RUB, 100500)
110+
if err != nil {
111+
log.Fatalln(err)
112+
}
113+
114+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
115+
defer cancel()
116+
117+
// Рисуем себе 100 акций TCS в портфеле песочницы
118+
err = client.SetPositionsBalance(ctx, "BBG005DXJS36", 100)
119+
if err != nil {
120+
log.Fatalln(err)
121+
}
122+
123+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
124+
defer cancel()
125+
126+
// Очищаем состояние портфеля в песочнице
127+
err = client.Clear(ctx)
128+
if err != nil {
129+
log.Fatalln(err)
130+
}
131+
}
132+
133+
func rest() {
134+
client := sdk.NewRestClient(token)
135+
136+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
137+
defer cancel()
138+
139+
// Получение валютных инструментов
140+
// Например: USD000UTSTOM - USD, EUR_RUB__TOM - EUR
141+
currencies, err := client.Currencies(ctx)
142+
if err != nil {
143+
log.Fatalln(err)
144+
}
145+
log.Println(currencies)
146+
147+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
148+
defer cancel()
149+
150+
// Получение фондовых инструментов
151+
// Например: FXMM - Казначейские облигации США, FXGD - золото
152+
etfs, err := client.ETFs(ctx)
153+
if err != nil {
154+
log.Fatalln(err)
155+
}
156+
log.Println(etfs)
157+
158+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
159+
defer cancel()
160+
161+
// Получение облигационных инструментов
162+
// Например: SU24019RMFS0 - ОФЗ 24019
163+
bonds, err := client.Bonds(ctx)
164+
if err != nil {
165+
log.Fatalln(err)
166+
}
167+
log.Println(bonds)
168+
169+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
170+
defer cancel()
171+
172+
// Получение акционных инструментов
173+
// Например: SBUX - Starbucks Corporation
174+
stocks, err := client.Stocks(ctx)
175+
if err != nil {
176+
log.Fatalln(err)
177+
}
178+
log.Println(stocks)
179+
180+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
181+
defer cancel()
182+
183+
// Получение инструмента по тикеру, возвращает массив инструментов потому что тикер уникален только в рамках одной биржи
184+
// но может совпадать на разных биржах у разных кампаний
185+
// Например: https://www.moex.com/ru/issue.aspx?code=FIVE и https://www.nasdaq.com/market-activity/stocks/FIVE
186+
// В этом примере получить нужную компанию можно проверив поле Currency
187+
instruments, err := client.SearchInstrumentByTicker(ctx, "TCS")
188+
if err != nil {
189+
log.Fatalln(err)
190+
}
191+
log.Println(instruments)
192+
193+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
194+
defer cancel()
195+
196+
// Получение инструмента по FIGI(https://en.wikipedia.org/wiki/Financial_Instrument_Global_Identifier)
197+
// Узнать FIGI нужного инструмента можно методами указанными выше
198+
// Например: BBG000B9XRY4 - Apple, BBG005DXJS36 - Tinkoff
199+
instrument, err := client.SearchInstrumentByFIGI(ctx, "BBG005DXJS36")
200+
if err != nil {
201+
log.Fatalln(err)
202+
}
203+
log.Println(instrument)
204+
205+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
206+
defer cancel()
207+
208+
// Получение списка операций за период по конкретному инструменту(FIGI)
209+
// Например: ниже запрашиваются операции за последнюю неделю по инструменту NEE
210+
operations, err := client.Operations(ctx, time.Now().AddDate(0, 0, -7), time.Now(), "BBG000BJSBJ0")
211+
if err != nil {
212+
log.Fatalln(err)
213+
}
214+
log.Println(operations)
215+
216+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
217+
defer cancel()
218+
219+
// Получение списка НЕ валютных активов портфеля
220+
positions, err := client.PositionsPortfolio(ctx)
221+
if err != nil {
222+
log.Fatalln(err)
223+
}
224+
log.Println(positions)
225+
226+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
227+
defer cancel()
228+
229+
// Получение списка валютных активов портфеля
230+
positionCurrencies, err := client.CurrenciesPortfolio(ctx)
231+
if err != nil {
232+
log.Fatalln(err)
233+
}
234+
log.Println(positionCurrencies)
235+
236+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
237+
defer cancel()
238+
239+
// Получение списка валютных и НЕ валютных активов портфеля, метод является совмещеним PositionsPortfolio и CurrenciesPortfolio
240+
portfolio, err := client.Portfolio(ctx)
241+
if err != nil {
242+
log.Fatalln(err)
243+
}
244+
log.Println(portfolio)
245+
246+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
247+
defer cancel()
248+
249+
// Получение списка выставленных заявок(ордеров)
250+
orders, err := client.Orders(ctx)
251+
if err != nil {
252+
log.Fatalln(err)
253+
}
254+
log.Println(orders)
255+
256+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
257+
defer cancel()
258+
259+
// Получение свечей(ордеров)
260+
// Внимание! Действуют ограничения на промежуток и доступный размер свечей за него
261+
// Интервал свечи и допустимый промежуток запроса:
262+
// - 1min [1 minute, 1 day]
263+
// - 2min [2 minutes, 1 day]
264+
// - 3min [3 minutes, 1 day]
265+
// - 5min [5 minutes, 1 day]
266+
// - 10min [10 minutes, 1 day]
267+
// - 15min [15 minutes, 1 day]
268+
// - 30min [30 minutes, 1 day]
269+
// - hour [1 hour, 7 days]
270+
// - day [1 day, 1 year]
271+
// - week [7 days, 2 years]
272+
// - month [1 month, 10 years]
273+
// Например получение часовых свечей за последние 24 часа по инструменту BBG005DXJS36 (TCS)
274+
candles, err := client.Candles(ctx, time.Now().AddDate(0, 0, -1), time.Now(), sdk.CandleInterval1Hour, "BBG005DXJS36")
275+
if err != nil {
276+
log.Fatalln(err)
277+
}
278+
log.Println(candles)
279+
280+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
281+
defer cancel()
282+
283+
// Получение ордербука(он же стакан) по инструменту
284+
orderbook, err := client.Orderbook(ctx, 10, "BBG005DXJS36")
285+
if err != nil {
286+
log.Fatalln(err)
287+
}
288+
log.Println(orderbook)
289+
290+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
291+
defer cancel()
292+
293+
// Выставление лимитной заявки
294+
// В примере ниже выставляется заявка на покупку ОДНОЙ акции BBG005DXJS36 (TCS) по цене не выше 20$
295+
placedOrder, err := client.LimitOrder(ctx, "BBG005DXJS36", 1, sdk.BUY, 20)
296+
if err != nil {
297+
log.Fatalln(err)
298+
}
299+
log.Println(placedOrder)
300+
301+
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
302+
defer cancel()
303+
304+
// Отмена ранее выставленной заявки.
305+
// ID заявки возвращается в структуре PlacedLimitOrder в поле ID в запросе выставления заявки client.LimitOrder
306+
// или в структуре Order в поле ID в запросе получения заявок client.Orders
307+
err = client.OrderCancel(ctx, "88320371430")
308+
if err != nil {
309+
log.Fatalln(err)
310+
}
311+
}
312+
313+
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
314+
315+
// Генерируем уникальный ID для запроса
316+
func requestID() string {
317+
b := make([]rune, 12)
318+
for i := range b {
319+
b[i] = letterRunes[rand.Intn(len(letterRunes))]
320+
}
321+
322+
return string(b)
323+
}

0 commit comments

Comments
 (0)