invest_tinkoff 0.9.0
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 +7 -0
- data/lib/invest_tinkoff/client_base.rb +51 -0
- data/lib/invest_tinkoff/v1/client.rb +171 -0
- data/lib/invest_tinkoff/v1/response.rb +24 -0
- data/lib/invest_tinkoff/v1/sandbox_client.rb +60 -0
- data/lib/invest_tinkoff/version.rb +3 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fec23d110b2a83bb181d43d24178a1a92f3aee95136db9f74f475e6bc20d5069
|
4
|
+
data.tar.gz: 2f23f8028c68369c29c1ef296cbcccbd54cbef310271b8ff8a43111f6da716cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c5158d70d7a6dbffecd3e2d877f85f1369922b7ee361d71c0905fae5ff4cb7ecd96bd86bbc81df576f4d7e77166063deb8b377de4f996934ee520e420e38fe0
|
7
|
+
data.tar.gz: cdfbeb57431f842ba3dd417c557675c5351a6f1ae95993c5651dc6ec87833bc8ad4ec7582105dd47e44c39400599c12eaa587272574143b79c04e3ccbcbc2444
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class InvestTinkoff::ClientBase
|
4
|
+
include HTTParty
|
5
|
+
|
6
|
+
def initialize token:, broker_account_id:, logger: nil
|
7
|
+
@token = token
|
8
|
+
@broker_account_id = broker_account_id
|
9
|
+
@logger = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def get_api_request path, query = nil
|
15
|
+
response = self.class.get(
|
16
|
+
path,
|
17
|
+
query: query || base_query,
|
18
|
+
logger: @logger,
|
19
|
+
headers: headers
|
20
|
+
)
|
21
|
+
parse_response response
|
22
|
+
end
|
23
|
+
|
24
|
+
def post_api_request path, body: {}, query: {}
|
25
|
+
response = self.class.post(
|
26
|
+
path,
|
27
|
+
query: base_query.merge(query),
|
28
|
+
body: body.to_json,
|
29
|
+
logger: @logger,
|
30
|
+
headers: headers
|
31
|
+
)
|
32
|
+
parse_response response
|
33
|
+
end
|
34
|
+
|
35
|
+
def headers
|
36
|
+
{
|
37
|
+
'Authorization' => "Bearer #{@token}",
|
38
|
+
'Content-Type' => 'application/json'
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def base_query
|
43
|
+
return {} if @broker_account_id.nil?
|
44
|
+
|
45
|
+
{ brokerAccountId: @broker_account_id }
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_response response
|
49
|
+
response.parsed_response
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class InvestTinkoff::V1::Client < InvestTinkoff::ClientBase
|
4
|
+
base_uri 'https://api-invest.tinkoff.ru/openapi/'
|
5
|
+
|
6
|
+
TIME_FORMAT = '%FT%T%:z'
|
7
|
+
CANDLES_INTERVALS = %w[1min 2min 3min 5min 10min 15min 30min hour day week month]
|
8
|
+
|
9
|
+
attr_accessor :broker_account_id
|
10
|
+
|
11
|
+
# token - рабочий API token
|
12
|
+
# broker_account_id (опционально) - идентификатор счета
|
13
|
+
# logger (опиционально) - например: Rails.logger
|
14
|
+
def initialize token:, broker_account_id: nil, logger: nil
|
15
|
+
super(
|
16
|
+
token: token,
|
17
|
+
broker_account_id: broker_account_id,
|
18
|
+
logger: logger
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# ==========================================
|
23
|
+
# Операции с заявками
|
24
|
+
# ==========================================
|
25
|
+
|
26
|
+
# Получение списка активных заявок
|
27
|
+
def orders
|
28
|
+
get_api_request '/orders'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Создание лимитной заявки
|
32
|
+
# Пример figi: 'BBG000B9XRY4'
|
33
|
+
# Пример operation: :buy, :sell
|
34
|
+
def orders_limit_order figi:, operation:, lots:, price:
|
35
|
+
post_api_request(
|
36
|
+
'/orders/limit-order',
|
37
|
+
body: {
|
38
|
+
lots: lots,
|
39
|
+
operation: operation.to_s.capitalize,
|
40
|
+
price: price
|
41
|
+
},
|
42
|
+
query: { figi: figi }
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Создание рыночной заявки
|
47
|
+
# Пример figi: 'BBG000B9XRY4'
|
48
|
+
# Пример operation: :buy, :sell
|
49
|
+
def orders_market_order figi:, operation:, lots:
|
50
|
+
post_api_request(
|
51
|
+
'/orders/market-order',
|
52
|
+
body: {
|
53
|
+
lots: lots,
|
54
|
+
operation: operation.to_s.capitalize
|
55
|
+
},
|
56
|
+
query: { figi: figi }
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Отмена заявки
|
61
|
+
def orders_cancel id
|
62
|
+
post_api_request '/orders/cancel', query: { orderId: id }
|
63
|
+
end
|
64
|
+
|
65
|
+
# ==========================================
|
66
|
+
# Операции с портфелем пользователя
|
67
|
+
# ==========================================
|
68
|
+
|
69
|
+
# Получение портфеля клиента
|
70
|
+
def portfolio
|
71
|
+
get_api_request '/portfolio'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Получение валютных активов клиента
|
75
|
+
def portfolio_currencies
|
76
|
+
get_api_request '/portfolio/currencies'
|
77
|
+
end
|
78
|
+
|
79
|
+
# ==========================================
|
80
|
+
# Получении информации по бумагам
|
81
|
+
# ==========================================
|
82
|
+
|
83
|
+
# Получение списка акций
|
84
|
+
def market_stocks
|
85
|
+
get_api_request '/market/stocks'
|
86
|
+
end
|
87
|
+
|
88
|
+
# Получение списка облигаций
|
89
|
+
def market_bonds
|
90
|
+
get_api_request '/market/bonds'
|
91
|
+
end
|
92
|
+
|
93
|
+
# Получение списка ETF
|
94
|
+
def market_etfs
|
95
|
+
get_api_request '/market/etfs'
|
96
|
+
end
|
97
|
+
|
98
|
+
# Получение списка валютных пар
|
99
|
+
def market_currencies
|
100
|
+
get_api_request '/market/currencies'
|
101
|
+
end
|
102
|
+
|
103
|
+
# Получение стакана по FIGI
|
104
|
+
# Пример figi: 'BBG000B9XRY4'
|
105
|
+
def market_orderbook figi:, depth: 20
|
106
|
+
get_api_request '/market/orderbook', { figi: figi, depth: depth }
|
107
|
+
end
|
108
|
+
|
109
|
+
# Получение исторических свечей по FIGI
|
110
|
+
# Пример figi: 'BBG000B9XRY4'
|
111
|
+
# Пример from: Time.zone.now.beginning_of_week
|
112
|
+
# Пример to: Time.zone.now
|
113
|
+
# Пример interval: :1min, :2min, :3min, :5min, :10min, :15min, :30min, :hour, :day, :week, :month
|
114
|
+
def market_candles figi:, from:, to:, interval:
|
115
|
+
raise ArgumentError, 'interval' unless CANDLES_INTERVALS.include? interval.to_s
|
116
|
+
|
117
|
+
get_api_request(
|
118
|
+
'/market/candles',
|
119
|
+
{
|
120
|
+
figi: figi,
|
121
|
+
from: from.strftime(TIME_FORMAT),
|
122
|
+
to: to.strftime(TIME_FORMAT),
|
123
|
+
interval: interval
|
124
|
+
}
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Получение инструмента по FIGI
|
129
|
+
# Пример figi: 'BBG000B9XRY4'
|
130
|
+
def market_search_by_figi figi
|
131
|
+
get_api_request '/market/search/by-figi', { figi: figi }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Получение инструмента по тикеру
|
135
|
+
# Пример tiker: 'AAPL'
|
136
|
+
def market_search_by_ticker ticker
|
137
|
+
get_api_request '/market/search/by-ticker', { ticker: ticker }
|
138
|
+
end
|
139
|
+
|
140
|
+
# ==========================================
|
141
|
+
# Получении информации по операциям
|
142
|
+
# ==========================================
|
143
|
+
|
144
|
+
# Получение списка операций
|
145
|
+
# Пример from: Time.zone.now.beginning_of_week
|
146
|
+
# Пример to: Time.zone.now
|
147
|
+
# Пример figi (опиционально): 'BBG000B9XRY4'
|
148
|
+
def operations from:, to:, figi: nil
|
149
|
+
query = {
|
150
|
+
from: from.strftime(TIME_FORMAT),
|
151
|
+
to: to.strftime(TIME_FORMAT)
|
152
|
+
}
|
153
|
+
query.merge! figi: figi if figi.present?
|
154
|
+
get_api_request '/operations', query
|
155
|
+
end
|
156
|
+
|
157
|
+
# ==========================================
|
158
|
+
# Получении информации по брокерским счетам
|
159
|
+
# ==========================================
|
160
|
+
|
161
|
+
# Получение брокерских счетов клиента
|
162
|
+
def user_accounts
|
163
|
+
get_api_request '/user/accounts'
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def parse_response response
|
169
|
+
InvestTinkoff::V1::Response.create response
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
InvestTinkoff::V1::Response = Struct.new(
|
4
|
+
:tracking_id,
|
5
|
+
:status,
|
6
|
+
:payload,
|
7
|
+
:http_code
|
8
|
+
)
|
9
|
+
|
10
|
+
class InvestTinkoff::V1::Response
|
11
|
+
def self.create response
|
12
|
+
attributes = response.parsed_response || {}
|
13
|
+
new(
|
14
|
+
attributes['trackingId'],
|
15
|
+
attributes['status'],
|
16
|
+
attributes['payload'],
|
17
|
+
response.code
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def success?
|
22
|
+
status == 'Ok'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class InvestTinkoff::V1::SandboxClient < InvestTinkoff::V1::Client
|
4
|
+
base_uri 'https://api-invest.tinkoff.ru/openapi/sandbox/'
|
5
|
+
|
6
|
+
attr_accessor :broker_account_id
|
7
|
+
|
8
|
+
# token - sandbox API token
|
9
|
+
# broker_account_id (опционально) - идентификатор счета
|
10
|
+
# logger (опиционально) - например: Rails.logger
|
11
|
+
def initialize token:, broker_account_id: nil, logger: nil
|
12
|
+
super(
|
13
|
+
token: token,
|
14
|
+
broker_account_id: broker_account_id,
|
15
|
+
logger: logger
|
16
|
+
)
|
17
|
+
@is_sandbox_created = false
|
18
|
+
end
|
19
|
+
|
20
|
+
# ==========================================
|
21
|
+
# Операции в sandbox
|
22
|
+
# ==========================================
|
23
|
+
|
24
|
+
# Создание счета и выставление баланса по валютным позициям
|
25
|
+
def register
|
26
|
+
return if @is_sandbox_created
|
27
|
+
|
28
|
+
res = post_api_request '/sandbox/register'
|
29
|
+
@is_sandbox_created = true
|
30
|
+
res
|
31
|
+
end
|
32
|
+
|
33
|
+
# Выставление баланса по валютным позициям
|
34
|
+
# Пример currency: :RUB, :USD, :EUR и т.д.
|
35
|
+
def currencies_balance currency:, balance:
|
36
|
+
register
|
37
|
+
body = { currency: currency, balance: balance }
|
38
|
+
post_api_request '/sandbox/currencies/balance', body: body
|
39
|
+
end
|
40
|
+
|
41
|
+
# Выставление баланса по инструментным позициям
|
42
|
+
# Пример figi: 'BBG000B9XRY4'
|
43
|
+
def position_balance figi:, balance:
|
44
|
+
register
|
45
|
+
body = { figi: figi, balance: balance }
|
46
|
+
post_api_request '/sandbox/positions/balance', body: body
|
47
|
+
end
|
48
|
+
|
49
|
+
# Удаление всех позиций клиента
|
50
|
+
def clear
|
51
|
+
register
|
52
|
+
post_api_request '/sandbox/clear'
|
53
|
+
end
|
54
|
+
|
55
|
+
# Удаление счета клиента
|
56
|
+
def remove
|
57
|
+
register
|
58
|
+
post_api_request '/sandbox/remove'
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: invest_tinkoff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Kalinichev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-05-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.20.0
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.20'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.20.0
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.20'
|
33
|
+
description: Tinkoff Invest Ruby Rest API Gem
|
34
|
+
email: alexander.kalinichev@gmail.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- lib/invest_tinkoff/client_base.rb
|
40
|
+
- lib/invest_tinkoff/v1/client.rb
|
41
|
+
- lib/invest_tinkoff/v1/response.rb
|
42
|
+
- lib/invest_tinkoff/v1/sandbox_client.rb
|
43
|
+
- lib/invest_tinkoff/version.rb
|
44
|
+
homepage: https://github.com/blackchestnut/invest_tinkoff
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.3.0
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.0.3
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: invest_tinkoff
|
67
|
+
test_files: []
|