ccxt 4.1.30 → 4.1.32

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 (56) hide show
  1. package/CHANGELOG.md +186 -0
  2. package/README.md +3 -3
  3. package/dist/ccxt.browser.js +428 -174
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/ascendex.js +89 -12
  7. package/dist/cjs/src/base/Exchange.js +6 -0
  8. package/dist/cjs/src/bitget.js +43 -27
  9. package/dist/cjs/src/bitvavo.js +43 -7
  10. package/dist/cjs/src/bybit.js +0 -3
  11. package/dist/cjs/src/coinex.js +2 -1
  12. package/dist/cjs/src/gemini.js +1 -2
  13. package/dist/cjs/src/hitbtc.js +32 -22
  14. package/dist/cjs/src/huobi.js +18 -12
  15. package/dist/cjs/src/krakenfutures.js +1 -0
  16. package/dist/cjs/src/mexc.js +2 -6
  17. package/dist/cjs/src/okx.js +1 -0
  18. package/dist/cjs/src/phemex.js +8 -6
  19. package/dist/cjs/src/pro/bittrex.js +68 -2
  20. package/dist/cjs/src/pro/huobi.js +76 -32
  21. package/dist/cjs/src/woo.js +27 -31
  22. package/js/ccxt.d.ts +3 -3
  23. package/js/ccxt.js +1 -1
  24. package/js/src/ascendex.d.ts +11 -1
  25. package/js/src/ascendex.js +89 -12
  26. package/js/src/base/Exchange.d.ts +5 -3
  27. package/js/src/base/Exchange.js +6 -0
  28. package/js/src/base/types.d.ts +9 -0
  29. package/js/src/binance.d.ts +1 -1
  30. package/js/src/bitget.d.ts +3 -3
  31. package/js/src/bitget.js +43 -27
  32. package/js/src/bitvavo.d.ts +13 -13
  33. package/js/src/bitvavo.js +43 -7
  34. package/js/src/bybit.js +0 -3
  35. package/js/src/coinex.d.ts +2 -2
  36. package/js/src/coinex.js +2 -1
  37. package/js/src/gate.d.ts +3 -3
  38. package/js/src/gemini.js +1 -2
  39. package/js/src/hitbtc.js +33 -23
  40. package/js/src/huobi.d.ts +1 -1
  41. package/js/src/huobi.js +18 -12
  42. package/js/src/krakenfutures.js +1 -0
  43. package/js/src/kucoinfutures.d.ts +2 -2
  44. package/js/src/mexc.d.ts +2 -2
  45. package/js/src/mexc.js +2 -6
  46. package/js/src/okx.d.ts +2 -2
  47. package/js/src/okx.js +1 -0
  48. package/js/src/phemex.d.ts +2 -2
  49. package/js/src/phemex.js +8 -6
  50. package/js/src/poloniexfutures.d.ts +2 -2
  51. package/js/src/pro/bittrex.d.ts +1 -0
  52. package/js/src/pro/bittrex.js +69 -3
  53. package/js/src/pro/huobi.js +76 -32
  54. package/js/src/woo.d.ts +1 -1
  55. package/js/src/woo.js +27 -31
  56. package/package.json +2 -2
