ccxt 4.1.77 → 4.1.78

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.
Files changed (55) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.js +500 -176
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/bingx.js +3 -2
  6. package/dist/cjs/src/bitget.js +71 -0
  7. package/dist/cjs/src/bitmart.js +9 -13
  8. package/dist/cjs/src/bybit.js +2 -0
  9. package/dist/cjs/src/coinbase.js +12 -3
  10. package/dist/cjs/src/coinex.js +7 -11
  11. package/dist/cjs/src/gate.js +4 -0
  12. package/dist/cjs/src/hitbtc.js +326 -123
  13. package/dist/cjs/src/idex.js +10 -1
  14. package/dist/cjs/src/mexc.js +33 -5
  15. package/dist/cjs/src/okx.js +5 -9
  16. package/dist/cjs/src/pro/binance.js +10 -2
  17. package/dist/cjs/src/pro/binanceus.js +1 -0
  18. package/dist/cjs/src/pro/gate.js +1 -1
  19. package/dist/cjs/src/upbit.js +5 -5
  20. package/js/ccxt.d.ts +1 -1
  21. package/js/ccxt.js +1 -1
  22. package/js/src/abstract/bybit.d.ts +2 -0
  23. package/js/src/abstract/gate.d.ts +3 -0
  24. package/js/src/abstract/gateio.d.ts +3 -0
  25. package/js/src/abstract/okx.d.ts +2 -0
  26. package/js/src/base/Exchange.d.ts +1 -1
  27. package/js/src/bingx.js +3 -2
  28. package/js/src/bitget.d.ts +5 -4
  29. package/js/src/bitget.js +71 -0
  30. package/js/src/bitmart.js +9 -13
  31. package/js/src/bybit.js +2 -0
  32. package/js/src/coinbase.js +12 -3
  33. package/js/src/coinex.js +7 -11
  34. package/js/src/gate.js +4 -0
  35. package/js/src/hitbtc.js +326 -123
  36. package/js/src/idex.js +10 -1
  37. package/js/src/mexc.d.ts +1 -0
  38. package/js/src/mexc.js +33 -5
  39. package/js/src/okx.js +5 -9
  40. package/js/src/pro/binance.js +10 -2
  41. package/js/src/pro/binanceus.js +1 -0
  42. package/js/src/pro/gate.js +1 -1
  43. package/js/src/upbit.js +5 -5
  44. package/package.json +1 -1
  45. package/skip-tests.json +2 -1
  46. package/js/src/huobipro.d.ts +0 -4
  47. package/js/src/huobipro.js +0 -20
  48. package/js/src/mexc3.d.ts +0 -4
  49. package/js/src/mexc3.js +0 -17
  50. package/js/src/okex.d.ts +0 -4
  51. package/js/src/okex.js +0 -17
  52. package/js/src/okex5.d.ts +0 -4
  53. package/js/src/okex5.js +0 -17
  54. package/js/src/tidex.d.ts +0 -36
  55. package/js/src/tidex.js +0 -1068
