invest_tinkoff 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72803a0f76ad49daa5442e51b65777d51afe7f617844362888b35889a7ac5b74
4
- data.tar.gz: 28f0c3cbf5154823e1942c3a7f20a8e4cf8ac715c20b7fb6d63fa1ff94b30785
3
+ metadata.gz: 15075f7de0ea08c8c024ccaa2fdec3e166c8d7d4a514a128b5b09a8fe4312ef4
4
+ data.tar.gz: 9df8ad68ffd0a8fbbdee0afb7322a8f544af22135155cbd5517f33cc48b3a49f
5
5
  SHA512:
6
- metadata.gz: 953ee207b8d3c3f53d695d6009d25adc53956dd83134b1706980aa779c6589c10b25a0529079a686029c2414122ac795db27ab30b4843f49349843bb13b25d43
7
- data.tar.gz: 166879c30f0a9ed386ff2a4836df6f71e21045a51b1b32a3fef918adc2d63a0b8928d63f8b5e339b000d1e6623f1394ac158dbb64f6d5a5feb431b2b1c636e59
6
+ metadata.gz: 82eefd3f326f9b8e7d14a8854938c23f805a3305a9afa9bbb6780763656b1d96b82c037436e4039b30ee6ab376a897f6ca236851d2d9887073c289af2675a69b
7
+ data.tar.gz: 6424579f75a7504c2a4cab2c646def21ddc2840eeef0d4636474ccd57d56719f3e467a1876c650a481d8e87088b1b43465490e856f8fb499b592a7e8191dd130
@@ -4,7 +4,7 @@ module InvestTinkoff
4
4
  class ClientBase
5
5
  include HTTParty
6
6
 
7
- def initialize token:, broker_account_id:, logger: nil
7
+ def initialize token:, broker_account_id: nil, logger: nil
8
8
  @token = token
9
9
  @broker_account_id = broker_account_id
