ccxt 4.4.48 → 4.4.49

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 (75) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +12 -12
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/bingx.js +88 -30
  5. package/dist/cjs/src/bitget.js +12 -10
  6. package/dist/cjs/src/coinsph.js +18 -9
  7. package/dist/cjs/src/deribit.js +82 -0
  8. package/dist/cjs/src/digifinex.js +131 -11
  9. package/dist/cjs/src/ellipx.js +61 -0
  10. package/dist/cjs/src/exmo.js +58 -0
  11. package/dist/cjs/src/hitbtc.js +99 -0
  12. package/dist/cjs/src/hollaex.js +73 -0
  13. package/dist/cjs/src/huobijp.js +73 -0
  14. package/dist/cjs/src/hyperliquid.js +22 -1
  15. package/dist/cjs/src/idex.js +71 -0
  16. package/dist/cjs/src/independentreserve.js +64 -0
  17. package/dist/cjs/src/indodax.js +61 -0
  18. package/dist/cjs/src/kuna.js +60 -1
  19. package/dist/cjs/src/latoken.js +64 -0
  20. package/dist/cjs/src/lbank.js +70 -0
  21. package/dist/cjs/src/luno.js +73 -0
  22. package/dist/cjs/src/lykke.js +64 -0
  23. package/dist/cjs/src/mercado.js +65 -0
  24. package/dist/cjs/src/mexc.js +1 -1
  25. package/dist/cjs/src/myokx.js +10 -0
  26. package/dist/cjs/src/ndax.js +71 -0
  27. package/dist/cjs/src/novadax.js +74 -0
  28. package/dist/cjs/src/oceanex.js +69 -0
  29. package/dist/cjs/src/okcoin.js +79 -2
  30. package/dist/cjs/src/onetrading.js +66 -0
  31. package/dist/cjs/src/oxfun.js +66 -0
  32. package/dist/cjs/src/p2b.js +63 -1
  33. package/dist/cjs/src/paradex.js +68 -0
  34. package/dist/cjs/src/pro/bitmart.js +6 -0
  35. package/js/ccxt.d.ts +1 -1
  36. package/js/ccxt.js +1 -1
  37. package/js/src/bingx.d.ts +8 -0
  38. package/js/src/bingx.js +88 -30
  39. package/js/src/bitget.d.ts +1 -0
  40. package/js/src/bitget.js +12 -10
  41. package/js/src/coinsph.d.ts +1 -0
  42. package/js/src/coinsph.js +18 -9
  43. package/js/src/deribit.js +82 -0
  44. package/js/src/digifinex.d.ts +1 -0
  45. package/js/src/digifinex.js +131 -11
  46. package/js/src/ellipx.d.ts +1 -0
  47. package/js/src/ellipx.js +61 -0
  48. package/js/src/exmo.js +58 -0
  49. package/js/src/hitbtc.js +99 -0
  50. package/js/src/hollaex.js +73 -0
  51. package/js/src/huobijp.js +73 -0
  52. package/js/src/hyperliquid.d.ts +1 -0
  53. package/js/src/hyperliquid.js +22 -1
  54. package/js/src/idex.js +71 -0
  55. package/js/src/independentreserve.js +64 -0
  56. package/js/src/indodax.js +61 -0
  57. package/js/src/kuna.js +60 -1
  58. package/js/src/latoken.js +64 -0
  59. package/js/src/lbank.js +70 -0
  60. package/js/src/luno.js +73 -0
  61. package/js/src/lykke.js +64 -0
  62. package/js/src/mercado.js +65 -0
  63. package/js/src/mexc.js +1 -1
  64. package/js/src/myokx.js +10 -0
  65. package/js/src/ndax.js +71 -0
  66. package/js/src/novadax.js +74 -0
  67. package/js/src/oceanex.js +69 -0
  68. package/js/src/okcoin.js +79 -2
  69. package/js/src/onetrading.js +66 -0
  70. package/js/src/oxfun.js +66 -0
  71. package/js/src/p2b.js +63 -1
  72. package/js/src/paradex.js +68 -0
  73. package/js/src/pro/bitmart.d.ts +1 -0
  74. package/js/src/pro/bitmart.js +6 -0
  75. package/package.json +2 -2
