vexapion 0.3.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/vexapion/base_exchanges.rb +66 -0
- data/lib/vexapion/bitflyer.rb +353 -0
- data/lib/vexapion/coincheck.rb +482 -0
- data/lib/vexapion/connect/http_client.rb +167 -0
- data/lib/vexapion/errors/http_errors.rb +74 -0
- data/lib/vexapion/errors/vexapion_errors.rb +31 -0
- data/lib/vexapion/poloniex.rb +173 -0
- data/lib/vexapion/version.rb +3 -0
- data/lib/vexapion/zaif.rb +257 -0
- data/lib/vexapion.rb +19 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13b088be62d4de49b5f471088077d2c0142e0fa8
|
4
|
+
data.tar.gz: 130e8e80c10272e6ff2a48c18c84f3a4516e7211
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3433e525af5857b92594d294fdb6e44c7dcd134f44ffaa718dddf6be58bfe0d16e22bfa9a2705d052c0344e66bac6e291cf2283e1aaff82902412739b6dbaf06
|
7
|
+
data.tar.gz: a42752f44c429d38b3bcf3428132f41cff7d7673c6096ad0dc602ce475c0b65b78410e4595446b948027b566512b9609978a4035d050d457d696bc2cfb2d0c8f
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Vexapion
|
4
|
+
|
5
|
+
# Virtual (crypto) Currency Exchanges API wrapper class
|
6
|
+
|
7
|
+
class BaseExchanges
|
8
|
+
|
9
|
+
def initialize(key = nil, secret = nil)
|
10
|
+
@key = key
|
11
|
+
@secret = secret
|
12
|
+
@conn = HTTPClient.new
|
13
|
+
base_time = Time.gm(2017, 1, 1, 0, 0, 0).to_i
|
14
|
+
@nonce = (Time.now.to_i - base_time) * 100 #max 100req/s
|
15
|
+
@verify_mode = nil
|
16
|
+
set_min_interval(0.5)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_min_interval(sec)
|
20
|
+
@conn.min_interval = sec
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_verify_mode(mode)
|
24
|
+
@verify_mode = mode
|
25
|
+
end
|
26
|
+
|
27
|
+
def do_command(uri, request)
|
28
|
+
response = nil
|
29
|
+
begin
|
30
|
+
response = @conn.http_request(uri, request, @verify_mode)
|
31
|
+
rescue VexapionRuntimeError => e
|
32
|
+
raise e
|
33
|
+
rescue HTTPError => e
|
34
|
+
raise e
|
35
|
+
end
|
36
|
+
|
37
|
+
response == '' ? '' : JSON.parse(response)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_nonce
|
41
|
+
@nonce += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
def error_check(res)
|
45
|
+
if res != nil && res != '' && res.kind_of?(Hash)
|
46
|
+
|
47
|
+
if res['success'] == 0 || res['success'] == 'false'
|
48
|
+
#polo
|
49
|
+
fail RequestFailed.new(
|
50
|
+
false, false, res)
|
51
|
+
elsif res.has_key?('error')
|
52
|
+
#zaif, polo
|
53
|
+
fail RequestFailed.new(
|
54
|
+
false, res['error'], res)
|
55
|
+
elsif res.has_key?('error_message')
|
56
|
+
#bitflyer
|
57
|
+
fail RequestFailed.new(
|
58
|
+
false, "#{res['status']} #{res['error_message']}", res)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end #of class
|
65
|
+
|
66
|
+
end #of Vexapion module
|
@@ -0,0 +1,353 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'vexapion'
|
4
|
+
|
5
|
+
module Vexapion
|
6
|
+
|
7
|
+
# bitflyerのAPIラッパークラスです
|
8
|
+
# 各メソッドの戻り値は下記URLを参照してください
|
9
|
+
# @see https://lightning.bitflyer.jp/docs?lang=ja&_ga=1.264432847.170149243.1463313992
|
10
|
+
|
11
|
+
class Bitflyer < BaseExchanges
|
12
|
+
|
13
|
+
def initialize(key = nil, secret = nil)
|
14
|
+
super(key, secret)
|
15
|
+
|
16
|
+
@public_url = 'https://api.bitflyer.jp/v1/'
|
17
|
+
@private_url = 'https://api.bitflyer.jp/v1/me/'
|
18
|
+
|
19
|
+
set_min_interval(0.3)
|
20
|
+
|
21
|
+
@available_pair = ['BTC_JPY', 'FX_BTC_JPY', 'ETH_BTC']
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public API
|
25
|
+
#板情報
|
26
|
+
def board(pair)
|
27
|
+
public_get('board', product_code: pair.upcase)
|
28
|
+
end
|
29
|
+
alias get_board board
|
30
|
+
|
31
|
+
#Ticker
|
32
|
+
def ticker(pair)
|
33
|
+
public_get('ticker', product_code: pair.upcase)
|
34
|
+
end
|
35
|
+
alias get_ticker ticker
|
36
|
+
|
37
|
+
#約定履歴
|
38
|
+
def executions(pair, count='', before='', after='')
|
39
|
+
params = {
|
40
|
+
product_code: pair.upcase
|
41
|
+
}
|
42
|
+
params[:count] = count if count != ''
|
43
|
+
params[:before] = before if before != ''
|
44
|
+
params[:after] = after if after != ''
|
45
|
+
public_get('executions', params)
|
46
|
+
end
|
47
|
+
#get_executionsは個人の約定履歴の取得に使っているので混同しないこと
|
48
|
+
alias get_public_executions executions
|
49
|
+
|
50
|
+
#チャット
|
51
|
+
def get_chats(date)
|
52
|
+
public_get('getchats', from_date: date)
|
53
|
+
end
|
54
|
+
|
55
|
+
#取引所の状態
|
56
|
+
def get_health
|
57
|
+
public_get('gethealth')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Private API
|
61
|
+
#APIキーの権限を取得
|
62
|
+
def get_permissions
|
63
|
+
get('getpermissions')
|
64
|
+
end
|
65
|
+
|
66
|
+
#資産残高を取得
|
67
|
+
def get_balance
|
68
|
+
get('getbalance')
|
69
|
+
end
|
70
|
+
|
71
|
+
#証拠金の状態を取得
|
72
|
+
def get_collateral
|
73
|
+
get('getcollateral')
|
74
|
+
end
|
75
|
+
|
76
|
+
#預入用BTC/ETHアドレス取得
|
77
|
+
def get_addresses
|
78
|
+
get('getaddresses')
|
79
|
+
end
|
80
|
+
|
81
|
+
#BTC/ETH預入履歴
|
82
|
+
def get_coin_ins(count='', before='', after='')
|
83
|
+
params = Hash.new
|
84
|
+
params[:count] = count if count != ''
|
85
|
+
params[:before] = before if before != ''
|
86
|
+
params[:after] = after if after != ''
|
87
|
+
get('getcoinins', params)
|
88
|
+
end
|
89
|
+
|
90
|
+
#BTC/ETH外部送付
|
91
|
+
def sendcoin(currency, amount, address, fee='', code='')
|
92
|
+
params = {
|
93
|
+
currency_code: currency.upcase,
|
94
|
+
amount: amount.to_f,
|
95
|
+
address: address,
|
96
|
+
}
|
97
|
+
if fee != ''
|
98
|
+
fee = 0.0005 < fee.to_f ? 0.0005 : fee.to_f
|
99
|
+
params[:additional_fee] = fee
|
100
|
+
end
|
101
|
+
params[:code] = code.to_i if code != ''
|
102
|
+
|
103
|
+
post('sendcoin', params)
|
104
|
+
end
|
105
|
+
|
106
|
+
#BTC/ETH送付履歴
|
107
|
+
def get_coin_outs(count='', before='', after='')
|
108
|
+
params = Hash.new
|
109
|
+
#params[:message_id] = id if id != ''
|
110
|
+
params[:count] = count if count != ''
|
111
|
+
params[:before] = before if before != ''
|
112
|
+
params[:after] = after if after != ''
|
113
|
+
|
114
|
+
get('getcoinouts', params)
|
115
|
+
end
|
116
|
+
|
117
|
+
#BTC/ETH送付状況確認
|
118
|
+
# @params [String] message_id sendcoinAPIの戻り値を指定
|
119
|
+
# @return [hash]
|
120
|
+
def get_coin_outs_id(message_id)
|
121
|
+
params = { message_id: message_id }
|
122
|
+
|
123
|
+
get('getcoinouts', params)
|
124
|
+
end
|
125
|
+
|
126
|
+
#銀行口座一覧取得
|
127
|
+
def get_bank_accounts
|
128
|
+
get('getbankaccounts')
|
129
|
+
end
|
130
|
+
|
131
|
+
#デポジット入金履歴
|
132
|
+
def get_deposits(count='', before='', after='')
|
133
|
+
params = Hash.new
|
134
|
+
params[:count] = count if count != ''
|
135
|
+
params[:before] = before if before != ''
|
136
|
+
params[:after] = after if after != ''
|
137
|
+
|
138
|
+
get('getdeposits', params)
|
139
|
+
end
|
140
|
+
|
141
|
+
#デポジット解約(出金)
|
142
|
+
def withdraw(currency, id, amount, code='')
|
143
|
+
params = {
|
144
|
+
currency_code: currency.upcase,
|
145
|
+
bank_account_id: id,
|
146
|
+
amount: amount
|
147
|
+
}
|
148
|
+
params[:code] = code if code != ''
|
149
|
+
|
150
|
+
post('withdraw', params)
|
151
|
+
end
|
152
|
+
|
153
|
+
#デポジット解約履歴(出金)
|
154
|
+
def get_withdrawals(count='', before='', after='')
|
155
|
+
params = Hash.new
|
156
|
+
params[:count] = count if count != ''
|
157
|
+
params[:before] = before if before != ''
|
158
|
+
params[:after] = after if after != ''
|
159
|
+
|
160
|
+
get('getwithdrawals', params)
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
#新規注文を出す
|
165
|
+
def send_child_order(pair, type, side, price, size, expire='', force='')
|
166
|
+
params = {
|
167
|
+
product_code: pair.upcase,
|
168
|
+
child_order_type: type.upcase,
|
169
|
+
side: side.upcase,
|
170
|
+
price: price,
|
171
|
+
size: size.to_f
|
172
|
+
}
|
173
|
+
params[:minute_to_expire] = expire if expire != ''
|
174
|
+
params[:time_in_force] = force if force != ''
|
175
|
+
|
176
|
+
post('sendchildorder', params)
|
177
|
+
end
|
178
|
+
|
179
|
+
#child_order_idを指定して、注文をキャンセルする
|
180
|
+
def cancel_child_order(pair, order_id)
|
181
|
+
params = {
|
182
|
+
product_code: pair.upcase,
|
183
|
+
child_order_id: order_id
|
184
|
+
}
|
185
|
+
|
186
|
+
post('cancelchildorder', params)
|
187
|
+
end
|
188
|
+
|
189
|
+
#child_order_acceptance_idを指定して、注文をキャンセルする
|
190
|
+
def cancel_child_order_specify_acceptance_id(pair, acceptance_id)
|
191
|
+
params = {
|
192
|
+
product_code: pair.upcase,
|
193
|
+
child_order_acceptance_id: acceptance_id
|
194
|
+
}
|
195
|
+
|
196
|
+
post('cancelchildorder', params)
|
197
|
+
end
|
198
|
+
|
199
|
+
#新規の親注文を出す(特殊注文)
|
200
|
+
#https://lightning.bitflyer.jp/docs/specialorder を熟読して使用のこと
|
201
|
+
#とても自由度が高いため、ユーザーがパラメータを組み立ててそれを引数にする
|
202
|
+
#def send_parent_order(params)
|
203
|
+
# post('sendparentorder', params)
|
204
|
+
#end
|
205
|
+
|
206
|
+
#parent_order_idを指定して、親注文をキャンセルする
|
207
|
+
#def cancel_parent_order(pair, order_id)
|
208
|
+
# params = {
|
209
|
+
# product_code: pair.upcase,
|
210
|
+
# parent_order_id: order_id
|
211
|
+
# }
|
212
|
+
|
213
|
+
# post('cancelparentorder', params)
|
214
|
+
#end
|
215
|
+
|
216
|
+
#parent_order_acceptance_idを指定して、親注文をキャンセルする
|
217
|
+
#def cancel_parent_order_specify_acceptance_id(pair, acceptance_id)
|
218
|
+
# params = {
|
219
|
+
# product_code: pair.upcase,
|
220
|
+
# parent_order_acceptance_id: acceptance_id
|
221
|
+
# }
|
222
|
+
# post('cancelparentorder', params)
|
223
|
+
#end
|
224
|
+
|
225
|
+
#すべての注文をキャンセルする
|
226
|
+
def cancel_all_child_order(pair)
|
227
|
+
post('cancelallchildorders', product_code: pair.upcase)
|
228
|
+
end
|
229
|
+
|
230
|
+
#注文の一覧を取得
|
231
|
+
def get_child_orders(pair, state='', pid='', count='', before='', after='')
|
232
|
+
params = {
|
233
|
+
product_code: pair.upcase
|
234
|
+
}
|
235
|
+
params[:child_order_state] = state if state != ''
|
236
|
+
params[:parent_order_id] = pid if pid != ''
|
237
|
+
params[:count] = count if count != ''
|
238
|
+
params[:before] = before if before != ''
|
239
|
+
params[:after] = after if after != ''
|
240
|
+
|
241
|
+
get('getchildorders', params)
|
242
|
+
end
|
243
|
+
|
244
|
+
#親注文の一覧を取得
|
245
|
+
#def get_parent_orders(pair, state='', count='', before='', after='')
|
246
|
+
# params = {
|
247
|
+
# product_code: pair.upcase
|
248
|
+
# }
|
249
|
+
# params[:parent_order_state] = state if state != ''
|
250
|
+
# params[:count] = count if count != ''
|
251
|
+
# params[:before] = before if before != ''
|
252
|
+
# params[:after] = after if after != ''
|
253
|
+
|
254
|
+
# get('getparentorders', params)
|
255
|
+
#end
|
256
|
+
|
257
|
+
#parent_order_idを指定して、親注文の詳細を取得
|
258
|
+
#def get_parent_order(parent_order_id)
|
259
|
+
# get('getparentorder', parent_order_id: parent_order_id)
|
260
|
+
#end
|
261
|
+
|
262
|
+
#parent_order_acceptance_idを指定して、親注文の詳細を取得
|
263
|
+
#def get_parent_order_specify_acceptance_id(acceptance_id)
|
264
|
+
# get('getparentorder', parent_order_acceptance_id: acceptance_id)
|
265
|
+
#end
|
266
|
+
|
267
|
+
#約定の一覧を取得
|
268
|
+
def get_executions(pair, coid='', child_order_acceptance_id='',
|
269
|
+
count='', before='', after='')
|
270
|
+
params = {
|
271
|
+
product_code: pair.upcase
|
272
|
+
}
|
273
|
+
params['child_order_id'] = coid if coid != ''
|
274
|
+
if child_order_acceptance_id != ''
|
275
|
+
params['child_order_acceptance_id'] = child_order_acceptance_id
|
276
|
+
end
|
277
|
+
params[:count] = count if count != ''
|
278
|
+
params[:before] = before if before != ''
|
279
|
+
params[:after] = after if after != ''
|
280
|
+
|
281
|
+
get('getexecutions', params)
|
282
|
+
end
|
283
|
+
|
284
|
+
#建玉の一覧を取得
|
285
|
+
def get_positions(pair='FX_BTC_JPY')
|
286
|
+
get('getpositions', product_code: pair.upcase)
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
# Create request header & body
|
291
|
+
|
292
|
+
private
|
293
|
+
|
294
|
+
def public_get(command, query={})
|
295
|
+
uri = URI.parse "#{@public_url}#{command}"
|
296
|
+
uri.query = URI.encode_www_form(query)
|
297
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
298
|
+
request.set_form_data(query) #クエリをURLエンコード(p1=v1&p2=v2...)
|
299
|
+
|
300
|
+
do_command(uri, request)
|
301
|
+
end
|
302
|
+
|
303
|
+
def get(command, query={})
|
304
|
+
method = 'GET'
|
305
|
+
uri = URI.parse "#{@private_url}#{command}"
|
306
|
+
uri.query = URI.encode_www_form(query) if query != {}
|
307
|
+
timestamp = get_nonce.to_s
|
308
|
+
text = "#{timestamp}#{method}#{uri.request_uri}"
|
309
|
+
sign = signature(text)
|
310
|
+
header = {
|
311
|
+
'ACCESS-KEY' => @key,
|
312
|
+
'ACCESS-TIMESTAMP' => timestamp,
|
313
|
+
'ACCESS-SIGN' => sign
|
314
|
+
}
|
315
|
+
|
316
|
+
request = Net::HTTP::Get.new(uri.request_uri, initheader = header)
|
317
|
+
|
318
|
+
do_command(uri, request)
|
319
|
+
end
|
320
|
+
|
321
|
+
def post(command, params={})
|
322
|
+
method = 'POST'
|
323
|
+
uri = URI.parse "#{@private_url}#{command}"
|
324
|
+
timestamp = get_nonce.to_s
|
325
|
+
body = params.to_json #add
|
326
|
+
|
327
|
+
text = "#{timestamp}#{method}#{uri.request_uri}#{body}"
|
328
|
+
sign = signature(text)
|
329
|
+
header = headers(sign, timestamp)
|
330
|
+
request = Net::HTTP::Post.new(uri.request_uri, initheader = header)
|
331
|
+
request.body = body
|
332
|
+
|
333
|
+
res = do_command(uri, request)
|
334
|
+
error_check(res)
|
335
|
+
res
|
336
|
+
end
|
337
|
+
|
338
|
+
def signature(data)
|
339
|
+
algo = OpenSSL::Digest.new('sha256')
|
340
|
+
OpenSSL::HMAC.hexdigest(algo, @secret, data)
|
341
|
+
end
|
342
|
+
|
343
|
+
def headers(sign, timestamp)
|
344
|
+
headers = {
|
345
|
+
'ACCESS-KEY' => @key,
|
346
|
+
'ACCESS-TIMESTAMP' => timestamp,
|
347
|
+
'ACCESS-SIGN' => sign,
|
348
|
+
'Content-Type' => 'application/json'
|
349
|
+
}
|
350
|
+
end
|
351
|
+
|
352
|
+
end #of class
|
353
|
+
end #of module
|