10
10
  @logger = logger
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Интервал свечей
4
+ # https://tinkoff.github.io/investAPI/marketdata/#candleinterval
5
+ class InvestTinkoff::V2::CandleInterval
6
+ # Интервал не определён
7
+ UNSPECIFIED = 0
8
+
9
+ # 1 минута
10
+ MIN_1 = 1
11
+
12
+ # 5 минут
13
+ MIN_5 = 2
14
+
15
+ # 15 минут
16
+ MIN_15 = 3
17
+
18
+ # 1 час
19
+ HOUR = 4
20
+
21
+ # 1 день
22
+ DAY = 5
23
+ end
@@ -0,0 +1,545 @@
1
+ # frozen_string_literal: true
2
+
3
+ class InvestTinkoff::V2::Client < InvestTinkoff::ClientBase
4
+ base_uri 'https://invest-public-api.tinkoff.ru/rest/'
5
+
6
+ TIME_FORMAT = '%Y-%m-%dT%H:%m:%S.000Z'
7
+
8
+ def initialize token:, logger: nil
9
+ super(
10
+ token: token,
11
+ logger: logger
12
+ )
13
+ end
14
+
15
+ # ==========================================
16
+ # InstrumentsService
17
+ # ==========================================
18
+
19
+ # Метод получения облигации по её идентификатору.
20
+ # https://tinkoff.github.io/investAPI/instruments/#bondby
21
+ #
22
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
23
+ # @id: String
24
+ # @class_code: String (Обязателен при id_type = TICKER)
25
+ #
26
+ # client.bond_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'BBG00T22WKV5'
27
+ def bond_by id_type:, id:, class_code: nil
28
+ body = { idType: id_type, classCode: class_code, id: id }
29
+ instrument_request '/BondBy', body
30
+ end
31
+
32
+ # Метод получения списка облигаций.
33
+ # https://tinkoff.github.io/investAPI/instruments/#bonds
34
+ #
35
+ # @instrument_status: InvestTinkoff::V2::InstrumentStatus
36
+ def bonds instrument_status: InvestTinkoff::V2::InstrumentStatus::BASE
37
+ instrument_request '/Bonds', { instrumentStatus: instrument_status }
38
+ end
39
+
40
+ # Метод получения списка валют.
41
+ # https://tinkoff.github.io/investAPI/instruments/#currencies
42
+ #
43
+ # @instrument_status: InvestTinkoff::V2::InstrumentStatus
44
+ def currencies instrument_status: InvestTinkoff::V2::InstrumentStatus::BASE
45
+ instrument_request '/Currencies', { instrumentStatus: instrument_status }
46
+ end
47
+
48
+ # Метод получения валюты по её идентификатору.
49
+ # https://tinkoff.github.io/investAPI/instruments/#currencyby
50
+ #
51
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
52
+ # @id: String
53
+ # @class_code: String (Обязателен при id_type = TICKER)
54
+ #
55
+ # client.currency_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'BBG0013HQ5F0'
56
+ # client.currency_by id_type: InvestTinkoff::V2::InstrumentIdType::TICKER, id: 'GBPRUB_TOM', class_code: 'CETS'
57
+ def currency_by id_type:, id:, class_code: nil
58
+ body = { idType: id_type, classCode: class_code, id: id }
59
+ instrument_request '/CurrencyBy', body
60
+ end
61
+
62
+ # Метод редактирования избранных инструментов.
63
+ # https://tinkoff.github.io/investAPI/instruments/#editfavorites
64
+ #
65
+ # @figis: String, пример: ['BBG000B9XRY4', 'BBG000BWXBC2']
66
+ # @action_type: InvestTinkoff::V2::EditFavoritesActionType
67
+ def edit_favorites figis:, action_type: InvestTinkoff::V2::EditFavoritesActionType::ADD
68
+ body = {
69
+ instruments: figis.map { |v| { figi: v } },
70
+ actionType: action_type
71
+ }
72
+ instrument_request '/EditFavorites', body
73
+ end
74
+
75
+ # Метод получения инвестиционного фонда по его идентификатору.
76
+ # https://tinkoff.github.io/investAPI/instruments/#etfby
77
+ #
78
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
79
+ # @id: String
80
+ # @class_code: String (Обязателен при id_type = TICKER)
81
+ #
82
+ # client.etf_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'BBG005DXDPK9'
83
+ def etf_by id_type:, id:, class_code: nil
84
+ body = { idType: id_type, classCode: class_code, id: id }
85
+ instrument_request '/EtfBy', body
86
+ end
87
+
88
+ # Метод получения списка инвестиционных фондов.
89
+ # https://tinkoff.github.io/investAPI/instruments/#etfs
90
+ #
91
+ # @instrument_status: InvestTinkoff::V2::InstrumentStatus
92
+ def etfs instrument_status: InvestTinkoff::V2::InstrumentStatus::BASE
93
+ instrument_request '/Etfs', { instrumentStatus: instrument_status }
94
+ end
95
+
96
+ # Метод получения фьючерса по его идентификатору.
97
+ # https://tinkoff.github.io/investAPI/instruments/#futureby
98
+ #
99
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
100
+ # @id: String
101
+ # @class_code: String (Обязателен при id_type = TICKER)
102
+ #
103
+ # client.future_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'FUTNL0422000'
104
+ def future_by id_type:, id:, class_code: nil
105
+ body = { idType: id_type, classCode: class_code, id: id }
106
+ instrument_request '/FutureBy', body
107
+ end
108
+
109
+ # Метод получения списка фьючерсов.
110
+ # https://tinkoff.github.io/investAPI/instruments/#futures
111
+ #
112
+ # @instrument_status: InvestTinkoff::V2::InstrumentStatus
113
+ def futures instrument_status: InvestTinkoff::V2::InstrumentStatus::BASE
114
+ instrument_request '/Futures', { instrumentStatus: instrument_status }
115
+ end
116
+
117
+ # Метод получения накопленного купонного дохода по облигации.
118
+ # https://tinkoff.github.io/investAPI/instruments/#getaccruedinterests
119
+ #
120
+ # @figi: String, пример: 'BBG00X6ZGSY7'
121
+ # @from: Time, пример: 1.year.ago
122
+ # @to: Time, пример: 2.months.from_now
123
+ def accrued_interests figi:, from:, to:
124
+ body = {
125
+ figi: figi,
126
+ from: from.strftime(TIME_FORMAT),
127
+ to: to.strftime(TIME_FORMAT)
128
+ }
129
+ instrument_request '/GetAccruedInterests', body
130
+ end
131
+
132
+ # Метод получения актива по его идентификатору.
133
+ # https://tinkoff.github.io/investAPI/instruments/#getassetby
134
+ #
135
+ # @id: String, пример: '9f083982-cf4c-418a-a0bf-8b82f16db42d'
136
+ def asset_by id:
137
+ instrument_request '/GetAssetBy', { id: id }
138
+ end
139
+
140
+ # Метод получения списка активов.
141
+ # https://tinkoff.github.io/investAPI/instruments/#getassets
142
+ def assets
143
+ instrument_request '/GetAssets'
144
+ end
145
+
146
+ # Метод получения графика выплат купонов по облигации.
147
+ # https://tinkoff.github.io/investAPI/instruments/#getbondcoupons
148
+ #
149
+ # @figi: String, пример: 'BBG00X6ZGSY7'
150
+ # @from: Time, пример: 1.year.ago
151
+ # @to: Time, пример: 6.months.from_now
152
+ def bond_coupons figi:, from:, to:
153
+ body = {
154
+ figi: figi,
155
+ from: from.strftime(TIME_FORMAT),
156
+ to: to.strftime(TIME_FORMAT)
157
+ }
158
+ instrument_request '/GetBondCoupons', body
159
+ end
160
+
161
+ # Метод для получения событий выплаты дивидендов по инструменту.
162
+ # https://tinkoff.github.io/investAPI/instruments/#getdividends
163
+ #
164
+ # @figi: String, пример: 'BBG000B9XRY4'
165
+ # @from: Time, пример: 1.year.ago
166
+ # @to: Time, пример: 1.month.from_now
167
+ def dividends figi:, from:, to:
168
+ body = {
169
+ figi: figi,
170
+ from: from.strftime(TIME_FORMAT),
171
+ to: to.strftime(TIME_FORMAT)
172
+ }
173
+ instrument_request '/GetDividends', body
174
+ end
175
+
176
+ # Метод получения избранных инструментов.
177
+ # https://tinkoff.github.io/investAPI/instruments/#getfavorites
178
+ def favorites
179
+ instrument_request '/GetFavorites'
180
+ end
181
+
182
+ # Метод получения размера гарантийного обеспечения по фьючерсам.
183
+ # https://tinkoff.github.io/investAPI/instruments/#getfuturesmargin
184
+ #
185
+ # @figi: String
186
+ def futures_margin figi:
187
+ instrument_request '/GetFuturesMargin', { figi: figi }
188
+ end
189
+
190
+ # Метод получения основной информации об инструменте.
191
+ # https://tinkoff.github.io/investAPI/instruments/#getinstrumentby
192
+ #
193
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
194
+ # @id: String
195
+ # @class_code: String (Обязателен при id_type = TICKER)
196
+ #
197
+ # client.instrument_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'BBG000B9XRY4'
198
+ def instrument_by id_type:, id:, class_code: nil
199
+ body = { idType: id_type, classCode: class_code, id: id }
200
+ instrument_request '/GetInstrumentBy', body
201
+ end
202
+
203
+ # Метод получения акции по её идентификатору.
204
+ # https://tinkoff.github.io/investAPI/instruments/#shareby
205
+ #
206
+ # @id_type: InvestTinkoff::V2::InstrumentIdType
207
+ # @id: String
208
+ # @class_code: String (Обязателен при id_type = TICKER)
209
+ #
210
+ # client.share_by id_type: InvestTinkoff::V2::InstrumentIdType::FIGI, id: 'BBG000B9XRY4'
211
+ def share_by id_type:, id:, class_code: nil
212
+ body = { idType: id_type, classCode: class_code, id: id }
213
+ instrument_request '/ShareBy', body
214
+ end
215
+
216
+ # Метод получения списка акций.
217
+ # https://tinkoff.github.io/investAPI/instruments/#shares
218
+ #
219
+ # @instrument_status: InvestTinkoff::V2::InstrumentStatus
220
+ def shares instrument_status: InvestTinkoff::V2::InstrumentStatus::BASE
221
+ instrument_request '/Shares', { instrumentStatus: instrument_status }
222
+ end
223
+
224
+ # Метод получения расписания торгов торговых площадок.
225
+ # https://tinkoff.github.io/investAPI/instruments/#tradingschedulesrequest
226
+ #
227
+ # @exchange: String, пример: 'MOEX'
228
+ # @from: Time, пример: 1.day.from_now
229
+ # @to: Time, пример: 5.days.from_now
230
+ def trading_schedules exchange:, from:, to:
231
+ body = {
232
+ exchange: exchange,
233
+ from: from.strftime(TIME_FORMAT),
234
+ to: to.strftime(TIME_FORMAT)
235
+ }
236
+ instrument_request '/TradingSchedules', body
237
+ end
238
+
239
+ # ==========================================
240
+ # MarketDataService
241
+ # ==========================================
242
+
243
+ # Метод запроса исторических свечей по инструменту.
244
+ # https://tinkoff.github.io/investAPI/marketdata/#getcandles
245
+ #
246
+ # @figi: String, пример: 'BBG000B9XRY4'
247
+ # @from: Time, пример: 1.hour.ago
248
+ # @to: Time, пример: Time.zone.now
249
+ # @interval: InvestTinkoff::V2::CandleInterval
250
+ def candles figi:, from:, to:, interval: InvestTinkoff::V2::CandleInterval::HOUR
251
+ body = {
252
+ figi: figi,
253
+ from: from.strftime(TIME_FORMAT),
254
+ to: to.strftime(TIME_FORMAT),
255
+ interval: interval
256
+ }
257
+ market_request '/GetCandles', body
258
+ end
259
+
260
+ # Метод запроса последних цен по инструментам.
261
+ # https://tinkoff.github.io/investAPI/marketdata/#getlastprices
262
+ #
263
+ # @figis: String, пример: ['BBG000B9XRY4', 'BBG000BWXBC2']
264
+ def last_prices figis:
265
+ market_request '/GetLastPrices', { figi: figis }
266
+ end
267
+
268
+ # Метод запроса последних обезличенных сделок по инструменту.
269
+ # https://tinkoff.github.io/investAPI/marketdata/#getlasttrades
270
+ #
271
+ # @figi: String, пример: 'BBG000B9XRY4'
272
+ # @from: Time, пример: 1.hour.ago
273
+ # @to: Time, пример: Time.zone.now
274
+ def last_trades figi:, from:, to:
275
+ body = {
276
+ figi: figi,
277
+ from: from.strftime(TIME_FORMAT),
278
+ to: to.strftime(TIME_FORMAT)
279
+ }
280
+ market_request '/GetLastTrades', body
281
+ end
282
+
283
+ # Метод получения стакана по инструменту.
284
+ # https://tinkoff.github.io/investAPI/marketdata/#getorderbook
285
+ #
286
+ # @figi: String, пример: 'BBG000B9XRY4'
287
+ # @depth: Integer
288
+ def order_book figi:, depth: 10
289
+ market_request '/GetOrderBook', { figi: figi, depth: depth }
290
+ end
291
+
292
+ # Метод запроса статуса торгов по инструментам.
293
+ # https://tinkoff.github.io/investAPI/marketdata/#gettradingstatus
294
+ #
295
+ # @figi: String, пример: 'BBG000B9XRY4'
296
+ def trading_status figi:
297
+ market_request '/GetTradingStatus', { figi: figi }
298
+ end
299
+
300
+ # ==========================================
301
+ # OperationsService
302
+ # ==========================================
303
+
304
+ # Метод получения брокерского отчёта.
305
+ # https://tinkoff.github.io/investAPI/operations/#getbrokerreport
306
+ def broker_report
307
+ # operation_request '/GetBrokerReport', body
308
+ raise NotImplementedError
309
+ end
310
+
311
+ # Метод получения отчёта "Справка о доходах за пределами РФ".
312
+ # https://tinkoff.github.io/investAPI/operations/#getdividendsforeignissuer
313
+ def dividends_foreign_issuer
314
+ # operation_request '/GetDividendsForeignIssuer', body
315
+ raise NotImplementedError
316
+ end
317
+
318
+ # Метод получения списка операций по счёту.
319
+ # https://tinkoff.github.io/investAPI/operations/#getoperations
320
+ #
321
+ # @account_id: String
322
+ # @figi: String, пример: 'BBG000B9XRY4'
323
+ # @from: Time
324
+ # @to: Time
325
+ # @state (опиционально): InvestTinkoff::V2::OperationState
326
+ def operations account_id:, figi:, from:, to:, state: InvestTinkoff::V2::OperationState::UNSPECIFIED
327
+ body = {
328
+ accountId: account_id,
329
+ figi: figi,
330
+ from: from.strftime(TIME_FORMAT),
331
+ to: to.strftime(TIME_FORMAT),
332
+ state: state || InvestTinkoff::V2::OperationState::UNSPECIFIED
333
+ }
334
+ operation_request '/GetOperations', body
335
+ end
336
+
337
+ # Метод получения портфеля по счёту.
338
+ # https://tinkoff.github.io/investAPI/operations/#getportfolio
339
+ #
340
+ # @account_id: String
341
+ def portfolio account_id:
342
+ operation_request '/GetPortfolio', { accountId: account_id }
343
+ end
344
+
345
+ # Метод получения списка позиций по счёту.
346
+ # https://tinkoff.github.io/investAPI/operations/#getpositions
347
+ #
348
+ # @account_id: String
349
+ def positions account_id:
350
+ operation_request '/GetPositions', { accountId: account_id }
351
+ end
352
+
353
+ # Метод получения доступного остатка для вывода средств.
354
+ # https://tinkoff.github.io/investAPI/operations/#getwithdrawlimits
355
+ def withdraw_limits account_id:
356
+ operation_request '/GetWithdrawLimits', { accountId: account_id }
357
+ end
358
+
359
+ # ==========================================
360
+ # OrdersService
361
+ # ==========================================
362
+
363
+ # Метод получения списка активных заявок по счёту.
364
+ #
365
+ # @account_id: String
366
+ def orders account_id:
367
+ order_request '/GetOrders', { accountId: account_id }
368
+ end
369
+
370
+ # Метод выставления заявки.
371
+ # https://tinkoff.github.io/investAPI/orders/#postorder
372
+ #
373
+ # @account_id: String
374
+ # @figi: String
375
+ # @quantity: Integer
376
+ # @price: Float
377
+ # @direction: InvestTinkoff::V2::OrderDirection
378
+ # @order_type: InvestTinkoff::V2::OrderType
379
+ # @order_id: String (max length 36)
380
+ def create_order( # rubocop: disable Metrics/ParameterLists
381
+ account_id:,
382
+ figi:,
383
+ quantity:,
384
+ price:,
385
+ direction:,
386
+ order_type:,
387
+ order_id:
388
+ )
389
+ body = {
390
+ accountId: account_id,
391
+ figi: figi,
392
+ quantity: quantity,
393
+ price: InvestTinkoff::V2::Quotation.create(price),
394
+ direction: direction,
395
+ orderType: order_type,
396
+ orderId: order_id
397
+ }
398
+ order_request '/PostOrder', body
399
+ end
400
+
401
+ # Метод получения статуса торгового поручения.
402
+ # https://tinkoff.github.io/investAPI/orders/#getorderstate
403
+ #
404
+ # @account_id: String
405
+ # @order_id: String
406
+ def order_state account_id:, order_id:
407
+ body = { accountId: account_id, orderId: order_id }
408
+ order_request '/GetOrderState', body
409
+ end
410
+
411
+ # Метод отмены биржевой заявки.
412
+ # https://tinkoff.github.io/investAPI/orders/#cancelorder
413
+ #
414
+ # @account_id: String
415
+ # @order_id: String
416
+ def cancel_order account_id:, order_id:
417
+ body = { accountId: account_id, orderId: order_id }
418
+ order_request '/CancelOrder', body
419
+ end
420
+
421
+ # ==========================================
422
+ # StopOrdersService
423
+ # ==========================================
424
+
425
+ # Метод получения списка активных стоп заявок по счёту.
426
+ # https://tinkoff.github.io/investAPI/stoporders/#getstoporders
427
+ def stop_orders account_id:
428
+ body = { accountId: account_id }
429
+ stop_order_request '/GetStopOrders', body
430
+ end
431
+
432
+ # Метод выставления стоп-заявки.
433
+ # https://tinkoff.github.io/investAPI/stoporders/#poststoporder
434
+ def create_stop_order account_id:, figi:, quantity:, price:, stop_price:, expiration_type: nil
435
+ # TODO: Еще остались не проброшенными некоторые аргументы.
436
+ # {
437
+ # "figi": "string",
438
+ # "quantity": "string",
439
+ # "price": {
440
+ # "nano": 6,
441
+ # "units": "units"
442
+ # },
443
+ # "stopPrice": {
444
+ # "nano": 6,
445
+ # "units": "units"
446
+ # },
447
+ # "direction": "STOP_ORDER_DIRECTION_UNSPECIFIED",
448
+ # "accountId": "string",
449
+ # "expirationType": "STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED",
450
+ # "stopOrderType": "STOP_ORDER_TYPE_UNSPECIFIED",
451
+ # "expireDate": "2022-05-15T16:08:27.339Z"
452
+ # }
453
+ body = {
454
+ figi: figi,
455
+ quantity: quantity,
456
+ price: InvestTinkoff::V2::Quotation.create(price),
457
+ stopPrice: InvestTinkoff::V2::Quotation.create(stop_price),
458
+ # ...
459
+ accountId: account_id,
460
+ expirationType: expiration_type || StopOrderExpirationType::UNSPECIFIED
461
+ # ...
462
+ }
463
+ stop_order_request '/PostStopOrder', body
464
+ end
465
+
466
+ # Метод отмены стоп-заявки.
467
+ # https://tinkoff.github.io/investAPI/stoporders/#cancelstoporder
468
+ def cancel_stop_order account_id:, order_id:
469
+ body = { accountId: account_id, stopOrderId: order_id }
470
+ stop_order_request '/CancelStopOrder', body
471
+ end
472
+
473
+ # ==========================================
474
+ # UsersService
475
+ # ==========================================
476
+
477
+ # Метод получения счетов пользователя.
478
+ def accounts
479
+ user_service_request '/GetAccounts'
480
+ end
481
+
482
+ # Метод получения информации о пользователе.
483
+ def info
484
+ user_service_request '/GetInfo'
485
+ end
486
+
487
+ # Расчёт маржинальных показателей по счёту.
488
+ def margin_attributes account_id:
489
+ body = { accountId: account_id }
490
+ user_service_request '/GetMarginAttributes', body
491
+ end
492
+
493
+ # Текущий тариф пользователя (лимиты запросов к API).
494
+ def user_tariff
495
+ user_service_request '/GetUserTariff'
496
+ end
497
+
498
+ private
499
+
500
+ def parse_response response
501
+ InvestTinkoff::V2::Response.create response
502
+ end
503
+
504
+ def instrument_request path, body = {}
505
+ post_api_request(
506
+ "/tinkoff.public.invest.api.contract.v1.InstrumentsService#{path}",
507
+ body: body
508
+ )
509
+ end
510
+
511
+ def market_request path, body = {}
512
+ post_api_request(
513
+ "/tinkoff.public.invest.api.contract.v1.MarketDataService#{path}",
514
+ body: body
515
+ )
516
+ end
517
+
518
+ def operation_request path, body = {}
519
+ post_api_request(
520
+ "/tinkoff.public.invest.api.contract.v1.OperationsService#{path}",
521
+ body: body
522
+ )
523
+ end
524
+
525
+ def order_request path, body = {}
526
+ post_api_request(
527
+ "/tinkoff.public.invest.api.contract.v1.OrdersService#{path}",
528
+ body: body
529
+ )
530
+ end
531
+
532
+ def stop_order_request path, body = {}
533
+ post_api_request(
534
+ "/tinkoff.public.invest.api.contract.v1.StopOrdersService#{path}",
535
+ body: body
536
+ )
537
+ end
538
+
539
+ def user_service_request path, body = {}
540
+ post_api_request(
541
+ "/tinkoff.public.invest.api.contract.v1.UsersService#{path}",
542
+ body: body
543
+ )
544
+ end
545
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Тип действия со списком избранных инструментов
4
+ # https://tinkoff.github.io/investAPI/instruments/#editfavoritesactiontype
5
+ class InvestTinkoff::V2::EditFavoritesActionType
6
+ # Тип не определён
7
+ UNSPECIFIED = 0
8
+
9
+ # Добавить в список
10
+ ADD = 1
11
+
12
+ # Удалить из списка
13
+ DEL = 2
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Тип идентификатора инструмента
4
+ # https://tinkoff.github.io/investAPI/instruments/#instrumentidtype
5
+ class InvestTinkoff::V2::InstrumentIdType
6
+ # Значение не определено
7
+ UNSPECIFIED = 0
8
+
9
+ # Figi
10
+ FIGI = 1
11
+
12
+ # Ticker
13
+ TICKER = 2
14
+
15
+ # Уникальный идентификатор
16
+ UID = 3
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Статус запрашиваемых инструментов
4
+ # https://tinkoff.github.io/investAPI/marketdata/#candleinterval
5
+ class InvestTinkoff::V2::InstrumentStatus
6
+ # Значение не определено
7
+ UNSPECIFIED = 0
8
+
9
+ # Базовый список инструментов (по умолчанию).
10
+ # Инструменты доступные для торговли через TINKOFF INVEST API.
11
+ BASE = 1
12
+
13
+ # Список всех инструментов
14
+ ALL = 2
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Статус запрашиваемых операций
4
+ class InvestTinkoff::V2::OperationState
5
+ # Значение не указано
6
+ UNSPECIFIED = 0
7
+
8
+ # Исполнена
9
+ EXECUTED = 1
10
+
11
+ # Отменена
12
+ CANCELED = 2
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Направление операции
4
+ class InvestTinkoff::V2::OrderDirection
5
+ # Значение не указано
6
+ UNSPECIFIED = 0
7
+
8
+ # Покупка
9
+ BUY = 1
10
+
11
+ # Продажа
12
+ SELL = 2
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Тип заявки
4
+ class InvestTinkoff::V2::OrderType
5
+ # Значение не указано
6
+ UNSPECIFIED = 0
7
+
8
+ # Лимитная
9
+ LIMIT = 1
10
+
11
+ # Рыночная
12
+ MARKET = 2
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ InvestTinkoff::V2::Quotation = Struct.new(
4
+ :units,
5
+ :nano
6
+ )
7
+
8
+ class InvestTinkoff::V2::Quotation
9
+ def self.create price
10
+ units = price.round
11
+ nano = ((price.to_d - units) * 1_000_000_000).to_i
12
+ new(
13
+ "#{price.positive? ? '' : '-'}#{units.abs}",
14
+ nano
15
+ )
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ InvestTinkoff::V2::Response = Struct.new(
4
+ :payload,
5
+ :http_code
6
+ )
7
+
8
+ class InvestTinkoff::V2::Response
9
+ def self.create response
10
+ attributes = response.parsed_response || {}
11
+ new(
12
+ attributes,
13
+ response.code
14
+ )
15
+ end
16
+
17
+ def success?
18
+ http_code == 200
19
+ end
20
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ class InvestTinkoff::V2::SandboxClient < InvestTinkoff::V2::Client
4
+ def initialize token:, logger: nil
5
+ super(
6
+ token: token,
7
+ logger: logger
8
+ )
9
+ end
10
+
11
+ # ==========================================
12
+ # SandboxService
13
+ # ==========================================
14
+
15
+ # Метод отмены торгового поручения в песочнице.
16
+ # https://tinkoff.github.io/investAPI/sandbox/#cancelsandboxorder
17
+ #
18
+ # @account_id: String
19
+ # @order_id: String
20
+ def cancel_sandbox_order account_id:, order_id:
21
+ body = { accountId: account_id, orderId: order_id }
22
+ sandbox_request '/CancelSandboxOrder', body
23
+ end
24
+
25
+ # Метод закрытия счёта в песочнице.
26
+ # https://tinkoff.github.io/investAPI/sandbox/#closesandboxaccount
27
+ #
28
+ # @account_id: String
29
+ def close_sandbox_account account_id:
30
+ sandbox_request '/CloseSandboxAccount', { accountId: account_id }
31
+ end
32
+
33
+ # Метод получения счетов в песочнице.
34
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxaccounts
35
+ def sandbox_accounts
36
+ sandbox_request '/GetSandboxAccounts'
37
+ end
38
+
39
+ # Метод получения операций в песочнице по номеру счёта.
40
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxoperations
41
+ #
42
+ # @account_id: String
43
+ # @figi: String, пример: 'BBG000B9XRY4'
44
+ # @from: Time
45
+ # @to: Time
46
+ # @state (опиционально): InvestTinkoff::V2::OperationState
47
+ def sandbox_operations account_id:, figi:, from:, to:, state: InvestTinkoff::V2::OperationState::UNSPECIFIED
48
+ body = {
49
+ accountId: account_id,
50
+ figi: figi,
51
+ from: from.strftime(TIME_FORMAT),
52
+ to: to.strftime(TIME_FORMAT),
53
+ state: state || InvestTinkoff::V2::OperationState::UNSPECIFIED
54
+ }
55
+ sandbox_request '/GetSandboxOperations', body
56
+ end
57
+
58
+ # Метод получения статуса заявки в песочнице.
59
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxorderstate
60
+ #
61
+ # @account_id: String
62
+ # @order_id: String
63
+ def sandbox_order_state account_id:, order_id:
64
+ body = { accountId: account_id, orderId: order_id }
65
+ sandbox_request '/GetSandboxOrderState', body
66
+ end
67
+
68
+ # Метод получения списка активных заявок по счёту в песочнице.
69
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxorders
70
+ #
71
+ # @account_id: String
72
+ def sandbox_orders account_id:
73
+ sandbox_request '/GetSandboxOrders', { accountId: account_id }
74
+ end
75
+
76
+ # Метод получения портфолио в песочнице.
77
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxportfolio
78
+ #
79
+ # @account_id: String
80
+ def sandbox_portfolio account_id:
81
+ sandbox_request '/GetSandboxPortfolio', { accountId: account_id }
82
+ end
83
+
84
+ # Метод получения позиций по виртуальному счёту песочницы.
85
+ # https://tinkoff.github.io/investAPI/sandbox/#getsandboxpositions
86
+ #
87
+ # @account_id: String
88
+ def sandbox_positions account_id:
89
+ sandbox_request '/GetSandboxPositions', { accountId: account_id }
90
+ end
91
+
92
+ # Метод регистрации счёта в песочнице.
93
+ # https://tinkoff.github.io/investAPI/sandbox/#opensandboxaccount
94
+ def open_sandbox_account
95
+ sandbox_request '/OpenSandboxAccount'
96
+ end
97
+
98
+ # Метод выставления торгового поручения в песочнице.
99
+ # https://tinkoff.github.io/investAPI/sandbox/#postsandboxorder
100
+ #
101
+ # @account_id: String
102
+ # @figi: String
103
+ # @quantity: Integer
104
+ # @price: Float
105
+ # @direction: InvestTinkoff::V2::OrderDirection
106
+ # @order_type: InvestTinkoff::V2::OrderType
107
+ # @order_id: String (max length 36)
108
+ def create_sandbox_order( # rubocop: disable Metrics/ParameterLists
109
+ account_id:,
110
+ figi:,
111
+ quantity:,
112
+ price:,
113
+ direction:,
114
+ order_type:,
115
+ order_id:
116
+ )
117
+ body = {
118
+ accountId: account_id,
119
+ figi: figi,
120
+ quantity: quantity,
121
+ price: InvestTinkoff::V2::Quotation.create(price),
122
+ direction: direction,
123
+ orderType: order_type,
124
+ orderId: order_id
125
+ }
126
+ sandbox_request '/PostSandboxOrder', body
127
+ end
128
+
129
+ # Метод пополнения счёта в песочнице.
130
+ # https://tinkoff.github.io/investAPI/sandbox/#sandboxpayin
131
+ #
132
+ # @account_id: String
133
+ # @amount: Float
134
+ # @currency: String, пример 'RUB', 'USD', 'EUR' и т.д.
135
+ def sandbox_pay_in account_id:, amount:, currency:
136
+ body = {
137
+ accountId: account_id,
138
+ amount: InvestTinkoff::V2::Quotation.create(amount),
139
+ currency: currency
140
+ }
141
+ sandbox_request '/SandboxPayIn', body
142
+ end
143
+
144
+ private
145
+
146
+ def sandbox_request path, body = {}
147
+ post_api_request(
148
+ "/tinkoff.public.invest.api.contract.v1.SandboxService#{path}",
149
+ body: body
150
+ )
151
+ end
152
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Тип экспирации стоп-заявки
4
+ class InvestTinkoff::V2::StopOrderExpirationType
5
+ # Значение не указано
6
+ UNSPECIFIED = 0
7
+
8
+ # Действительно до отмены
9
+ GOOD_TILL_CANCEL = 1
10
+
11
+ # Действительно до даты снятия
12
+ GOOD_TILL_DATE = 2
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module InvestTinkoff
2
- VERSION = '0.9.2'
4
+ VERSION = '0.9.4'
3
5
  end
