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 +4 -4
- data/lib/invest_tinkoff/client_base.rb +1 -1
- data/lib/invest_tinkoff/v2/candle_interval.rb +23 -0
- data/lib/invest_tinkoff/v2/client.rb +545 -0
- data/lib/invest_tinkoff/v2/edit_favorites_action_type.rb +14 -0
- data/lib/invest_tinkoff/v2/instrument_id_type.rb +17 -0
- data/lib/invest_tinkoff/v2/instrument_status.rb +15 -0
- data/lib/invest_tinkoff/v2/operation_state.rb +13 -0
- data/lib/invest_tinkoff/v2/order_direction.rb +13 -0
- data/lib/invest_tinkoff/v2/order_type.rb +13 -0
- data/lib/invest_tinkoff/v2/quotation.rb +17 -0
- data/lib/invest_tinkoff/v2/response.rb +20 -0
- data/lib/invest_tinkoff/v2/sandbox_client.rb +152 -0
- data/lib/invest_tinkoff/v2/stop_order_expiration_type.rb +13 -0
- data/lib/invest_tinkoff/version.rb +3 -1
- data/lib/invest_tinkoff.rb +4 -0
- metadata +13 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15075f7de0ea08c8c024ccaa2fdec3e166c8d7d4a514a128b5b09a8fe4312ef4
|
4
|
+
data.tar.gz: 9df8ad68ffd0a8fbbdee0afb7322a8f544af22135155cbd5517f33cc48b3a49f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82eefd3f326f9b8e7d14a8854938c23f805a3305a9afa9bbb6780763656b1d96b82c037436e4039b30ee6ab376a897f6ca236851d2d9887073c289af2675a69b
|
7
|
+
data.tar.gz: 6424579f75a7504c2a4cab2c646def21ddc2840eeef0d4636474ccd57d56719f3e467a1876c650a481d8e87088b1b43465490e856f8fb499b592a7e8191dd130
|
@@ -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,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
|
data/lib/invest_tinkoff.rb
CHANGED
@@ -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.
|
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:
|