package/dist/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.1.30';
183
+ const version = '4.1.32';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -29,7 +29,7 @@ class ascendex extends ascendex$1 {
29
29
  'spot': true,
30
30
  'margin': true,
31
31
  'swap': true,
32
- 'future': true,
32
+ 'future': false,
33
33
  'option': false,
34
34
  'addMargin': true,
35
35
  'cancelAllOrders': true,
@@ -51,7 +51,7 @@ class ascendex extends ascendex$1 {
51
51
  'fetchDepositsWithdrawals': true,
52
52
  'fetchDepositWithdrawFee': 'emulated',
53
53
  'fetchDepositWithdrawFees': true,
54
- 'fetchFundingHistory': false,
54
+ 'fetchFundingHistory': true,
55
55
  'fetchFundingRate': 'emulated',
56
56
  'fetchFundingRateHistory': false,
57
57
  'fetchFundingRates': true,
@@ -265,7 +265,6 @@ class ascendex extends ascendex$1 {
265
265
  'accountsByType': {
266
266
  'spot': 'cash',
267
267
  'swap': 'futures',
268
- 'future': 'futures',
269
268
  'margin': 'margin',
270
269
  },
271
270
  'transfer': {
@@ -2763,22 +2762,21 @@ class ascendex extends ascendex$1 {
2763
2762
  * @method
2764
2763
  * @name ascendex#setLeverage
2765
2764
  * @description set the level of leverage for a market
2765
+ * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-contract-leverage
2766
2766
  * @param {float} leverage the rate of leverage
2767
2767
  * @param {string} symbol unified market symbol
2768
2768
  * @param {object} [params] extra parameters specific to the ascendex api endpoint
2769
2769
  * @returns {object} response from the exchange
2770
2770
  */
2771
- if (symbol === undefined) {
2772
- throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
2773
- }
2771
+ this.checkRequiredSymbol('setLeverage', symbol);
2774
2772
  if ((leverage < 1) || (leverage > 100)) {
2775
2773
  throw new errors.BadRequest(this.id + ' leverage should be between 1 and 100');
2776
2774
  }
2777
2775
  await this.loadMarkets();
2778
2776
  await this.loadAccounts();
2779
2777
  const market = this.market(symbol);
2780
- if (market['type'] !== 'future') {
2781
- throw new errors.BadSymbol(this.id + ' setLeverage() supports futures contracts only');
2778
+ if (!market['swap']) {
2779
+ throw new errors.BadSymbol(this.id + ' setLeverage() supports swap contracts only');
2782
2780
  }
2783
2781
  const account = this.safeValue(this.accounts, 0, {});
2784
2782
  const accountGroup = this.safeString(account, 'id');
@@ -2794,11 +2792,13 @@ class ascendex extends ascendex$1 {
2794
2792
  * @method
2795
2793
  * @name ascendex#setMarginMode
2796
2794
  * @description set margin mode to 'cross' or 'isolated'
2795
+ * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#change-margin-type
2797
2796
  * @param {string} marginMode 'cross' or 'isolated'
2798
2797
  * @param {string} symbol unified market symbol
2799
2798
  * @param {object} [params] extra parameters specific to the ascendex api endpoint
2800
2799
  * @returns {object} response from the exchange
2801
2800
  */
2801
+ this.checkRequiredSymbol('setMarginMode', symbol);
2802
2802
  marginMode = marginMode.toLowerCase();
2803
2803
  if (marginMode === 'cross') {
2804
2804
  marginMode = 'crossed';
@@ -2814,10 +2814,10 @@ class ascendex extends ascendex$1 {
2814
2814
  const request = {
2815
2815
  'account-group': accountGroup,
2816
2816
  'symbol': market['id'],
2817
- 'marginMode': marginMode,
2817
+ 'marginType': marginMode,
2818
2818
  };
2819
- if (market['type'] !== 'future') {
2820
- throw new errors.BadSymbol(this.id + ' setMarginMode() supports futures contracts only');
2819
+ if (!market['swap']) {
2820
+ throw new errors.BadSymbol(this.id + ' setMarginMode() supports swap contracts only');
2821
2821
  }
2822
2822
  return await this.v2PrivateAccountGroupPostFuturesMarginType(this.extend(request, params));
2823
2823
  }
@@ -2998,7 +2998,7 @@ class ascendex extends ascendex$1 {
2998
2998
  const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
2999
2999
  const toId = this.safeString(accountsByType, toAccount, toAccount);
3000
3000
  if (fromId !== 'cash' && toId !== 'cash') {
3001
- throw new errors.ExchangeError(this.id + ' transfer() only supports direct balance transfer between spot and future, spot and margin');
3001
+ throw new errors.ExchangeError(this.id + ' transfer() only supports direct balance transfer between spot and swap, spot and margin');
3002
3002
  }
3003
3003
  const request = {
3004
3004
  'account-group': accountGroup,
@@ -3047,6 +3047,83 @@ class ascendex extends ascendex$1 {
3047
3047
  }
3048
3048
  return 'failed';
3049
3049
  }
3050
+ async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3051
+ /**
3052
+ * @method
3053
+ * @name ascendex#fetchFundingHistory
3054
+ * @description fetch the history of funding payments paid and received on this account
3055
+ * @see https://ascendex.github.io/ascendex-futures-pro-api-v2/#funding-payment-history
3056
+ * @param {string} [symbol] unified market symbol
3057
+ * @param {int} [since] the earliest time in ms to fetch funding history for
3058
+ * @param {int} [limit] the maximum number of funding history structures to retrieve
3059
+ * @param {object} [params] extra parameters specific to the ascendex api endpoint
3060
+ * @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)
3061
+ * @returns {object} a [funding history structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#funding-history-structure}
3062
+ */
3063
+ await this.loadMarkets();
3064
+ await this.loadAccounts();
3065
+ let paginate = false;
3066
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingHistory', 'paginate');
3067
+ if (paginate) {
3068
+ return await this.fetchPaginatedCallIncremental('fetchFundingHistory', symbol, since, limit, params, 'page', 25);
3069
+ }
3070
+ const account = this.safeValue(this.accounts, 0, {});
3071
+ const accountGroup = this.safeString(account, 'id');
3072
+ const request = {
3073
+ 'account-group': accountGroup,
3074
+ };
3075
+ let market = undefined;
3076
+ if (symbol !== undefined) {
3077
+ market = this.market(symbol);
3078
+ request['symbol'] = market['id'];
3079
+ }
3080
+ if (limit !== undefined) {
3081
+ request['pageSize'] = limit;
3082
+ }
3083
+ const response = await this.v2PrivateAccountGroupGetFuturesFundingPayments(this.extend(request, params));
3084
+ //
3085
+ // {
3086
+ // "code": 0,
3087
+ // "data": {
3088
+ // "data": [
3089
+ // {
3090
+ // "timestamp": 1640476800000,
3091
+ // "symbol": "BTC-PERP",
3092
+ // "paymentInUSDT": "-0.013991178",
3093
+ // "fundingRate": "0.000173497"
3094
+ // },
3095
+ // ],
3096
+ // "page": 1,
3097
+ // "pageSize": 3,
3098
+ // "hasNext": true
3099
+ // }
3100
+ // }
3101
+ //
3102
+ const data = this.safeValue(response, 'data', {});
3103
+ const rows = this.safeValue(data, 'data', []);
3104
+ return this.parseIncomes(rows, market, since, limit);
3105
+ }
3106
+ parseIncome(income, market = undefined) {
3107
+ //
3108
+ // {
3109
+ // "timestamp": 1640476800000,
3110
+ // "symbol": "BTC-PERP",
3111
+ // "paymentInUSDT": "-0.013991178",
3112
+ // "fundingRate": "0.000173497"
3113
+ // }
3114
+ //
3115
+ const marketId = this.safeString(income, 'symbol');
3116
+ const timestamp = this.safeInteger(income, 'timestamp');
3117
+ return {
3118
+ 'info': income,
3119
+ 'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
3120
+ 'code': 'USDT',
3121
+ 'timestamp': timestamp,
3122
+ 'datetime': this.iso8601(timestamp),
3123
+ 'id': undefined,
3124
+ 'amount': this.safeNumber(income, 'paymentInUSDT'),
3125
+ };
3126
+ }
3050
3127
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3051
3128
  const version = api[0];
3052
3129
  const access = api[1];
@@ -78,6 +78,7 @@ class Exchange {
78
78
  this.last_http_response = undefined;
79
79
  this.last_json_response = undefined;
80
80
  this.last_response_headers = undefined;
81
+ this.last_request_headers = undefined;
81
82
  this.id = undefined;
82
83
  this.markets = undefined;
83
84
  this.status = undefined;
@@ -272,6 +273,7 @@ class Exchange {
272
273
  this.last_http_response = undefined;
273
274
  this.last_json_response = undefined;
274
275
  this.last_response_headers = undefined;
276
+ this.last_request_headers = undefined;
275
277
  // camelCase and snake_notation support
276
278
  const unCamelCaseProperties = (obj = this) => {
277
279
  if (obj !== null) {
@@ -2830,6 +2832,7 @@ class Exchange {
2830
2832
  }
2831
2833
  this.lastRestRequestTimestamp = this.milliseconds();
2832
2834
  const request = this.sign(path, api, method, params, headers, body);
2835
+ this.last_request_headers = request['headers'];
2833
2836
  return await this.fetch(request['url'], request['method'], request['headers'], request['body']);
2834
2837
  }
2835
2838
  async request(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined, config = {}) {
@@ -3414,6 +3417,9 @@ class Exchange {
3414
3417
  async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3415
3418
  throw new errors.NotSupported(this.id + ' fetchFundingRateHistory() is not supported yet');
3416
3419
  }
3420
+ async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3421
+ throw new errors.NotSupported(this.id + ' fetchFundingHistory() is not supported yet');
3422
+ }
3417
3423
  parseLastPrice(price, market = undefined) {
3418
3424
  throw new errors.NotSupported(this.id + ' parseLastPrice() is not supported yet');
3419
3425
  }
@@ -1303,11 +1303,16 @@ class bitget extends bitget$1 {
1303
1303
  };
1304
1304
  }
1305
1305
  async fetchMarketsByType(type, params = {}) {
1306
- const method = this.getSupportedMapping(type, {
1307
- 'spot': 'publicSpotGetPublicProducts',
1308
- 'swap': 'publicMixGetMarketContracts',
1309
- });
1310
- const response = await this[method](params);
1306
+ let response = undefined;
1307
+ if (type === 'spot') {
1308
+ response = await this.publicSpotGetPublicProducts(params);
1309
+ }
1310
+ else if (type === 'swap') {
1311
+ response = await this.publicMixGetMarketContracts(params);
1312
+ }
1313
+ else {
1314
+ throw new errors.NotSupported(this.id + ' does not support ' + type + ' market');
1315
+ }
1311
1316
  //
1312
1317
  // spot
1313
1318
  //
@@ -3565,11 +3570,6 @@ class bitget extends bitget$1 {
3565
3570
  if (!isStopOrder && !isTriggerOrder) {
3566
3571
  throw new errors.InvalidOrder(this.id + ' editOrder() only support plan orders');
3567
3572
  }
3568
- let method = this.getSupportedMapping(marketType, {
3569
- 'spot': 'privateSpotPostPlanModifyPlan',
3570
- 'swap': 'privateMixPostPlanModifyPlan',
3571
- 'future': 'privateMixPostPlanModifyPlan',
3572
- });
3573
3573
  if (triggerPrice !== undefined) {
3574
3574
  // default triggerType to market price for unification
3575
3575
  const triggerType = this.safeString(params, 'triggerType', 'market_price');
@@ -3577,6 +3577,8 @@ class bitget extends bitget$1 {
3577
3577
  request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
3578
3578
  request['executePrice'] = this.priceToPrecision(symbol, price);
3579
3579
  }
3580
+ const omitted = this.omit(query, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice']);
3581
+ let response = undefined;
3580
3582
  if (marketType === 'spot') {
3581
3583
  if (isStopOrder) {
3582
3584
  throw new errors.InvalidOrder(this.id + ' editOrder() does not support stop orders on spot markets, only swap markets');
@@ -3596,10 +3598,15 @@ class bitget extends bitget$1 {
3596
3598
  else {
3597
3599
  request['size'] = this.amountToPrecision(symbol, amount);
3598
3600
  }
3601
+ response = await this.privateSpotPostPlanModifyPlan(this.extend(request, omitted));
3599
3602
  }
3600
3603
  else {
3601
3604
  request['symbol'] = market['id'];
3602
3605
  request['size'] = this.amountToPrecision(symbol, amount);
3606
+ if ((marketType !== 'swap') && (marketType !== 'future')) {
3607
+ throw new errors.NotSupported(this.id + ' editOrder() does not support ' + marketType + ' market');
3608
+ }
3609
+ request['marginCoin'] = market['settleId'];
3603
3610
  if (isStopOrder) {
3604
3611
  if (!isMarketOrder) {
3605
3612
  throw new errors.ExchangeError(this.id + ' editOrder() bitget stopLoss or takeProfit orders must be market orders');
@@ -3612,12 +3619,12 @@ class bitget extends bitget$1 {
3612
3619
  request['triggerPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
3613
3620
  request['planType'] = 'profit_plan';
3614
3621
  }
3615
- method = 'privateMixPostPlanModifyTPSLPlan';
3622
+ response = await this.privateMixPostPlanModifyTPSLPlan(this.extend(request, omitted));
3623
+ }
3624
+ else {
3625
+ response = await this.privateMixPostPlanModifyPlan(this.extend(request, omitted));
3616
3626
  }
3617
- request['marginCoin'] = market['settleId'];
3618
3627
  }
3619
- const omitted = this.omit(query, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice']);
3620
- const response = await this[method](this.extend(request, omitted));
3621
3628
  //
3622
3629
  // spot
3623
3630
  // {
@@ -3947,16 +3954,20 @@ class bitget extends bitget$1 {
3947
3954
  await this.loadMarkets();
3948
3955
  const market = this.market(symbol);
3949
3956
  const [marketType, query] = this.handleMarketTypeAndParams('fetchOrder', market, params);
3950
- const method = this.getSupportedMapping(marketType, {
3951
- 'spot': 'privateSpotPostTradeOrderInfo',
3952
- 'swap': 'privateMixGetOrderDetail',
3953
- 'future': 'privateMixGetOrderDetail',
3954
- });
3955
3957
  const request = {
3956
3958
  'symbol': market['id'],
3957
3959
  'orderId': id,
3958
3960
  };
3959
- let response = await this[method](this.extend(request, query));
3961
+ let response = undefined;
3962
+ if (marketType === 'spot') {
3963
+ response = await this.privateSpotPostTradeOrderInfo(this.extend(request, query));
3964
+ }
3965
+ else if ((marketType === 'swap') || (marketType === 'future')) {
3966
+ response = await this.privateMixGetOrderDetail(this.extend(request, query));
3967
+ }
3968
+ else {
3969
+ throw new errors.NotSupported(this.id + ' fetchOrder() does not support ' + marketType + ' market');
3970
+ }
3960
3971
  // spot
3961
3972
  // {
3962
3973
  // code: '00000',
@@ -4882,16 +4893,20 @@ class bitget extends bitget$1 {
4882
4893
  await this.loadMarkets();
4883
4894
  const market = this.market(symbol);
4884
4895
  const [marketType, query] = this.handleMarketTypeAndParams('fetchOrderTrades', market, params);
4885
- const method = this.getSupportedMapping(marketType, {
4886
- 'spot': 'privateSpotPostTradeFills',
4887
- 'swap': 'privateMixGetOrderFills',
4888
- 'future': 'privateMixGetOrderFills',
4889
- });
4890
4896
  const request = {
4891
4897
  'symbol': market['id'],
4892
4898
  'orderId': id,
4893
4899
  };
4894
- const response = await this[method](this.extend(request, query));
4900
+ let response = undefined;
4901
+ if (marketType === 'spot') {
4902
+ response = await this.privateSpotPostTradeFills(this.extend(request, query));
4903
+ }
4904
+ else if ((marketType === 'swap') || (marketType === 'future')) {
4905
+ response = await this.privateMixGetOrderFills(this.extend(request, query));
4906
+ }
4907
+ else {
4908
+ throw new errors.NotSupported(this.id + ' fetchOrderTrades() does not support ' + marketType + ' market');
4909
+ }
4895
4910
  // spot
4896
4911
  //
4897
4912
  // swap
@@ -5355,7 +5370,7 @@ class bitget extends bitget$1 {
5355
5370
  'previousFundingDatetime': undefined,
5356
5371
  };
5357
5372
  }
5358
- async fetchFundingHistory(symbol, since = undefined, limit = undefined, params = {}) {
5373
+ async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
5359
5374
  /**
5360
5375
  * @method
5361
5376
  * @name bitget#fetchFundingHistory
@@ -5368,6 +5383,7 @@ class bitget extends bitget$1 {
5368
5383
  * @returns {object[]} a list of [funding history structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#funding-history-structure}
5369
5384
  */
5370
5385
  await this.loadMarkets();
5386
+ this.checkRequiredSymbol('fetchFundingHistory', symbol);
5371
5387
  const market = this.market(symbol);
5372
5388
  if (!market['swap']) {
5373
5389
  throw new errors.BadSymbol(this.id + ' fetchFundingHistory() supports swap contracts only');
@@ -501,6 +501,7 @@ class bitvavo extends bitvavo$1 {
501
501
  /**
502
502
  * @method
503
503
  * @name bitvavo#fetchTicker
504
+ * @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1ticker~124h/get
504
505
  * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
505
506
  * @param {string} symbol unified symbol of the market to fetch the ticker for
506
507
  * @param {object} [params] extra parameters specific to the bitvavo api endpoint
@@ -614,16 +615,24 @@ class bitvavo extends bitvavo$1 {
614
615
  /**
615
616
  * @method
616
617
  * @name bitvavo#fetchTrades
618
+ * @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1trades/get
617
619
  * @description get the list of most recent trades for a particular symbol
618
620
  * @param {string} symbol unified symbol of the market to fetch trades for
619
621
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
620
622
  * @param {int} [limit] the maximum amount of trades to fetch
621
623
  * @param {object} [params] extra parameters specific to the bitvavo api endpoint
624
+ * @param {int} [params.until] the latest time in ms to fetch entries for
625
+ * @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)
622
626
  * @returns {Trade[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#public-trades}
623
627
  */
624
628
  await this.loadMarkets();
625
629
  const market = this.market(symbol);
626
- const request = {
630
+ let paginate = false;
631
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchTrades', 'paginate');
632
+ if (paginate) {
633
+ return await this.fetchPaginatedCallDynamic('fetchTrades', symbol, since, limit, params);
634
+ }
635
+ let request = {
627
636
  'market': market['id'],
628
637
  // 'limit': 500, // default 500, max 1000
629
638
  // 'start': since,
@@ -637,6 +646,7 @@ class bitvavo extends bitvavo$1 {
637
646
  if (since !== undefined) {
638
647
  request['start'] = since;
639
648
  }
649
+ [request, params] = this.handleUntilOption('end', request, params);
640
650
  const response = await this.publicGetMarketTrades(this.extend(request, params));
641
651
  //
642
652
  // [
@@ -787,6 +797,7 @@ class bitvavo extends bitvavo$1 {
787
797
  /**
788
798
  * @method
789
799
  * @name bitvavo#fetchOrderBook
800
+ * @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1book/get
790
801
  * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
791
802
  * @param {string} symbol unified symbol of the market to fetch the order book for
792
803
  * @param {int} [limit] the maximum amount of order book entries to return
@@ -846,17 +857,25 @@ class bitvavo extends bitvavo$1 {
846
857
  /**
847
858
  * @method
848
859
  * @name bitvavo#fetchOHLCV
860
+ * @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1candles/get
849
861
  * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
850
862
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
851
863
  * @param {string} timeframe the length of time each candle represents
852
864
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
853
865
  * @param {int} [limit] the maximum amount of candles to fetch
854
866
  * @param {object} [params] extra parameters specific to the bitvavo api endpoint
867
+ * @param {int} [params.until] the latest time in ms to fetch entries for
868
+ * @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)
855
869
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
856
870
  */
857
871
  await this.loadMarkets();
858
872
  const market = this.market(symbol);
859
- const request = {
873
+ let paginate = false;
874
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
875
+ if (paginate) {
876
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1440);
877
+ }
878
+ let request = {
860
879
  'market': market['id'],
861
880
  'interval': this.safeString(this.timeframes, timeframe, timeframe),
862
881
  // 'limit': 1440, // default 1440, max 1440
@@ -872,6 +891,7 @@ class bitvavo extends bitvavo$1 {
872
891
  }
873
892
  request['end'] = this.sum(since, limit * duration * 1000);
874
893
  }
894
+ [request, params] = this.handleUntilOption('end', request, params);
875
895
  if (limit !== undefined) {
876
896
  request['limit'] = limit; // default 1440, max 1440
877
897
  }
@@ -1225,19 +1245,25 @@ class bitvavo extends bitvavo$1 {
1225
1245
  /**
1226
1246
  * @method
1227
1247
  * @name bitvavo#fetchOrders
1248
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1orders/get
1228
1249
  * @description fetches information on multiple orders made by the user
1229
1250
  * @param {string} symbol unified market symbol of the market orders were made in
1230
1251
  * @param {int} [since] the earliest time in ms to fetch orders for
1231
1252
  * @param {int} [limit] the maximum number of orde structures to retrieve
1232
1253
  * @param {object} [params] extra parameters specific to the bitvavo api endpoint
1254
+ * @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)
1255
+ * @param {int} [params.until] the latest time in ms to fetch entries for
1233
1256
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1234
1257
  */
1235
- if (symbol === undefined) {
1236
- throw new errors.ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
1237
- }
1258
+ this.checkRequiredSymbol('fetchOrders', symbol);
1238
1259
  await this.loadMarkets();
1260
+ let paginate = false;
1261
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOrders', 'paginate');
1262
+ if (paginate) {
1263
+ return await this.fetchPaginatedCallDynamic('fetchOrders', symbol, since, limit, params);
1264
+ }
1239
1265
  const market = this.market(symbol);
1240
- const request = {
1266
+ let request = {
1241
1267
  'market': market['id'],
1242
1268
  // 'limit': 500,
1243
1269
  // 'start': since,
@@ -1251,6 +1277,7 @@ class bitvavo extends bitvavo$1 {
1251
1277
  if (limit !== undefined) {
1252
1278
  request['limit'] = limit; // default 500, max 1000
1253
1279
  }
1280
+ [request, params] = this.handleUntilOption('end', request, params);
1254
1281
  const response = await this.privateGetOrders(this.extend(request, params));
1255
1282
  //
1256
1283
  // [
@@ -1475,19 +1502,27 @@ class bitvavo extends bitvavo$1 {
1475
1502
  /**
1476
1503
  * @method
1477
1504
  * @name bitvavo#fetchMyTrades
1505
+ * @see https://docs.bitvavo.com/#tag/Trades/paths/~1trades/get
1478
1506
  * @description fetch all trades made by the user
1479
1507
  * @param {string} symbol unified market symbol
1480
1508
  * @param {int} [since] the earliest time in ms to fetch trades for
1481
1509
  * @param {int} [limit] the maximum number of trades structures to retrieve
1482
1510
  * @param {object} [params] extra parameters specific to the bitvavo api endpoint
1511
+ * @param {int} [params.until] the latest time in ms to fetch entries for
1512
+ * @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)
1483
1513
  * @returns {Trade[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#trade-structure}
1484
1514
  */
1485
1515
  if (symbol === undefined) {
1486
1516
  throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
1487
1517
  }
1488
1518
  await this.loadMarkets();
1519
+ let paginate = false;
1520
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
1521
+ if (paginate) {
1522
+ return await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params);
1523
+ }
1489
1524
  const market = this.market(symbol);
1490
- const request = {
1525
+ let request = {
1491
1526
  'market': market['id'],
1492
1527
  // 'limit': 500,
1493
1528
  // 'start': since,
@@ -1501,6 +1536,7 @@ class bitvavo extends bitvavo$1 {
1501
1536
  if (limit !== undefined) {
1502
1537
  request['limit'] = limit; // default 500, max 1000
1503
1538
  }
1539
+ [request, params] = this.handleUntilOption('end', request, params);
1504
1540
  const response = await this.privateGetTrades(this.extend(request, params));
1505
1541
  //
1506
1542
  // [
@@ -1198,9 +1198,6 @@ class bybit extends bybit$1 {
1198
1198
  'deposit': {},
1199
1199
  },
1200
1200
  },
1201
- 'commonCurrencies': {
1202
- 'GAS': 'GASDAO',
1203
- },
1204
1201
  });
1205
1202
  }
1206
1203
  nonce() {
@@ -1751,7 +1751,8 @@ class coinex extends coinex$1 {
1751
1751
  const remainingString = this.safeString(order, 'left');
1752
1752
  const marketId = this.safeString(order, 'market');
1753
1753
  const defaultType = this.safeString(this.options, 'defaultType');
1754
- market = this.safeMarket(marketId, market, undefined, defaultType);
1754
+ const orderType = ('source' in order) ? 'swap' : defaultType;
1755
+ market = this.safeMarket(marketId, market, undefined, orderType);
1755
1756
  const feeCurrencyId = this.safeString(order, 'fee_asset');
1756
1757
  let feeCurrency = this.safeCurrencyCode(feeCurrencyId);
1757
1758
  if (feeCurrency === undefined) {
@@ -557,11 +557,10 @@ class gemini extends gemini$1 {
557
557
  }
558
558
  for (let i = 0; i < marketIds.length; i++) {
559
559
  const marketId = marketIds[i];
560
- const method = 'publicGetV1SymbolsDetailsSymbol';
561
560
  const request = {
562
561
  'symbol': marketId,
563
562
  };
564
- promises.push(this[method](this.extend(request, params)));
563
+ promises.push(this.publicGetV1SymbolsDetailsSymbol(this.extend(request, params)));
565
564
  //
566
565
  // {
567
566
  // "symbol": "BTCUSD",