@@ -13,3 +13,7 @@ require 'invest_tinkoff/client_base'
13
13
  require 'invest_tinkoff/v1/client'
14
14
  require 'invest_tinkoff/v1/response'
15
15
  require 'invest_tinkoff/v1/sandbox_client'
16
+
17
+ require 'invest_tinkoff/v2/client'
18
+ require 'invest_tinkoff/v2/response'
19
+ require 'invest_tinkoff/v2/sandbox_client'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invest_tinkoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Kalinichev
@@ -41,6 +41,18 @@ files:
41
41
  - lib/invest_tinkoff/v1/client.rb
42
42
  - lib/invest_tinkoff/v1/response.rb
43
43
  - lib/invest_tinkoff/v1/sandbox_client.rb
44
+ - lib/invest_tinkoff/v2/candle_interval.rb
45
+ - lib/invest_tinkoff/v2/client.rb
46
+ - lib/invest_tinkoff/v2/edit_favorites_action_type.rb
47
+ - lib/invest_tinkoff/v2/instrument_id_type.rb
48
+ - lib/invest_tinkoff/v2/instrument_status.rb
49
+ - lib/invest_tinkoff/v2/operation_state.rb
50
+ - lib/invest_tinkoff/v2/order_direction.rb
51
+ - lib/invest_tinkoff/v2/order_type.rb
52
+ - lib/invest_tinkoff/v2/quotation.rb
53
+ - lib/invest_tinkoff/v2/response.rb
54
+ - lib/invest_tinkoff/v2/sandbox_client.rb
55
+ - lib/invest_tinkoff/v2/stop_order_expiration_type.rb
44
56
  - lib/invest_tinkoff/version.rb
45
57
  homepage: https://github.com/blackchestnut/invest_tinkoff
46
58
  licenses: