poloniex.rb 0.0.0 → 0.1.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 +4 -4
- data/Gemfile +7 -8
- data/README.md +150 -5
- data/lib/Hash/x_www_form_urlencode.rb +7 -0
- data/lib/Object/inQ.rb +18 -0
- data/lib/Poloniex/V1/Client.rb +571 -86
- data/lib/Poloniex/V1.rb +14 -0
- data/lib/Poloniex/VERSION.rb +1 -1
- data/lib/Thoran/Hash/XWwwFormUrlencode/x_www_form_urlencode.rb +26 -0
- data/lib/Thoran/String/UrlEncode/url_encode.rb +26 -0
- data/lib/poloniex.rb +4 -3
- data/poloniex.rb.gemspec +1 -1
- data/test/Poloniex/Configuration_test.rb +70 -9
- data/test/Poloniex/V1/Client/test_account_endpoints.rb +69 -0
- data/test/Poloniex/V1/Client/test_margin_endpoints.rb +57 -0
- data/test/Poloniex/V1/{Client_test.rb → Client/test_public_endpoints.rb} +22 -57
- data/test/Poloniex/V1/Client/test_trading_endpoints.rb +139 -0
- data/test/Poloniex/V1/Client/test_wallet_endpoints.rb +60 -0
- data/test/Poloniex/VERSION_test.rb +16 -0
- data/test/helper.rb +5 -6
- metadata +14 -7
- data/lib/Poloniex/Client.rb +0 -8
- data/test/Poloniex/Client_test.rb +0 -26
- data/test/poloniex_test.rb +0 -23
data/lib/Poloniex/V1/Client.rb
CHANGED
|
@@ -10,66 +10,137 @@ require 'openssl'
|
|
|
10
10
|
|
|
11
11
|
require_relative '../Configuration'
|
|
12
12
|
require_relative '../Error'
|
|
13
|
+
require_relative '../../Hash/x_www_form_urlencode'
|
|
14
|
+
require_relative '../../Object/inQ'
|
|
13
15
|
|
|
14
16
|
module Poloniex
|
|
15
17
|
module V1
|
|
16
18
|
class Client
|
|
17
19
|
|
|
20
|
+
ALLOWABLE_VERBS = %w{GET POST PUT DELETE}
|
|
18
21
|
API_HOST = 'api.poloniex.com'
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
class << self
|
|
24
|
+
def path_prefix
|
|
25
|
+
''
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Public endpoints
|
|
30
|
+
|
|
31
|
+
## Reference Data
|
|
32
|
+
|
|
33
|
+
### Symbol Information
|
|
34
|
+
### GET https://api.poloniex.com/markets
|
|
35
|
+
### GET https://api.poloniex.com/markets/{symbol}
|
|
36
|
+
### https://api-docs.poloniex.com/spot/api/public/reference-data#symbol-information
|
|
37
|
+
def markets(symbol = nil)
|
|
38
|
+
path = "/markets"
|
|
39
|
+
path += "/#{symbol}"if symbol
|
|
40
|
+
response = get(path: path)
|
|
24
41
|
handle_response(response)
|
|
25
42
|
end
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
### Currency Information
|
|
45
|
+
### GET https://api.poloniex.com/currencies
|
|
46
|
+
### GET https://api.poloniex.com/currencies/{currency}
|
|
47
|
+
### https://api-docs.poloniex.com/spot/api/public/reference-data#currency-information
|
|
48
|
+
def currencies(currency = nil, include_multichain_currencies: nil)
|
|
49
|
+
args = {}
|
|
50
|
+
args.merge!(includeMultiChainCurrencies: include_multichain_currencies) if include_multichain_currencies
|
|
51
|
+
path = '/currencies'
|
|
30
52
|
path += "/#{currency}" if currency
|
|
53
|
+
response = get(path: path, args: args)
|
|
54
|
+
handle_response(response)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
### System Timestamp
|
|
58
|
+
### GET https://api.poloniex.com/timestamp
|
|
59
|
+
### GET https://api.poloniex.com/timestamp
|
|
60
|
+
### https://api-docs.poloniex.com/spot/api/public/reference-data#system-timestamp
|
|
61
|
+
def timestamp
|
|
62
|
+
response = get(path: '/timestamp')
|
|
63
|
+
handle_response(response)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
## Market Data
|
|
67
|
+
|
|
68
|
+
### Prices
|
|
69
|
+
### GET https://api.poloniex.com/markets/price
|
|
70
|
+
### GET https://api.poloniex.com/markets/{symbol}/price
|
|
71
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#prices
|
|
72
|
+
def price(symbol = nil)
|
|
73
|
+
path = '/markets/price'
|
|
74
|
+
path = "/markets/#{symbol}/price" if symbol
|
|
31
75
|
response = get(path: path)
|
|
32
76
|
handle_response(response)
|
|
33
77
|
end
|
|
34
78
|
|
|
35
|
-
|
|
36
|
-
|
|
79
|
+
### Mark Price
|
|
80
|
+
### GET https://api.poloniex.com/markets/markPrice
|
|
81
|
+
### GET https://api.poloniex.com/markets/{symbol}/markPrice
|
|
82
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#mark-price
|
|
83
|
+
def mark_price(symbol = nil)
|
|
37
84
|
path = '/markets/markPrice'
|
|
38
85
|
path = "/markets/#{symbol}/markPrice" if symbol
|
|
39
86
|
response = get(path: path)
|
|
40
87
|
handle_response(response)
|
|
41
88
|
end
|
|
42
89
|
|
|
43
|
-
|
|
90
|
+
### Mark Price Components
|
|
91
|
+
### GET https://api.poloniex.com/markets/{symbol}/markPriceComponents
|
|
92
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#mark-price-components
|
|
44
93
|
def mark_price_components(symbol)
|
|
45
94
|
response = get(path: "/markets/#{symbol}/markPriceComponents")
|
|
46
95
|
handle_response(response)
|
|
47
96
|
end
|
|
48
97
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
response = get(
|
|
98
|
+
### Order Book
|
|
99
|
+
### GET https://api.poloniex.com/markets/{symbol}/orderBook
|
|
100
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#order-book
|
|
101
|
+
def order_book(symbol, scale: nil, limit: nil)
|
|
102
|
+
response = get(
|
|
103
|
+
path: "/markets/#{symbol}/orderBook",
|
|
104
|
+
args: {
|
|
105
|
+
scale: scale,
|
|
106
|
+
limit: limit
|
|
107
|
+
}
|
|
108
|
+
)
|
|
54
109
|
handle_response(response)
|
|
55
110
|
end
|
|
56
111
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
112
|
+
### Candles
|
|
113
|
+
### GET https://api.poloniex.com/markets/{symbol}/candles
|
|
114
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#candles
|
|
115
|
+
### interval: The unit of time by which to aggregate data. Valid values are: MINUTE_1, MINUTE_5, MINUTE_10, MINUTE_15, MINUTE_30, HOUR_1, HOUR_2, HOUR_4, HOUR_6, HOUR_12, DAY_1, DAY_3, WEEK_1 and MONTH_1.
|
|
116
|
+
def candles(symbol, interval: 'DAY_1', start_time: nil, end_time: nil, limit: nil)
|
|
117
|
+
response = get(
|
|
118
|
+
path: "/markets/#{symbol}/candles",
|
|
119
|
+
args: {
|
|
120
|
+
interval: interval,
|
|
121
|
+
startTime: start_time,
|
|
122
|
+
endTime: end_time,
|
|
123
|
+
limit: limit
|
|
124
|
+
}
|
|
125
|
+
)
|
|
61
126
|
handle_response(response)
|
|
62
127
|
end
|
|
63
128
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
response = get(
|
|
129
|
+
### Trades
|
|
130
|
+
### GET https://api.poloniex.com/markets/{symbol}/trades
|
|
131
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#trades
|
|
132
|
+
def trades(symbol, limit: nil)
|
|
133
|
+
response = get(
|
|
134
|
+
path: "/markets/#{symbol}/trades",
|
|
135
|
+
args: {limit: limit}
|
|
136
|
+
)
|
|
69
137
|
handle_response(response)
|
|
70
138
|
end
|
|
71
139
|
|
|
72
|
-
|
|
140
|
+
### Ticker
|
|
141
|
+
### GET https://api.poloniex.com/markets/ticker24h
|
|
142
|
+
### GET https://api.poloniex.com/markets/{symbol}/ticker24h
|
|
143
|
+
### https://api-docs.poloniex.com/spot/api/public/market-data#ticker
|
|
73
144
|
def ticker_24h(symbol = nil)
|
|
74
145
|
path = '/markets/ticker24h'
|
|
75
146
|
path = "/markets/#{symbol}/ticker24h" if symbol
|
|
@@ -77,16 +148,369 @@ module Poloniex
|
|
|
77
148
|
handle_response(response)
|
|
78
149
|
end
|
|
79
150
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
151
|
+
## Margin
|
|
152
|
+
|
|
153
|
+
### Collateral Info
|
|
154
|
+
### GET https://api.poloniex.com/markets/collateralInfo
|
|
155
|
+
### GET https://api.poloniex.com/markets/{currency}/collateralInfo
|
|
156
|
+
### https://api-docs.poloniex.com/spot/api/public/margin#collateral-info
|
|
157
|
+
def collateral_info(currency = nil)
|
|
158
|
+
path = '/markets/collateralInfo'
|
|
159
|
+
path = "/markets/#{currency}/collateralInfo" if currency
|
|
160
|
+
response = get(path: path)
|
|
83
161
|
handle_response(response)
|
|
84
162
|
end
|
|
85
163
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
164
|
+
### Borrow Rates Info
|
|
165
|
+
### GET https://api.poloniex.com/markets/borrowRatesInfo
|
|
166
|
+
### https://api-docs.poloniex.com/spot/api/public/margin#borrow-rates-info
|
|
167
|
+
def borrow_rates_info
|
|
168
|
+
response = get(path: '/markets/borrowRatesInfo')
|
|
169
|
+
handle_response(response)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Authenticated endpoints
|
|
173
|
+
|
|
174
|
+
## Account
|
|
175
|
+
|
|
176
|
+
### Account Information
|
|
177
|
+
### GET https://api.poloniex.com/accounts
|
|
178
|
+
### https://api-docs.poloniex.com/spot/api/private/account#account-activity
|
|
179
|
+
def accounts
|
|
180
|
+
response = get(path: '/accounts')
|
|
181
|
+
handle_response(response)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
### All Account Balances
|
|
185
|
+
### GET https://api.poloniex.com/accounts/balances
|
|
186
|
+
### GET https://api.poloniex.com/accounts/{id}/balances
|
|
187
|
+
### https://api-docs.poloniex.com/spot/api/private/account#account-activity
|
|
188
|
+
def accounts_balances(account_id: nil, account_type: nil)
|
|
189
|
+
path = '/accounts/balances'
|
|
190
|
+
path = "/accounts/#{account_id}/balances" if account_id
|
|
191
|
+
response = get(path: path, args: {accountType: account_type})
|
|
192
|
+
handle_response(response)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
### Account Activity
|
|
196
|
+
### GET https://api.poloniex.com/accounts/activity
|
|
197
|
+
### https://api-docs.poloniex.com/spot/api/private/account#account-activity
|
|
198
|
+
def accounts_activity(start_time: nil, end_time: nil, acivity_type: nil, limit: nil, from: nil, direction: nil, currency: nil)
|
|
199
|
+
response = get(
|
|
200
|
+
path: '/accounts/activity',
|
|
201
|
+
args: {
|
|
202
|
+
startTime: start_time,
|
|
203
|
+
endTime: end_time,
|
|
204
|
+
acivityType: acivity_type,
|
|
205
|
+
limit: limit,
|
|
206
|
+
from: from,
|
|
207
|
+
direction: direction,
|
|
208
|
+
currency: currency
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
handle_response(response)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
### Accounts Transfer
|
|
215
|
+
### POST https://api.poloniex.com/accounts/transfer
|
|
216
|
+
### https://api-docs.poloniex.com/spot/api/private/account#accounts-transfer
|
|
217
|
+
def accounts_transfer(currency:, amount:, from_account:, to_account:)
|
|
218
|
+
response = post(
|
|
219
|
+
path: '/accounts/transfer',
|
|
220
|
+
args: {
|
|
221
|
+
currency: currency,
|
|
222
|
+
amount: amount,
|
|
223
|
+
fromAccount: from_account,
|
|
224
|
+
toAccount: to_account
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
handle_response(response)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
### Accounts Transfer Records
|
|
231
|
+
### GET https://api.poloniex.com/accounts/transfer
|
|
232
|
+
### GET https://api.poloniex.com/accounts/transfer/{id}
|
|
233
|
+
### https://api-docs.poloniex.com/spot/api/private/account#accounts-transfer-records
|
|
234
|
+
def accounts_transfer_records(transfer_id: nil, limit: nil, from: nil, direction: nil, currency: nil, start_time: nil, end_time: nil)
|
|
235
|
+
path = '/accounts/transfer'
|
|
236
|
+
path += "/#{transfer_id}" if transfer_id
|
|
237
|
+
response = get(
|
|
238
|
+
path: path,
|
|
239
|
+
args: {
|
|
240
|
+
limit: limit,
|
|
241
|
+
from: from,
|
|
242
|
+
direction: direction,
|
|
243
|
+
currency: currency,
|
|
244
|
+
startTime: start_time,
|
|
245
|
+
endTime: end_time
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
handle_response(response)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
### Fee Info
|
|
252
|
+
### GET https://api.poloniex.com/feeinfo
|
|
253
|
+
### https://api-docs.poloniex.com/spot/api/private/account#fee-info
|
|
254
|
+
### Should it be called accounts_fee_info?
|
|
255
|
+
def fee_info
|
|
256
|
+
response = get(path: '/feeinfo')
|
|
257
|
+
handle_response(response)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
### Interest History
|
|
261
|
+
### GET https://api.poloniex.com/accounts/interest/history
|
|
262
|
+
### https://api-docs.poloniex.com/spot/api/private/account#interest-history
|
|
263
|
+
def accounts_interest_history(limit: nil, from: nil, direction: nil, start_time: nil, end_time: nil)
|
|
264
|
+
response = get(
|
|
265
|
+
path: '/accounts/interest/history',
|
|
266
|
+
args: {
|
|
267
|
+
limit: limit,
|
|
268
|
+
from: from,
|
|
269
|
+
direction: direction,
|
|
270
|
+
startTime: start_time,
|
|
271
|
+
endTime: end_time
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
handle_response(response)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
## Wallet
|
|
278
|
+
|
|
279
|
+
### Deposit Addresses
|
|
280
|
+
### GET https://api.poloniex.com/wallets/addresses
|
|
281
|
+
### https://api-docs.poloniex.com/spot/api/private/wallet#deposit-addresses
|
|
282
|
+
def deposit_addresses(currency = nil)
|
|
283
|
+
response = get(path: '/wallets/addresses', args: {currency: currency})
|
|
284
|
+
handle_response(response)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
### Wallets Activity Records
|
|
288
|
+
### GET https://api.poloniex.com/wallets/activity
|
|
289
|
+
### https://api-docs.poloniex.com/spot/api/private/wallet#wallets-activity-records
|
|
290
|
+
def wallets_activity(start:, finish:, activity_type: nil)
|
|
291
|
+
response = get(
|
|
292
|
+
path: '/wallets/activity',
|
|
293
|
+
args: {
|
|
294
|
+
start: start,
|
|
295
|
+
end: finish,
|
|
296
|
+
activityType: activity_type
|
|
297
|
+
}
|
|
298
|
+
)
|
|
299
|
+
handle_response(response)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
### New Currency Address
|
|
303
|
+
### POST https://api.poloniex.com/wallets/address
|
|
304
|
+
### https://api-docs.poloniex.com/spot/api/private/wallet#new-currency-address
|
|
305
|
+
def new_currency_address(currency)
|
|
306
|
+
response = post(path: '/wallets/address', args: {currency: currency})
|
|
307
|
+
handle_response(response)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
### Withdraw Currency
|
|
311
|
+
### POST https://api.poloniex.com/wallets/withdraw
|
|
312
|
+
### https://api-docs.poloniex.com/spot/api/private/wallet#withdraw-currency
|
|
313
|
+
def withdraw_currency(currency:, amount:, address:, payment_id: nil, allow_borrow: nil)
|
|
314
|
+
response = post(
|
|
315
|
+
path: '/wallets/withdraw',
|
|
316
|
+
args: {
|
|
317
|
+
currency: currency,
|
|
318
|
+
amount: amount,
|
|
319
|
+
address: address,
|
|
320
|
+
paymentId: payment_id,
|
|
321
|
+
allowBorrow: allow_borrow
|
|
322
|
+
}
|
|
323
|
+
)
|
|
324
|
+
handle_response(response)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
## Margin
|
|
328
|
+
|
|
329
|
+
### Account Margin
|
|
330
|
+
### GET https://api.poloniex.com/margin/accountMargin
|
|
331
|
+
### https://api-docs.poloniex.com/spot/api/private/margin#account-margin
|
|
332
|
+
### account_type: Currently only SPOT is supported.
|
|
333
|
+
def account_margin(account_type: 'SPOT')
|
|
334
|
+
response = get(path: '/margin/accountMargin', args: {accountType: account_type})
|
|
335
|
+
handle_response(response)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
### Borrow Status
|
|
339
|
+
### GET https://api.poloniex.com/margin/borrowStatus
|
|
340
|
+
### https://api-docs.poloniex.com/spot/api/private/margin#borrow-status
|
|
341
|
+
def borrow_status(currency: nil)
|
|
342
|
+
response = get(path: '/margin/borrowStatus', args: {currency: currency})
|
|
343
|
+
handle_response(response)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
### Maximum Buy/Sell Amount
|
|
347
|
+
### GET https://api.poloniex.com/margin/maxSize
|
|
348
|
+
### https://api-docs.poloniex.com/spot/api/private/margin#maximum-buysell-amount
|
|
349
|
+
def max_buy_sell_amount(symbol)
|
|
350
|
+
response = get(path: '/margin/maxSize', args: {symbol: symbol})
|
|
351
|
+
handle_response(response)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
## Orders
|
|
355
|
+
|
|
356
|
+
### Create Order
|
|
357
|
+
### POST https://api.poloniex.com/orders
|
|
358
|
+
### https://api-docs.poloniex.com/spot/api/private/order#create-order
|
|
359
|
+
def create_order(
|
|
360
|
+
symbol:,
|
|
361
|
+
side:,
|
|
362
|
+
time_in_force: nil,
|
|
363
|
+
type: nil,
|
|
364
|
+
account_type: nil,
|
|
365
|
+
price: nil,
|
|
366
|
+
quantity: nil,
|
|
367
|
+
amount: nil,
|
|
368
|
+
client_order_id: nil,
|
|
369
|
+
allow_borrow: nil,
|
|
370
|
+
stp_mode: nil,
|
|
371
|
+
slippage_tolerance: nil
|
|
372
|
+
)
|
|
373
|
+
response = post(
|
|
374
|
+
path: '/orders',
|
|
375
|
+
args: {
|
|
376
|
+
symbol: symbol,
|
|
377
|
+
side: side,
|
|
378
|
+
timeInForce: time_in_force,
|
|
379
|
+
type: type,
|
|
380
|
+
accountType: account_type,
|
|
381
|
+
price: price,
|
|
382
|
+
quantity: quantity,
|
|
383
|
+
amount: amount,
|
|
384
|
+
clientOrderId: client_order_id,
|
|
385
|
+
allowBorrow: allow_borrow,
|
|
386
|
+
stpMode: stp_mode,
|
|
387
|
+
slippageTolerance: slippage_tolerance,
|
|
388
|
+
}
|
|
389
|
+
)
|
|
390
|
+
handle_response(response)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
### Create Multiple Orders
|
|
394
|
+
### POST https://api.poloniex.com/orders/batch
|
|
395
|
+
### https://api-docs.poloniex.com/spot/api/private/order#create-multiple-orders
|
|
396
|
+
def create_multiple_orders(orders)
|
|
397
|
+
response = post(path: '/orders/batch', args: orders)
|
|
398
|
+
handle_response(response)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
### Cancel Replace Order
|
|
402
|
+
### PUT https://api.poloniex.com/orders/{id}
|
|
403
|
+
### PUT https://api.poloniex.com/orders/cid:{clientOrderId}
|
|
404
|
+
### https://api-docs.poloniex.com/spot/api/private/order#cancel-replace-order
|
|
405
|
+
def cancel_replace_order(
|
|
406
|
+
order_id: nil,
|
|
407
|
+
client_order_id: false,
|
|
408
|
+
price: nil,
|
|
409
|
+
quantity: nil,
|
|
410
|
+
amount: nil,
|
|
411
|
+
type: nil,
|
|
412
|
+
time_in_force: nil,
|
|
413
|
+
allow_borrow: nil,
|
|
414
|
+
proceed_on_failure: nil,
|
|
415
|
+
slippage_tolerance: nil
|
|
416
|
+
)
|
|
417
|
+
path = "/orders/#{order_id}"
|
|
418
|
+
path = "/orders/cid:#{order_id}" if client_order_id
|
|
419
|
+
args = {
|
|
420
|
+
price: price,
|
|
421
|
+
quantity: quantity,
|
|
422
|
+
amount: amount,
|
|
423
|
+
type: type,
|
|
424
|
+
timeInForce: time_in_force,
|
|
425
|
+
allowBorrow: allow_borrow,
|
|
426
|
+
proceedOnFailure: proceed_on_failure,
|
|
427
|
+
slippageTolerance: slippage_tolerance,
|
|
428
|
+
}
|
|
429
|
+
args.merge!(clientOrderId: order_id) if client_order_id
|
|
430
|
+
response = put(path: path, args: args)
|
|
431
|
+
handle_response(response)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
### Open Orders
|
|
435
|
+
### GET https://api.poloniex.com/orders
|
|
436
|
+
### https://api-docs.poloniex.com/spot/api/private/order#open-orders
|
|
437
|
+
def open_orders(symbol: nil, side: nil, from: nil, direction: nil, limit: nil)
|
|
438
|
+
response = get(
|
|
439
|
+
path: '/orders',
|
|
440
|
+
args: {
|
|
441
|
+
symbol: symbol,
|
|
442
|
+
side: side,
|
|
443
|
+
from: from,
|
|
444
|
+
direction: direction,
|
|
445
|
+
limit: limit
|
|
446
|
+
}
|
|
447
|
+
)
|
|
448
|
+
handle_response(response)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
### Order Details
|
|
452
|
+
### GET https://api.poloniex.com/orders/{id}
|
|
453
|
+
### GET https://api.poloniex.com/orders/cid:{clientOrderId}
|
|
454
|
+
### https://api-docs.poloniex.com/spot/api/private/order#order-details
|
|
455
|
+
def order_details(order_id:, client_order_id: false)
|
|
456
|
+
path = "/orders/#{order_id}"
|
|
457
|
+
path = "/orders/cid:#{order_id}" if client_order_id
|
|
458
|
+
response = get(path: path, args: {id: order_id})
|
|
459
|
+
handle_response(response)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
### Cancel Order by Id
|
|
463
|
+
### DELETE https://api.poloniex.com/orders/{id}
|
|
464
|
+
### DELETE https://api.poloniex.com/orders/cid:{clientOrderId}
|
|
465
|
+
### https://api-docs.poloniex.com/spot/api/private/order#cancel-order-by-id
|
|
466
|
+
def cancel_order(order_id:, client_order_id: false)
|
|
467
|
+
path = "/orders/#{order_id}"
|
|
468
|
+
path = "/orders/cid:#{order_id}" if client_order_id
|
|
469
|
+
response = delete(path: path, args: {id: order_id})
|
|
470
|
+
handle_response(response)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
### Cancel Multiple Orders by Ids
|
|
474
|
+
### DELETE https://api.poloniex.com/orders/cancelByIds
|
|
475
|
+
### https://api-docs.poloniex.com/spot/api/private/order#cancel-multiple-orders-by-ids
|
|
476
|
+
def cancel_multiple_orders(order_ids: nil, client_order_ids: nil)
|
|
477
|
+
response = delete(
|
|
478
|
+
path: '/orders/cancelByIds',
|
|
479
|
+
args: {
|
|
480
|
+
orderIds: order_ids,
|
|
481
|
+
clientOrderIds: client_order_ids
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
handle_response(response)
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
### Cancel All Orders
|
|
488
|
+
### DELETE https://api.poloniex.com/orders
|
|
489
|
+
### https://api-docs.poloniex.com/spot/api/private/order#cancel-all-orders
|
|
490
|
+
def cancel_all_orders(symbols: nil, account_types: nil)
|
|
491
|
+
response = delete(
|
|
492
|
+
path: '/orders',
|
|
493
|
+
args: {
|
|
494
|
+
symbols: symbols,
|
|
495
|
+
accountTypes: account_types
|
|
496
|
+
}
|
|
497
|
+
)
|
|
498
|
+
handle_response(response)
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
### Kill Switch
|
|
502
|
+
### POST https://api.poloniex.com/orders/killSwitch
|
|
503
|
+
### https://api-docs.poloniex.com/spot/api/private/order#kill-switch
|
|
504
|
+
def kill_switch(timeout:)
|
|
505
|
+
response = post(path: '/orders/killSwitch', args: {timeout: timeout})
|
|
506
|
+
handle_response(response)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
### Kill Switch Status
|
|
510
|
+
### GET https://api.poloniex.com/orders/killSwitchStatus
|
|
511
|
+
### https://api-docs.poloniex.com/spot/api/private/order#kill-switch-status
|
|
512
|
+
def kill_switch_status
|
|
513
|
+
response = get(path: '/orders/killSwitchStatus')
|
|
90
514
|
handle_response(response)
|
|
91
515
|
end
|
|
92
516
|
|
|
@@ -101,58 +525,109 @@ module Poloniex
|
|
|
101
525
|
def initialize(api_key: nil, api_secret: nil, debug: nil, logger: nil, configuration: nil)
|
|
102
526
|
@api_key = api_key || configuration&.api_key || Poloniex.configuration.api_key
|
|
103
527
|
@api_secret = api_secret || configuration&.api_secret || Poloniex.configuration.api_secret
|
|
104
|
-
@debug = debug
|
|
528
|
+
@debug = !![debug, configuration&.debug, Poloniex.configuration.debug].compact.first
|
|
105
529
|
@logger = logger || configuration&.logger || Poloniex.configuration.logger
|
|
106
530
|
end
|
|
107
531
|
|
|
108
|
-
def
|
|
109
|
-
|
|
532
|
+
def get(path:, args: {})
|
|
533
|
+
do_request(verb: 'GET', path: path, args: args)
|
|
110
534
|
end
|
|
111
535
|
|
|
112
|
-
def
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
536
|
+
def post(path:, args: {})
|
|
537
|
+
do_request(verb: 'POST', path: path, args: args)
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def delete(path:, args: {})
|
|
541
|
+
do_request(verb: 'DELETE', path: path, args: args)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def put(path:, args: {})
|
|
545
|
+
do_request(verb: 'PUT', path: path, args: args)
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def do_request(verb:, path:, args: {})
|
|
549
|
+
verb = verb.to_s.upcase
|
|
550
|
+
raise ArgumentError, "Unsupported HTTP method: #{verb}" unless verb.in?(Poloniex::V1::Client::ALLOWABLE_VERBS)
|
|
551
|
+
request_string = request_string(path:)
|
|
552
|
+
args = args(verb: verb, path: path, supplied_args: args)
|
|
553
|
+
headers = headers(verb: verb, path: path, args: args)
|
|
554
|
+
log_request(verb: verb, request_string: request_string, args: args, headers: headers) if use_logging?
|
|
555
|
+
response =
|
|
556
|
+
if verb.in?(%w{POST PUT}) && args.is_a?(Hash) && (args.key?(:body) || args.key?('body'))
|
|
557
|
+
raw_body = args[:body] || args['body']
|
|
558
|
+
HTTP.send(verb.downcase, request_string, raw_body, headers)
|
|
117
559
|
else
|
|
118
|
-
|
|
119
|
-
[request_timestamp, verb, path, '?', query_string].join
|
|
560
|
+
HTTP.send(verb.downcase, request_string, args, headers)
|
|
120
561
|
end
|
|
562
|
+
@request_timestamp = nil
|
|
563
|
+
response
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def request_string(path:)
|
|
567
|
+
"https://#{Poloniex::V1::Client::API_HOST}#{self.class.path_prefix}#{path}"
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
def args(verb:, path:, supplied_args:)
|
|
571
|
+
return supplied_args if supplied_args.is_a?(Array) # create_multiple_orders() supplies an array.
|
|
572
|
+
args = supplied_args.reject{|_, v| v.nil?}.transform_keys(&:to_s).transform_values(&:to_s)
|
|
573
|
+
if verb.in?(%w{POST PUT})
|
|
574
|
+
return { body: '' } if args.empty?
|
|
575
|
+
return { body: request_body(args) }
|
|
576
|
+
end
|
|
577
|
+
if verb.in?(%w{GET DELETE}) && use_auth?(path)
|
|
578
|
+
args.merge!("signTimestamp" => request_timestamp.to_s)
|
|
121
579
|
end
|
|
580
|
+
args
|
|
122
581
|
end
|
|
123
582
|
|
|
124
|
-
def
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
583
|
+
def headers(verb:, path:, args:)
|
|
584
|
+
headers = {}
|
|
585
|
+
if use_auth?(path)
|
|
586
|
+
if verb.in?(%w{POST PUT})
|
|
587
|
+
if args.is_a?(Hash) && (args.key?(:body) || args.key?('body'))
|
|
588
|
+
body_str = args[:body] || args['body']
|
|
589
|
+
headers["Content-Type"] = "application/json; charset=UTF-8" unless body_str.to_s.empty?
|
|
590
|
+
else
|
|
591
|
+
headers["Content-Type"] = "application/json; charset=UTF-8"
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
headers.merge!(
|
|
595
|
+
'key' => @api_key,
|
|
596
|
+
'signature' => signature(verb: verb, path: path, args: args),
|
|
597
|
+
'signTimestamp' => request_timestamp.to_s
|
|
598
|
+
)
|
|
599
|
+
end
|
|
600
|
+
headers
|
|
133
601
|
end
|
|
134
602
|
|
|
135
|
-
def
|
|
136
|
-
|
|
603
|
+
def request_timestamp
|
|
604
|
+
@request_timestamp ||= (Time.now.to_f * 1000).to_i
|
|
137
605
|
end
|
|
138
606
|
|
|
139
|
-
def
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
607
|
+
def signature_message(verb:, path:, args:)
|
|
608
|
+
case verb
|
|
609
|
+
when 'GET', 'DELETE'
|
|
610
|
+
args_for_signing = args.merge("signTimestamp" => request_timestamp.to_s).transform_values(&:to_s)
|
|
611
|
+
signed_args = args_for_signing.sort_by{|k, _| k}.to_h.x_www_form_urlencode
|
|
612
|
+
when 'POST', 'PUT'
|
|
613
|
+
body_str = request_body(args)
|
|
614
|
+
signed_args = "requestBody=#{body_str}&signTimestamp=#{request_timestamp}"
|
|
615
|
+
end
|
|
616
|
+
"#{verb}\n#{path}\n#{signed_args}"
|
|
148
617
|
end
|
|
149
618
|
|
|
150
|
-
def
|
|
151
|
-
|
|
619
|
+
def request_body(args)
|
|
620
|
+
return '' if args.nil?
|
|
621
|
+
if args.respond_to?(:keys) && (args.key?(:body) || args.key?('body'))
|
|
622
|
+
return args[:body] || args['body']
|
|
623
|
+
end
|
|
624
|
+
return '' if args.empty?
|
|
625
|
+
JSON.generate(args, separators: [',', ':'])
|
|
152
626
|
end
|
|
153
627
|
|
|
154
|
-
def
|
|
155
|
-
|
|
628
|
+
def signature(verb:, path:, args:)
|
|
629
|
+
digest = OpenSSL::HMAC.digest("sha256", @api_secret, signature_message(verb: verb, path: path, args: args).encode("utf-8"))
|
|
630
|
+
Base64.strict_encode64(digest)
|
|
156
631
|
end
|
|
157
632
|
|
|
158
633
|
def log_request(verb:, request_string:, args:, headers:)
|
|
@@ -178,24 +653,15 @@ module Poloniex
|
|
|
178
653
|
@logger.error(log_string)
|
|
179
654
|
end
|
|
180
655
|
|
|
181
|
-
def do_request(verb:, path:, args: {})
|
|
182
|
-
sorted_args = args.reject{|_, v| v.nil?}.sort.to_h
|
|
183
|
-
message = message(verb: verb, path: path, args: sorted_args)
|
|
184
|
-
signature = signature(message)
|
|
185
|
-
headers = headers(signature)
|
|
186
|
-
log_request(verb: verb, request_string: request_string(path), args: sorted_args, headers: headers) if use_logging?
|
|
187
|
-
@request_timestamp = nil
|
|
188
|
-
HTTP.send(verb.to_s.downcase, request_string(path), sorted_args, headers)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def get(path:, args: {})
|
|
192
|
-
do_request(verb: 'GET', path: path, args: args)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
656
|
def handle_response(response)
|
|
196
657
|
if response.success?
|
|
197
|
-
|
|
198
|
-
|
|
658
|
+
body = response.body.to_s
|
|
659
|
+
if body.strip.empty?
|
|
660
|
+
log_response(code: response.code, message: response.message, body: body) if use_logging?
|
|
661
|
+
return {}
|
|
662
|
+
end
|
|
663
|
+
parsed_body = JSON.parse(body)
|
|
664
|
+
log_response(code: response.code, message: response.message, body: body) if use_logging?
|
|
199
665
|
parsed_body
|
|
200
666
|
else
|
|
201
667
|
case response.code.to_i
|
|
@@ -204,32 +670,51 @@ module Poloniex
|
|
|
204
670
|
raise Poloniex::InvalidRequestError.new(
|
|
205
671
|
code: response.code,
|
|
206
672
|
message: response.message,
|
|
207
|
-
body: body
|
|
673
|
+
body: response.body
|
|
208
674
|
)
|
|
209
675
|
when 401
|
|
210
676
|
log_error(code: response.code, message: response.message, body: response.body) if use_logging?
|
|
211
677
|
raise Poloniex::AuthenticationError.new(
|
|
212
678
|
code: response.code,
|
|
213
679
|
message: response.message,
|
|
214
|
-
body: body
|
|
680
|
+
body: response.body
|
|
215
681
|
)
|
|
216
682
|
when 429
|
|
217
683
|
log_error(code: response.code, message: response.message, body: response.body) if use_logging?
|
|
218
684
|
raise Poloniex::RateLimitError.new(
|
|
219
685
|
code: response.code,
|
|
220
686
|
message: response.message,
|
|
221
|
-
body: body
|
|
687
|
+
body: response.body
|
|
222
688
|
)
|
|
223
689
|
else
|
|
224
690
|
log_error(code: response.code, message: response.message, body: response.body) if use_logging?
|
|
225
691
|
raise Poloniex::APIError.new(
|
|
226
692
|
code: response.code,
|
|
227
693
|
message: response.message,
|
|
228
|
-
body: body
|
|
694
|
+
body: response.body
|
|
229
695
|
)
|
|
230
696
|
end
|
|
231
697
|
end
|
|
232
698
|
end
|
|
699
|
+
|
|
700
|
+
def log_args?(args)
|
|
701
|
+
return false if args.nil?
|
|
702
|
+
return !args.values.all?(&:nil?) if args.respond_to?(:values) # Hash-like
|
|
703
|
+
return !args.empty? if args.respond_to?(:empty?) # Array-like or others
|
|
704
|
+
true
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
def public_path?(path)
|
|
708
|
+
Poloniex::V1::PUBLIC_PATH_PREFIXES.any?{|prefix| path.start_with?(prefix)}
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
def use_auth?(path)
|
|
712
|
+
!public_path?(path)
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
def use_logging?
|
|
716
|
+
!@logger.nil?
|
|
717
|
+
end
|
|
233
718
|
end
|
|
234
719
|
end
|
|
235
720
|
end
|