package/js/src/tidex.js DELETED
@@ -1,1068 +0,0 @@
1
- // ----------------------------------------------------------------------------
2
-
3
- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
- // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
-
7
- import Exchange from './abstract/tidex.js';
8
- import { ExchangeError, ArgumentsRequired, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, DDoSProtection, InvalidOrder, AuthenticationError, PermissionDenied } from './base/errors.js';
9
- import { Precise } from './base/Precise.js';
10
- import { TICK_SIZE } from './base/functions/number.js';
11
- import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
12
- /**
13
- * @class tidex
14
- * @extends Exchange
15
- */
16
- export default class tidex extends Exchange {
17
- describe() {
18
- return this.deepExtend(super.describe(), {
19
- 'id': 'tidex',
20
- 'name': 'Tidex',
21
- 'countries': ['UK'],
22
- 'rateLimit': 2000,
23
- 'version': '3',
24
- 'userAgent': this.userAgents['chrome'],
25
- 'has': {
26
- 'CORS': undefined,
27
- 'spot': true,
28
- 'margin': false,
29
- 'swap': false,
30
- 'future': false,
31
- 'option': false,
32
- 'addMargin': false,
33
- 'cancelOrder': true,
34
- 'createMarketOrder': false,
35
- 'createOrder': true,
36
- 'createReduceOnlyOrder': false,
37
- 'fetchBalance': true,
38
- 'fetchBorrowRateHistories': false,
39
- 'fetchBorrowRateHistory': false,
40
- 'fetchCrossBorrowRate': false,
41
- 'fetchCrossBorrowRates': false,
42
- 'fetchCurrencies': true,
43
- 'fetchFundingHistory': false,
44
- 'fetchFundingRate': false,
45
- 'fetchFundingRateHistory': false,
46
- 'fetchFundingRates': false,
47
- 'fetchIndexOHLCV': false,
48
- 'fetchIsolatedBorrowRate': false,
49
- 'fetchIsolatedBorrowRates': false,
50
- 'fetchLeverage': false,
51
- 'fetchLeverageTiers': false,
52
- 'fetchMarginMode': false,
53
- 'fetchMarkets': true,
54
- 'fetchMarkOHLCV': false,
55
- 'fetchMyTrades': true,
56
- 'fetchOpenInterestHistory': false,
57
- 'fetchOpenOrders': true,
58
- 'fetchOrder': true,
59
- 'fetchOrderBook': true,
60
- 'fetchOrderBooks': true,
61
- 'fetchPosition': false,
62
- 'fetchPositionMode': false,
63
- 'fetchPositions': false,
64
- 'fetchPositionsRisk': false,
65
- 'fetchPremiumIndexOHLCV': false,
66
- 'fetchTicker': true,
67
- 'fetchTickers': true,
68
- 'fetchTrades': true,
69
- 'reduceMargin': false,
70
- 'setLeverage': false,
71
- 'setMarginMode': false,
72
- 'setPositionMode': false,
73
- 'withdraw': true,
74
- },
75
- 'urls': {
76
- 'logo': 'https://user-images.githubusercontent.com/1294454/30781780-03149dc4-a12e-11e7-82bb-313b269d24d4.jpg',
77
- 'api': {
78
- 'web': 'https://gate.tidex.com/api',
79
- 'public': 'https://api.tidex.com/api/3',
80
- 'private': 'https://api.tidex.com/tapi',
81
- },
82
- 'www': 'https://tidex.com',
83
- 'doc': 'https://tidex.com/exchange/public-api',
84
- 'referral': 'https://tidex.com/exchange',
85
- 'fees': [
86
- 'https://tidex.com/exchange/assets-spec',
87
- 'https://tidex.com/exchange/pairs-spec',
88
- ],
89
- },
90
- 'api': {
91
- 'web': {
92
- 'get': [
93
- 'currency',
94
- 'pairs',
95
- 'tickers',
96
- 'orders',
97
- 'ordershistory',
98
- 'trade-data',
99
- 'trade-data/{id}',
100
- ],
101
- },
102
- 'public': {
103
- 'get': [
104
- 'info',
105
- 'ticker/{pair}',
106
- 'depth/{pair}',
107
- 'trades/{pair}',
108
- ],
109
- },
110
- 'private': {
111
- 'post': [
112
- 'getInfoExt',
113
- 'getInfo',
114
- 'Trade',
115
- 'ActiveOrders',
116
- 'OrderInfo',
117
- 'CancelOrder',
118
- 'TradeHistory',
119
- 'getDepositAddress',
120
- 'createWithdraw',
121
- 'getWithdraw',
122
- ],
123
- },
124
- },
125
- 'fees': {
126
- 'trading': {
127
- 'feeSide': 'get',
128
- 'tierBased': false,
129
- 'percentage': true,
130
- 'taker': this.parseNumber('0.001'),
131
- 'maker': this.parseNumber('0.001'),
132
- },
133
- },
134
- 'commonCurrencies': {
135
- 'DSH': 'DASH',
136
- 'EMGO': 'MGO',
137
- 'MGO': 'WMGO',
138
- },
139
- 'precisionMode': TICK_SIZE,
140
- 'exceptions': {
141
- 'exact': {
142
- '803': InvalidOrder,
143
- '804': InvalidOrder,
144
- '805': InvalidOrder,
145
- '806': InvalidOrder,
146
- '807': InvalidOrder,
147
- '831': InsufficientFunds,
148
- '832': InsufficientFunds,
149
- '833': OrderNotFound, // "Order with id X was not found." (cancelling non-existent, closed and cancelled order)
150
- },
151
- 'broad': {
152
- 'Invalid pair name': ExchangeError,
153
- 'invalid api key': AuthenticationError,
154
- 'invalid sign': AuthenticationError,
155
- 'api key dont have trade permission': AuthenticationError,
156
- 'invalid parameter': InvalidOrder,
157
- 'invalid order': InvalidOrder,
158
- 'Requests too often': DDoSProtection,
159
- 'not available': ExchangeNotAvailable,
160
- 'data unavailable': ExchangeNotAvailable,
161
- 'external service unavailable': ExchangeNotAvailable,
162
- 'IP restricted': PermissionDenied, // {"success":0,"code":0,"error":"IP restricted (223.xxx.xxx.xxx)"}
163
- },
164
- },
165
- 'options': {
166
- 'fetchTickersMaxLength': 2048,
167
- },
168
- 'orders': {}, // orders cache / emulation
169
- });
170
- }
171
- async fetchCurrencies(params = {}) {
172
- /**
173
- * @method
174
- * @name tidex#fetchCurrencies
175
- * @description fetches all available currencies on an exchange
176
- * @param {object} [params] extra parameters specific to the exchange API endpoint
177
- * @returns {object} an associative dictionary of currencies
178
- */
179
- const response = await this.webGetCurrency(params);
180
- //
181
- // [
182
- // {
183
- // "id":2,
184
- // "symbol":"BTC",
185
- // "type":2,
186
- // "name":"Bitcoin",
187
- // "amountPoint":8,
188
- // "depositEnable":true,
189
- // "depositMinAmount":0.0005,
190
- // "withdrawEnable":true,
191
- // "withdrawFee":0.0004,
192
- // "withdrawMinAmount":0.0005,
193
- // "settings":{
194
- // "Blockchain":"https://blockchair.com/bitcoin/",
195
- // "TxUrl":"https://blockchair.com/bitcoin/transaction/{0}",
196
- // "AddrUrl":"https://blockchair.com/bitcoin/address/{0}",
197
- // "ConfirmationCount":3,
198
- // "NeedMemo":false
199
- // },
200
- // "visible":true,
201
- // "isDelisted":false
202
- // }
203
- // ]
204
- //
205
- const result = {};
206
- for (let i = 0; i < response.length; i++) {
207
- const currency = response[i];
208
- const id = this.safeString(currency, 'symbol');
209
- const code = this.safeCurrencyCode(id);
210
- const visible = this.safeValue(currency, 'visible');
211
- let active = visible === true;
212
- const withdrawEnable = this.safeValue(currency, 'withdrawEnable', true);
213
- const depositEnable = this.safeValue(currency, 'depositEnable', true);
214
- if (!withdrawEnable || !depositEnable) {
215
- active = false;
216
- }
217
- const name = this.safeString(currency, 'name');
218
- const fee = this.safeNumber(currency, 'withdrawFee');
219
- result[code] = {
220
- 'id': id,
221
- 'code': code,
222
- 'name': name,
223
- 'active': active,
224
- 'deposit': depositEnable,
225
- 'withdraw': withdrawEnable,
226
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(currency, 'amountPoint'))),
227
- 'funding': {
228
- 'withdraw': {
229
- 'active': withdrawEnable,
230
- 'fee': fee,
231
- },
232
- 'deposit': {
233
- 'active': depositEnable,
234
- 'fee': this.parseNumber('0'),
235
- },
236
- },
237
- 'limits': {
238
- 'amount': {
239
- 'min': undefined,
240
- 'max': undefined,
241
- },
242
- 'withdraw': {
243
- 'min': this.safeNumber(currency, 'withdrawMinAmount'),
244
- 'max': undefined,
245
- },
246
- 'deposit': {
247
- 'min': this.safeNumber(currency, 'depositMinAmount'),
248
- 'max': undefined,
249
- },
250
- },
251
- 'info': currency,
252
- };
253
- }
254
- return result;
255
- }
256
- async fetchMarkets(params = {}) {
257
- /**
258
- * @method
259
- * @name tidex#fetchMarkets
260
- * @description retrieves data on all markets for tidex
261
- * @param {object} [params] extra parameters specific to the exchange API endpoint
262
- * @returns {object[]} an array of objects representing market data
263
- */
264
- const response = await this.publicGetInfo(params);
265
- //
266
- // {
267
- // "server_time":1615861869,
268
- // "pairs":{
269
- // "ltc_btc":{
270
- // "decimal_places":8,
271
- // "min_price":0.00000001,
272
- // "max_price":3.0,
273
- // "min_amount":0.001,
274
- // "max_amount":1000000.0,
275
- // "min_total":0.0001,
276
- // "hidden":0,
277
- // "fee":0.1,
278
- // },
279
- // },
280
- // }
281
- //
282
- const markets = response['pairs'];
283
- const keys = Object.keys(markets);
284
- const result = [];
285
- for (let i = 0; i < keys.length; i++) {
286
- const id = keys[i];
287
- const market = markets[id];
288
- const [baseId, quoteId] = id.split('_');
289
- const base = this.safeCurrencyCode(baseId);
290
- const quote = this.safeCurrencyCode(quoteId);
291
- const hidden = this.safeInteger(market, 'hidden');
292
- let takerFeeString = this.safeString(market, 'fee');
293
- takerFeeString = Precise.stringDiv(takerFeeString, '100');
294
- result.push({
295
- 'id': id,
296
- 'symbol': base + '/' + quote,
297
- 'base': base,
298
- 'quote': quote,
299
- 'settle': undefined,
300
- 'baseId': baseId,
301
- 'quoteId': quoteId,
302
- 'settleId': undefined,
303
- 'type': 'spot',
304
- 'spot': true,
305
- 'margin': false,
306
- 'swap': false,
307
- 'future': false,
308
- 'option': false,
309
- 'active': (hidden === 0),
310
- 'contract': false,
311
- 'linear': undefined,
312
- 'inverse': undefined,
313
- 'taker': this.parseNumber(takerFeeString),
314
- 'contractSize': undefined,
315
- 'expiry': undefined,
316
- 'expiryDatetime': undefined,
317
- 'strike': undefined,
318
- 'optionType': undefined,
319
- 'precision': {
320
- 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'decimal_places'))),
321
- 'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'decimal_places'))),
322
- },
323
- 'limits': {
324
- 'leverage': {
325
- 'min': undefined,
326
- 'max': undefined,
327
- },
328
- 'amount': {
329
- 'min': this.safeNumber(market, 'min_amount'),
330
- 'max': this.safeNumber(market, 'max_amount'),
331
- },
332
- 'price': {
333
- 'min': this.safeNumber(market, 'min_price'),
334
- 'max': this.safeNumber(market, 'max_price'),
335
- },
336
- 'cost': {
337
- 'min': this.safeNumber(market, 'min_total'),
338
- 'max': undefined,
339
- },
340
- },
341
- 'created': undefined,
342
- 'info': market,
343
- });
344
- }
345
- return result;
346
- }
347
- parseBalance(response) {
348
- const balances = this.safeValue(response, 'return');
349
- const timestamp = this.safeTimestamp(balances, 'server_time');
350
- const result = {
351
- 'info': response,
352
- 'timestamp': timestamp,
353
- 'datetime': this.iso8601(timestamp),
354
- };
355
- const funds = this.safeValue(balances, 'funds', {});
356
- const currencyIds = Object.keys(funds);
357
- for (let i = 0; i < currencyIds.length; i++) {
358
- const currencyId = currencyIds[i];
359
- const code = this.safeCurrencyCode(currencyId);
360
- const balance = this.safeValue(funds, currencyId, {});
361
- const account = this.account();
362
- account['free'] = this.safeString(balance, 'value');
363
- account['used'] = this.safeString(balance, 'inOrders');
364
- result[code] = account;
365
- }
366
- return this.safeBalance(result);
367
- }
368
- async fetchBalance(params = {}) {
369
- /**
370
- * @method
371
- * @name tidex#fetchBalance
372
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
373
- * @param {object} [params] extra parameters specific to the exchange API endpoint
374
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
375
- */
376
- await this.loadMarkets();
377
- const response = await this.privatePostGetInfoExt(params);
378
- //
379
- // {
380
- // "success":1,
381
- // "return":{
382
- // "funds":{
383
- // "btc":{"value":0.0000499885629956,"inOrders":0.0},
384
- // "eth":{"value":0.000000030741708,"inOrders":0.0},
385
- // "tdx":{"value":0.0000000155385356,"inOrders":0.0}
386
- // },
387
- // "rights":{
388
- // "info":true,
389
- // "trade":true,
390
- // "withdraw":false
391
- // },
392
- // "transaction_count":0,
393
- // "open_orders":0,
394
- // "server_time":1619436907
395
- // },
396
- // "stat":{
397
- // "isSuccess":true,
398
- // "serverTime":"00:00:00.0001157",
399
- // "time":"00:00:00.0101364",
400
- // "errors":null
401
- // }
402
- // }
403
- //
404
- return this.parseBalance(response);
405
- }
406
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
407
- /**
408
- * @method
409
- * @name tidex#fetchOrderBook
410
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
411
- * @param {string} symbol unified symbol of the market to fetch the order book for
412
- * @param {int} [limit] the maximum amount of order book entries to return
413
- * @param {object} [params] extra parameters specific to the exchange API endpoint
414
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
415
- */
416
- await this.loadMarkets();
417
- const market = this.market(symbol);
418
- const request = {
419
- 'pair': market['id'],
420
- };
421
- if (limit !== undefined) {
422
- request['limit'] = limit; // default = 150, max = 2000
423
- }
424
- const response = await this.publicGetDepthPair(this.extend(request, params));
425
- const market_id_in_reponse = (market['id'] in response);
426
- if (!market_id_in_reponse) {
427
- throw new ExchangeError(this.id + ' ' + market['symbol'] + ' order book is empty or not available');
428
- }
429
- const orderbook = response[market['id']];
430
- return this.parseOrderBook(orderbook, symbol);
431
- }
432
- async fetchOrderBooks(symbols = undefined, limit = undefined, params = {}) {
433
- /**
434
- * @method
435
- * @name tidex#fetchOrderBooks
436
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data for multiple markets
437
- * @param {string[]|undefined} symbols list of unified market symbols, all symbols fetched if undefined, default is undefined
438
- * @param {int} [limit] max number of entries per orderbook to return, default is undefined
439
- * @param {object} [params] extra parameters specific to the exchange API endpoint
440
- * @returns {object} a dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbol
441
- */
442
- await this.loadMarkets();
443
- let ids = undefined;
444
- if (symbols === undefined) {
445
- ids = this.ids.join('-');
446
- // max URL length is 2083 symbols, including http schema, hostname, tld, etc...
447
- if (ids.length > 2048) {
448
- const numIds = this.ids.length;
449
- throw new ExchangeError(this.id + ' fetchOrderBooks() has ' + numIds.toString() + ' symbols exceeding max URL length, you are required to specify a list of symbols in the first argument to fetchOrderBooks');
450
- }
451
- }
452
- else {
453
- ids = this.marketIds(symbols);
454
- ids = ids.join('-');
455
- }
456
- const request = {
457
- 'pair': ids,
458
- };
459
- if (limit !== undefined) {
460
- request['limit'] = limit; // default = 150, max = 2000
461
- }
462
- const response = await this.publicGetDepthPair(this.extend(request, params));
463
- const result = {};
464
- ids = Object.keys(response);
465
- for (let i = 0; i < ids.length; i++) {
466
- const id = ids[i];
467
- const symbol = this.safeSymbol(id);
468
- result[symbol] = this.parseOrderBook(response[id], symbol);
469
- }
470
- return result;
471
- }
472
- parseTicker(ticker, market = undefined) {
473
- //
474
- // {
475
- // "high": 0.03497582,
476
- // "low": 0.03248474,
477
- // "avg": 0.03373028,
478
- // "vol": 120.11485715062999,
479
- // "vol_cur": 3572.24914074,
480
- // "last": 0.0337611,
481
- // "buy": 0.0337442,
482
- // "sell": 0.03377798,
483
- // "updated": 1537522009
484
- // }
485
- //
486
- const timestamp = this.safeTimestamp(ticker, 'updated');
487
- market = this.safeMarket(undefined, market);
488
- const last = this.safeString(ticker, 'last');
489
- return this.safeTicker({
490
- 'symbol': market['symbol'],
491
- 'timestamp': timestamp,
492
- 'datetime': this.iso8601(timestamp),
493
- 'high': this.safeString(ticker, 'high'),
494
- 'low': this.safeString(ticker, 'low'),
495
- 'bid': this.safeString(ticker, 'buy'),
496
- 'bidVolume': undefined,
497
- 'ask': this.safeString(ticker, 'sell'),
498
- 'askVolume': undefined,
499
- 'vwap': undefined,
500
- 'open': undefined,
501
- 'close': last,
502
- 'last': last,
503
- 'previousClose': undefined,
504
- 'change': undefined,
505
- 'percentage': undefined,
506
- 'average': this.safeString(ticker, 'avg'),
507
- 'baseVolume': this.safeString(ticker, 'vol_cur'),
508
- 'quoteVolume': this.safeString(ticker, 'vol'),
509
- 'info': ticker,
510
- }, market);
511
- }
512
- async fetchTickers(symbols = undefined, params = {}) {
513
- /**
514
- * @method
515
- * @name tidex#fetchTickers
516
- * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
517
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
518
- * @param {object} [params] extra parameters specific to the exchange API endpoint
519
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
520
- */
521
- await this.loadMarkets();
522
- symbols = this.marketSymbols(symbols);
523
- let ids = undefined;
524
- if (symbols === undefined) {
525
- const numIds = this.ids.length;
526
- ids = this.ids.join('-');
527
- // max URL length is 2048 symbols, including http schema, hostname, tld, etc...
528
- if (ids.length > this.options['fetchTickersMaxLength']) {
529
- const maxLength = this.safeInteger(this.options, 'fetchTickersMaxLength', 2048);
530
- throw new ArgumentsRequired(this.id + ' fetchTickers() has ' + numIds.toString() + ' markets exceeding max URL length for this endpoint (' + maxLength.toString() + ' characters), please, specify a list of symbols of interest in the first argument to fetchTickers');
531
- }
532
- }
533
- else {
534
- const newIds = this.marketIds(symbols);
535
- ids = newIds.join('-');
536
- }
537
- const request = {
538
- 'pair': ids,
539
- };
540
- const response = await this.publicGetTickerPair(this.extend(request, params));
541
- const result = {};
542
- const keys = Object.keys(response);
543
- for (let i = 0; i < keys.length; i++) {
544
- const id = keys[i];
545
- const market = this.safeMarket(id);
546
- const symbol = market['symbol'];
547
- result[symbol] = this.parseTicker(response[id], market);
548
- }
549
- return this.filterByArrayTickers(result, 'symbol', symbols);
550
- }
551
- async fetchTicker(symbol, params = {}) {
552
- /**
553
- * @method
554
- * @name tidex#fetchTicker
555
- * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
556
- * @param {string} symbol unified symbol of the market to fetch the ticker for
557
- * @param {object} [params] extra parameters specific to the exchange API endpoint
558
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
559
- */
560
- const tickers = await this.fetchTickers([symbol], params);
561
- return tickers[symbol];
562
- }
563
- parseTrade(trade, market = undefined) {
564
- const timestamp = this.safeTimestamp(trade, 'timestamp');
565
- let side = this.safeString(trade, 'type');
566
- if (side === 'ask') {
567
- side = 'sell';
568
- }
569
- else if (side === 'bid') {
570
- side = 'buy';
571
- }
572
- const priceString = this.safeString2(trade, 'rate', 'price');
573
- const id = this.safeString2(trade, 'trade_id', 'tid');
574
- const orderId = this.safeString(trade, 'order_id');
575
- const marketId = this.safeString(trade, 'pair');
576
- const symbol = this.safeSymbol(marketId, market);
577
- const amountString = this.safeString(trade, 'amount');
578
- const price = this.parseNumber(priceString);
579
- const amount = this.parseNumber(amountString);
580
- const cost = this.parseNumber(Precise.stringMul(priceString, amountString));
581
- const type = 'limit'; // all trades are still limit trades
582
- let takerOrMaker = undefined;
583
- let fee = undefined;
584
- const feeCost = this.safeNumber(trade, 'commission');
585
- if (feeCost !== undefined) {
586
- const feeCurrencyId = this.safeString(trade, 'commissionCurrency');
587
- const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
588
- fee = {
589
- 'cost': feeCost,
590
- 'currency': feeCurrencyCode,
591
- };
592
- }
593
- const isYourOrder = this.safeValue(trade, 'is_your_order');
594
- if (isYourOrder !== undefined) {
595
- takerOrMaker = 'taker';
596
- if (isYourOrder) {
597
- takerOrMaker = 'maker';
598
- }
599
- if (fee === undefined) {
600
- fee = this.calculateFee(symbol, type, side, amount, price, takerOrMaker);
601
- }
602
- }
603
- return {
604
- 'id': id,
605
- 'order': orderId,
606
- 'timestamp': timestamp,
607
- 'datetime': this.iso8601(timestamp),
608
- 'symbol': symbol,
609
- 'type': type,
610
- 'side': side,
611
- 'takerOrMaker': takerOrMaker,
612
- 'price': price,
613
- 'amount': amount,
614
- 'cost': cost,
615
- 'fee': fee,
616
- 'info': trade,
617
- };
618
- }
619
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
620
- /**
621
- * @method
622
- * @name tidex#fetchTrades
623
- * @description get the list of most recent trades for a particular symbol
624
- * @param {string} symbol unified symbol of the market to fetch trades for
625
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
626
- * @param {int} [limit] the maximum amount of trades to fetch
627
- * @param {object} [params] extra parameters specific to the exchange API endpoint
628
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
629
- */
630
- await this.loadMarkets();
631
- const market = this.market(symbol);
632
- const request = {
633
- 'pair': market['id'],
634
- };
635
- if (limit !== undefined) {
636
- request['limit'] = limit;
637
- }
638
- const response = await this.publicGetTradesPair(this.extend(request, params));
639
- if (Array.isArray(response)) {
640
- const numElements = response.length;
641
- if (numElements === 0) {
642
- return [];
643
- }
644
- }
645
- return this.parseTrades(response[market['id']], market, since, limit);
646
- }
647
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
648
- /**
649
- * @method
650
- * @name tidex#createOrder
651
- * @description create a trade order
652
- * @param {string} symbol unified symbol of the market to create an order in
653
- * @param {string} type 'market' or 'limit'
654
- * @param {string} side 'buy' or 'sell'
655
- * @param {float} amount how much of currency you want to trade in units of base currency
656
- * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
657
- * @param {object} [params] extra parameters specific to the exchange API endpoint
658
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
659
- */
660
- if (type === 'market') {
661
- throw new ExchangeError(this.id + ' createOrder() allows limit orders only');
662
- }
663
- const amountString = amount.toString();
664
- const priceString = price.toString();
665
- await this.loadMarkets();
666
- const market = this.market(symbol);
667
- const request = {
668
- 'pair': market['id'],
669
- 'type': side,
670
- 'amount': this.amountToPrecision(symbol, amount),
671
- 'rate': this.priceToPrecision(symbol, price),
672
- };
673
- const response = await this.privatePostTrade(this.extend(request, params));
674
- let id = undefined;
675
- let status = 'open';
676
- let filledString = '0.0';
677
- let remainingString = amountString;
678
- const returnResult = this.safeValue(response, 'return');
679
- if (returnResult !== undefined) {
680
- id = this.safeString(returnResult, 'order_id');
681
- if (id === '0') {
682
- id = this.safeString(returnResult, 'init_order_id');
683
- status = 'closed';
684
- }
685
- filledString = this.safeString(returnResult, 'received', filledString);
686
- remainingString = this.safeString(returnResult, 'remains', amountString);
687
- }
688
- const timestamp = this.milliseconds();
689
- return this.safeOrder({
690
- 'id': id,
691
- 'timestamp': timestamp,
692
- 'datetime': this.iso8601(timestamp),
693
- 'lastTradeTimestamp': undefined,
694
- 'status': status,
695
- 'symbol': symbol,
696
- 'type': type,
697
- 'side': side,
698
- 'price': priceString,
699
- 'cost': undefined,
700
- 'amount': amountString,
701
- 'remaining': remainingString,
702
- 'filled': filledString,
703
- 'fee': undefined,
704
- // 'trades': this.parseTrades (order['trades'], market),
705
- 'info': response,
706
- 'clientOrderId': undefined,
707
- 'average': undefined,
708
- 'trades': undefined,
709
- }, market);
710
- }
711
- async cancelOrder(id, symbol = undefined, params = {}) {
712
- /**
713
- * @method
714
- * @name tidex#cancelOrder
715
- * @description cancels an open order
716
- * @param {string} id order id
717
- * @param {string} symbol not used by tidex cancelOrder ()
718
- * @param {object} [params] extra parameters specific to the exchange API endpoint
719
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
720
- */
721
- await this.loadMarkets();
722
- const request = {
723
- 'order_id': parseInt(id),
724
- };
725
- return await this.privatePostCancelOrder(this.extend(request, params));
726
- }
727
- parseOrderStatus(status) {
728
- const statuses = {
729
- '0': 'open',
730
- '1': 'closed',
731
- '2': 'canceled',
732
- '3': 'canceled', // or partially-filled and still open? https://github.com/ccxt/ccxt/issues/1594
733
- };
734
- return this.safeString(statuses, status, status);
735
- }
736
- parseOrder(order, market = undefined) {
737
- const id = this.safeString(order, 'id');
738
- const status = this.parseOrderStatus(this.safeString(order, 'status'));
739
- const timestamp = this.safeTimestamp(order, 'timestamp_created');
740
- const marketId = this.safeString(order, 'pair');
741
- const symbol = this.safeSymbol(marketId, market);
742
- let remaining;
743
- let amount;
744
- const price = this.safeString(order, 'rate');
745
- if ('start_amount' in order) {
746
- amount = this.safeString(order, 'start_amount');
747
- remaining = this.safeString(order, 'amount');
748
- }
749
- else {
750
- remaining = this.safeString(order, 'amount');
751
- }
752
- const fee = undefined;
753
- return this.safeOrder({
754
- 'info': order,
755
- 'id': id,
756
- 'clientOrderId': undefined,
757
- 'symbol': symbol,
758
- 'timestamp': timestamp,
759
- 'datetime': this.iso8601(timestamp),
760
- 'lastTradeTimestamp': undefined,
761
- 'type': 'limit',
762
- 'timeInForce': undefined,
763
- 'postOnly': undefined,
764
- 'side': this.safeString(order, 'type'),
765
- 'price': price,
766
- 'stopPrice': undefined,
767
- 'triggerPrice': undefined,
768
- 'cost': undefined,
769
- 'amount': amount,
770
- 'remaining': remaining,
771
- 'filled': undefined,
772
- 'status': status,
773
- 'fee': fee,
774
- 'average': undefined,
775
- 'trades': undefined,
776
- }, market);
777
- }
778
- async fetchOrder(id, symbol = undefined, params = {}) {
779
- /**
780
- * @method
781
- * @name tidex#fetchOrder
782
- * @description fetches information on an order made by the user
783
- * @param {string} symbol not used by tidex fetchOrder
784
- * @param {object} [params] extra parameters specific to the exchange API endpoint
785
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
786
- */
787
- await this.loadMarkets();
788
- const request = {
789
- 'order_id': parseInt(id),
790
- };
791
- const response = await this.privatePostOrderInfo(this.extend(request, params));
792
- id = id.toString();
793
- const result = this.safeValue(response, 'return', {});
794
- const order = this.safeValue(result, id);
795
- return this.parseOrder(this.extend({ 'id': id }, order));
796
- }
797
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
798
- /**
799
- * @method
800
- * @name tidex#fetchOpenOrders
801
- * @description fetch all unfilled currently open orders
802
- * @param {string} symbol unified market symbol
803
- * @param {int} [since] the earliest time in ms to fetch open orders for
804
- * @param {int} [limit] the maximum number of open orders structures to retrieve
805
- * @param {object} [params] extra parameters specific to the exchange API endpoint
806
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
807
- */
808
- await this.loadMarkets();
809
- const request = {};
810
- let market = undefined;
811
- if (symbol !== undefined) {
812
- market = this.market(symbol);
813
- request['pair'] = market['id'];
814
- }
815
- const response = await this.privatePostActiveOrders(this.extend(request, params));
816
- //
817
- // {
818
- // "success":1,
819
- // "return":{
820
- // "1255468911":{
821
- // "status":0,
822
- // "pair":"spike_usdt",
823
- // "type":"sell",
824
- // "amount":35028.44256388,
825
- // "rate":0.00199989,
826
- // "timestamp_created":1602684432
827
- // }
828
- // },
829
- // "stat":{
830
- // "isSuccess":true,
831
- // "serverTime":"00:00:00.0000826",
832
- // "time":"00:00:00.0091423",
833
- // "errors":null
834
- // }
835
- // }
836
- //
837
- // it can only return 'open' orders (i.e. no way to fetch 'closed' orders)
838
- const orders = this.safeValue(response, 'return', []);
839
- return this.parseOrders(orders, market, since, limit);
840
- }
841
- async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
842
- /**
843
- * @method
844
- * @name tidex#fetchMyTrades
845
- * @description fetch all trades made by the user
846
- * @param {string} symbol unified market symbol
847
- * @param {int} [since] the earliest time in ms to fetch trades for
848
- * @param {int} [limit] the maximum number of trades structures to retrieve
849
- * @param {object} [params] extra parameters specific to the exchange API endpoint
850
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
851
- */
852
- await this.loadMarkets();
853
- let market = undefined;
854
- // some derived classes use camelcase notation for request fields
855
- const request = {
856
- // 'from': 123456789, // trade ID, from which the display starts numerical 0 (test result: liqui ignores this field)
857
- // 'count': 1000, // the number of trades for display numerical, default = 1000
858
- // 'from_id': trade ID, from which the display starts numerical 0
859
- // 'end_id': trade ID on which the display ends numerical ∞
860
- // 'order': 'ASC', // sorting, default = DESC (test result: liqui ignores this field, most recent trade always goes last)
861
- // 'since': 1234567890, // UTC start time, default = 0 (test result: liqui ignores this field)
862
- // 'end': 1234567890, // UTC end time, default = ∞ (test result: liqui ignores this field)
863
- // 'pair': 'eth_btc', // default = all markets
864
- };
865
- if (symbol !== undefined) {
866
- market = this.market(symbol);
867
- request['pair'] = market['id'];
868
- }
869
- if (limit !== undefined) {
870
- request['count'] = limit;
871
- }
872
- if (since !== undefined) {
873
- request['since'] = this.parseToInt(since / 1000);
874
- }
875
- const response = await this.privatePostTradeHistory(this.extend(request, params));
876
- const trades = this.safeValue(response, 'return', []);
877
- return this.parseTrades(trades, market, since, limit);
878
- }
879
- async withdraw(code, amount, address, tag = undefined, params = {}) {
880
- /**
881
- * @method
882
- * @name tidex#withdraw
883
- * @description make a withdrawal
884
- * @param {string} code unified currency code
885
- * @param {float} amount the amount to withdraw
886
- * @param {string} address the address to withdraw to
887
- * @param {string} tag
888
- * @param {object} [params] extra parameters specific to the exchange API endpoint
889
- * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
890
- */
891
- [tag, params] = this.handleWithdrawTagAndParams(tag, params);
892
- this.checkAddress(address);
893
- await this.loadMarkets();
894
- const currency = this.currency(code);
895
- const request = {
896
- 'asset': currency['id'],
897
- 'amount': parseFloat(amount),
898
- 'address': address,
899
- };
900
- if (tag !== undefined) {
901
- request['memo'] = tag;
902
- }
903
- const response = await this.privatePostCreateWithdraw(this.extend(request, params));
904
- //
905
- // {
906
- // "success":1,
907
- // "return":{
908
- // "withdraw_id":1111,
909
- // "withdraw_info":{
910
- // "id":1111,
911
- // "asset_id":1,
912
- // "asset":"BTC",
913
- // "amount":0.0093,
914
- // "fee":0.0007,
915
- // "create_time":1575128018,
916
- // "status":"Created",
917
- // "data":{
918
- // "address":"1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY",
919
- // "memo":"memo",
920
- // "tx":null,
921
- // "error":null
922
- // },
923
- // "in_blockchain":false
924
- // }
925
- // }
926
- // }
927
- //
928
- const result = this.safeValue(response, 'return', {});
929
- const withdrawInfo = this.safeValue(result, 'withdraw_info', {});
930
- return this.parseTransaction(withdrawInfo, currency);
931
- }
932
- parseTransaction(transaction, currency = undefined) {
933
- //
934
- // {
935
- // "id":1111,
936
- // "asset_id":1,
937
- // "asset":"BTC",
938
- // "amount":0.0093,
939
- // "fee":0.0007,
940
- // "create_time":1575128018,
941
- // "status":"Created",
942
- // "data":{
943
- // "address":"1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY",
944
- // "memo":"memo",
945
- // "tx":null,
946
- // "error":null
947
- // },
948
- // "in_blockchain":false
949
- // }
950
- //
951
- currency = this.safeCurrency(undefined, currency);
952
- return {
953
- 'id': this.safeString(transaction, 'id'),
954
- 'txid': undefined,
955
- 'timestamp': undefined,
956
- 'datetime': undefined,
957
- 'network': undefined,
958
- 'addressFrom': undefined,
959
- 'address': undefined,
960
- 'addressTo': undefined,
961
- 'amount': undefined,
962
- 'type': undefined,
963
- 'currency': currency['code'],
964
- 'status': undefined,
965
- 'updated': undefined,
966
- 'tagFrom': undefined,
967
- 'tag': undefined,
968
- 'tagTo': undefined,
969
- 'comment': undefined,
970
- 'internal': undefined,
971
- 'fee': undefined,
972
- 'info': transaction,
973
- };
974
- }
975
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
976
- let url = this.urls['api'][api];
977
- const query = this.omit(params, this.extractParams(path));
978
- if (api === 'private') {
979
- this.checkRequiredCredentials();
980
- const nonce = this.nonce();
981
- body = this.urlencode(this.extend({
982
- 'nonce': nonce,
983
- 'method': path,
984
- }, query));
985
- const signature = this.hmac(this.encode(body), this.encode(this.secret), sha512);
986
- headers = {
987
- 'Content-Type': 'application/x-www-form-urlencoded',
988
- 'Key': this.apiKey,
989
- 'Sign': signature,
990
- };
991
- }
992
- else if (api === 'public') {
993
- url += '/' + this.implodeParams(path, params);
994
- if (Object.keys(query).length) {
995
- url += '?' + this.urlencode(query);
996
- }
997
- }
998
- else {
999
- url += '/' + this.implodeParams(path, params);
1000
- if (method === 'GET') {
1001
- if (Object.keys(query).length) {
1002
- url += '?' + this.urlencode(query);
1003
- }
1004
- }
1005
- else {
1006
- if (Object.keys(query).length) {
1007
- body = this.json(query);
1008
- headers = {
1009
- 'Content-Type': 'application/json',
1010
- };
1011
- }
1012
- }
1013
- }
1014
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1015
- }
1016
- handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1017
- if (response === undefined) {
1018
- return undefined; // fallback to default error handler
1019
- }
1020
- if ('success' in response) {
1021
- //
1022
- // 1 - The exchange only returns the integer 'success' key from their private API
1023
- //
1024
- // { "success": 1, ... } httpCode === 200
1025
- // { "success": 0, ... } httpCode === 200
1026
- //
1027
- // 2 - However, derived exchanges can return non-integers
1028
- //
1029
- // It can be a numeric string
1030
- // { "sucesss": "1", ... }
1031
- // { "sucesss": "0", ... }, httpCode >= 200 (can be 403, 502, etc)
1032
- //
1033
- // Or just a string
1034
- // { "success": "true", ... }
1035
- // { "success": "false", ... }, httpCode >= 200
1036
- //
1037
- // Or a boolean
1038
- // { "success": true, ... }
1039
- // { "success": false, ... }, httpCode >= 200
1040
- //
1041
- // 3 - Oversimplified, Python PEP8 forbids comparison operator (===) of different types
1042
- //
1043
- // 4 - We do not want to copy-paste and duplicate the code of this handler to other exchanges derived from Liqui
1044
- //
1045
- // To cover points 1, 2, 3 and 4 combined this handler should work like this:
1046
- //
1047
- let success = this.safeValue(response, 'success', false);
1048
- if (typeof success === 'string') {
1049
- if ((success === 'true') || (success === '1')) {
1050
- success = true;
1051
- }
1052
- else {
1053
- success = false;
1054
- }
1055
- }
1056
- if (!success) {
1057
- const code = this.safeString(response, 'code');
1058
- const message = this.safeString(response, 'error');
1059
- const feedback = this.id + ' ' + body;
1060
- this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
1061
- this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
1062
- this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
1063
- throw new ExchangeError(feedback); // unknown message
1064
- }
1065
- }
1066
- return undefined;
1067
- }
1068
- }