package/js/src/bitget.js CHANGED
@@ -1384,18 +1384,18 @@ export default class bitget extends Exchange {
1384
1384
  '1m': 30,
1385
1385
  '3m': 30,
1386
1386
  '5m': 30,
1387
- '10m': 52,
1387
+ '10m': 30,
1388
1388
  '15m': 52,
1389
- '30m': 52,
1389
+ '30m': 62,
1390
1390
  '1h': 83,
1391
1391
  '2h': 120,
1392
1392
  '4h': 240,
1393
1393
  '6h': 360,
1394
1394
  '12h': 360,
1395
- '1d': 360,
1396
- '3d': 1000,
1397
- '1w': 1000,
1398
- '1M': 1000,
1395
+ '1d': 300,
1396
+ '3d': 300,
1397
+ '1w': 300,
1398
+ '1M': 300,
1399
1399
  },
1400
1400
  },
1401
1401
  'fetchTrades': {
@@ -3557,6 +3557,7 @@ export default class bitget extends Exchange {
3557
3557
  * @param {int} [limit] the maximum amount of candles to fetch
3558
3558
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3559
3559
  * @param {int} [params.until] timestamp in ms of the latest candle to fetch
3560
+ * @param {boolean} [params.useHistoryEndpoint] whether to force to use historical endpoint (it has max limit of 200)
3560
3561
  * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3561
3562
  * @param {string} [params.price] *swap only* "mark" (to fetch mark price candles) or "index" (to fetch index price candles)
3562
3563
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
@@ -3569,9 +3570,10 @@ export default class bitget extends Exchange {
3569
3570
  let paginate = false;
3570
3571
  [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
3571
3572
  if (paginate) {
3572
- return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForHistoryEndpoint);
3573
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForRecentEndpoint);
3573
3574
  }
3574
3575
  const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
3576
+ const useHistoryEndpoint = this.safeBool(params, 'useHistoryEndpoint', false);
3575
3577
  let market = undefined;
3576
3578
  if (sandboxMode) {
3577
3579
  const sandboxSymbol = this.convertSymbolForSandbox(symbol);
@@ -3601,7 +3603,7 @@ export default class bitget extends Exchange {
3601
3603
  const ohlcOptions = this.safeDict(this.options, 'fetchOHLCV', {});
3602
3604
  const retrievableDaysMap = this.safeDict(ohlcOptions, 'maxDaysPerTimeframe', {});
3603
3605
  const maxRetrievableDaysForRecent = this.safeInteger(retrievableDaysMap, timeframe, 30); // default to safe minimum
3604
- const endpointTsBoundary = now - maxRetrievableDaysForRecent * msInDay;
3606
+ const endpointTsBoundary = now - (maxRetrievableDaysForRecent - 1) * msInDay;
3605
3607
  if (limitDefined) {
3606
3608
  limit = Math.min(limit, maxLimitForRecentEndpoint);
3607
3609
  request['limit'] = limit;
@@ -3640,7 +3642,7 @@ export default class bitget extends Exchange {
3640
3642
  // make request
3641
3643
  if (market['spot']) {
3642
3644
  // checks if we need history endpoint
3643
- if (historicalEndpointNeeded) {
3645
+ if (historicalEndpointNeeded || useHistoryEndpoint) {
3644
3646
  response = await this.publicSpotGetV2SpotMarketHistoryCandles(this.extend(request, params));
3645
3647
  }
3646
3648
  else {
@@ -3672,7 +3674,7 @@ export default class bitget extends Exchange {
3672
3674
  response = await this.publicMixGetV2MixMarketHistoryIndexCandles(extended);
3673
3675
  }
3674
3676
  else {
3675
- if (historicalEndpointNeeded) {
3677
+ if (historicalEndpointNeeded || useHistoryEndpoint) {
3676
3678
  response = await this.publicMixGetV2MixMarketHistoryCandles(extended);
3677
3679
  }
3678
3680
  else {
@@ -86,6 +86,7 @@ export default class coinsph extends Exchange {
86
86
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
87
87
  * @param {int} [limit] the maximum amount of candles to fetch (default 500, max 1000)
88
88
  * @param {object} [params] extra parameters specific to the exchange API endpoint
89
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
89
90
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
90
91
  */
91
92
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
package/js/src/coinsph.js CHANGED
@@ -876,33 +876,42 @@ export default class coinsph extends Exchange {
876
876
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
877
877
  * @param {int} [limit] the maximum amount of candles to fetch (default 500, max 1000)
878
878
  * @param {object} [params] extra parameters specific to the exchange API endpoint
879
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
879
880
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
880
881
  */
881
882
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
882
883
  await this.loadMarkets();
883
884
  const market = this.market(symbol);
884
885
  const interval = this.safeString(this.timeframes, timeframe);
886
+ const until = this.safeInteger(params, 'until');
885
887
  const request = {
886
888
  'symbol': market['id'],
887
889
  'interval': interval,
888
890
  };
891
+ if (limit === undefined) {
892
+ limit = 1000;
893
+ }
889
894
  if (since !== undefined) {
890
895
  request['startTime'] = since;
891
- request['limit'] = 1000;
892
896
  // since work properly only when it is "younger" than last "limit" candle
893
- if (limit !== undefined) {
894
- const duration = this.parseTimeframe(timeframe) * 1000;
895
- request['endTime'] = this.sum(since, duration * (limit - 1));
897
+ if (until !== undefined) {
898
+ request['endTime'] = until;
896
899
  }
897
900
  else {
898
- request['endTime'] = this.milliseconds();
901
+ const duration = this.parseTimeframe(timeframe) * 1000;
902
+ const endTimeByLimit = this.sum(since, duration * (limit - 1));
903
+ const now = this.milliseconds();
904
+ request['endTime'] = Math.min(endTimeByLimit, now);
899
905
  }
900
906
  }
901
- else {
902
- if (limit !== undefined) {
903
- request['limit'] = limit;
904
- }
907
+ else if (until !== undefined) {
908
+ request['endTime'] = until;
909
+ // since work properly only when it is "younger" than last "limit" candle
910
+ const duration = this.parseTimeframe(timeframe) * 1000;
911
+ request['startTime'] = until - (duration * (limit - 1));
905
912
  }
913
+ request['limit'] = limit;
914
+ params = this.omit(params, 'until');
906
915
  const response = await this.publicGetOpenapiQuoteV1Klines(this.extend(request, params));
907
916
  //
908
917
  // [
package/js/src/deribit.js CHANGED
@@ -281,6 +281,88 @@ export default class deribit extends Exchange {
281
281
  },
282
282
  },
283
283
  },
284
+ 'features': {
285
+ 'default': {
286
+ 'sandbox': true,
287
+ 'createOrder': {
288
+ 'marginMode': false,
289
+ 'triggerPrice': true,
290
+ // todo implement
291
+ 'triggerPriceType': {
292
+ 'last': true,
293
+ 'mark': true,
294
+ 'index': true,
295
+ },
296
+ 'triggerDirection': false,
297
+ 'stopLossPrice': false,
298
+ 'takeProfitPrice': false,
299
+ 'attachedStopLossTakeProfit': undefined,
300
+ 'timeInForce': {
301
+ 'IOC': true,
302
+ 'FOK': true,
303
+ 'PO': true,
304
+ 'GTD': true,
305
+ },
306
+ 'hedged': false,
307
+ 'selfTradePrevention': false,
308
+ 'trailing': true,
309
+ 'leverage': false,
310
+ 'marketBuyByCost': true,
311
+ 'marketBuyRequiresPrice': false,
312
+ 'iceberg': true, // todo
313
+ },
314
+ 'createOrders': undefined,
315
+ 'fetchMyTrades': {
316
+ 'marginMode': false,
317
+ 'limit': 100,
318
+ 'daysBack': 100000,
319
+ 'untilDays': 100000,
320
+ },
321
+ 'fetchOrder': {
322
+ 'marginMode': false,
323
+ 'trigger': false,
324
+ 'trailing': false,
325
+ },
326
+ 'fetchOpenOrders': {
327
+ 'marginMode': false,
328
+ 'limit': undefined,
329
+ 'trigger': false,
330
+ 'trailing': false,
331
+ },
332
+ 'fetchOrders': undefined,
333
+ 'fetchClosedOrders': {
334
+ 'marginMode': false,
335
+ 'limit': 100,
336
+ 'daysBack': 100000,
337
+ 'daysBackCanceled': 1,
338
+ 'untilDays': 100000,
339
+ 'trigger': false,
340
+ 'trailing': false,
341
+ },
342
+ 'fetchOHLCV': {
343
+ 'limit': 1000, // todo: recheck
344
+ },
345
+ },
346
+ 'spot': {
347
+ 'extends': 'default',
348
+ },
349
+ 'swap': {
350
+ 'linear': {
351
+ 'extends': 'default',
352
+ },
353
+ 'inverse': {
354
+ 'extends': 'default',
355
+ },
356
+ },
357
+ 'future': {
358
+ 'linear': {
359
+ 'extends': 'default',
360
+ },
361
+ 'inverse': {
362
+ 'extends': 'default',
363
+ },
364
+ },
365
+ },
284
366
  'exceptions': {
285
367
  // 0 or absent Success, No error.
286
368
  '9999': PermissionDenied,
@@ -119,6 +119,7 @@ export default class digifinex extends Exchange {
119
119
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
120
120
  * @param {int} [limit] the maximum amount of candles to fetch
121
121
  * @param {object} [params] extra parameters specific to the exchange API endpoint
122
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
122
123
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
123
124
  */
124
125
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
@@ -237,6 +237,109 @@ export default class digifinex extends Exchange {
237
237
  },
238
238
  },
239
239
  },
240
+ 'features': {
241
+ 'default': {
242
+ 'sandbox': false,
243
+ 'createOrder': {
244
+ 'marginMode': true,
245
+ 'triggerPrice': false,
246
+ 'triggerPriceType': undefined,
247
+ 'triggerDirection': false,
248
+ 'stopLossPrice': false,
249
+ 'takeProfitPrice': false,
250
+ 'attachedStopLossTakeProfit': undefined,
251
+ 'timeInForce': {
252
+ 'IOC': false,
253
+ 'FOK': false,
254
+ 'PO': true,
255
+ 'GTD': false,
256
+ },
257
+ 'hedged': false,
258
+ 'selfTradePrevention': false,
259
+ 'trailing': false,
260
+ 'leverage': false,
261
+ 'marketBuyByCost': false,
262
+ 'marketBuyRequiresPrice': false,
263
+ 'iceberg': false,
264
+ },
265
+ 'createOrders': {
266
+ 'max': 10,
267
+ 'marginMode': true,
268
+ },
269
+ 'fetchMyTrades': {
270
+ 'marginMode': true,
271
+ 'limit': 500,
272
+ 'daysBack': 100000,
273
+ 'untilDays': 30,
274
+ },
275
+ 'fetchOrder': {
276
+ 'marginMode': true,
277
+ 'trigger': false,
278
+ 'trailing': false,
279
+ 'marketType': true,
280
+ },
281
+ 'fetchOpenOrders': {
282
+ 'marginMode': true,
283
+ 'limit': undefined,
284
+ 'trigger': false,
285
+ 'trailing': false,
286
+ },
287
+ 'fetchOrders': {
288
+ 'marginMode': true,
289
+ 'limit': 100,
290
+ 'daysBack': 100000,
291
+ 'untilDays': 30,
292
+ 'trigger': false,
293
+ 'trailing': false,
294
+ },
295
+ 'fetchClosedOrders': undefined,
296
+ 'fetchOHLCV': {
297
+ 'limit': 500,
298
+ },
299
+ },
300
+ 'spot': {
301
+ 'extends': 'default',
302
+ },
303
+ 'forDerivatives': {
304
+ 'extends': 'default',
305
+ 'createOrders': {
306
+ 'max': 20,
307
+ 'marginMode': false,
308
+ },
309
+ 'fetchMyTrades': {
310
+ 'marginMode': false,
311
+ 'limit': 100,
312
+ 'daysBack': 100000,
313
+ 'untilDays': 100000, // todo
314
+ },
315
+ 'fetchOrder': {
316
+ 'marginMode': false,
317
+ },
318
+ 'fetchOpenOrders': {
319
+ 'marginMode': false,
320
+ 'limit': 100,
321
+ },
322
+ 'fetchOrders': {
323
+ 'marginMode': false,
324
+ 'daysBack': 100000, // todo
325
+ },
326
+ 'fetchOHLCV': {
327
+ 'limit': 100,
328
+ },
329
+ },
330
+ 'swap': {
331
+ 'linear': {
332
+ 'extends': 'forDerivatives',
333
+ },
334
+ 'inverse': {
335
+ 'extends': 'forDerivatives',
336
+ },
337
+ },
338
+ 'future': {
339
+ 'linear': undefined,
340
+ 'inverse': undefined,
341
+ },
342
+ },
240
343
  'fees': {
241
344
  'trading': {
242
345
  'tierBased': true,
@@ -1504,6 +1607,7 @@ export default class digifinex extends Exchange {
1504
1607
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
1505
1608
  * @param {int} [limit] the maximum amount of candles to fetch
1506
1609
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1610
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
1507
1611
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1508
1612
  */
1509
1613
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
@@ -1520,22 +1624,38 @@ export default class digifinex extends Exchange {
1520
1624
  response = await this.publicSwapGetPublicCandles(this.extend(request, params));
1521
1625
  }
1522
1626
  else {
1627
+ const until = this.safeInteger(params, 'until');
1523
1628
  request['symbol'] = market['id'];
1524
1629
  request['period'] = this.safeString(this.timeframes, timeframe, timeframe);
1525
- if (since !== undefined) {
1526
- const startTime = this.parseToInt(since / 1000);
1527
- request['start_time'] = startTime;
1528
- if (limit !== undefined) {
1529
- const duration = this.parseTimeframe(timeframe);
1530
- request['end_time'] = this.sum(startTime, limit * duration);
1630
+ let startTime = since;
1631
+ const duration = this.parseTimeframe(timeframe);
1632
+ if (startTime === undefined) {
1633
+ if ((limit !== undefined) || (until !== undefined)) {
1634
+ const endTime = (until !== undefined) ? until : this.milliseconds();
1635
+ const startLimit = (limit !== undefined) ? limit : 200;
1636
+ startTime = endTime - (startLimit * duration * 1000);
1531
1637
  }
1532
1638
  }
1533
- else if (limit !== undefined) {
1534
- const endTime = this.seconds();
1535
- const duration = this.parseTimeframe(timeframe);
1536
- const auxLimit = limit; // in c# -limit is mutating the arg
1537
- request['start_time'] = this.sum(endTime, -auxLimit * duration);
1639
+ if (startTime !== undefined) {
1640
+ startTime = this.parseToInt(startTime / 1000);
1641
+ request['start_time'] = startTime;
1642
+ if ((limit !== undefined) || (until !== undefined)) {
1643
+ if (until !== undefined) {
1644
+ const endByUntil = this.parseToInt(until / 1000);
1645
+ if (limit !== undefined) {
1646
+ const endByLimit = this.sum(startTime, limit * duration);
1647
+ request['end_time'] = Math.min(endByLimit, endByUntil);
1648
+ }
1649
+ else {
1650
+ request['end_time'] = endByUntil;
1651
+ }
1652
+ }
1653
+ else {
1654
+ request['end_time'] = this.sum(startTime, limit * duration);
1655
+ }
1656
+ }
1538
1657
  }
1658
+ params = this.omit(params, 'until');
1539
1659
  response = await this.publicSpotGetKline(this.extend(request, params));
1540
1660
  }
1541
1661
  //
@@ -56,6 +56,7 @@ export default class ellipx extends Exchange {
56
56
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
57
57
  * @param {int} [limit] the maximum amount of candles to fetch
58
58
  * @param {object} [params] extra parameters specific to the API endpoint
59
+ * @param {int} [params.until] timestamp in ms of the earliest candle to fetch
59
60
  * @returns {OHLCV[]} A list of candles ordered as timestamp, open, high, low, close, volume
60
61
  */
61
62
  fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
package/js/src/ellipx.js CHANGED
@@ -235,6 +235,66 @@ export default class ellipx extends Exchange {
235
235
  'ETH': 'Ethereum',
236
236
  },
237
237
  },
238
+ 'features': {
239
+ 'spot': {
240
+ 'sandbox': false,
241
+ 'createOrder': {
242
+ 'marginMode': false,
243
+ 'triggerPrice': false,
244
+ 'triggerPriceType': undefined,
245
+ 'triggerDirection': false,
246
+ 'stopLossPrice': false,
247
+ 'takeProfitPrice': false,
248
+ 'attachedStopLossTakeProfit': undefined,
249
+ 'timeInForce': {
250
+ 'IOC': false,
251
+ 'FOK': false,
252
+ 'PO': false,
253
+ 'GTD': false,
254
+ },
255
+ 'hedged': false,
256
+ 'selfTradePrevention': false,
257
+ 'trailing': false,
258
+ 'leverage': false,
259
+ 'marketBuyByCost': true,
260
+ 'marketBuyRequiresPrice': false,
261
+ 'iceberg': false,
262
+ },
263
+ 'createOrders': undefined,
264
+ 'fetchMyTrades': undefined,
265
+ 'fetchOrder': {
266
+ 'marginMode': false,
267
+ 'trigger': false,
268
+ 'trailing': false,
269
+ },
270
+ 'fetchOpenOrders': {
271
+ 'marginMode': false,
272
+ 'limit': undefined,
273
+ 'trigger': false,
274
+ 'trailing': false,
275
+ },
276
+ 'fetchOrders': {
277
+ 'marginMode': false,
278
+ 'limit': undefined,
279
+ 'daysBack': undefined,
280
+ 'untilDays': undefined,
281
+ 'trigger': false,
282
+ 'trailing': false,
283
+ },
284
+ 'fetchClosedOrders': undefined,
285
+ 'fetchOHLCV': {
286
+ 'limit': 100,
287
+ },
288
+ },
289
+ 'swap': {
290
+ 'linear': undefined,
291
+ 'inverse': undefined,
292
+ },
293
+ 'future': {
294
+ 'linear': undefined,
295
+ 'inverse': undefined,
296
+ },
297
+ },
238
298
  'commonCurrencies': {},
239
299
  'exceptions': {
240
300
  'exact': {
@@ -669,6 +729,7 @@ export default class ellipx extends Exchange {
669
729
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
670
730
  * @param {int} [limit] the maximum amount of candles to fetch
671
731
  * @param {object} [params] extra parameters specific to the API endpoint
732
+ * @param {int} [params.until] timestamp in ms of the earliest candle to fetch
672
733
  * @returns {OHLCV[]} A list of candles ordered as timestamp, open, high, low, close, volume
673
734
  */
674
735
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
package/js/src/exmo.js CHANGED
@@ -211,6 +211,64 @@ export default class exmo extends Exchange {
211
211
  'fillResponseFromRequest': true,
212
212
  },
213
213
  },
214
+ 'features': {
215
+ 'spot': {
216
+ 'sandbox': false,
217
+ 'createOrder': {
218
+ 'marginMode': true,
219
+ 'triggerPrice': true,
220
+ 'triggerPriceType': undefined,
221
+ 'triggerDirection': false,
222
+ 'stopLossPrice': false,
223
+ 'takeProfitPrice': false,
224
+ 'attachedStopLossTakeProfit': undefined,
225
+ 'timeInForce': {
226
+ 'IOC': true,
227
+ 'FOK': true,
228
+ 'PO': true,
229
+ 'GTD': true,
230
+ },
231
+ 'hedged': false,
232
+ 'selfTradePrevention': false,
233
+ 'trailing': false,
234
+ 'leverage': true,
235
+ 'marketBuyByCost': true,
236
+ 'marketBuyRequiresPrice': false,
237
+ 'iceberg': false,
238
+ },
239
+ 'createOrders': undefined,
240
+ 'fetchMyTrades': {
241
+ 'marginMode': true,
242
+ 'limit': 100,
243
+ 'daysBack': undefined,
244
+ 'untilDays': undefined,
245
+ },
246
+ 'fetchOrder': {
247
+ 'marginMode': false,
248
+ 'trigger': false,
249
+ 'trailing': false,
250
+ },
251
+ 'fetchOpenOrders': {
252
+ 'marginMode': false,
253
+ 'limit': undefined,
254
+ 'trigger': false,
255
+ 'trailing': false,
256
+ },
257
+ 'fetchOrders': undefined,
258
+ 'fetchClosedOrders': undefined,
259
+ 'fetchOHLCV': {
260
+ 'limit': 1000, // todo, not in request
261
+ },
262
+ },
263
+ 'swap': {
264
+ 'linear': undefined,
265
+ 'inverse': undefined,
266
+ },
267
+ 'future': {
268
+ 'linear': undefined,
269
+ 'inverse': undefined,
270
+ },
271
+ },
214
272
  'commonCurrencies': {
215
273
  'GMT': 'GMT Token',
216
274
  },
package/js/src/hitbtc.js CHANGED
@@ -290,6 +290,105 @@ export default class hitbtc extends Exchange {
290
290
  },
291
291
  },
292
292
  },
293
+ 'features': {
294
+ 'default': {
295
+ 'sandbox': true,
296
+ 'createOrder': {
297
+ 'marginMode': false,
298
+ 'triggerPrice': true,
299
+ 'triggerPriceType': undefined,
300
+ 'triggerDirection': false,
301
+ 'stopLossPrice': false,
302
+ 'takeProfitPrice': false,
303
+ 'attachedStopLossTakeProfit': undefined,
304
+ 'timeInForce': {
305
+ 'IOC': true,
306
+ 'FOK': true,
307
+ 'PO': true,
308
+ 'GTD': true,
309
+ },
310
+ 'hedged': false,
311
+ 'selfTradePrevention': false,
312
+ 'trailing': false,
313
+ 'leverage': false,
314
+ 'marketBuyByCost': false,
315
+ 'marketBuyRequiresPrice': false,
316
+ 'iceberg': true,
317
+ },
318
+ 'createOrders': undefined,
319
+ 'fetchMyTrades': {
320
+ 'marginMode': true,
321
+ 'limit': 1000,
322
+ 'daysBack': 100000,
323
+ 'untilDays': 100000,
324
+ 'marketType': true,
325
+ },
326
+ 'fetchOrder': {
327
+ 'marginMode': true,
328
+ 'trigger': false,
329
+ 'trailing': false,
330
+ 'marketType': true,
331
+ },
332
+ 'fetchOpenOrders': {
333
+ 'marginMode': true,
334
+ 'limit': 1000,
335
+ 'trigger': false,
336
+ 'trailing': false,
337
+ 'marketType': true,
338
+ },
339
+ 'fetchOrders': undefined,
340
+ 'fetchClosedOrders': {
341
+ 'marginMode': true,
342
+ 'limit': 1000,
343
+ 'daysBack': 100000,
344
+ 'daysBackCanceled': 1,
345
+ 'untilDays': 100000,
346
+ 'trigger': false,
347
+ 'trailing': false,
348
+ 'marketType': true,
349
+ },
350
+ 'fetchOHLCV': {
351
+ 'limit': 1000,
352
+ },
353
+ },
354
+ 'spot': {
355
+ 'extends': 'default',
356
+ },
357
+ 'forDerivatives': {
358
+ 'extends': 'default',
359
+ 'createOrder': {
360
+ 'marginMode': true,
361
+ },
362
+ 'fetchOrder': {
363
+ 'marginMode': false,
364
+ },
365
+ 'fetchMyTrades': {
366
+ 'marginMode': false,
367
+ },
368
+ 'fetchOpenOrders': {
369
+ 'marginMode': false,
370
+ },
371
+ 'fetchClosedOrders': {
372
+ 'marginMode': false,
373
+ },
374
+ },
375
+ 'swap': {
376
+ 'linear': {
377
+ 'extends': 'forDerivatives',
378
+ },
379
+ 'inverse': {
380
+ 'extends': 'forDerivatives',
381
+ },
382
+ },
383
+ 'future': {
384
+ 'linear': {
385
+ 'extends': 'forDerivatives',
386
+ },
387
+ 'inverse': {
388
+ 'extends': 'forDerivatives',
389
+ },
390
+ },
391
+ },
293
392
  'timeframes': {
294
393
  '1m': 'M1',
295
394
  '3m': 'M3',