ccxt 4.3.65 → 4.3.67
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.
- package/README.md +4 -3
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +2 -2
- package/dist/cjs/src/bingx.js +151 -19
- package/dist/cjs/src/bithumb.js +61 -17
- package/dist/cjs/src/hyperliquid.js +63 -7
- package/dist/cjs/src/independentreserve.js +0 -1
- package/dist/cjs/src/kraken.js +27 -0
- package/dist/cjs/src/pro/hyperliquid.js +103 -1
- package/dist/cjs/src/pro/okx.js +22 -9
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/bingx.d.ts +7 -0
- package/js/src/base/Exchange.d.ts +14 -13
- package/js/src/base/Exchange.js +2 -2
- package/js/src/bingx.js +151 -19
- package/js/src/bithumb.js +61 -17
- package/js/src/hyperliquid.d.ts +3 -1
- package/js/src/hyperliquid.js +63 -7
- package/js/src/independentreserve.js +1 -1
- package/js/src/kraken.d.ts +7 -0
- package/js/src/kraken.js +27 -0
- package/js/src/pro/bitget.d.ts +1 -1
- package/js/src/pro/bybit.d.ts +1 -1
- package/js/src/pro/coinone.d.ts +1 -1
- package/js/src/pro/currencycom.d.ts +1 -1
- package/js/src/pro/hollaex.d.ts +1 -1
- package/js/src/pro/hyperliquid.d.ts +5 -2
- package/js/src/pro/hyperliquid.js +103 -1
- package/js/src/pro/kucoin.d.ts +1 -1
- package/js/src/pro/kucoinfutures.d.ts +1 -1
- package/js/src/pro/mexc.d.ts +1 -1
- package/js/src/pro/okcoin.d.ts +1 -1
- package/js/src/pro/okx.d.ts +2 -2
- package/js/src/pro/okx.js +23 -10
- package/js/src/pro/oxfun.d.ts +1 -1
- package/js/src/pro/p2b.d.ts +1 -1
- package/js/src/pro/poloniex.d.ts +1 -1
- package/js/src/pro/whitebit.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cjs/src/abstract/bittrex.js +0 -9
- package/dist/cjs/src/bittrex.js +0 -2308
- package/dist/cjs/src/pro/bittrex.js +0 -959
- package/js/src/bittrex.d.ts +0 -97
- package/js/src/bittrex.js +0 -2309
- package/js/src/pro/bittrex.d.ts +0 -69
- package/js/src/pro/bittrex.js +0 -960
package/dist/cjs/src/bittrex.js
DELETED
|
@@ -1,2308 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var bittrex$1 = require('./abstract/bittrex.js');
|
|
4
|
-
var errors = require('./base/errors.js');
|
|
5
|
-
var number = require('./base/functions/number.js');
|
|
6
|
-
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
/**
|
|
11
|
-
* @class bittrex
|
|
12
|
-
* @augments Exchange
|
|
13
|
-
*/
|
|
14
|
-
class bittrex extends bittrex$1 {
|
|
15
|
-
describe() {
|
|
16
|
-
return this.deepExtend(super.describe(), {
|
|
17
|
-
'id': 'bittrex',
|
|
18
|
-
'name': 'Bittrex',
|
|
19
|
-
'countries': ['US'],
|
|
20
|
-
'version': 'v3',
|
|
21
|
-
'rateLimit': 1500,
|
|
22
|
-
'certified': false,
|
|
23
|
-
'pro': true,
|
|
24
|
-
// new metainfo interface
|
|
25
|
-
'has': {
|
|
26
|
-
'CORS': undefined,
|
|
27
|
-
'spot': true,
|
|
28
|
-
'margin': false,
|
|
29
|
-
'swap': false,
|
|
30
|
-
'future': false,
|
|
31
|
-
'option': false,
|
|
32
|
-
'addMargin': false,
|
|
33
|
-
'cancelAllOrders': true,
|
|
34
|
-
'cancelOrder': true,
|
|
35
|
-
'closeAllPositions': false,
|
|
36
|
-
'closePosition': false,
|
|
37
|
-
'createDepositAddress': true,
|
|
38
|
-
'createMarketOrder': true,
|
|
39
|
-
'createOrder': true,
|
|
40
|
-
'createReduceOnlyOrder': false,
|
|
41
|
-
'createStopLimitOrder': true,
|
|
42
|
-
'createStopMarketOrder': true,
|
|
43
|
-
'createStopOrder': true,
|
|
44
|
-
'fetchBalance': true,
|
|
45
|
-
'fetchBidsAsks': true,
|
|
46
|
-
'fetchBorrowRateHistories': false,
|
|
47
|
-
'fetchBorrowRateHistory': false,
|
|
48
|
-
'fetchClosedOrders': true,
|
|
49
|
-
'fetchCrossBorrowRate': false,
|
|
50
|
-
'fetchCrossBorrowRates': false,
|
|
51
|
-
'fetchCurrencies': true,
|
|
52
|
-
'fetchDeposit': true,
|
|
53
|
-
'fetchDepositAddress': true,
|
|
54
|
-
'fetchDeposits': true,
|
|
55
|
-
'fetchDepositWithdrawFee': 'emulated',
|
|
56
|
-
'fetchDepositWithdrawFees': true,
|
|
57
|
-
'fetchFundingHistory': false,
|
|
58
|
-
'fetchFundingRate': false,
|
|
59
|
-
'fetchFundingRateHistory': false,
|
|
60
|
-
'fetchFundingRates': false,
|
|
61
|
-
'fetchIndexOHLCV': false,
|
|
62
|
-
'fetchIsolatedBorrowRate': false,
|
|
63
|
-
'fetchIsolatedBorrowRates': false,
|
|
64
|
-
'fetchLeverage': false,
|
|
65
|
-
'fetchLeverageTiers': false,
|
|
66
|
-
'fetchMarginMode': false,
|
|
67
|
-
'fetchMarkets': true,
|
|
68
|
-
'fetchMarkOHLCV': false,
|
|
69
|
-
'fetchMyTrades': true,
|
|
70
|
-
'fetchOHLCV': true,
|
|
71
|
-
'fetchOpenInterestHistory': false,
|
|
72
|
-
'fetchOpenOrders': true,
|
|
73
|
-
'fetchOrder': true,
|
|
74
|
-
'fetchOrderBook': true,
|
|
75
|
-
'fetchOrderTrades': true,
|
|
76
|
-
'fetchPosition': false,
|
|
77
|
-
'fetchPositionMode': false,
|
|
78
|
-
'fetchPositions': false,
|
|
79
|
-
'fetchPositionsRisk': false,
|
|
80
|
-
'fetchPremiumIndexOHLCV': false,
|
|
81
|
-
'fetchTicker': true,
|
|
82
|
-
'fetchTickers': true,
|
|
83
|
-
'fetchTime': true,
|
|
84
|
-
'fetchTrades': true,
|
|
85
|
-
'fetchTradingFee': true,
|
|
86
|
-
'fetchTradingFees': true,
|
|
87
|
-
'fetchTransactionFees': undefined,
|
|
88
|
-
'fetchTransactions': false,
|
|
89
|
-
'fetchWithdrawal': true,
|
|
90
|
-
'fetchWithdrawals': true,
|
|
91
|
-
'reduceMargin': false,
|
|
92
|
-
'setLeverage': false,
|
|
93
|
-
'setMarginMode': false,
|
|
94
|
-
'setPositionMode': false,
|
|
95
|
-
'withdraw': true,
|
|
96
|
-
},
|
|
97
|
-
'timeframes': {
|
|
98
|
-
'1m': 'MINUTE_1',
|
|
99
|
-
'5m': 'MINUTE_5',
|
|
100
|
-
'1h': 'HOUR_1',
|
|
101
|
-
'1d': 'DAY_1',
|
|
102
|
-
},
|
|
103
|
-
'hostname': 'bittrex.com',
|
|
104
|
-
'urls': {
|
|
105
|
-
'logo': 'https://user-images.githubusercontent.com/51840849/87153921-edf53180-c2c0-11ea-96b9-f2a9a95a455b.jpg',
|
|
106
|
-
'api': {
|
|
107
|
-
'public': 'https://api.bittrex.com',
|
|
108
|
-
'private': 'https://api.bittrex.com',
|
|
109
|
-
},
|
|
110
|
-
'www': 'https://bittrex.com',
|
|
111
|
-
'doc': [
|
|
112
|
-
'https://bittrex.github.io/api/v3',
|
|
113
|
-
],
|
|
114
|
-
'fees': [
|
|
115
|
-
'https://bittrex.zendesk.com/hc/en-us/articles/115003684371-BITTREX-SERVICE-FEES-AND-WITHDRAWAL-LIMITATIONS',
|
|
116
|
-
'https://bittrex.zendesk.com/hc/en-us/articles/115000199651-What-fees-does-Bittrex-charge-',
|
|
117
|
-
],
|
|
118
|
-
'referral': 'https://bittrex.com/Account/Register?referralCode=1ZE-G0G-M3B',
|
|
119
|
-
},
|
|
120
|
-
'api': {
|
|
121
|
-
'public': {
|
|
122
|
-
'get': [
|
|
123
|
-
'ping',
|
|
124
|
-
'currencies',
|
|
125
|
-
'currencies/{symbol}',
|
|
126
|
-
'markets',
|
|
127
|
-
'markets/tickers',
|
|
128
|
-
'markets/summaries',
|
|
129
|
-
'markets/{marketSymbol}',
|
|
130
|
-
'markets/{marketSymbol}/summary',
|
|
131
|
-
'markets/{marketSymbol}/orderbook',
|
|
132
|
-
'markets/{marketSymbol}/trades',
|
|
133
|
-
'markets/{marketSymbol}/ticker',
|
|
134
|
-
'markets/{marketSymbol}/candles/{candleInterval}/recent',
|
|
135
|
-
'markets/{marketSymbol}/candles/{candleInterval}/historical/{year}/{month}/{day}',
|
|
136
|
-
'markets/{marketSymbol}/candles/{candleInterval}/historical/{year}/{month}',
|
|
137
|
-
'markets/{marketSymbol}/candles/{candleInterval}/historical/{year}',
|
|
138
|
-
],
|
|
139
|
-
},
|
|
140
|
-
'private': {
|
|
141
|
-
'get': [
|
|
142
|
-
'account',
|
|
143
|
-
'account/fees/fiat',
|
|
144
|
-
'account/fees/fiat/{currencySymbol}',
|
|
145
|
-
'account/fees/trading',
|
|
146
|
-
'account/fees/trading/{marketSymbol}',
|
|
147
|
-
'account/volume',
|
|
148
|
-
'account/permissions/markets',
|
|
149
|
-
'account/permissions/markets/{marketSymbol}',
|
|
150
|
-
'account/permissions/currencies',
|
|
151
|
-
'account/permissions/currencies/{currencySymbol}',
|
|
152
|
-
'addresses',
|
|
153
|
-
'addresses/{currencySymbol}',
|
|
154
|
-
'balances',
|
|
155
|
-
'balances/{currencySymbol}',
|
|
156
|
-
'deposits/open',
|
|
157
|
-
'deposits/closed',
|
|
158
|
-
'deposits/ByTxId/{txId}',
|
|
159
|
-
'deposits/{depositId}',
|
|
160
|
-
'executions',
|
|
161
|
-
'executions/last-id',
|
|
162
|
-
'executions/{executionId}',
|
|
163
|
-
'orders/closed',
|
|
164
|
-
'orders/open',
|
|
165
|
-
'orders/{orderId}',
|
|
166
|
-
'orders/{orderId}/executions',
|
|
167
|
-
'ping',
|
|
168
|
-
'subaccounts/{subaccountId}',
|
|
169
|
-
'subaccounts',
|
|
170
|
-
'subaccounts/withdrawals/open',
|
|
171
|
-
'subaccounts/withdrawals/closed',
|
|
172
|
-
'subaccounts/deposits/open',
|
|
173
|
-
'subaccounts/deposits/closed',
|
|
174
|
-
'withdrawals/open',
|
|
175
|
-
'withdrawals/closed',
|
|
176
|
-
'withdrawals/ByTxId/{txId}',
|
|
177
|
-
'withdrawals/{withdrawalId}',
|
|
178
|
-
'withdrawals/allowed-addresses',
|
|
179
|
-
'conditional-orders/{conditionalOrderId}',
|
|
180
|
-
'conditional-orders/closed',
|
|
181
|
-
'conditional-orders/open',
|
|
182
|
-
'transfers/sent',
|
|
183
|
-
'transfers/received',
|
|
184
|
-
'transfers/{transferId}',
|
|
185
|
-
'funds-transfer-methods/{fundsTransferMethodId}',
|
|
186
|
-
],
|
|
187
|
-
'post': [
|
|
188
|
-
'addresses',
|
|
189
|
-
'orders',
|
|
190
|
-
'subaccounts',
|
|
191
|
-
'withdrawals',
|
|
192
|
-
'conditional-orders',
|
|
193
|
-
'transfers',
|
|
194
|
-
'batch',
|
|
195
|
-
],
|
|
196
|
-
'delete': [
|
|
197
|
-
'orders/open',
|
|
198
|
-
'orders/{orderId}',
|
|
199
|
-
'withdrawals/{withdrawalId}',
|
|
200
|
-
'conditional-orders/{conditionalOrderId}',
|
|
201
|
-
],
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
'fees': {
|
|
205
|
-
'trading': {
|
|
206
|
-
'tierBased': true,
|
|
207
|
-
'percentage': true,
|
|
208
|
-
'maker': this.parseNumber('0.0075'),
|
|
209
|
-
'taker': this.parseNumber('0.0075'),
|
|
210
|
-
},
|
|
211
|
-
'funding': {
|
|
212
|
-
'tierBased': false,
|
|
213
|
-
'percentage': false,
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
'precisionMode': number.TICK_SIZE,
|
|
217
|
-
'exceptions': {
|
|
218
|
-
'exact': {
|
|
219
|
-
'BAD_REQUEST': errors.BadRequest,
|
|
220
|
-
'STARTDATE_OUT_OF_RANGE': errors.BadRequest,
|
|
221
|
-
// 'Call to Cancel was throttled. Try again in 60 seconds.': DDoSProtection,
|
|
222
|
-
// 'Call to GetBalances was throttled. Try again in 60 seconds.': DDoSProtection,
|
|
223
|
-
'APISIGN_NOT_PROVIDED': errors.AuthenticationError,
|
|
224
|
-
'APIKEY_INVALID': errors.AuthenticationError,
|
|
225
|
-
'INVALID_SIGNATURE': errors.AuthenticationError,
|
|
226
|
-
'INVALID_CURRENCY': errors.ExchangeError,
|
|
227
|
-
'INVALID_PERMISSION': errors.AuthenticationError,
|
|
228
|
-
'INSUFFICIENT_FUNDS': errors.InsufficientFunds,
|
|
229
|
-
'INVALID_CEILING_MARKET_BUY': errors.InvalidOrder,
|
|
230
|
-
'INVALID_FIAT_ACCOUNT': errors.InvalidOrder,
|
|
231
|
-
'INVALID_ORDER_TYPE': errors.InvalidOrder,
|
|
232
|
-
'QUANTITY_NOT_PROVIDED': errors.InvalidOrder,
|
|
233
|
-
'MIN_TRADE_REQUIREMENT_NOT_MET': errors.InvalidOrder,
|
|
234
|
-
'NOT_FOUND': errors.OrderNotFound,
|
|
235
|
-
'ORDER_NOT_OPEN': errors.OrderNotFound,
|
|
236
|
-
'INVALID_ORDER': errors.InvalidOrder,
|
|
237
|
-
'UUID_INVALID': errors.OrderNotFound,
|
|
238
|
-
'RATE_NOT_PROVIDED': errors.InvalidOrder,
|
|
239
|
-
'INVALID_MARKET': errors.BadSymbol,
|
|
240
|
-
'WHITELIST_VIOLATION_IP': errors.PermissionDenied,
|
|
241
|
-
'DUST_TRADE_DISALLOWED_MIN_VALUE': errors.InvalidOrder,
|
|
242
|
-
'RESTRICTED_MARKET': errors.BadSymbol,
|
|
243
|
-
'We are down for scheduled maintenance, but we\u2019ll be back up shortly.': errors.OnMaintenance, // {"success":false,"message":"We are down for scheduled maintenance, but we\u2019ll be back up shortly.","result":null,"explanation":null}
|
|
244
|
-
},
|
|
245
|
-
'broad': {
|
|
246
|
-
'throttled': errors.DDoSProtection,
|
|
247
|
-
'problem': errors.ExchangeNotAvailable,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
'options': {
|
|
251
|
-
'fetchTicker': {
|
|
252
|
-
'method': 'publicGetMarketsMarketSymbolTicker', // publicGetMarketsMarketSymbolSummary
|
|
253
|
-
},
|
|
254
|
-
'fetchTickers': {
|
|
255
|
-
'method': 'publicGetMarketsTickers', // publicGetMarketsSummaries
|
|
256
|
-
},
|
|
257
|
-
'fetchDeposits': {
|
|
258
|
-
'status': 'ok',
|
|
259
|
-
},
|
|
260
|
-
'fetchWithdrawals': {
|
|
261
|
-
'status': 'ok',
|
|
262
|
-
},
|
|
263
|
-
'parseOrderStatus': false,
|
|
264
|
-
'hasAlreadyAuthenticatedSuccessfully': false,
|
|
265
|
-
'subaccountId': undefined,
|
|
266
|
-
// see the implementation of fetchClosedOrdersV3 below
|
|
267
|
-
// 'fetchClosedOrdersMethod': 'fetch_closed_orders_v3',
|
|
268
|
-
'fetchClosedOrdersFilterBySince': true,
|
|
269
|
-
// 'createOrderMethod': 'create_order_v1',
|
|
270
|
-
},
|
|
271
|
-
'commonCurrencies': {
|
|
272
|
-
'BIFI': 'Bifrost Finance',
|
|
273
|
-
'BTR': 'BTRIPS',
|
|
274
|
-
'GMT': 'GMT Token',
|
|
275
|
-
'MEME': 'Memetic',
|
|
276
|
-
'MER': 'Mercury',
|
|
277
|
-
'PROS': 'Pros.Finance',
|
|
278
|
-
'REPV2': 'REP',
|
|
279
|
-
'TON': 'Tokamak Network',
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
feeToPrecision(symbol, fee) {
|
|
284
|
-
return this.decimalToPrecision(fee, number.TRUNCATE, this.markets[symbol]['precision']['price'], this.precisionMode);
|
|
285
|
-
}
|
|
286
|
-
async fetchMarkets(params = {}) {
|
|
287
|
-
/**
|
|
288
|
-
* @method
|
|
289
|
-
* @name bittrex#fetchMarkets
|
|
290
|
-
* @description retrieves data on all markets for bittrex
|
|
291
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
292
|
-
* @returns {object[]} an array of objects representing market data
|
|
293
|
-
*/
|
|
294
|
-
const response = await this.publicGetMarkets(params);
|
|
295
|
-
//
|
|
296
|
-
// [
|
|
297
|
-
// {
|
|
298
|
-
// "symbol":"LTC-BTC",
|
|
299
|
-
// "baseCurrencySymbol":"LTC",
|
|
300
|
-
// "quoteCurrencySymbol":"BTC",
|
|
301
|
-
// "minTradeSize":"0.01686767",
|
|
302
|
-
// "precision":8,
|
|
303
|
-
// "status":"ONLINE", // "OFFLINE"
|
|
304
|
-
// "createdAt":"2014-02-13T00:00:00Z"
|
|
305
|
-
// },
|
|
306
|
-
// {
|
|
307
|
-
// "symbol":"VDX-USDT",
|
|
308
|
-
// "baseCurrencySymbol":"VDX",
|
|
309
|
-
// "quoteCurrencySymbol":"USDT",
|
|
310
|
-
// "minTradeSize":"300.00000000",
|
|
311
|
-
// "precision":8,
|
|
312
|
-
// "status":"ONLINE", // "OFFLINE"
|
|
313
|
-
// "createdAt":"2019-05-23T00:41:21.843Z",
|
|
314
|
-
// "notice":"USDT has swapped to an ERC20-based token as of August 5, 2019."
|
|
315
|
-
// }
|
|
316
|
-
// ]
|
|
317
|
-
//
|
|
318
|
-
return this.parseMarkets(response);
|
|
319
|
-
}
|
|
320
|
-
parseMarket(market) {
|
|
321
|
-
const baseId = this.safeString(market, 'baseCurrencySymbol');
|
|
322
|
-
const quoteId = this.safeString(market, 'quoteCurrencySymbol');
|
|
323
|
-
const base = this.safeCurrencyCode(baseId);
|
|
324
|
-
const quote = this.safeCurrencyCode(quoteId);
|
|
325
|
-
const status = this.safeString(market, 'status');
|
|
326
|
-
return {
|
|
327
|
-
'id': this.safeString(market, 'symbol'),
|
|
328
|
-
'symbol': base + '/' + quote,
|
|
329
|
-
'base': base,
|
|
330
|
-
'quote': quote,
|
|
331
|
-
'settle': undefined,
|
|
332
|
-
'baseId': baseId,
|
|
333
|
-
'quoteId': quoteId,
|
|
334
|
-
'settleId': undefined,
|
|
335
|
-
'type': 'spot',
|
|
336
|
-
'spot': true,
|
|
337
|
-
'margin': false,
|
|
338
|
-
'swap': false,
|
|
339
|
-
'future': false,
|
|
340
|
-
'option': false,
|
|
341
|
-
'active': (status === 'ONLINE'),
|
|
342
|
-
'contract': false,
|
|
343
|
-
'linear': undefined,
|
|
344
|
-
'inverse': undefined,
|
|
345
|
-
'contractSize': undefined,
|
|
346
|
-
'expiry': undefined,
|
|
347
|
-
'expiryDatetime': undefined,
|
|
348
|
-
'strike': undefined,
|
|
349
|
-
'optionType': undefined,
|
|
350
|
-
'precision': {
|
|
351
|
-
'amount': this.parseNumber('1e-8'),
|
|
352
|
-
'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'precision'))),
|
|
353
|
-
},
|
|
354
|
-
'limits': {
|
|
355
|
-
'leverage': {
|
|
356
|
-
'min': undefined,
|
|
357
|
-
'max': undefined,
|
|
358
|
-
},
|
|
359
|
-
'amount': {
|
|
360
|
-
'min': this.safeNumber(market, 'minTradeSize'),
|
|
361
|
-
'max': undefined,
|
|
362
|
-
},
|
|
363
|
-
'price': {
|
|
364
|
-
'min': undefined,
|
|
365
|
-
'max': undefined,
|
|
366
|
-
},
|
|
367
|
-
'cost': {
|
|
368
|
-
'min': undefined,
|
|
369
|
-
'max': undefined,
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
'created': this.parse8601(this.safeString(market, 'createdAt')),
|
|
373
|
-
'info': market,
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
parseBalance(response) {
|
|
377
|
-
const result = { 'info': response };
|
|
378
|
-
const indexed = this.indexBy(response, 'currencySymbol');
|
|
379
|
-
const currencyIds = Object.keys(indexed);
|
|
380
|
-
for (let i = 0; i < currencyIds.length; i++) {
|
|
381
|
-
const currencyId = currencyIds[i];
|
|
382
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
383
|
-
const account = this.account();
|
|
384
|
-
const balance = indexed[currencyId];
|
|
385
|
-
account['free'] = this.safeString(balance, 'available');
|
|
386
|
-
account['total'] = this.safeString(balance, 'total');
|
|
387
|
-
result[code] = account;
|
|
388
|
-
}
|
|
389
|
-
return this.safeBalance(result);
|
|
390
|
-
}
|
|
391
|
-
async fetchBalance(params = {}) {
|
|
392
|
-
/**
|
|
393
|
-
* @method
|
|
394
|
-
* @name bittrex#fetchBalance
|
|
395
|
-
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
396
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
397
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
398
|
-
*/
|
|
399
|
-
await this.loadMarkets();
|
|
400
|
-
const response = await this.privateGetBalances(params);
|
|
401
|
-
return this.parseBalance(response);
|
|
402
|
-
}
|
|
403
|
-
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
404
|
-
/**
|
|
405
|
-
* @method
|
|
406
|
-
* @name bittrex#fetchOrderBook
|
|
407
|
-
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
408
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
409
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
410
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
411
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
412
|
-
*/
|
|
413
|
-
await this.loadMarkets();
|
|
414
|
-
const market = this.market(symbol);
|
|
415
|
-
const request = {
|
|
416
|
-
'marketSymbol': market['id'],
|
|
417
|
-
};
|
|
418
|
-
if (limit !== undefined) {
|
|
419
|
-
if ((limit !== 1) && (limit !== 25) && (limit !== 500)) {
|
|
420
|
-
throw new errors.BadRequest(this.id + ' fetchOrderBook() limit argument must be undefined, 1, 25 or 500, default is 25');
|
|
421
|
-
}
|
|
422
|
-
request['depth'] = limit;
|
|
423
|
-
}
|
|
424
|
-
const response = await this.publicGetMarketsMarketSymbolOrderbook(this.extend(request, params));
|
|
425
|
-
//
|
|
426
|
-
// {
|
|
427
|
-
// "bid":[
|
|
428
|
-
// {"quantity":"0.01250000","rate":"10718.56200003"},
|
|
429
|
-
// {"quantity":"0.10000000","rate":"10718.56200002"},
|
|
430
|
-
// {"quantity":"0.39648292","rate":"10718.56200001"},
|
|
431
|
-
// ],
|
|
432
|
-
// "ask":[
|
|
433
|
-
// {"quantity":"0.05100000","rate":"10724.30099631"},
|
|
434
|
-
// {"quantity":"0.10000000","rate":"10724.30099632"},
|
|
435
|
-
// {"quantity":"0.26000000","rate":"10724.30099634"},
|
|
436
|
-
// ]
|
|
437
|
-
// }
|
|
438
|
-
//
|
|
439
|
-
const sequence = this.safeInteger(this.last_response_headers, 'Sequence');
|
|
440
|
-
const orderbook = this.parseOrderBook(response, market['symbol'], undefined, 'bid', 'ask', 'rate', 'quantity');
|
|
441
|
-
orderbook['nonce'] = sequence;
|
|
442
|
-
return orderbook;
|
|
443
|
-
}
|
|
444
|
-
async fetchCurrencies(params = {}) {
|
|
445
|
-
/**
|
|
446
|
-
* @method
|
|
447
|
-
* @name bittrex#fetchCurrencies
|
|
448
|
-
* @description fetches all available currencies on an exchange
|
|
449
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
450
|
-
* @returns {object} an associative dictionary of currencies
|
|
451
|
-
*/
|
|
452
|
-
const response = await this.publicGetCurrencies(params);
|
|
453
|
-
//
|
|
454
|
-
// [
|
|
455
|
-
// {
|
|
456
|
-
// "symbol":"1ST",
|
|
457
|
-
// "name":"Firstblood",
|
|
458
|
-
// "coinType":"ETH_CONTRACT",
|
|
459
|
-
// "status":"ONLINE",
|
|
460
|
-
// "minConfirmations":36,
|
|
461
|
-
// "notice":"",
|
|
462
|
-
// "txFee":"4.50000000",
|
|
463
|
-
// "logoUrl":"https://bittrexblobstorage.blob.core.windows.net/public/5685a7be-1edf-4ba0-a313-b5309bb204f8.png",
|
|
464
|
-
// "prohibitedIn":[],
|
|
465
|
-
// "baseAddress":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98",
|
|
466
|
-
// "associatedTermsOfService":[]
|
|
467
|
-
// }
|
|
468
|
-
// ]
|
|
469
|
-
//
|
|
470
|
-
const result = {};
|
|
471
|
-
for (let i = 0; i < response.length; i++) {
|
|
472
|
-
const currency = response[i];
|
|
473
|
-
const id = this.safeString(currency, 'symbol');
|
|
474
|
-
const code = this.safeCurrencyCode(id);
|
|
475
|
-
const precision = this.parseNumber('1e-8'); // default precision, seems exchange has same amount-precision across all pairs in UI too. todo: fix "magic constants"
|
|
476
|
-
const fee = this.safeNumber(currency, 'txFee'); // todo: redesign
|
|
477
|
-
const isActive = this.safeString(currency, 'status');
|
|
478
|
-
const coinType = this.safeString(currency, 'coinType');
|
|
479
|
-
let type = undefined;
|
|
480
|
-
if (coinType === 'FIAT') {
|
|
481
|
-
type = 'fiat';
|
|
482
|
-
}
|
|
483
|
-
else if (coinType === 'Award') {
|
|
484
|
-
// these are exchange credits
|
|
485
|
-
type = 'other';
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
// all others are cryptos
|
|
489
|
-
type = 'crypto';
|
|
490
|
-
}
|
|
491
|
-
result[code] = {
|
|
492
|
-
'id': id,
|
|
493
|
-
'code': code,
|
|
494
|
-
'info': currency,
|
|
495
|
-
'type': type,
|
|
496
|
-
'name': this.safeString(currency, 'name'),
|
|
497
|
-
'active': (isActive === 'ONLINE'),
|
|
498
|
-
'deposit': undefined,
|
|
499
|
-
'withdraw': undefined,
|
|
500
|
-
'fee': fee,
|
|
501
|
-
'precision': precision,
|
|
502
|
-
'limits': {
|
|
503
|
-
'amount': {
|
|
504
|
-
'min': precision,
|
|
505
|
-
'max': undefined,
|
|
506
|
-
},
|
|
507
|
-
'withdraw': {
|
|
508
|
-
'min': fee,
|
|
509
|
-
'max': undefined,
|
|
510
|
-
},
|
|
511
|
-
},
|
|
512
|
-
'networks': {},
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
return result;
|
|
516
|
-
}
|
|
517
|
-
parseTicker(ticker, market = undefined) {
|
|
518
|
-
//
|
|
519
|
-
// ticker
|
|
520
|
-
//
|
|
521
|
-
// {
|
|
522
|
-
// "symbol":"ETH-BTC",
|
|
523
|
-
// "lastTradeRate":"0.03284496",
|
|
524
|
-
// "bidRate":"0.03284523",
|
|
525
|
-
// "askRate":"0.03286857"
|
|
526
|
-
// }
|
|
527
|
-
//
|
|
528
|
-
// summary
|
|
529
|
-
//
|
|
530
|
-
// {
|
|
531
|
-
// "symbol":"ETH-BTC",
|
|
532
|
-
// "high":"0.03369528",
|
|
533
|
-
// "low":"0.03282442",
|
|
534
|
-
// "volume":"4307.83794556",
|
|
535
|
-
// "quoteVolume":"143.08608869",
|
|
536
|
-
// "percentChange":"0.79",
|
|
537
|
-
// "updatedAt":"2020-09-29T07:36:57.823Z"
|
|
538
|
-
// }
|
|
539
|
-
//
|
|
540
|
-
const timestamp = this.parse8601(this.safeString(ticker, 'updatedAt'));
|
|
541
|
-
const marketId = this.safeString(ticker, 'symbol');
|
|
542
|
-
market = this.safeMarket(marketId, market, '-');
|
|
543
|
-
const symbol = market['symbol'];
|
|
544
|
-
const percentage = this.safeString(ticker, 'percentChange');
|
|
545
|
-
const last = this.safeString(ticker, 'lastTradeRate');
|
|
546
|
-
return this.safeTicker({
|
|
547
|
-
'symbol': symbol,
|
|
548
|
-
'timestamp': timestamp,
|
|
549
|
-
'datetime': this.iso8601(timestamp),
|
|
550
|
-
'high': this.safeString(ticker, 'high'),
|
|
551
|
-
'low': this.safeString(ticker, 'low'),
|
|
552
|
-
'bid': this.safeString(ticker, 'bidRate'),
|
|
553
|
-
'bidVolume': undefined,
|
|
554
|
-
'ask': this.safeString(ticker, 'askRate'),
|
|
555
|
-
'askVolume': undefined,
|
|
556
|
-
'vwap': undefined,
|
|
557
|
-
'open': undefined,
|
|
558
|
-
'close': last,
|
|
559
|
-
'last': last,
|
|
560
|
-
'previousClose': undefined,
|
|
561
|
-
'change': undefined,
|
|
562
|
-
'percentage': percentage,
|
|
563
|
-
'average': undefined,
|
|
564
|
-
'baseVolume': this.safeString(ticker, 'volume'),
|
|
565
|
-
'quoteVolume': this.safeString(ticker, 'quoteVolume'),
|
|
566
|
-
'info': ticker,
|
|
567
|
-
}, market);
|
|
568
|
-
}
|
|
569
|
-
async fetchTickers(symbols = undefined, params = {}) {
|
|
570
|
-
/**
|
|
571
|
-
* @method
|
|
572
|
-
* @name bittrex#fetchTickers
|
|
573
|
-
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
574
|
-
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
575
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
576
|
-
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
577
|
-
*/
|
|
578
|
-
await this.loadMarkets();
|
|
579
|
-
symbols = this.marketSymbols(symbols);
|
|
580
|
-
const options = this.safeValue(this.options, 'fetchTickers', {});
|
|
581
|
-
const defaultMethod = this.safeString(options, 'method', 'publicGetMarketsTickers');
|
|
582
|
-
const method = this.safeString(params, 'method', defaultMethod);
|
|
583
|
-
params = this.omit(params, 'method');
|
|
584
|
-
const response = await this[method](params);
|
|
585
|
-
//
|
|
586
|
-
// publicGetMarketsTickers
|
|
587
|
-
//
|
|
588
|
-
// [
|
|
589
|
-
// {
|
|
590
|
-
// "symbol":"4ART-BTC",
|
|
591
|
-
// "lastTradeRate":"0.00000210",
|
|
592
|
-
// "bidRate":"0.00000210",
|
|
593
|
-
// "askRate":"0.00000215"
|
|
594
|
-
// }
|
|
595
|
-
// ]
|
|
596
|
-
//
|
|
597
|
-
// publicGetMarketsSummaries
|
|
598
|
-
//
|
|
599
|
-
// [
|
|
600
|
-
// {
|
|
601
|
-
// "symbol":"4ART-BTC",
|
|
602
|
-
// "high":"0.00000206",
|
|
603
|
-
// "low":"0.00000196",
|
|
604
|
-
// "volume":"14871.32000233",
|
|
605
|
-
// "quoteVolume":"0.02932756",
|
|
606
|
-
// "percentChange":"1.48",
|
|
607
|
-
// "updatedAt":"2020-09-29T07:34:32.757Z"
|
|
608
|
-
// }
|
|
609
|
-
// ]
|
|
610
|
-
//
|
|
611
|
-
const tickers = [];
|
|
612
|
-
for (let i = 0; i < response.length; i++) {
|
|
613
|
-
const ticker = this.parseTicker(response[i]);
|
|
614
|
-
tickers.push(ticker);
|
|
615
|
-
}
|
|
616
|
-
return this.filterByArrayTickers(tickers, 'symbol', symbols);
|
|
617
|
-
}
|
|
618
|
-
async fetchTicker(symbol, params = {}) {
|
|
619
|
-
/**
|
|
620
|
-
* @method
|
|
621
|
-
* @name bittrex#fetchTicker
|
|
622
|
-
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
623
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
624
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
625
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
626
|
-
*/
|
|
627
|
-
await this.loadMarkets();
|
|
628
|
-
const market = this.market(symbol);
|
|
629
|
-
const request = {
|
|
630
|
-
'marketSymbol': market['id'],
|
|
631
|
-
};
|
|
632
|
-
const options = this.safeValue(this.options, 'fetchTicker', {});
|
|
633
|
-
const defaultMethod = this.safeString(options, 'method', 'publicGetMarketsMarketSymbolTicker');
|
|
634
|
-
const method = this.safeString(params, 'method', defaultMethod);
|
|
635
|
-
params = this.omit(params, 'method');
|
|
636
|
-
const response = await this[method](this.extend(request, params));
|
|
637
|
-
//
|
|
638
|
-
// publicGetMarketsMarketSymbolTicker
|
|
639
|
-
//
|
|
640
|
-
// {
|
|
641
|
-
// "symbol":"ETH-BTC",
|
|
642
|
-
// "lastTradeRate":"0.03284496",
|
|
643
|
-
// "bidRate":"0.03284523",
|
|
644
|
-
// "askRate":"0.03286857"
|
|
645
|
-
// }
|
|
646
|
-
//
|
|
647
|
-
//
|
|
648
|
-
// publicGetMarketsMarketSymbolSummary
|
|
649
|
-
//
|
|
650
|
-
// {
|
|
651
|
-
// "symbol":"ETH-BTC",
|
|
652
|
-
// "high":"0.03369528",
|
|
653
|
-
// "low":"0.03282442",
|
|
654
|
-
// "volume":"4307.83794556",
|
|
655
|
-
// "quoteVolume":"143.08608869",
|
|
656
|
-
// "percentChange":"0.79",
|
|
657
|
-
// "updatedAt":"2020-09-29T07:36:57.823Z"
|
|
658
|
-
// }
|
|
659
|
-
//
|
|
660
|
-
return this.parseTicker(response, market);
|
|
661
|
-
}
|
|
662
|
-
async fetchBidsAsks(symbols = undefined, params = {}) {
|
|
663
|
-
/**
|
|
664
|
-
* @method
|
|
665
|
-
* @name bittrex#fetchBidsAsks
|
|
666
|
-
* @description fetches the bid and ask price and volume for multiple markets
|
|
667
|
-
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
668
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
669
|
-
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
670
|
-
*/
|
|
671
|
-
await this.loadMarkets();
|
|
672
|
-
const response = await this.publicGetMarketsTickers(params);
|
|
673
|
-
//
|
|
674
|
-
// [
|
|
675
|
-
// {
|
|
676
|
-
// "symbol":"ETH-BTC",
|
|
677
|
-
// "lastTradeRate":"0.03284496",
|
|
678
|
-
// "bidRate":"0.03284523",
|
|
679
|
-
// "askRate":"0.03286857"
|
|
680
|
-
// }
|
|
681
|
-
// ]
|
|
682
|
-
//
|
|
683
|
-
return this.parseTickers(response, symbols);
|
|
684
|
-
}
|
|
685
|
-
parseTrade(trade, market = undefined) {
|
|
686
|
-
//
|
|
687
|
-
// public fetchTrades
|
|
688
|
-
//
|
|
689
|
-
// {
|
|
690
|
-
// "id": "8a614d4e-e455-45b0-9aac-502b0aeb433f",
|
|
691
|
-
// "executedAt": "2021-11-25T14:54:44.65Z",
|
|
692
|
-
// "quantity": "30.00000000",
|
|
693
|
-
// "rate": "1.72923112",
|
|
694
|
-
// "takerSide": "SELL"
|
|
695
|
-
// }
|
|
696
|
-
//
|
|
697
|
-
// private fetchOrderTrades
|
|
698
|
-
// {
|
|
699
|
-
// "id": "8a614d4e-e455-45b0-9aac-502b0aeb433f",
|
|
700
|
-
// "marketSymbol": "ADA-USDT",
|
|
701
|
-
// "executedAt": "2021-11-25T14:54:44.65Z",
|
|
702
|
-
// "quantity": "30.00000000",
|
|
703
|
-
// "rate": "1.72923112",
|
|
704
|
-
// "orderId": "6f7abf18-6901-4659-a48c-db0e88440ea4",
|
|
705
|
-
// "commission": "0.38907700",
|
|
706
|
-
// "isTaker": true
|
|
707
|
-
// }
|
|
708
|
-
//
|
|
709
|
-
// private fetchMyTrades
|
|
710
|
-
// {
|
|
711
|
-
// "id":"7e6488c9-294f-4137-b0f2-9f86578186fe",
|
|
712
|
-
// "marketSymbol":"DOGE-USDT",
|
|
713
|
-
// "executedAt":"2022-08-12T21:27:37.92Z",
|
|
714
|
-
// "quantity":"100.00000000",
|
|
715
|
-
// "rate":"0.071584100000",
|
|
716
|
-
// "orderId":"2d53f11a-fb22-4820-b04d-80e5f48e6005",
|
|
717
|
-
// "commission":"0.05368807",
|
|
718
|
-
// "isTaker":true,
|
|
719
|
-
// "direction":"BUY"
|
|
720
|
-
// }
|
|
721
|
-
//
|
|
722
|
-
const timestamp = this.parse8601(this.safeString(trade, 'executedAt'));
|
|
723
|
-
const id = this.safeString(trade, 'id');
|
|
724
|
-
const order = this.safeString(trade, 'orderId');
|
|
725
|
-
const marketId = this.safeString(trade, 'marketSymbol');
|
|
726
|
-
market = this.safeMarket(marketId, market, '-');
|
|
727
|
-
const priceString = this.safeString(trade, 'rate');
|
|
728
|
-
const amountString = this.safeString(trade, 'quantity');
|
|
729
|
-
let takerOrMaker = undefined;
|
|
730
|
-
let side = this.safeStringLower2(trade, 'takerSide', 'direction');
|
|
731
|
-
const isTaker = this.safeValue(trade, 'isTaker');
|
|
732
|
-
if (isTaker !== undefined) {
|
|
733
|
-
takerOrMaker = isTaker ? 'taker' : 'maker';
|
|
734
|
-
if (!isTaker) { // as noted in PR #15655 this API provides confusing value - when it's 'maker' trade, then side value should reversed
|
|
735
|
-
if (side === 'buy') {
|
|
736
|
-
side = 'sell';
|
|
737
|
-
}
|
|
738
|
-
else if (side === 'sell') {
|
|
739
|
-
side = 'buy';
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
let fee = undefined;
|
|
744
|
-
const feeCostString = this.safeString(trade, 'commission');
|
|
745
|
-
if (feeCostString !== undefined) {
|
|
746
|
-
fee = {
|
|
747
|
-
'cost': feeCostString,
|
|
748
|
-
'currency': market['quote'],
|
|
749
|
-
};
|
|
750
|
-
}
|
|
751
|
-
return this.safeTrade({
|
|
752
|
-
'info': trade,
|
|
753
|
-
'timestamp': timestamp,
|
|
754
|
-
'datetime': this.iso8601(timestamp),
|
|
755
|
-
'symbol': market['symbol'],
|
|
756
|
-
'id': id,
|
|
757
|
-
'order': order,
|
|
758
|
-
'takerOrMaker': takerOrMaker,
|
|
759
|
-
'type': undefined,
|
|
760
|
-
'side': side,
|
|
761
|
-
'price': priceString,
|
|
762
|
-
'amount': amountString,
|
|
763
|
-
'cost': undefined,
|
|
764
|
-
'fee': fee,
|
|
765
|
-
}, market);
|
|
766
|
-
}
|
|
767
|
-
async fetchTime(params = {}) {
|
|
768
|
-
/**
|
|
769
|
-
* @method
|
|
770
|
-
* @name bittrex#fetchTime
|
|
771
|
-
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
772
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
773
|
-
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
774
|
-
*/
|
|
775
|
-
const response = await this.publicGetPing(params);
|
|
776
|
-
//
|
|
777
|
-
// {
|
|
778
|
-
// "serverTime": 1594596023162
|
|
779
|
-
// }
|
|
780
|
-
//
|
|
781
|
-
return this.safeInteger(response, 'serverTime');
|
|
782
|
-
}
|
|
783
|
-
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
784
|
-
/**
|
|
785
|
-
* @method
|
|
786
|
-
* @name bittrex#fetchTrades
|
|
787
|
-
* @description get the list of most recent trades for a particular symbol
|
|
788
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
789
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
790
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
791
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
792
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
793
|
-
*/
|
|
794
|
-
await this.loadMarkets();
|
|
795
|
-
const market = this.market(symbol);
|
|
796
|
-
const request = {
|
|
797
|
-
'marketSymbol': market['id'],
|
|
798
|
-
};
|
|
799
|
-
const response = await this.publicGetMarketsMarketSymbolTrades(this.extend(request, params));
|
|
800
|
-
//
|
|
801
|
-
// [
|
|
802
|
-
// {
|
|
803
|
-
// "id":"9c5589db-42fb-436c-b105-5e2edcb95673",
|
|
804
|
-
// "executedAt":"2020-10-03T11:48:43.38Z",
|
|
805
|
-
// "quantity":"0.17939626",
|
|
806
|
-
// "rate":"0.03297952",
|
|
807
|
-
// "takerSide":"BUY"
|
|
808
|
-
// }
|
|
809
|
-
// ]
|
|
810
|
-
//
|
|
811
|
-
return this.parseTrades(response, market, since, limit);
|
|
812
|
-
}
|
|
813
|
-
async fetchTradingFee(symbol, params = {}) {
|
|
814
|
-
/**
|
|
815
|
-
* @method
|
|
816
|
-
* @name bittrex#fetchTradingFee
|
|
817
|
-
* @description fetch the trading fees for a market
|
|
818
|
-
* @param {string} symbol unified market symbol
|
|
819
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
820
|
-
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
821
|
-
*/
|
|
822
|
-
await this.loadMarkets();
|
|
823
|
-
const market = this.market(symbol);
|
|
824
|
-
const request = {
|
|
825
|
-
'marketSymbol': market['id'],
|
|
826
|
-
};
|
|
827
|
-
const response = await this.privateGetAccountFeesTradingMarketSymbol(this.extend(request, params));
|
|
828
|
-
//
|
|
829
|
-
// {
|
|
830
|
-
// "marketSymbol":"1INCH-ETH",
|
|
831
|
-
// "makerRate":"0.00750000",
|
|
832
|
-
// "takerRate":"0.00750000"
|
|
833
|
-
// }
|
|
834
|
-
//
|
|
835
|
-
return this.parseTradingFee(response, market);
|
|
836
|
-
}
|
|
837
|
-
async fetchTradingFees(params = {}) {
|
|
838
|
-
/**
|
|
839
|
-
* @method
|
|
840
|
-
* @name bittrex#fetchTradingFees
|
|
841
|
-
* @description fetch the trading fees for multiple markets
|
|
842
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
843
|
-
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
844
|
-
*/
|
|
845
|
-
await this.loadMarkets();
|
|
846
|
-
const response = await this.privateGetAccountFeesTrading(params);
|
|
847
|
-
//
|
|
848
|
-
// [
|
|
849
|
-
// {"marketSymbol":"1ECO-BTC","makerRate":"0.00750000","takerRate":"0.00750000"},
|
|
850
|
-
// {"marketSymbol":"1ECO-USDT","makerRate":"0.00750000","takerRate":"0.00750000"},
|
|
851
|
-
// {"marketSymbol":"1INCH-BTC","makerRate":"0.00750000","takerRate":"0.00750000"},
|
|
852
|
-
// {"marketSymbol":"1INCH-ETH","makerRate":"0.00750000","takerRate":"0.00750000"},
|
|
853
|
-
// {"marketSymbol":"1INCH-USD","makerRate":"0.00750000","takerRate":"0.00750000"},
|
|
854
|
-
// ]
|
|
855
|
-
//
|
|
856
|
-
return this.parseTradingFees(response);
|
|
857
|
-
}
|
|
858
|
-
parseTradingFee(fee, market = undefined) {
|
|
859
|
-
const marketId = this.safeString(fee, 'marketSymbol');
|
|
860
|
-
const maker = this.safeNumber(fee, 'makerRate');
|
|
861
|
-
const taker = this.safeNumber(fee, 'takerRate');
|
|
862
|
-
return {
|
|
863
|
-
'info': fee,
|
|
864
|
-
'symbol': this.safeSymbol(marketId, market),
|
|
865
|
-
'maker': maker,
|
|
866
|
-
'taker': taker,
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
parseTradingFees(fees) {
|
|
870
|
-
const result = {
|
|
871
|
-
'info': fees,
|
|
872
|
-
};
|
|
873
|
-
for (let i = 0; i < fees.length; i++) {
|
|
874
|
-
const fee = this.parseTradingFee(fees[i]);
|
|
875
|
-
const symbol = fee['symbol'];
|
|
876
|
-
result[symbol] = fee;
|
|
877
|
-
}
|
|
878
|
-
return result;
|
|
879
|
-
}
|
|
880
|
-
parseOHLCV(ohlcv, market = undefined) {
|
|
881
|
-
//
|
|
882
|
-
// {
|
|
883
|
-
// "startsAt":"2020-06-12T02:35:00Z",
|
|
884
|
-
// "open":"0.02493753",
|
|
885
|
-
// "high":"0.02493753",
|
|
886
|
-
// "low":"0.02493753",
|
|
887
|
-
// "close":"0.02493753",
|
|
888
|
-
// "volume":"0.09590123",
|
|
889
|
-
// "quoteVolume":"0.00239153"
|
|
890
|
-
// }
|
|
891
|
-
//
|
|
892
|
-
return [
|
|
893
|
-
this.parse8601(this.safeString(ohlcv, 'startsAt')),
|
|
894
|
-
this.safeNumber(ohlcv, 'open'),
|
|
895
|
-
this.safeNumber(ohlcv, 'high'),
|
|
896
|
-
this.safeNumber(ohlcv, 'low'),
|
|
897
|
-
this.safeNumber(ohlcv, 'close'),
|
|
898
|
-
this.safeNumber(ohlcv, 'volume'),
|
|
899
|
-
];
|
|
900
|
-
}
|
|
901
|
-
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
902
|
-
/**
|
|
903
|
-
* @method
|
|
904
|
-
* @name bittrex#fetchOHLCV
|
|
905
|
-
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
906
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
907
|
-
* @param {string} timeframe the length of time each candle represents
|
|
908
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
909
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
910
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
911
|
-
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
912
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
913
|
-
*/
|
|
914
|
-
let paginate = false;
|
|
915
|
-
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
|
|
916
|
-
if (paginate) {
|
|
917
|
-
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1440);
|
|
918
|
-
}
|
|
919
|
-
await this.loadMarkets();
|
|
920
|
-
const market = this.market(symbol);
|
|
921
|
-
const reverseId = market['baseId'] + '-' + market['quoteId'];
|
|
922
|
-
const request = {
|
|
923
|
-
'candleInterval': this.safeString(this.timeframes, timeframe, timeframe),
|
|
924
|
-
'marketSymbol': reverseId,
|
|
925
|
-
};
|
|
926
|
-
let method = 'publicGetMarketsMarketSymbolCandlesCandleIntervalRecent';
|
|
927
|
-
if (since !== undefined) {
|
|
928
|
-
const now = this.milliseconds();
|
|
929
|
-
const difference = Math.abs(now - since);
|
|
930
|
-
const sinceDate = this.yyyymmdd(since);
|
|
931
|
-
const parts = sinceDate.split('-');
|
|
932
|
-
const sinceYear = this.safeInteger(parts, 0);
|
|
933
|
-
const sinceMonth = this.safeInteger(parts, 1);
|
|
934
|
-
const sinceDay = this.safeInteger(parts, 2);
|
|
935
|
-
if (timeframe === '1d') {
|
|
936
|
-
// if the since argument is beyond one year into the past
|
|
937
|
-
if (difference > 31622400000) {
|
|
938
|
-
method = 'publicGetMarketsMarketSymbolCandlesCandleIntervalHistoricalYear';
|
|
939
|
-
request['year'] = sinceYear;
|
|
940
|
-
}
|
|
941
|
-
// request['year'] = year;
|
|
942
|
-
}
|
|
943
|
-
else if (timeframe === '1h') {
|
|
944
|
-
// if the since argument is beyond 31 days into the past
|
|
945
|
-
if (difference > 2678400000) {
|
|
946
|
-
method = 'publicGetMarketsMarketSymbolCandlesCandleIntervalHistoricalYearMonth';
|
|
947
|
-
request['year'] = sinceYear;
|
|
948
|
-
request['month'] = sinceMonth;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
else {
|
|
952
|
-
// if the since argument is beyond 1 day into the past
|
|
953
|
-
if (difference > 86400000) {
|
|
954
|
-
method = 'publicGetMarketsMarketSymbolCandlesCandleIntervalHistoricalYearMonthDay';
|
|
955
|
-
request['year'] = sinceYear;
|
|
956
|
-
request['month'] = sinceMonth;
|
|
957
|
-
request['day'] = sinceDay;
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
const response = await this[method](this.extend(request, params));
|
|
962
|
-
//
|
|
963
|
-
// [
|
|
964
|
-
// {"startsAt":"2020-06-12T02:35:00Z","open":"0.02493753","high":"0.02493753","low":"0.02493753","close":"0.02493753","volume":"0.09590123","quoteVolume":"0.00239153"},
|
|
965
|
-
// {"startsAt":"2020-06-12T02:40:00Z","open":"0.02491874","high":"0.02491874","low":"0.02490970","close":"0.02490970","volume":"0.04515695","quoteVolume":"0.00112505"},
|
|
966
|
-
// {"startsAt":"2020-06-12T02:45:00Z","open":"0.02490753","high":"0.02493143","low":"0.02490753","close":"0.02493143","volume":"0.17769640","quoteVolume":"0.00442663"}
|
|
967
|
-
// ]
|
|
968
|
-
//
|
|
969
|
-
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
970
|
-
}
|
|
971
|
-
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
972
|
-
/**
|
|
973
|
-
* @method
|
|
974
|
-
* @name bittrex#fetchOpenOrders
|
|
975
|
-
* @description fetch all unfilled currently open orders
|
|
976
|
-
* @param {string} symbol unified market symbol
|
|
977
|
-
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
978
|
-
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
979
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
980
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
981
|
-
*/
|
|
982
|
-
await this.loadMarkets();
|
|
983
|
-
const request = {};
|
|
984
|
-
let market = undefined;
|
|
985
|
-
const stop = this.safeValue(params, 'stop');
|
|
986
|
-
if (symbol !== undefined) {
|
|
987
|
-
market = this.market(symbol);
|
|
988
|
-
request['marketSymbol'] = market['id'];
|
|
989
|
-
}
|
|
990
|
-
let method = 'privateGetOrdersOpen';
|
|
991
|
-
if (stop) {
|
|
992
|
-
method = 'privateGetConditionalOrdersOpen';
|
|
993
|
-
}
|
|
994
|
-
const query = this.omit(params, 'stop');
|
|
995
|
-
const response = await this[method](this.extend(request, query));
|
|
996
|
-
//
|
|
997
|
-
// Spot
|
|
998
|
-
//
|
|
999
|
-
// [
|
|
1000
|
-
// {
|
|
1001
|
-
// "id": "df6cf5ee-fc27-4b61-991a-cc94b6459ac9",
|
|
1002
|
-
// "marketSymbol": "BTC-USDT",
|
|
1003
|
-
// "direction": "BUY",
|
|
1004
|
-
// "type": "LIMIT",
|
|
1005
|
-
// "quantity": "0.00023277",
|
|
1006
|
-
// "limit": "30000.00000000",
|
|
1007
|
-
// "timeInForce": "GOOD_TIL_CANCELLED",
|
|
1008
|
-
// "fillQuantity": "0.00000000",
|
|
1009
|
-
// "commission": "0.00000000",
|
|
1010
|
-
// "proceeds": "0.00000000",
|
|
1011
|
-
// "status": "OPEN",
|
|
1012
|
-
// "createdAt": "2022-04-20T02:33:53.16Z",
|
|
1013
|
-
// "updatedAt": "2022-04-20T02:33:53.16Z"
|
|
1014
|
-
// }
|
|
1015
|
-
// ]
|
|
1016
|
-
//
|
|
1017
|
-
// Stop
|
|
1018
|
-
//
|
|
1019
|
-
// [
|
|
1020
|
-
// {
|
|
1021
|
-
// "id": "f64f7c4f-295c-408b-9cbc-601981abf100",
|
|
1022
|
-
// "marketSymbol": "BTC-USDT",
|
|
1023
|
-
// "operand": "LTE",
|
|
1024
|
-
// "triggerPrice": "0.10000000",
|
|
1025
|
-
// "orderToCreate": {
|
|
1026
|
-
// "marketSymbol": "BTC-USDT",
|
|
1027
|
-
// "direction": "BUY",
|
|
1028
|
-
// "type": "LIMIT",
|
|
1029
|
-
// "quantity": "0.00020000",
|
|
1030
|
-
// "limit": "30000.00000000",
|
|
1031
|
-
// "timeInForce": "GOOD_TIL_CANCELLED"
|
|
1032
|
-
// },
|
|
1033
|
-
// "status": "OPEN",
|
|
1034
|
-
// "createdAt": "2022-04-20T02:38:12.26Z",
|
|
1035
|
-
// "updatedAt": "2022-04-20T02:38:12.26Z"
|
|
1036
|
-
// }
|
|
1037
|
-
// ]
|
|
1038
|
-
//
|
|
1039
|
-
return this.parseOrders(response, market, since, limit);
|
|
1040
|
-
}
|
|
1041
|
-
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1042
|
-
/**
|
|
1043
|
-
* @method
|
|
1044
|
-
* @name bittrex#fetchOrderTrades
|
|
1045
|
-
* @description fetch all the trades made from a single order
|
|
1046
|
-
* @param {string} id order id
|
|
1047
|
-
* @param {string} symbol unified market symbol
|
|
1048
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1049
|
-
* @param {int} [limit] the maximum number of trades to retrieve
|
|
1050
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1051
|
-
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1052
|
-
*/
|
|
1053
|
-
await this.loadMarkets();
|
|
1054
|
-
const request = {
|
|
1055
|
-
'orderId': id,
|
|
1056
|
-
};
|
|
1057
|
-
const response = await this.privateGetOrdersOrderIdExecutions(this.extend(request, params));
|
|
1058
|
-
let market = undefined;
|
|
1059
|
-
if (symbol !== undefined) {
|
|
1060
|
-
market = this.market(symbol);
|
|
1061
|
-
}
|
|
1062
|
-
return this.parseTrades(response, market, since, limit);
|
|
1063
|
-
}
|
|
1064
|
-
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1065
|
-
/**
|
|
1066
|
-
* @method
|
|
1067
|
-
* @name bittrex#createOrder
|
|
1068
|
-
* @description create a trade order
|
|
1069
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1070
|
-
* @param {string} type 'market' or 'limit'
|
|
1071
|
-
* @param {string} side 'buy' or 'sell'
|
|
1072
|
-
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1073
|
-
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1074
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1075
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1076
|
-
*/
|
|
1077
|
-
// A ceiling order is a market or limit order that allows you to specify
|
|
1078
|
-
// the amount of quote currency you want to spend (or receive, if selling)
|
|
1079
|
-
// instead of the quantity of the market currency (e.g. buy $100 USD of BTC
|
|
1080
|
-
// at the current market BTC price)
|
|
1081
|
-
await this.loadMarkets();
|
|
1082
|
-
const market = this.market(symbol);
|
|
1083
|
-
let uppercaseType = undefined;
|
|
1084
|
-
if (type !== undefined) {
|
|
1085
|
-
uppercaseType = type.toUpperCase();
|
|
1086
|
-
}
|
|
1087
|
-
const reverseId = market['baseId'] + '-' + market['quoteId'];
|
|
1088
|
-
const stop = this.safeValue(params, 'stop');
|
|
1089
|
-
const stopPrice = this.safeNumber2(params, 'triggerPrice', 'stopPrice');
|
|
1090
|
-
const request = {
|
|
1091
|
-
'marketSymbol': reverseId, // SPOT and STOP
|
|
1092
|
-
// 'direction': side.toUpperCase (), // SPOT, STOP 'orderToCreate'
|
|
1093
|
-
// 'type': uppercaseType, // SPOT: LIMIT, MARKET, CEILING_LIMIT, CEILING_MARKET
|
|
1094
|
-
// 'quantity': this.amountToPrecision (symbol, amount), // SPOT, required for limit orders, excluded for ceiling orders
|
|
1095
|
-
// 'ceiling': this.priceToPrecision (symbol, price), // SPOT, required for ceiling orders, excluded for non-ceiling orders
|
|
1096
|
-
// 'limit': this.priceToPrecision (symbol, price), // SPOT, required for limit orders, excluded for market orders
|
|
1097
|
-
// 'timeInForce': 'GOOD_TIL_CANCELLED', // SPOT, IMMEDIATE_OR_CANCEL, FILL_OR_KILL, POST_ONLY_GOOD_TIL_CANCELLED
|
|
1098
|
-
// 'useAwards': false, // SPOT, optional
|
|
1099
|
-
// 'operand': 'LTE', // STOP, price above (GTE) or below (LTE) which the conditional order will trigger. either this or trailingStopPercent must be specified.
|
|
1100
|
-
// 'triggerPrice': this.priceToPrecision (symbol, stopPrice), // STOP
|
|
1101
|
-
// 'trailingStopPercent': this.priceToPrecision (symbol, stopPrice), // STOP, either this or triggerPrice must be set
|
|
1102
|
-
// 'orderToCreate': {direction:side,type:uppercaseType}, // STOP, The spot order to be triggered
|
|
1103
|
-
// 'orderToCancel': {id:'f03d5e98-b5ac-48fb-8647-dd4db828a297',type:uppercaseType}, // STOP, The spot order to be canceled
|
|
1104
|
-
// 'clineConditionalOrderId': 'f03d5e98-b5ac-48fb-8647-dd4db828a297', // STOP
|
|
1105
|
-
};
|
|
1106
|
-
let method = 'privatePostOrders';
|
|
1107
|
-
if (stop || stopPrice) {
|
|
1108
|
-
method = 'privatePostConditionalOrders';
|
|
1109
|
-
const operand = this.safeString(params, 'operand');
|
|
1110
|
-
if (operand === undefined) {
|
|
1111
|
-
throw new errors.ArgumentsRequired(this.id + ' createOrder() requires an operand parameter');
|
|
1112
|
-
}
|
|
1113
|
-
const trailingStopPercent = this.safeNumber(params, 'trailingStopPercent');
|
|
1114
|
-
const orderToCreate = this.safeValue(params, 'orderToCreate');
|
|
1115
|
-
const orderToCancel = this.safeValue(params, 'orderToCancel');
|
|
1116
|
-
if (stopPrice === undefined) {
|
|
1117
|
-
request['trailingStopPercent'] = this.priceToPrecision(symbol, trailingStopPercent);
|
|
1118
|
-
}
|
|
1119
|
-
if (orderToCreate) {
|
|
1120
|
-
const isCeilingLimit = (uppercaseType === 'CEILING_LIMIT');
|
|
1121
|
-
const isCeilingMarket = (uppercaseType === 'CEILING_MARKET');
|
|
1122
|
-
const isCeilingOrder = isCeilingLimit || isCeilingMarket;
|
|
1123
|
-
let ceiling = undefined;
|
|
1124
|
-
let limit = undefined;
|
|
1125
|
-
let timeInForce = undefined;
|
|
1126
|
-
if (isCeilingOrder) {
|
|
1127
|
-
let cost = undefined;
|
|
1128
|
-
if (isCeilingLimit) {
|
|
1129
|
-
limit = this.priceToPrecision(symbol, price);
|
|
1130
|
-
cost = this.safeNumber2(params, 'ceiling', 'cost', amount);
|
|
1131
|
-
}
|
|
1132
|
-
else if (isCeilingMarket) {
|
|
1133
|
-
cost = this.safeNumber2(params, 'ceiling', 'cost');
|
|
1134
|
-
if (cost === undefined) {
|
|
1135
|
-
if (price === undefined) {
|
|
1136
|
-
cost = amount;
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
cost = amount * price;
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
ceiling = this.costToPrecision(symbol, cost);
|
|
1144
|
-
timeInForce = 'IMMEDIATE_OR_CANCEL';
|
|
1145
|
-
}
|
|
1146
|
-
else {
|
|
1147
|
-
if (uppercaseType === 'LIMIT') {
|
|
1148
|
-
limit = this.priceToPrecision(symbol, price);
|
|
1149
|
-
timeInForce = 'GOOD_TIL_CANCELLED';
|
|
1150
|
-
}
|
|
1151
|
-
else {
|
|
1152
|
-
timeInForce = 'IMMEDIATE_OR_CANCEL';
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
request['orderToCreate'] = {
|
|
1156
|
-
'marketSymbol': reverseId,
|
|
1157
|
-
'direction': side.toUpperCase(),
|
|
1158
|
-
'type': uppercaseType,
|
|
1159
|
-
'quantity': this.amountToPrecision(symbol, amount),
|
|
1160
|
-
'ceiling': ceiling,
|
|
1161
|
-
'limit': limit,
|
|
1162
|
-
'timeInForce': timeInForce,
|
|
1163
|
-
'clientOrderId': this.safeString(params, 'clientOrderId'),
|
|
1164
|
-
'useAwards': this.safeValue(params, 'useAwards'),
|
|
1165
|
-
};
|
|
1166
|
-
}
|
|
1167
|
-
if (orderToCancel) {
|
|
1168
|
-
request['orderToCancel'] = orderToCancel;
|
|
1169
|
-
}
|
|
1170
|
-
request['triggerPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
1171
|
-
request['operand'] = operand;
|
|
1172
|
-
}
|
|
1173
|
-
else {
|
|
1174
|
-
if (side !== undefined) {
|
|
1175
|
-
request['direction'] = side.toUpperCase();
|
|
1176
|
-
}
|
|
1177
|
-
request['type'] = uppercaseType;
|
|
1178
|
-
const isCeilingLimit = (uppercaseType === 'CEILING_LIMIT');
|
|
1179
|
-
const isCeilingMarket = (uppercaseType === 'CEILING_MARKET');
|
|
1180
|
-
const isCeilingOrder = isCeilingLimit || isCeilingMarket;
|
|
1181
|
-
if (isCeilingOrder) {
|
|
1182
|
-
let cost = undefined;
|
|
1183
|
-
if (isCeilingLimit) {
|
|
1184
|
-
request['limit'] = this.priceToPrecision(symbol, price);
|
|
1185
|
-
cost = this.safeNumber2(params, 'ceiling', 'cost', amount);
|
|
1186
|
-
}
|
|
1187
|
-
else if (isCeilingMarket) {
|
|
1188
|
-
cost = this.safeNumber2(params, 'ceiling', 'cost');
|
|
1189
|
-
if (cost === undefined) {
|
|
1190
|
-
if (price === undefined) {
|
|
1191
|
-
cost = amount;
|
|
1192
|
-
}
|
|
1193
|
-
else {
|
|
1194
|
-
cost = amount * price;
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
request['ceiling'] = this.costToPrecision(symbol, cost);
|
|
1199
|
-
// bittrex only accepts IMMEDIATE_OR_CANCEL or FILL_OR_KILL for ceiling orders
|
|
1200
|
-
request['timeInForce'] = 'IMMEDIATE_OR_CANCEL';
|
|
1201
|
-
}
|
|
1202
|
-
else {
|
|
1203
|
-
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
1204
|
-
if (uppercaseType === 'LIMIT') {
|
|
1205
|
-
request['limit'] = this.priceToPrecision(symbol, price);
|
|
1206
|
-
request['timeInForce'] = 'GOOD_TIL_CANCELLED';
|
|
1207
|
-
}
|
|
1208
|
-
else {
|
|
1209
|
-
// bittrex does not allow GOOD_TIL_CANCELLED for market orders
|
|
1210
|
-
request['timeInForce'] = 'IMMEDIATE_OR_CANCEL';
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
const query = this.omit(params, ['stop', 'stopPrice', 'ceiling', 'cost', 'operand', 'trailingStopPercent', 'orderToCreate', 'orderToCancel']);
|
|
1215
|
-
const response = await this[method](this.extend(request, query));
|
|
1216
|
-
//
|
|
1217
|
-
// Spot
|
|
1218
|
-
//
|
|
1219
|
-
// {
|
|
1220
|
-
// "id": "f03d5e98-b5ac-48fb-8647-dd4db828a297",
|
|
1221
|
-
// "marketSymbol": "BTC-USDT",
|
|
1222
|
-
// "direction": "SELL",
|
|
1223
|
-
// "type": "LIMIT",
|
|
1224
|
-
// "quantity": "0.01",
|
|
1225
|
-
// "limit": "6000",
|
|
1226
|
-
// "timeInForce": "GOOD_TIL_CANCELLED",
|
|
1227
|
-
// "fillQuantity": "0.00000000",
|
|
1228
|
-
// "commission": "0.00000000",
|
|
1229
|
-
// "proceeds": "0.00000000",
|
|
1230
|
-
// "status": "OPEN",
|
|
1231
|
-
// "createdAt": "2020-03-18T02:37:33.42Z",
|
|
1232
|
-
// "updatedAt": "2020-03-18T02:37:33.42Z"
|
|
1233
|
-
// }
|
|
1234
|
-
//
|
|
1235
|
-
// Stop
|
|
1236
|
-
//
|
|
1237
|
-
// {
|
|
1238
|
-
// "id": "9791fe52-a3e5-4ac3-ae03-e327b2993571",
|
|
1239
|
-
// "marketSymbol": "BTC-USDT",
|
|
1240
|
-
// "operand": "LTE",
|
|
1241
|
-
// "triggerPrice": "0.1",
|
|
1242
|
-
// "orderToCreate": {
|
|
1243
|
-
// "marketSymbol": "BTC-USDT",
|
|
1244
|
-
// "direction": "BUY",
|
|
1245
|
-
// "type": "LIMIT",
|
|
1246
|
-
// "quantity": "0.0002",
|
|
1247
|
-
// "limit": "30000",
|
|
1248
|
-
// "timeInForce": "GOOD_TIL_CANCELLED"
|
|
1249
|
-
// },
|
|
1250
|
-
// "status": "OPEN",
|
|
1251
|
-
// "createdAt": "2022-04-19T21:02:14.17Z",
|
|
1252
|
-
// "updatedAt": "2022-04-19T21:02:14.17Z"
|
|
1253
|
-
// }
|
|
1254
|
-
//
|
|
1255
|
-
return this.parseOrder(response, market);
|
|
1256
|
-
}
|
|
1257
|
-
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1258
|
-
/**
|
|
1259
|
-
* @method
|
|
1260
|
-
* @name bittrex#cancelOrder
|
|
1261
|
-
* @description cancels an open order
|
|
1262
|
-
* @param {string} id order id
|
|
1263
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1264
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1265
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1266
|
-
*/
|
|
1267
|
-
await this.loadMarkets();
|
|
1268
|
-
const stop = this.safeValue(params, 'stop');
|
|
1269
|
-
let request = {};
|
|
1270
|
-
let method = undefined;
|
|
1271
|
-
let market = undefined;
|
|
1272
|
-
if (symbol !== undefined) {
|
|
1273
|
-
market = this.market(symbol);
|
|
1274
|
-
}
|
|
1275
|
-
if (stop) {
|
|
1276
|
-
method = 'privateDeleteConditionalOrdersConditionalOrderId';
|
|
1277
|
-
request = {
|
|
1278
|
-
'conditionalOrderId': id,
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
else {
|
|
1282
|
-
method = 'privateDeleteOrdersOrderId';
|
|
1283
|
-
request = {
|
|
1284
|
-
'orderId': id,
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
const query = this.omit(params, 'stop');
|
|
1288
|
-
const response = await this[method](this.extend(request, query));
|
|
1289
|
-
//
|
|
1290
|
-
// Spot
|
|
1291
|
-
//
|
|
1292
|
-
// [
|
|
1293
|
-
// {
|
|
1294
|
-
// "id": "df6cf5ee-fc27-4b61-991a-cc94b6459ac9",
|
|
1295
|
-
// "marketSymbol": "BTC-USDT",
|
|
1296
|
-
// "direction": "BUY",
|
|
1297
|
-
// "type": "LIMIT",
|
|
1298
|
-
// "quantity": "0.00023277",
|
|
1299
|
-
// "limit": "30000.00000000",
|
|
1300
|
-
// "timeInForce": "GOOD_TIL_CANCELLED",
|
|
1301
|
-
// "fillQuantity": "0.00000000",
|
|
1302
|
-
// "commission": "0.00000000",
|
|
1303
|
-
// "proceeds": "0.00000000",
|
|
1304
|
-
// "status": "CANCELLED",
|
|
1305
|
-
// "createdAt": "2022-04-20T02:33:53.16Z",
|
|
1306
|
-
// "updatedAt": "2022-04-20T02:33:53.16Z"
|
|
1307
|
-
// }
|
|
1308
|
-
// ]
|
|
1309
|
-
//
|
|
1310
|
-
// Stop
|
|
1311
|
-
//
|
|
1312
|
-
// [
|
|
1313
|
-
// {
|
|
1314
|
-
// "id": "f64f7c4f-295c-408b-9cbc-601981abf100",
|
|
1315
|
-
// "marketSymbol": "BTC-USDT",
|
|
1316
|
-
// "operand": "LTE",
|
|
1317
|
-
// "triggerPrice": "0.10000000",
|
|
1318
|
-
// "orderToCreate": {
|
|
1319
|
-
// "marketSymbol": "BTC-USDT",
|
|
1320
|
-
// "direction": "BUY",
|
|
1321
|
-
// "type": "LIMIT",
|
|
1322
|
-
// "quantity": "0.00020000",
|
|
1323
|
-
// "limit": "30000.00000000",
|
|
1324
|
-
// "timeInForce": "GOOD_TIL_CANCELLED"
|
|
1325
|
-
// },
|
|
1326
|
-
// "status": "CANCELLED",
|
|
1327
|
-
// "createdAt": "2022-04-20T02:38:12.26Z",
|
|
1328
|
-
// "updatedAt": "2022-04-20T02:38:12.26Z"
|
|
1329
|
-
// "closedAt": "2022-04-20T03:47:24.69Z"
|
|
1330
|
-
// }
|
|
1331
|
-
// ]
|
|
1332
|
-
//
|
|
1333
|
-
return this.extend(this.parseOrder(response, market), {
|
|
1334
|
-
'id': id,
|
|
1335
|
-
'info': response,
|
|
1336
|
-
'status': 'canceled',
|
|
1337
|
-
});
|
|
1338
|
-
}
|
|
1339
|
-
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1340
|
-
/**
|
|
1341
|
-
* @method
|
|
1342
|
-
* @name bittrex#cancelAllOrders
|
|
1343
|
-
* @description cancel all open orders
|
|
1344
|
-
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
1345
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1346
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1347
|
-
*/
|
|
1348
|
-
await this.loadMarkets();
|
|
1349
|
-
const request = {};
|
|
1350
|
-
let market = undefined;
|
|
1351
|
-
if (symbol !== undefined) {
|
|
1352
|
-
market = this.market(symbol);
|
|
1353
|
-
request['marketSymbol'] = market['id'];
|
|
1354
|
-
}
|
|
1355
|
-
const response = await this.privateDeleteOrdersOpen(this.extend(request, params));
|
|
1356
|
-
//
|
|
1357
|
-
// [
|
|
1358
|
-
// {
|
|
1359
|
-
// "id":"66582be0-5337-4d8c-b212-c356dd525801",
|
|
1360
|
-
// "statusCode":"SUCCESS",
|
|
1361
|
-
// "result":{
|
|
1362
|
-
// "id":"66582be0-5337-4d8c-b212-c356dd525801",
|
|
1363
|
-
// "marketSymbol":"BTC-USDT",
|
|
1364
|
-
// "direction":"BUY",
|
|
1365
|
-
// "type":"LIMIT",
|
|
1366
|
-
// "quantity":"0.01000000",
|
|
1367
|
-
// "limit":"3000.00000000",
|
|
1368
|
-
// "timeInForce":"GOOD_TIL_CANCELLED",
|
|
1369
|
-
// "fillQuantity":"0.00000000",
|
|
1370
|
-
// "commission":"0.00000000",
|
|
1371
|
-
// "proceeds":"0.00000000",
|
|
1372
|
-
// "status":"CLOSED",
|
|
1373
|
-
// "createdAt":"2020-10-06T12:31:53.39Z",
|
|
1374
|
-
// "updatedAt":"2020-10-06T12:54:28.8Z",
|
|
1375
|
-
// "closedAt":"2020-10-06T12:54:28.8Z"
|
|
1376
|
-
// }
|
|
1377
|
-
// }
|
|
1378
|
-
// ]
|
|
1379
|
-
//
|
|
1380
|
-
const orders = [];
|
|
1381
|
-
for (let i = 0; i < response.length; i++) {
|
|
1382
|
-
const result = this.safeValue(response[i], 'result', {});
|
|
1383
|
-
orders.push(result);
|
|
1384
|
-
}
|
|
1385
|
-
return this.parseOrders(orders, market);
|
|
1386
|
-
}
|
|
1387
|
-
async fetchDeposit(id, code = undefined, params = {}) {
|
|
1388
|
-
/**
|
|
1389
|
-
* @method
|
|
1390
|
-
* @name bittrex#fetchDeposit
|
|
1391
|
-
* @description fetch data on a currency deposit via the deposit id
|
|
1392
|
-
* @param {string} id deposit id
|
|
1393
|
-
* @param {string} code filter by currency code
|
|
1394
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1395
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1396
|
-
*/
|
|
1397
|
-
await this.loadMarkets();
|
|
1398
|
-
const request = {
|
|
1399
|
-
'txId': id,
|
|
1400
|
-
};
|
|
1401
|
-
let currency = undefined;
|
|
1402
|
-
if (code !== undefined) {
|
|
1403
|
-
currency = this.currency(code);
|
|
1404
|
-
}
|
|
1405
|
-
const response = await this.privateGetDepositsByTxIdTxId(this.extend(request, params));
|
|
1406
|
-
const transactions = this.parseTransactions(response, currency, undefined, undefined);
|
|
1407
|
-
return this.safeValue(transactions, 0);
|
|
1408
|
-
}
|
|
1409
|
-
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1410
|
-
/**
|
|
1411
|
-
* @method
|
|
1412
|
-
* @name bittrex#fetchDeposits
|
|
1413
|
-
* @description fetch all deposits made to an account
|
|
1414
|
-
* @param {string} code unified currency code
|
|
1415
|
-
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
1416
|
-
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
1417
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1418
|
-
* @param {int} [params.endDate] Filters out result after this timestamp. Uses ISO-8602 format.
|
|
1419
|
-
* @param {string} [params.nextPageToken] The unique identifier of the item that the resulting query result should start after, in the sort order of the given endpoint. Used for traversing a paginated set in the forward direction.
|
|
1420
|
-
* @param {string} [params.previousPageToken] The unique identifier of the item that the resulting query result should end before, in the sort order of the given endpoint. Used for traversing a paginated set in the reverse direction.
|
|
1421
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1422
|
-
*/
|
|
1423
|
-
await this.loadMarkets();
|
|
1424
|
-
// https://support.bittrex.com/hc/en-us/articles/115003723911
|
|
1425
|
-
const request = {};
|
|
1426
|
-
let currency = undefined;
|
|
1427
|
-
if (code !== undefined) {
|
|
1428
|
-
currency = this.currency(code);
|
|
1429
|
-
request['currencySymbol'] = currency['id'];
|
|
1430
|
-
}
|
|
1431
|
-
if (since !== undefined) {
|
|
1432
|
-
const startDate = this.parseToInt(since / 1000) * 1000;
|
|
1433
|
-
request['startDate'] = this.iso8601(startDate);
|
|
1434
|
-
}
|
|
1435
|
-
if (limit !== undefined) {
|
|
1436
|
-
request['pageSize'] = limit;
|
|
1437
|
-
}
|
|
1438
|
-
let method = undefined;
|
|
1439
|
-
const options = this.safeValue(this.options, 'fetchDeposits', {});
|
|
1440
|
-
const defaultStatus = this.safeString(options, 'status', 'ok');
|
|
1441
|
-
const status = this.safeString(params, 'status', defaultStatus);
|
|
1442
|
-
if (status === 'pending') {
|
|
1443
|
-
method = 'privateGetDepositsOpen';
|
|
1444
|
-
}
|
|
1445
|
-
else {
|
|
1446
|
-
method = 'privateGetDepositsClosed';
|
|
1447
|
-
}
|
|
1448
|
-
params = this.omit(params, 'status');
|
|
1449
|
-
const response = await this[method](this.extend(request, params));
|
|
1450
|
-
// we cannot filter by `since` timestamp, as it isn't set by Bittrex
|
|
1451
|
-
// see https://github.com/ccxt/ccxt/issues/4067
|
|
1452
|
-
// return this.parseTransactions (response, currency, since, limit);
|
|
1453
|
-
return this.parseTransactions(response, currency, undefined, limit);
|
|
1454
|
-
}
|
|
1455
|
-
async fetchPendingDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1456
|
-
/**
|
|
1457
|
-
* @method
|
|
1458
|
-
* @name bittrex#fetchPendingDeposits
|
|
1459
|
-
* @description fetch all pending deposits made from an account
|
|
1460
|
-
* @param {string} code unified currency code
|
|
1461
|
-
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1462
|
-
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1463
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1464
|
-
* @param {int} [params.endDate] Filters out result after this timestamp. Uses ISO-8602 format.
|
|
1465
|
-
* @param {string} [params.nextPageToken] The unique identifier of the item that the resulting query result should start after, in the sort order of the given endpoint. Used for traversing a paginated set in the forward direction.
|
|
1466
|
-
* @param {string} [params.previousPageToken] The unique identifier of the item that the resulting query result should end before, in the sort order of the given endpoint. Used for traversing a paginated set in the reverse direction.
|
|
1467
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1468
|
-
*/
|
|
1469
|
-
await this.loadMarkets();
|
|
1470
|
-
return this.fetchDeposits(code, since, limit, this.extend(params, { 'status': 'pending' }));
|
|
1471
|
-
}
|
|
1472
|
-
async fetchWithdrawal(id, code = undefined, params = {}) {
|
|
1473
|
-
/**
|
|
1474
|
-
* @method
|
|
1475
|
-
* @name bittrex#fetchWithdrawal
|
|
1476
|
-
* @description fetch data on a currency withdrawal via the withdrawal id
|
|
1477
|
-
* @param {string} id withdrawal id
|
|
1478
|
-
* @param {string} code filter by currency code
|
|
1479
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1480
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1481
|
-
*/
|
|
1482
|
-
await this.loadMarkets();
|
|
1483
|
-
const request = {
|
|
1484
|
-
'txId': id,
|
|
1485
|
-
};
|
|
1486
|
-
let currency = undefined;
|
|
1487
|
-
if (code !== undefined) {
|
|
1488
|
-
currency = this.currency(code);
|
|
1489
|
-
}
|
|
1490
|
-
const response = await this.privateGetWithdrawalsByTxIdTxId(this.extend(request, params));
|
|
1491
|
-
const transactions = this.parseTransactions(response, currency, undefined, undefined);
|
|
1492
|
-
return this.safeValue(transactions, 0);
|
|
1493
|
-
}
|
|
1494
|
-
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1495
|
-
/**
|
|
1496
|
-
* @method
|
|
1497
|
-
* @name bittrex#fetchWithdrawals
|
|
1498
|
-
* @description fetch all withdrawals made from an account
|
|
1499
|
-
* @param {string} code unified currency code
|
|
1500
|
-
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1501
|
-
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1502
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1503
|
-
* @param {int} [params.endDate] Filters out result after this timestamp. Uses ISO-8602 format.
|
|
1504
|
-
* @param {string} [params.nextPageToken] The unique identifier of the item that the resulting query result should start after, in the sort order of the given endpoint. Used for traversing a paginated set in the forward direction.
|
|
1505
|
-
* @param {string} [params.previousPageToken] The unique identifier of the item that the resulting query result should end before, in the sort order of the given endpoint. Used for traversing a paginated set in the reverse direction.
|
|
1506
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1507
|
-
*/
|
|
1508
|
-
await this.loadMarkets();
|
|
1509
|
-
// https://support.bittrex.com/hc/en-us/articles/115003723911
|
|
1510
|
-
const request = {};
|
|
1511
|
-
let currency = undefined;
|
|
1512
|
-
if (code !== undefined) {
|
|
1513
|
-
currency = this.currency(code);
|
|
1514
|
-
request['currencySymbol'] = currency['id'];
|
|
1515
|
-
}
|
|
1516
|
-
if (since !== undefined) {
|
|
1517
|
-
const startDate = this.parseToInt(since / 1000) * 1000;
|
|
1518
|
-
request['startDate'] = this.iso8601(startDate);
|
|
1519
|
-
}
|
|
1520
|
-
if (limit !== undefined) {
|
|
1521
|
-
request['pageSize'] = limit;
|
|
1522
|
-
}
|
|
1523
|
-
let method = undefined;
|
|
1524
|
-
const options = this.safeValue(this.options, 'fetchWithdrawals', {});
|
|
1525
|
-
const defaultStatus = this.safeString(options, 'status', 'ok');
|
|
1526
|
-
const status = this.safeString(params, 'status', defaultStatus);
|
|
1527
|
-
if (status === 'pending') {
|
|
1528
|
-
method = 'privateGetWithdrawalsOpen';
|
|
1529
|
-
}
|
|
1530
|
-
else {
|
|
1531
|
-
method = 'privateGetWithdrawalsClosed';
|
|
1532
|
-
}
|
|
1533
|
-
params = this.omit(params, 'status');
|
|
1534
|
-
const response = await this[method](this.extend(request, params));
|
|
1535
|
-
return this.parseTransactions(response, currency, since, limit);
|
|
1536
|
-
}
|
|
1537
|
-
async fetchPendingWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1538
|
-
/**
|
|
1539
|
-
* @method
|
|
1540
|
-
* @name bittrex#fetchPendingWithdrawals
|
|
1541
|
-
* @description fetch all pending withdrawals made from an account
|
|
1542
|
-
* @param {string} code unified currency code
|
|
1543
|
-
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1544
|
-
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1545
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1546
|
-
* @param {int} [params.endDate] Filters out result after this timestamp. Uses ISO-8602 format.
|
|
1547
|
-
* @param {string} [params.nextPageToken] The unique identifier of the item that the resulting query result should start after, in the sort order of the given endpoint. Used for traversing a paginated set in the forward direction.
|
|
1548
|
-
* @param {string} [params.previousPageToken] The unique identifier of the item that the resulting query result should end before, in the sort order of the given endpoint. Used for traversing a paginated set in the reverse direction.
|
|
1549
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1550
|
-
*/
|
|
1551
|
-
await this.loadMarkets();
|
|
1552
|
-
return this.fetchWithdrawals(code, since, limit, this.extend(params, { 'status': 'pending' }));
|
|
1553
|
-
}
|
|
1554
|
-
parseTransaction(transaction, currency = undefined) {
|
|
1555
|
-
//
|
|
1556
|
-
// fetchDeposits
|
|
1557
|
-
//
|
|
1558
|
-
// {
|
|
1559
|
-
// "id": "77f2e4f0-a33d-4285-9140-ed5b20533a17",
|
|
1560
|
-
// "currencySymbol": "ETH",
|
|
1561
|
-
// "quantity": "0.36487773",
|
|
1562
|
-
// "cryptoAddress": "0xeee7cff0f587706acdddfc1ff65968936fcf621e",
|
|
1563
|
-
// "txId": "0x059fd3279452a245b308a944a0ee341ff9d17652a8a1bc663e6006282128c782",
|
|
1564
|
-
// "confirmations": 44,
|
|
1565
|
-
// "updatedAt": "2017-12-28T13:57:42.753Z",
|
|
1566
|
-
// "completedAt": "2017-12-28T13:57:42.753Z",
|
|
1567
|
-
// "status": "COMPLETED",
|
|
1568
|
-
// "source": "BLOCKCHAIN"
|
|
1569
|
-
// }
|
|
1570
|
-
//
|
|
1571
|
-
// fetchWithdrawals
|
|
1572
|
-
//
|
|
1573
|
-
// {
|
|
1574
|
-
// "id":"d20d556c-59ac-4480-95d8-268f8d4adedb",
|
|
1575
|
-
// "currencySymbol":"OMG",
|
|
1576
|
-
// "quantity":"2.67000000",
|
|
1577
|
-
// "cryptoAddress":"0xa7daa9acdb41c0c476966ee23d388d6f2a1448cd",
|
|
1578
|
-
// "cryptoAddressTag":"",
|
|
1579
|
-
// "txCost":"0.10000000",
|
|
1580
|
-
// "txId":"0xb54b8c5fb889aa9f9154e013cc5dd67b3048a3e0ae58ba845868225cda154bf5",
|
|
1581
|
-
// "status":"COMPLETED",
|
|
1582
|
-
// "createdAt":"2017-12-16T20:46:22.5Z",
|
|
1583
|
-
// "completedAt":"2017-12-16T20:48:03.887Z",
|
|
1584
|
-
// "target":"BLOCKCHAIN"
|
|
1585
|
-
// }
|
|
1586
|
-
//
|
|
1587
|
-
// withdraw
|
|
1588
|
-
//
|
|
1589
|
-
// {
|
|
1590
|
-
// "currencySymbol": "string",
|
|
1591
|
-
// "quantity": "number (double)",
|
|
1592
|
-
// "cryptoAddress": "string",
|
|
1593
|
-
// "cryptoAddressTag": "string",
|
|
1594
|
-
// "fundsTransferMethodId": "string (uuid)",
|
|
1595
|
-
// "clientWithdrawalId": "string (uuid)"
|
|
1596
|
-
// }
|
|
1597
|
-
//
|
|
1598
|
-
const id = this.safeString2(transaction, 'id', 'clientWithdrawalId');
|
|
1599
|
-
const amount = this.safeNumber(transaction, 'quantity');
|
|
1600
|
-
const address = this.safeString(transaction, 'cryptoAddress');
|
|
1601
|
-
let addressTo = undefined;
|
|
1602
|
-
let addressFrom = undefined;
|
|
1603
|
-
const isDeposit = this.safeString(transaction, 'source') === 'BLOCKCHAIN';
|
|
1604
|
-
if (isDeposit) {
|
|
1605
|
-
addressFrom = address;
|
|
1606
|
-
}
|
|
1607
|
-
else {
|
|
1608
|
-
addressTo = address;
|
|
1609
|
-
}
|
|
1610
|
-
const txid = this.safeString(transaction, 'txId');
|
|
1611
|
-
const updated = this.parse8601(this.safeString(transaction, 'updatedAt'));
|
|
1612
|
-
const opened = this.parse8601(this.safeString(transaction, 'createdAt'));
|
|
1613
|
-
const timestamp = opened ? opened : updated;
|
|
1614
|
-
const type = (opened === undefined) ? 'deposit' : 'withdrawal';
|
|
1615
|
-
const currencyId = this.safeString(transaction, 'currencySymbol');
|
|
1616
|
-
const code = this.safeCurrencyCode(currencyId, currency);
|
|
1617
|
-
let status = 'pending';
|
|
1618
|
-
if (type === 'deposit') {
|
|
1619
|
-
//
|
|
1620
|
-
// deposits numConfirmations never reach the minConfirmations number
|
|
1621
|
-
// we set all of them to 'ok', otherwise they'd all be 'pending'
|
|
1622
|
-
//
|
|
1623
|
-
// const numConfirmations = this.safeInteger (transaction, 'Confirmations', 0);
|
|
1624
|
-
// const minConfirmations = this.safeInteger (currency['info'], 'MinConfirmation');
|
|
1625
|
-
// if (numConfirmations >= minConfirmations) {
|
|
1626
|
-
// status = 'ok';
|
|
1627
|
-
// }
|
|
1628
|
-
//
|
|
1629
|
-
status = 'ok';
|
|
1630
|
-
}
|
|
1631
|
-
else {
|
|
1632
|
-
const responseStatus = this.safeString(transaction, 'status');
|
|
1633
|
-
if (responseStatus === 'ERROR_INVALID_ADDRESS') {
|
|
1634
|
-
status = 'failed';
|
|
1635
|
-
}
|
|
1636
|
-
else if (responseStatus === 'CANCELLED') {
|
|
1637
|
-
status = 'canceled';
|
|
1638
|
-
}
|
|
1639
|
-
else if (responseStatus === 'PENDING') {
|
|
1640
|
-
status = 'pending';
|
|
1641
|
-
}
|
|
1642
|
-
else if (responseStatus === 'COMPLETED') {
|
|
1643
|
-
status = 'ok';
|
|
1644
|
-
}
|
|
1645
|
-
else if (responseStatus === 'AUTHORIZED' && (txid !== undefined)) {
|
|
1646
|
-
status = 'ok';
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
let feeCost = this.safeNumber(transaction, 'txCost');
|
|
1650
|
-
if (feeCost === undefined) {
|
|
1651
|
-
if (type === 'deposit') {
|
|
1652
|
-
// according to https://support.bittrex.com/hc/en-us/articles/115000199651-What-fees-does-Bittrex-charge-
|
|
1653
|
-
feeCost = 0;
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
return {
|
|
1657
|
-
'info': transaction,
|
|
1658
|
-
'id': id,
|
|
1659
|
-
'currency': code,
|
|
1660
|
-
'amount': amount,
|
|
1661
|
-
'network': undefined,
|
|
1662
|
-
'address': address,
|
|
1663
|
-
'addressTo': addressTo,
|
|
1664
|
-
'addressFrom': addressFrom,
|
|
1665
|
-
'tag': undefined,
|
|
1666
|
-
'tagTo': undefined,
|
|
1667
|
-
'tagFrom': undefined,
|
|
1668
|
-
'status': status,
|
|
1669
|
-
'type': type,
|
|
1670
|
-
'updated': updated,
|
|
1671
|
-
'txid': txid,
|
|
1672
|
-
'timestamp': timestamp,
|
|
1673
|
-
'datetime': this.iso8601(timestamp),
|
|
1674
|
-
'comment': undefined,
|
|
1675
|
-
'internal': undefined,
|
|
1676
|
-
'fee': {
|
|
1677
|
-
'currency': code,
|
|
1678
|
-
'cost': feeCost,
|
|
1679
|
-
},
|
|
1680
|
-
};
|
|
1681
|
-
}
|
|
1682
|
-
parseTimeInForce(timeInForce) {
|
|
1683
|
-
const timeInForces = {
|
|
1684
|
-
'GOOD_TIL_CANCELLED': 'GTC',
|
|
1685
|
-
'IMMEDIATE_OR_CANCEL': 'IOC',
|
|
1686
|
-
'FILL_OR_KILL': 'FOK',
|
|
1687
|
-
'POST_ONLY_GOOD_TIL_CANCELLED': 'PO',
|
|
1688
|
-
};
|
|
1689
|
-
return this.safeString(timeInForces, timeInForce, timeInForce);
|
|
1690
|
-
}
|
|
1691
|
-
parseOrder(order, market = undefined) {
|
|
1692
|
-
//
|
|
1693
|
-
// Spot createOrder, fetchOpenOrders, fetchClosedOrders, fetchOrder, cancelOrder
|
|
1694
|
-
//
|
|
1695
|
-
// {
|
|
1696
|
-
// "id": "1be35109-b763-44ce-b6ea-05b6b0735c0c",
|
|
1697
|
-
// "marketSymbol": "LTC-ETH",
|
|
1698
|
-
// "direction": "BUY",
|
|
1699
|
-
// "type": "LIMIT",
|
|
1700
|
-
// "quantity": "0.50000000",
|
|
1701
|
-
// "limit": "0.17846699",
|
|
1702
|
-
// "timeInForce": "GOOD_TIL_CANCELLED",
|
|
1703
|
-
// "clientOrderId": "ff156d39-fe01-44ca-8f21-b0afa19ef228",
|
|
1704
|
-
// "fillQuantity": "0.50000000",
|
|
1705
|
-
// "commission": "0.00022286",
|
|
1706
|
-
// "proceeds": "0.08914915",
|
|
1707
|
-
// "status": "CLOSED",
|
|
1708
|
-
// "createdAt": "2018-06-23T13:14:28.613Z",
|
|
1709
|
-
// "updatedAt": "2018-06-23T13:14:30.19Z",
|
|
1710
|
-
// "closedAt": "2018-06-23T13:14:30.19Z"
|
|
1711
|
-
// }
|
|
1712
|
-
//
|
|
1713
|
-
// Stop createOrder, fetchOpenOrders, fetchClosedOrders, fetchOrder, cancelOrder
|
|
1714
|
-
//
|
|
1715
|
-
// {
|
|
1716
|
-
// "id": "9791fe52-a3e5-4ac3-ae03-e327b2993571",
|
|
1717
|
-
// "marketSymbol": "BTC-USDT",
|
|
1718
|
-
// "operand": "LTE",
|
|
1719
|
-
// "triggerPrice": "0.1",
|
|
1720
|
-
// "orderToCreate": {
|
|
1721
|
-
// "marketSymbol": "BTC-USDT",
|
|
1722
|
-
// "direction": "BUY",
|
|
1723
|
-
// "type": "LIMIT",
|
|
1724
|
-
// "quantity": "0.0002",
|
|
1725
|
-
// "limit": "30000",
|
|
1726
|
-
// "timeInForce": "GOOD_TIL_CANCELLED"
|
|
1727
|
-
// },
|
|
1728
|
-
// "status": "OPEN",
|
|
1729
|
-
// "createdAt": "2022-04-19T21:02:14.17Z",
|
|
1730
|
-
// "updatedAt": "2022-04-19T21:02:14.17Z",
|
|
1731
|
-
// "closedAt": "2022-04-20T03:47:24.69Z"
|
|
1732
|
-
// }
|
|
1733
|
-
//
|
|
1734
|
-
const marketSymbol = this.safeString(order, 'marketSymbol');
|
|
1735
|
-
market = this.safeMarket(marketSymbol, market, '-');
|
|
1736
|
-
const symbol = market['symbol'];
|
|
1737
|
-
const feeCurrency = market['quote'];
|
|
1738
|
-
const createdAt = this.safeString(order, 'createdAt');
|
|
1739
|
-
const updatedAt = this.safeString(order, 'updatedAt');
|
|
1740
|
-
const closedAt = this.safeString(order, 'closedAt');
|
|
1741
|
-
const clientOrderId = this.safeString(order, 'clientOrderId');
|
|
1742
|
-
let lastTradeTimestamp = undefined;
|
|
1743
|
-
if (closedAt !== undefined) {
|
|
1744
|
-
lastTradeTimestamp = this.parse8601(closedAt);
|
|
1745
|
-
}
|
|
1746
|
-
else if (updatedAt) {
|
|
1747
|
-
lastTradeTimestamp = this.parse8601(updatedAt);
|
|
1748
|
-
}
|
|
1749
|
-
const timestamp = this.parse8601(createdAt);
|
|
1750
|
-
let direction = this.safeStringLower(order, 'direction');
|
|
1751
|
-
if (direction === undefined) {
|
|
1752
|
-
let conditionalOrder = this.safeValue(order, 'orderToCreate');
|
|
1753
|
-
if (conditionalOrder === undefined) {
|
|
1754
|
-
conditionalOrder = this.safeValue(order, 'orderToCancel');
|
|
1755
|
-
}
|
|
1756
|
-
direction = this.safeStringLower(conditionalOrder, 'direction');
|
|
1757
|
-
}
|
|
1758
|
-
let type = this.safeStringLower(order, 'type');
|
|
1759
|
-
if (type === undefined) {
|
|
1760
|
-
let conditionalOrder = this.safeValue(order, 'orderToCreate');
|
|
1761
|
-
if (conditionalOrder === undefined) {
|
|
1762
|
-
conditionalOrder = this.safeValue(order, 'orderToCancel');
|
|
1763
|
-
}
|
|
1764
|
-
type = this.safeStringLower(conditionalOrder, 'type');
|
|
1765
|
-
}
|
|
1766
|
-
let quantity = this.safeString(order, 'quantity');
|
|
1767
|
-
if (quantity === undefined) {
|
|
1768
|
-
let conditionalOrder = this.safeValue(order, 'orderToCreate');
|
|
1769
|
-
if (conditionalOrder === undefined) {
|
|
1770
|
-
conditionalOrder = this.safeValue(order, 'orderToCancel');
|
|
1771
|
-
}
|
|
1772
|
-
quantity = this.safeString(conditionalOrder, 'quantity');
|
|
1773
|
-
}
|
|
1774
|
-
let limit = this.safeString(order, 'limit');
|
|
1775
|
-
if (limit === undefined) {
|
|
1776
|
-
let conditionalOrder = this.safeValue(order, 'orderToCreate');
|
|
1777
|
-
if (conditionalOrder === undefined) {
|
|
1778
|
-
conditionalOrder = this.safeValue(order, 'orderToCancel');
|
|
1779
|
-
}
|
|
1780
|
-
limit = this.safeString(conditionalOrder, 'limit');
|
|
1781
|
-
}
|
|
1782
|
-
let timeInForce = this.parseTimeInForce(this.safeString(order, 'timeInForce'));
|
|
1783
|
-
if (timeInForce === undefined) {
|
|
1784
|
-
let conditionalOrder = this.safeValue(order, 'orderToCreate');
|
|
1785
|
-
if (conditionalOrder === undefined) {
|
|
1786
|
-
conditionalOrder = this.safeValue(order, 'orderToCancel');
|
|
1787
|
-
}
|
|
1788
|
-
timeInForce = this.parseTimeInForce(this.safeString(conditionalOrder, 'timeInForce'));
|
|
1789
|
-
}
|
|
1790
|
-
const fillQuantity = this.safeString(order, 'fillQuantity');
|
|
1791
|
-
const commission = this.safeNumber(order, 'commission');
|
|
1792
|
-
const proceeds = this.safeString(order, 'proceeds');
|
|
1793
|
-
const status = this.safeStringLower(order, 'status');
|
|
1794
|
-
const postOnly = (timeInForce === 'PO');
|
|
1795
|
-
return this.safeOrder({
|
|
1796
|
-
'id': this.safeString(order, 'id'),
|
|
1797
|
-
'clientOrderId': clientOrderId,
|
|
1798
|
-
'timestamp': timestamp,
|
|
1799
|
-
'datetime': this.iso8601(timestamp),
|
|
1800
|
-
'lastTradeTimestamp': lastTradeTimestamp,
|
|
1801
|
-
'symbol': symbol,
|
|
1802
|
-
'type': type,
|
|
1803
|
-
'timeInForce': timeInForce,
|
|
1804
|
-
'postOnly': postOnly,
|
|
1805
|
-
'side': direction,
|
|
1806
|
-
'price': limit,
|
|
1807
|
-
'stopPrice': this.safeString(order, 'triggerPrice'),
|
|
1808
|
-
'triggerPrice': this.safeString(order, 'triggerPrice'),
|
|
1809
|
-
'cost': proceeds,
|
|
1810
|
-
'average': undefined,
|
|
1811
|
-
'amount': quantity,
|
|
1812
|
-
'filled': fillQuantity,
|
|
1813
|
-
'remaining': undefined,
|
|
1814
|
-
'status': status,
|
|
1815
|
-
'fee': {
|
|
1816
|
-
'cost': commission,
|
|
1817
|
-
'currency': feeCurrency,
|
|
1818
|
-
},
|
|
1819
|
-
'info': order,
|
|
1820
|
-
'trades': undefined,
|
|
1821
|
-
}, market);
|
|
1822
|
-
}
|
|
1823
|
-
parseOrders(orders, market = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1824
|
-
if (this.options['fetchClosedOrdersFilterBySince']) {
|
|
1825
|
-
return super.parseOrders(orders, market, since, limit, params);
|
|
1826
|
-
}
|
|
1827
|
-
else {
|
|
1828
|
-
return super.parseOrders(orders, market, undefined, limit, params);
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
parseOrderStatus(status) {
|
|
1832
|
-
const statuses = {
|
|
1833
|
-
'CLOSED': 'closed',
|
|
1834
|
-
'OPEN': 'open',
|
|
1835
|
-
'CANCELLED': 'canceled',
|
|
1836
|
-
'CANCELED': 'canceled',
|
|
1837
|
-
};
|
|
1838
|
-
return this.safeString(statuses, status, status);
|
|
1839
|
-
}
|
|
1840
|
-
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1841
|
-
/**
|
|
1842
|
-
* @method
|
|
1843
|
-
* @name bittrex#fetchOrder
|
|
1844
|
-
* @description fetches information on an order made by the user
|
|
1845
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1846
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1847
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1848
|
-
*/
|
|
1849
|
-
await this.loadMarkets();
|
|
1850
|
-
const stop = this.safeValue(params, 'stop');
|
|
1851
|
-
let market = undefined;
|
|
1852
|
-
if (symbol !== undefined) {
|
|
1853
|
-
market = this.market(symbol);
|
|
1854
|
-
}
|
|
1855
|
-
let response = undefined;
|
|
1856
|
-
let method = undefined;
|
|
1857
|
-
try {
|
|
1858
|
-
const request = {};
|
|
1859
|
-
if (stop) {
|
|
1860
|
-
method = 'privateGetConditionalOrdersConditionalOrderId';
|
|
1861
|
-
request['conditionalOrderId'] = id;
|
|
1862
|
-
}
|
|
1863
|
-
else {
|
|
1864
|
-
method = 'privateGetOrdersOrderId';
|
|
1865
|
-
request['orderId'] = id;
|
|
1866
|
-
}
|
|
1867
|
-
const query = this.omit(params, 'stop');
|
|
1868
|
-
response = await this[method](this.extend(request, query));
|
|
1869
|
-
}
|
|
1870
|
-
catch (e) {
|
|
1871
|
-
if (this.last_json_response) {
|
|
1872
|
-
const message = this.safeString(this.last_json_response, 'message');
|
|
1873
|
-
if (message === 'UUID_INVALID') {
|
|
1874
|
-
throw new errors.OrderNotFound(this.id + ' fetchOrder() error: ' + this.last_http_response);
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
throw e;
|
|
1878
|
-
}
|
|
1879
|
-
return this.parseOrder(response, market);
|
|
1880
|
-
}
|
|
1881
|
-
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1882
|
-
/**
|
|
1883
|
-
* @method
|
|
1884
|
-
* @name bittrex#fetchMyTrades
|
|
1885
|
-
* @description fetch all trades made by the user
|
|
1886
|
-
* @param {string} symbol unified market symbol
|
|
1887
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1888
|
-
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1889
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1890
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1891
|
-
*/
|
|
1892
|
-
await this.loadMarkets();
|
|
1893
|
-
const request = {};
|
|
1894
|
-
if (limit !== undefined) {
|
|
1895
|
-
request['pageSize'] = limit;
|
|
1896
|
-
}
|
|
1897
|
-
if (since !== undefined) {
|
|
1898
|
-
request['startDate'] = this.ymdhms(since, 'T') + 'Z';
|
|
1899
|
-
}
|
|
1900
|
-
let market = undefined;
|
|
1901
|
-
if (symbol !== undefined) {
|
|
1902
|
-
market = this.market(symbol);
|
|
1903
|
-
request['marketSymbol'] = market['id'];
|
|
1904
|
-
}
|
|
1905
|
-
const response = await this.privateGetExecutions(this.extend(request, params));
|
|
1906
|
-
return this.parseTrades(response, market, since, limit);
|
|
1907
|
-
}
|
|
1908
|
-
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1909
|
-
/**
|
|
1910
|
-
* @method
|
|
1911
|
-
* @name bittrex#fetchClosedOrders
|
|
1912
|
-
* @description fetches information on multiple closed orders made by the user
|
|
1913
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1914
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1915
|
-
* @param {int} [limit] the maximum number of orde structures to retrieve
|
|
1916
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1917
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1918
|
-
*/
|
|
1919
|
-
await this.loadMarkets();
|
|
1920
|
-
const stop = this.safeValue(params, 'stop');
|
|
1921
|
-
const request = {};
|
|
1922
|
-
if (limit !== undefined) {
|
|
1923
|
-
request['pageSize'] = limit;
|
|
1924
|
-
}
|
|
1925
|
-
if (since !== undefined) {
|
|
1926
|
-
request['startDate'] = this.ymdhms(since, 'T') + 'Z';
|
|
1927
|
-
}
|
|
1928
|
-
let market = undefined;
|
|
1929
|
-
if (symbol !== undefined) {
|
|
1930
|
-
market = this.market(symbol);
|
|
1931
|
-
// because of this line we will have to rethink the entire v3
|
|
1932
|
-
// in other words, markets define all the rest of the API
|
|
1933
|
-
// and v3 market ids are reversed in comparison to v1
|
|
1934
|
-
// v3 has to be a completely separate implementation
|
|
1935
|
-
// otherwise we will have to shuffle symbols and currencies everywhere
|
|
1936
|
-
// which is prone to errors, as was shown here
|
|
1937
|
-
// https://github.com/ccxt/ccxt/pull/5219#issuecomment-499646209
|
|
1938
|
-
request['marketSymbol'] = market['base'] + '-' + market['quote'];
|
|
1939
|
-
}
|
|
1940
|
-
let method = 'privateGetOrdersClosed';
|
|
1941
|
-
if (stop) {
|
|
1942
|
-
method = 'privateGetConditionalOrdersClosed';
|
|
1943
|
-
}
|
|
1944
|
-
const query = this.omit(params, 'stop');
|
|
1945
|
-
const response = await this[method](this.extend(request, query));
|
|
1946
|
-
//
|
|
1947
|
-
// Spot
|
|
1948
|
-
//
|
|
1949
|
-
// [
|
|
1950
|
-
// {
|
|
1951
|
-
// "id": "df6cf5ee-fc27-4b61-991a-cc94b6459ac9",
|
|
1952
|
-
// "marketSymbol": "BTC-USDT",
|
|
1953
|
-
// "direction": "BUY",
|
|
1954
|
-
// "type": "LIMIT",
|
|
1955
|
-
// "quantity": "0.00023277",
|
|
1956
|
-
// "limit": "30000.00000000",
|
|
1957
|
-
// "timeInForce": "GOOD_TIL_CANCELLED",
|
|
1958
|
-
// "fillQuantity": "0.00000000",
|
|
1959
|
-
// "commission": "0.00000000",
|
|
1960
|
-
// "proceeds": "0.00000000",
|
|
1961
|
-
// "status": "OPEN",
|
|
1962
|
-
// "createdAt": "2022-04-20T02:33:53.16Z",
|
|
1963
|
-
// "updatedAt": "2022-04-20T02:33:53.16Z"
|
|
1964
|
-
// }
|
|
1965
|
-
// ]
|
|
1966
|
-
//
|
|
1967
|
-
// Stop
|
|
1968
|
-
//
|
|
1969
|
-
// [
|
|
1970
|
-
// {
|
|
1971
|
-
// "id": "f64f7c4f-295c-408b-9cbc-601981abf100",
|
|
1972
|
-
// "marketSymbol": "BTC-USDT",
|
|
1973
|
-
// "operand": "LTE",
|
|
1974
|
-
// "triggerPrice": "0.10000000",
|
|
1975
|
-
// "orderToCreate": {
|
|
1976
|
-
// "marketSymbol": "BTC-USDT",
|
|
1977
|
-
// "direction": "BUY",
|
|
1978
|
-
// "type": "LIMIT",
|
|
1979
|
-
// "quantity": "0.00020000",
|
|
1980
|
-
// "limit": "30000.00000000",
|
|
1981
|
-
// "timeInForce": "GOOD_TIL_CANCELLED"
|
|
1982
|
-
// },
|
|
1983
|
-
// "status": "OPEN",
|
|
1984
|
-
// "createdAt": "2022-04-20T02:38:12.26Z",
|
|
1985
|
-
// "updatedAt": "2022-04-20T02:38:12.26Z"
|
|
1986
|
-
// }
|
|
1987
|
-
// ]
|
|
1988
|
-
//
|
|
1989
|
-
return this.parseOrders(response, market, since, limit);
|
|
1990
|
-
}
|
|
1991
|
-
async createDepositAddress(code, params = {}) {
|
|
1992
|
-
/**
|
|
1993
|
-
* @method
|
|
1994
|
-
* @name bittrex#createDepositAddress
|
|
1995
|
-
* @description create a currency deposit address
|
|
1996
|
-
* @param {string} code unified currency code of the currency for the deposit address
|
|
1997
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1998
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1999
|
-
*/
|
|
2000
|
-
await this.loadMarkets();
|
|
2001
|
-
const currency = this.currency(code);
|
|
2002
|
-
const request = {
|
|
2003
|
-
'currencySymbol': currency['id'],
|
|
2004
|
-
};
|
|
2005
|
-
const response = await this.privatePostAddresses(this.extend(request, params));
|
|
2006
|
-
//
|
|
2007
|
-
// {
|
|
2008
|
-
// "status":"PROVISIONED",
|
|
2009
|
-
// "currencySymbol":"XRP",
|
|
2010
|
-
// "cryptoAddress":"rPVMhWBsfF9iMXYj3aAzJVkPDTFNSyWdKy",
|
|
2011
|
-
// "cryptoAddressTag":"392034158"
|
|
2012
|
-
// }
|
|
2013
|
-
//
|
|
2014
|
-
const address = this.safeString(response, 'cryptoAddress');
|
|
2015
|
-
const message = this.safeString(response, 'status');
|
|
2016
|
-
if (!address || message === 'REQUESTED') {
|
|
2017
|
-
throw new errors.AddressPending(this.id + ' the address for ' + code + ' is being generated (pending, not ready yet, retry again later)');
|
|
2018
|
-
}
|
|
2019
|
-
this.checkAddress(address);
|
|
2020
|
-
return {
|
|
2021
|
-
'currency': code,
|
|
2022
|
-
'address': address,
|
|
2023
|
-
'tag': this.safeString(response, 'cryptoAddressTag'),
|
|
2024
|
-
'network': undefined,
|
|
2025
|
-
'info': response,
|
|
2026
|
-
};
|
|
2027
|
-
}
|
|
2028
|
-
async fetchDepositAddress(code, params = {}) {
|
|
2029
|
-
/**
|
|
2030
|
-
* @method
|
|
2031
|
-
* @name bittrex#fetchDepositAddress
|
|
2032
|
-
* @description fetch the deposit address for a currency associated with this account
|
|
2033
|
-
* @param {string} code unified currency code
|
|
2034
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2035
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
2036
|
-
*/
|
|
2037
|
-
await this.loadMarkets();
|
|
2038
|
-
const currency = this.currency(code);
|
|
2039
|
-
const request = {
|
|
2040
|
-
'currencySymbol': currency['id'],
|
|
2041
|
-
};
|
|
2042
|
-
const response = await this.privateGetAddressesCurrencySymbol(this.extend(request, params));
|
|
2043
|
-
//
|
|
2044
|
-
// {
|
|
2045
|
-
// "status":"PROVISIONED",
|
|
2046
|
-
// "currencySymbol":"XRP",
|
|
2047
|
-
// "cryptoAddress":"rPVMhWBsfF9iMXYj3aAzJVkPDTFNSyWdKy",
|
|
2048
|
-
// "cryptoAddressTag":"392034158"
|
|
2049
|
-
// }
|
|
2050
|
-
//
|
|
2051
|
-
const address = this.safeString(response, 'cryptoAddress');
|
|
2052
|
-
const message = this.safeString(response, 'status');
|
|
2053
|
-
if (!address || message === 'REQUESTED') {
|
|
2054
|
-
throw new errors.AddressPending(this.id + ' the address for ' + code + ' is being generated (pending, not ready yet, retry again later)');
|
|
2055
|
-
}
|
|
2056
|
-
this.checkAddress(address);
|
|
2057
|
-
return {
|
|
2058
|
-
'currency': code,
|
|
2059
|
-
'address': address,
|
|
2060
|
-
'tag': this.safeString(response, 'cryptoAddressTag'),
|
|
2061
|
-
'network': undefined,
|
|
2062
|
-
'info': response,
|
|
2063
|
-
};
|
|
2064
|
-
}
|
|
2065
|
-
parseDepositWithdrawFee(fee, currency = undefined) {
|
|
2066
|
-
//
|
|
2067
|
-
// {
|
|
2068
|
-
// "symbol": "APXP",
|
|
2069
|
-
// "name": "APEX Protocol",
|
|
2070
|
-
// "coinType": "ETH_CONTRACT",
|
|
2071
|
-
// "status": "ONLINE",
|
|
2072
|
-
// "minConfirmations": 36,
|
|
2073
|
-
// "notice": "",
|
|
2074
|
-
// "txFee": "4702.00000000",
|
|
2075
|
-
// "logoUrl": "https://bittrex.com/content/dynamic/currencies/logos/6cbff899-0ba6-4284-931b-5306a0a2333a.png",
|
|
2076
|
-
// "prohibitedIn": [
|
|
2077
|
-
// "US"
|
|
2078
|
-
// ],
|
|
2079
|
-
// "baseAddress": "0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98",
|
|
2080
|
-
// "associatedTermsOfService": [
|
|
2081
|
-
// ],
|
|
2082
|
-
// "tags": [
|
|
2083
|
-
// ]
|
|
2084
|
-
// }
|
|
2085
|
-
//
|
|
2086
|
-
return {
|
|
2087
|
-
'info': fee,
|
|
2088
|
-
'withdraw': {
|
|
2089
|
-
'fee': this.safeNumber(fee, 'txFee'),
|
|
2090
|
-
'percentage': false,
|
|
2091
|
-
},
|
|
2092
|
-
'deposit': {
|
|
2093
|
-
'fee': undefined,
|
|
2094
|
-
'percentage': undefined,
|
|
2095
|
-
},
|
|
2096
|
-
'networks': {},
|
|
2097
|
-
};
|
|
2098
|
-
}
|
|
2099
|
-
async fetchDepositWithdrawFees(codes = undefined, params = {}) {
|
|
2100
|
-
/**
|
|
2101
|
-
* @method
|
|
2102
|
-
* @name bittrex#fetchDepositWithdrawFees
|
|
2103
|
-
* @description fetch deposit and withdraw fees
|
|
2104
|
-
* @param {string[]|undefined} codes list of unified currency codes
|
|
2105
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2106
|
-
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
2107
|
-
*/
|
|
2108
|
-
await this.loadMarkets();
|
|
2109
|
-
const response = await this.publicGetCurrencies(params);
|
|
2110
|
-
//
|
|
2111
|
-
// [
|
|
2112
|
-
// {
|
|
2113
|
-
// "symbol": "APXP",
|
|
2114
|
-
// "name": "APEX Protocol",
|
|
2115
|
-
// "coinType": "ETH_CONTRACT",
|
|
2116
|
-
// "status": "ONLINE",
|
|
2117
|
-
// "minConfirmations": 36,
|
|
2118
|
-
// "notice": "",
|
|
2119
|
-
// "txFee": "4702.00000000",
|
|
2120
|
-
// "logoUrl": "https://bittrex.com/content/dynamic/currencies/logos/6cbff899-0ba6-4284-931b-5306a0a2333a.png",
|
|
2121
|
-
// "prohibitedIn": [
|
|
2122
|
-
// "US"
|
|
2123
|
-
// ],
|
|
2124
|
-
// "baseAddress": "0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98",
|
|
2125
|
-
// "associatedTermsOfService": [
|
|
2126
|
-
// ],
|
|
2127
|
-
// "tags": [
|
|
2128
|
-
// ]
|
|
2129
|
-
// },
|
|
2130
|
-
// ]
|
|
2131
|
-
//
|
|
2132
|
-
return this.parseDepositWithdrawFees(response, codes, 'symbol');
|
|
2133
|
-
}
|
|
2134
|
-
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2135
|
-
/**
|
|
2136
|
-
* @method
|
|
2137
|
-
* @name bittrex#withdraw
|
|
2138
|
-
* @description make a withdrawal
|
|
2139
|
-
* @param {string} code unified currency code
|
|
2140
|
-
* @param {float} amount the amount to withdraw
|
|
2141
|
-
* @param {string} address the address to withdraw to
|
|
2142
|
-
* @param {string} tag
|
|
2143
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2144
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2145
|
-
*/
|
|
2146
|
-
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
2147
|
-
this.checkAddress(address);
|
|
2148
|
-
await this.loadMarkets();
|
|
2149
|
-
const currency = this.currency(code);
|
|
2150
|
-
const request = {
|
|
2151
|
-
'currencySymbol': currency['id'],
|
|
2152
|
-
'quantity': amount,
|
|
2153
|
-
'cryptoAddress': address,
|
|
2154
|
-
};
|
|
2155
|
-
if (tag !== undefined) {
|
|
2156
|
-
request['cryptoAddressTag'] = tag;
|
|
2157
|
-
}
|
|
2158
|
-
const response = await this.privatePostWithdrawals(this.extend(request, params));
|
|
2159
|
-
//
|
|
2160
|
-
// {
|
|
2161
|
-
// "currencySymbol": "string",
|
|
2162
|
-
// "quantity": "number (double)",
|
|
2163
|
-
// "cryptoAddress": "string",
|
|
2164
|
-
// "cryptoAddressTag": "string",
|
|
2165
|
-
// "fundsTransferMethodId": "string (uuid)",
|
|
2166
|
-
// "clientWithdrawalId": "string (uuid)"
|
|
2167
|
-
// }
|
|
2168
|
-
//
|
|
2169
|
-
return this.parseTransaction(response, currency);
|
|
2170
|
-
}
|
|
2171
|
-
sign(path, api = 'v3', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2172
|
-
let url = this.implodeParams(this.urls['api'][api], {
|
|
2173
|
-
'hostname': this.hostname,
|
|
2174
|
-
}) + '/';
|
|
2175
|
-
if (api === 'private') {
|
|
2176
|
-
url += this.version + '/';
|
|
2177
|
-
this.checkRequiredCredentials();
|
|
2178
|
-
url += this.implodeParams(path, params);
|
|
2179
|
-
params = this.omit(params, this.extractParams(path));
|
|
2180
|
-
let hashString = '';
|
|
2181
|
-
if (method === 'POST') {
|
|
2182
|
-
body = this.json(params);
|
|
2183
|
-
hashString = body;
|
|
2184
|
-
}
|
|
2185
|
-
else {
|
|
2186
|
-
if (Object.keys(params).length) {
|
|
2187
|
-
url += '?' + this.rawencode(params);
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
const contentHash = this.hash(this.encode(hashString), sha512.sha512, 'hex');
|
|
2191
|
-
const timestamp = this.milliseconds().toString();
|
|
2192
|
-
let auth = timestamp + url + method + contentHash;
|
|
2193
|
-
const subaccountId = this.safeValue(this.options, 'subaccountId');
|
|
2194
|
-
if (subaccountId !== undefined) {
|
|
2195
|
-
auth += subaccountId;
|
|
2196
|
-
}
|
|
2197
|
-
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha512.sha512);
|
|
2198
|
-
headers = {
|
|
2199
|
-
'Api-Key': this.apiKey,
|
|
2200
|
-
'Api-Timestamp': timestamp,
|
|
2201
|
-
'Api-Content-Hash': contentHash,
|
|
2202
|
-
'Api-Signature': signature,
|
|
2203
|
-
};
|
|
2204
|
-
if (subaccountId !== undefined) {
|
|
2205
|
-
headers['Api-Subaccount-Id'] = subaccountId;
|
|
2206
|
-
}
|
|
2207
|
-
if (method === 'POST') {
|
|
2208
|
-
headers['Content-Type'] = 'application/json';
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
else {
|
|
2212
|
-
if (api === 'public') {
|
|
2213
|
-
url += this.version + '/';
|
|
2214
|
-
}
|
|
2215
|
-
url += this.implodeParams(path, params);
|
|
2216
|
-
params = this.omit(params, this.extractParams(path));
|
|
2217
|
-
if (Object.keys(params).length) {
|
|
2218
|
-
url += '?' + this.urlencode(params);
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
2221
|
-
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2222
|
-
}
|
|
2223
|
-
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2224
|
-
if (response === undefined) {
|
|
2225
|
-
return undefined; // fallback to default error handler
|
|
2226
|
-
}
|
|
2227
|
-
//
|
|
2228
|
-
// { success: false, message: "message" }
|
|
2229
|
-
//
|
|
2230
|
-
if (body[0] === '{') {
|
|
2231
|
-
const feedback = this.id + ' ' + body;
|
|
2232
|
-
let success = this.safeValue(response, 'success');
|
|
2233
|
-
if (success === undefined) {
|
|
2234
|
-
const codeInner = this.safeString(response, 'code');
|
|
2235
|
-
if ((codeInner === 'NOT_FOUND') && (url.indexOf('addresses') >= 0)) {
|
|
2236
|
-
throw new errors.InvalidAddress(feedback);
|
|
2237
|
-
}
|
|
2238
|
-
if (codeInner !== undefined) {
|
|
2239
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], codeInner, feedback);
|
|
2240
|
-
this.throwBroadlyMatchedException(this.exceptions['broad'], codeInner, feedback);
|
|
2241
|
-
}
|
|
2242
|
-
// throw new ExchangeError (this.id + ' malformed response ' + this.json (response));
|
|
2243
|
-
return undefined;
|
|
2244
|
-
}
|
|
2245
|
-
if (typeof success === 'string') {
|
|
2246
|
-
// bleutrade uses string instead of boolean
|
|
2247
|
-
success = (success === 'true');
|
|
2248
|
-
}
|
|
2249
|
-
if (!success) {
|
|
2250
|
-
const message = this.safeString(response, 'message');
|
|
2251
|
-
if (message === 'APIKEY_INVALID') {
|
|
2252
|
-
if (this.options['hasAlreadyAuthenticatedSuccessfully']) {
|
|
2253
|
-
throw new errors.DDoSProtection(feedback);
|
|
2254
|
-
}
|
|
2255
|
-
else {
|
|
2256
|
-
throw new errors.AuthenticationError(feedback);
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
|
-
// https://github.com/ccxt/ccxt/issues/4932
|
|
2260
|
-
// the following two lines are now redundant, see line 171 in describe()
|
|
2261
|
-
//
|
|
2262
|
-
// if (message === 'DUST_TRADE_DISALLOWED_MIN_VALUE_50K_SAT')
|
|
2263
|
-
// throw new InvalidOrder (this.id + ' order cost should be over 50k satoshi ' + this.json (response));
|
|
2264
|
-
//
|
|
2265
|
-
if (message === 'INVALID_ORDER') {
|
|
2266
|
-
// Bittrex will return an ambiguous INVALID_ORDER message
|
|
2267
|
-
// upon canceling already-canceled and closed orders
|
|
2268
|
-
// therefore this special case for cancelOrder
|
|
2269
|
-
// let url = 'https://bittrex.com/api/v1.1/market/cancel?apikey=API_KEY&uuid=ORDER_UUID'
|
|
2270
|
-
const cancel = 'cancel';
|
|
2271
|
-
const indexOfCancel = url.indexOf(cancel);
|
|
2272
|
-
if (indexOfCancel >= 0) {
|
|
2273
|
-
const urlParts = url.split('?');
|
|
2274
|
-
const numParts = urlParts.length;
|
|
2275
|
-
if (numParts > 1) {
|
|
2276
|
-
const query = urlParts[1];
|
|
2277
|
-
const params = query.split('&');
|
|
2278
|
-
const numParams = params.length;
|
|
2279
|
-
let orderId = undefined;
|
|
2280
|
-
for (let i = 0; i < numParams; i++) {
|
|
2281
|
-
const param = params[i];
|
|
2282
|
-
const keyValue = param.split('=');
|
|
2283
|
-
if (keyValue[0] === 'uuid') {
|
|
2284
|
-
orderId = keyValue[1];
|
|
2285
|
-
break;
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
if (orderId !== undefined) {
|
|
2289
|
-
throw new errors.OrderNotFound(this.id + ' cancelOrder ' + orderId + ' ' + this.json(response));
|
|
2290
|
-
}
|
|
2291
|
-
else {
|
|
2292
|
-
throw new errors.OrderNotFound(this.id + ' cancelOrder ' + this.json(response));
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
}
|
|
2297
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2298
|
-
if (message !== undefined) {
|
|
2299
|
-
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2300
|
-
}
|
|
2301
|
-
throw new errors.ExchangeError(feedback);
|
|
2302
|
-
}
|
|
2303
|
-
}
|
|
2304
|
-
return undefined;
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
module.exports = bittrex;
|