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