bitget.rb 0.4.0 → 0.5.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.
@@ -1,500 +0,0 @@
1
- # Bitget/V2/Client.rb
2
- # Bitget::V2::Client
3
-
4
- require 'fileutils'
5
- gem 'http.rb'; require 'http.rb'
6
- require 'json'
7
- require 'logger'
8
- require 'openssl'
9
-
10
- require_relative '../Error'
11
- require_relative '../../Hash/to_parameter_string'
12
- require_relative '../../Hash/x_www_form_urlencode'
13
-
14
- module Bitget
15
- module V2
16
- class Client
17
-
18
- API_HOST = 'api.bitget.com'
19
-
20
- class << self
21
- attr_writer :log_file_path
22
-
23
- def path_prefix
24
- '/api/v2'
25
- end
26
-
27
- def default_log_file_path
28
- File.join(%w{~ log bitget log.txt})
29
- end
30
-
31
- def log_file_path
32
- File.expand_path(@log_file_path || default_log_file_path)
33
- end
34
-
35
- def log_file
36
- FileUtils.mkdir_p(File.dirname(log_file_path))
37
- File.open(log_file_path, File::WRONLY | File::APPEND | File::CREAT)
38
- end
39
-
40
- def logger
41
- @logger ||= Logger.new(log_file, 'daily')
42
- end
43
- end # class << self
44
-
45
- # Market
46
-
47
- def spot_public_coins(coin: nil)
48
- response = get(path: '/spot/public/coins', args: {coin: coin})
49
- handle_response(response)
50
- end
51
-
52
- def spot_public_symbols(symbol: nil)
53
- response = get(path: '/spot/public/symbols', args: {symbol: symbol})
54
- handle_response(response)
55
- end
56
-
57
- def spot_market_vip_free_rate
58
- response = get(path: '/spot/market/vip-fee-rate')
59
- handle_response(response)
60
- end
61
-
62
- def spot_market_tickers(symbol: nil)
63
- response = get(path: '/spot/market/tickers', args: {symbol: symbol})
64
- handle_response(response)
65
- end
66
-
67
- def spot_market_merge_depth(symbol:, precision: nil, limit: nil)
68
- response = get(path: '/spot/market/merge-depth', args: {symbol: symbol, precision: precision, limit: limit})
69
- handle_response(response)
70
- end
71
-
72
- def spot_market_orderbook(symbol:, type: nil, limit: nil)
73
- response = get(path: '/spot/market/orderbook', args: {symbol: symbol, type: type, limit: limit})
74
- handle_response(response)
75
- end
76
-
77
- def spot_market_candles(symbol:, granularity:, start_time: nil, end_time: nil, limit: nil)
78
- response = get(
79
- path: '/spot/market/candles',
80
- args: {symbol: symbol, granularity: granularity, startTime: start_time, endTime: end_time, limit: limit}
81
- )
82
- handle_response(response)
83
- end
84
-
85
- def spot_market_history_candles(symbol:, granularity:, end_time: nil, limit: nil)
86
- response = get(
87
- path: '/spot/market/history-candles',
88
- args: {symbol: symbol, granularity: granularity, endTime: end_time, limit: limit}
89
- )
90
- handle_response(response)
91
- end
92
-
93
- def spot_market_fills(symbol:, limit: nil)
94
- response = get(path: '/spot/market/fills', args: {symbol: symbol, limit: limit})
95
- handle_response(response)
96
- end
97
-
98
- def spot_market_fills_history(symbol:, limit: nil, id_less_than: nil, start_time: nil, end_time: nil)
99
- response = get(
100
- path: '/spot/market/fills-history',
101
- args: {symbol: symbol, limit: limit, idLessThan: id_less_than, startTime: start_time, endTime: end_time}
102
- )
103
- handle_response(response)
104
- end
105
-
106
- # Trade
107
-
108
- def trade_place_order(
109
- symbol:,
110
- side:,
111
- order_type:,
112
- force:,
113
- price: nil,
114
- size:,
115
- client_order_id: nil,
116
- trigger_price: nil,
117
- tpsl_type: nil,
118
- request_time: nil,
119
- receive_window: nil,
120
- stp_mode: nil,
121
- preset_take_profit_price: nil,
122
- execute_take_profit_price: nil,
123
- preset_stop_loss_price: nil,
124
- execute_stop_loss_price: nil
125
- )
126
- response = post(
127
- path: '/trade/place-order',
128
- args: {
129
- symbol: symbol,
130
- side: side,
131
- orderType: order_type,
132
- force: force,
133
- price: price,
134
- size: size,
135
- client_order_id: clientOid,
136
- trigger_price: triggerPrice,
137
- tpsl_type: tpslType,
138
- request_time: requestTime,
139
- receive_window: receiveWindow,
140
- stp_mode: stpMode,
141
- preset_take_profit_price: presetTakeProfitPrice,
142
- execute_take_profit_price: executeTakeProfitPrice,
143
- preset_stop_loss_price: presetStopLossPrice,
144
- execute_stop_loss_price: executeStopLossPrice,
145
- }
146
- )
147
- handle_response(response)
148
- end
149
-
150
- def trade_cancel_replace_order(
151
- symbol:,
152
- price:,
153
- size:,
154
- client_order_id: nil,
155
- order_id: nil,
156
- new_client_order_id: nil,
157
- preset_take_profit_price: nil,
158
- execute_take_profit_price: nil,
159
- preset_stop_loss_price: nil,
160
- execute_stop_loss_price: nil
161
- )
162
- response = post(
163
- path: '/trade/cancel-replace-order',
164
- args: {
165
- symbol: symbol,
166
- price: price,
167
- size: size,
168
- client_order_id: clientOid,
169
- order_id: orderId,
170
- newClientOid: new_client_order_id,
171
- preset_take_profit_price: presetTakeProfitPrice,
172
- execute_take_profit_price: executeTakeProfitPrice,
173
- preset_stop_loss_price: presetStopLossPrice,
174
- execute_stop_loss_price: executeStopLossPrice,
175
- }
176
- )
177
- handle_response(response)
178
- end
179
-
180
- # I got lazy... (with specifying the args)
181
-
182
- def trade_batch_cancel_replace_order(**args)
183
- response = post(path: '/trade/batch-cancel-replace-order', args: args)
184
- handle_response(response)
185
- end
186
-
187
- def trade_cancel_order(**args)
188
- response = post(path: '/trade/cancel-order', args: args)
189
- handle_response(response)
190
- end
191
-
192
- def trade_batch_orders(**args)
193
- response = post(path: '/trade/batch-orders', args: args)
194
- handle_response(response)
195
- end
196
-
197
- def trade_batch_cancel_order
198
- response = post(path: '/trade/batch-cancel-order', args: args)
199
- handle_response(response)
200
- end
201
-
202
- def trade_cancel_symbol_order(symbol:)
203
- response = post(path: '/trade/cancel-symbol-order', args: {symbol: symbol})
204
- handle_response(response)
205
- end
206
-
207
- def trade_order_info(**args)
208
- response = get(path: '/trade/orderInfo', args: args)
209
- handle_response(response)
210
- end
211
-
212
- def trade_unfilled_orders(**args)
213
- response = get(path: '/trade/unfilled-orders', args: args)
214
- handle_response(response)
215
- end
216
-
217
- def trade_history_orders(**args)
218
- response = get(path: '/trade/history-orders', args: args)
219
- handle_response(response)
220
- end
221
-
222
- def trade_fills(**args)
223
- response = get(path: '/trade/fills', args: args)
224
- handle_response(response)
225
- end
226
-
227
- # Trigger
228
-
229
- # Place Plan Order
230
- # POST /api/v2/spot/trade/place-plan-order
231
-
232
- # Modify Plan Order
233
- # POST /api/v2/spot/trade/modify-plan-order
234
-
235
- # Cancel Plan Order
236
- # POST /api/v2/spot/trade/cancel-plan-order
237
-
238
- # Get Current Plan Orders
239
- # GET /api/v2/spot/trade/current-plan-order
240
-
241
- # Get Plan Sub Order
242
- # GET /api/v2/spot/trade/plan-sub-order
243
-
244
- # Get History Plan Orders
245
- # GET /api/v2/spot/trade/history-plan-order
246
-
247
- # Cancel Plan Orders in Batch
248
- # POST /api/v2/spot/trade/batch-cancel-plan-order
249
-
250
- # Account
251
-
252
- # Get Account Information
253
- # GET /api/v2/spot/account/info
254
- def spot_account_info
255
- response = get(path: '/spot/account/info')
256
- handle_response(response)
257
- end
258
-
259
- # Get Account Assets
260
- # GET /api/v2/spot/account/assets
261
- def spot_account_assets(**args)
262
- response = get(path: '/spot/account/assets', args: args)
263
- handle_response(response)
264
- end
265
-
266
- # Get Sub-accounts Assets
267
- # GET /api/v2/spot/account/subaccount-assets
268
- def spot_account_subaccount_assets(**args)
269
- response = get(path: '/spot/account/subaccount-assets', args: args)
270
- handle_response(response)
271
- end
272
-
273
- # Modify Deposit Account
274
- # POST /api/v2/spot/wallet/modify-deposit-account
275
- def spot_wallet_modify_deposit_account(**args)
276
- response = post(path: '/spot/wallet/modify-deposit-account', args: args)
277
- handle_response(response)
278
- end
279
-
280
- # Get Account Bills
281
- # GET /api/v2/spot/account/bills
282
- def spot_account_bills(**args)
283
- response = get(path: '/spot/account/bills', args: args)
284
- handle_response(response)
285
- end
286
-
287
- # Transfer
288
- # POST /api/v2/spot/wallet/transfer
289
- def spot_wallet_transfer(**args)
290
- response = post(path: '/spot/wallet/transfer', args: args)
291
- handle_response(response)
292
- end
293
-
294
- # GET Transferable Coin List
295
- # GET /api/v2/spot/wallet/transfer-coin-info
296
- def spot_wallet_transfer_coin_info(**args)
297
- response = get(path: '/spot/wallet/transfer-coin-info', args: args)
298
- handle_response(response)
299
- end
300
-
301
- # Sub Transfer
302
- # POST /api/v2/spot/wallet/subaccount-transfer
303
- def spot_wallet_subaccount_transer(**args)
304
- response = post(path: '/spot/wallet/subaccount-transfer', args: args)
305
- handle_response(response)
306
- end
307
-
308
- # Withdraw
309
- # POST /api/v2/spot/wallet/withdrawal
310
- def spot_wallet_withdrawal(**args)
311
- response = post(path: '/spot/wallet/withdrawal', args: args)
312
- handle_response(response)
313
- end
314
-
315
- # Get MainSub Transfer Record
316
- # GET /api/v2/spot/account/sub-main-trans-record
317
- def spot_account_sub_main_trans_record(**args)
318
- response = get(path: '/spot/account/sub-main-trans-record', args: args)
319
- handle_response(response)
320
- end
321
-
322
- # Get Transfer Record
323
- # GET /api/v2/spot/account/transferRecords
324
- def spot_account_transfer_records(**args)
325
- response = get(path: '/spot/account/transferRecords', args: args)
326
- handle_response(response)
327
- end
328
-
329
- # Switch BGB Deduct
330
- # POST /api/v2/spot/account/switch-deduct
331
- def spot_account_switch_deduct(deduct:)
332
- response = post(path: '/spot/account/switch-deduct', args: {deduct: deduct})
333
- handle_response(response)
334
- end
335
-
336
- # Get Deposit Address
337
- # GET /api/v2/spot/wallet/deposit-address
338
- def spot_wallet_deposit_address(**args)
339
- response = get(path: '/spot/wallet/deposit-address', args: args)
340
- handle_response(response)
341
- end
342
-
343
- # Get SubAccount Deposit Address
344
- # GET /api/v2/spot/wallet/subaccount-deposit-address
345
- def spot_wallet_subaccount_deposit_address(**args)
346
- response = get(path: '/spot/wallet/subaccount-deposit-address', args: args)
347
- handle_response(response)
348
- end
349
-
350
- # Get BGB Deduct Info
351
- # GET /api/v2/spot/account/deduct-info
352
- def spot_account_deduct_info
353
- response = get(path: '/spot/account/deduct-info')
354
- handle_response(response)
355
- end
356
-
357
- # Cancel Withdrawal
358
- # POST /api/v2/spot/wallet/cancel-withdrawal
359
- def spot_wallet_cancel_withdrawal(order_id:)
360
- response = post(path: '/spot/wallet/cancel-withdrawal', args: {order_id: order_id})
361
- handle_response(response)
362
- end
363
-
364
- # Get SubAccount Deposit Records
365
- # GET /api/v2/spot/wallet/subaccount-deposit-records
366
- def spot_wallet_subaccount_deposit_records(**args)
367
- response = get(path: '/spot/wallet/subaccount-deposit-records', args: args)
368
- handle_response(response)
369
- end
370
-
371
- # Get Withdrawal Records
372
- # GET /api/v2/spot/wallet/withdrawal-records
373
- def spot_wallet_withdrawal_records(**args)
374
- response = get(path: '/spot/wallet/withdrawal-records', args: args)
375
- handle_response(response)
376
- end
377
-
378
- # Get Deposit Records
379
- # GET /api/v2/spot/wallet/deposit-records
380
- def spot_wallet_deposit_records(**args)
381
- response = get(path: '/spot/wallet/deposit-records', args: args)
382
- handle_response(response)
383
- end
384
-
385
- private
386
-
387
- def initialize(api_key:, api_secret:, api_passphrase:)
388
- @api_key = api_key
389
- @api_secret = api_secret
390
- @api_passphrase = api_passphrase
391
- end
392
-
393
- def initialize(api_key:, api_secret:, api_passphrase:)
394
- @api_key = api_key.encode('UTF-8')
395
- @api_secret = api_secret.encode('UTF-8')
396
- @api_passphrase = api_passphrase.encode('UTF-8')
397
- end
398
-
399
- def full_path(path)
400
- self.class.path_prefix + path
401
- end
402
-
403
- def encoded_payload(args)
404
- args.reject!{|k,v| v.nil?}
405
- OpenSSL::Digest::SHA512.hexdigest(JSON.dump(args))
406
- end
407
-
408
- def timestamp
409
- @timestamp ||= (Time.now.to_f * 1000).to_i.to_s
410
- end
411
-
412
- def message(verb:, path:, args:)
413
- case verb
414
- when 'GET'
415
- if args.empty?
416
- [timestamp, verb, full_path(path)].join
417
- else
418
- query_string = args.to_parameter_string
419
- [timestamp, verb, full_path(path), '?', query_string].join
420
- end
421
- when 'POST'
422
- body = args.to_json
423
- [timestamp, verb, full_path(path), body].join
424
- end
425
- end
426
-
427
- def signature(message)
428
- digest = OpenSSL::Digest.new('SHA256')
429
- hmac = OpenSSL::HMAC.digest(digest, @api_secret, message)
430
- Base64.strict_encode64(hmac)
431
- end
432
-
433
- def request_string(path)
434
- "https://#{API_HOST}#{self.class.path_prefix}#{path}"
435
- end
436
-
437
- def headers(signature)
438
- {
439
- 'ACCESS-KEY' => @api_key,
440
- 'ACCESS-SIGN' => signature,
441
- 'ACCESS-TIMESTAMP' => timestamp,
442
- 'ACCESS-PASSPHRASE' => @api_passphrase,
443
- 'Content-Type' => 'application/json',
444
- 'X-CHANNEL-API-CODE' => 'spot',
445
- }
446
- end
447
-
448
- def log_args?(args)
449
- !args.values.all?(&:nil?)
450
- end
451
-
452
- def log_request(verb:, request_string:, args:)
453
- log_string = "#{verb} #{request_string}"
454
- if log_args?(args)
455
- log_string << "?#{args.x_www_form_urlencode}"
456
- end
457
- self.class.logger.info(log_string)
458
- end
459
-
460
- def log_error(code:, message:, body:)
461
- log_string = "#{code}\n#{message}\n#{body}"
462
- self.class.logger.error(log_string)
463
- end
464
-
465
- def do_request(verb:, path:, args: {})
466
- log_request(verb: verb, request_string: request_string(path), args: args)
467
- message = message(verb: verb, path: path, args: args)
468
- signature = signature(message)
469
- headers = headers(signature)
470
- @timestamp = nil
471
- HTTP.send(verb.to_s.downcase, request_string(path), args, headers)
472
- end
473
-
474
- def get(path:, args: {})
475
- do_request(verb: 'GET', path: path, args: args)
476
- end
477
-
478
- def post(path:, args: {})
479
- do_request(verb: 'POST', path: path, args: args)
480
- end
481
-
482
- def handle_response(response)
483
- if response.success?
484
- JSON.parse(response.body)
485
- else
486
- log_error(
487
- code: response.code,
488
- message: response.message,
489
- body: response.body
490
- )
491
- raise Bitget::Error.new(
492
- code: response.code,
493
- message: response.message,
494
- body: response.body
495
- )
496
- end
497
- end
498
- end
499
- end
500
- end
@@ -1,26 +0,0 @@
1
- # Hash#to_parameter_string
2
-
3
- # 20120610
4
- # 1.0.2
5
-
6
- # Changes since 0:
7
- # 1. I changed it from a class method to an instance method and hence removed references to any arguments and substituted self for those arguments.
8
- # 0/1
9
- # 2. I forget about needing String#url_encode, which for now I'll paste in here.
10
- # 1/2
11
- # 3. - String#url_encode.
12
- # 4. + require 'String/url_encode'.
13
-
14
- require 'String/url_encode'
15
-
16
- class Hash
17
-
18
- def to_parameter_string
19
- parameters_string_parts = []
20
- self.each do |k,v|
21
- parameters_string_parts << (k.to_s + '=' + v.url_encode) unless v.nil?
22
- end
23
- parameters_string_parts.join('&')
24
- end
25
-
26
- end