ccxt 4.1.7 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/ccxt.js CHANGED
@@ -179,7 +179,7 @@ var woo$1 = require('./src/pro/woo.js');
179
179
 
180
180
  //-----------------------------------------------------------------------------
181
181
  // this is updated by vss.js when building
182
- const version = '4.1.7';
182
+ const version = '4.1.8';
183
183
  Exchange["default"].ccxtVersion = version;
184
184
  const exchanges = {
185
185
  'ace': ace,
@@ -438,13 +438,13 @@ class bitbns extends bitbns$1 {
438
438
  if (numParts > 1) {
439
439
  let currencyId = this.safeString(parts, 1);
440
440
  // note that "Money" stands for INR - the only fiat in bitbns
441
+ const account = this.account();
442
+ account['free'] = this.safeString(data, key);
443
+ account['used'] = this.safeString(data, 'inorder' + currencyId);
441
444
  if (currencyId === 'Money') {
442
445
  currencyId = 'INR';
443
446
  }
444
447
  const code = this.safeCurrencyCode(currencyId);
445
- const account = this.account();
446
- account['free'] = this.safeString(data, key);
447
- account['used'] = this.safeString(data, 'inorder' + currencyId);
448
448
  result[code] = account;
449
449
  }
450
450
  }
@@ -179,6 +179,8 @@ class bitmart extends bitmart$1 {
179
179
  'spot/v1/margin/isolated/account': 6,
180
180
  'spot/v1/trade_fee': 6,
181
181
  'spot/v1/user_fee': 6,
182
+ // broker
183
+ 'spot/v1/broker/rebate': 1,
182
184
  // contract
183
185
  'contract/private/assets-detail': 5,
184
186
  'contract/private/order': 1.2,
@@ -933,9 +933,9 @@ class coinfalcon extends coinfalcon$1 {
933
933
  const amountString = this.safeString(transaction, 'amount');
934
934
  const amount = this.parseNumber(amountString);
935
935
  const feeCostString = this.safeString(transaction, 'fee');
936
- let feeCost = 0;
936
+ let feeCost = '0';
937
937
  if (feeCostString !== undefined) {
938
- feeCost = this.parseNumber(feeCostString);
938
+ feeCost = feeCostString;
939
939
  }
940
940
  return {
941
941
  'info': transaction,
@@ -957,7 +957,7 @@ class coinfalcon extends coinfalcon$1 {
957
957
  'updated': undefined,
958
958
  'fee': {
959
959
  'currency': code,
960
- 'cost': feeCost,
960
+ 'cost': this.parseNumber(feeCost),
961
961
  },
962
962
  };
963
963
  }
@@ -2225,7 +2225,7 @@ class kucoin extends kucoin$1 {
2225
2225
  * @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)
2226
2226
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2227
2227
  */
2228
- await this.loadMarkets;
2228
+ await this.loadMarkets();
2229
2229
  let paginate = false;
2230
2230
  [paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
2231
2231
  if (paginate) {
@@ -2258,7 +2258,7 @@ class kucoin extends kucoin$1 {
2258
2258
  * @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)
2259
2259
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2260
2260
  */
2261
- await this.loadMarkets;
2261
+ await this.loadMarkets();
2262
2262
  let paginate = false;
2263
2263
  [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'paginate');
2264
2264
  if (paginate) {
@@ -1534,7 +1534,7 @@ class kucoinfutures extends kucoinfutures$1 {
1534
1534
  * @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)
1535
1535
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1536
1536
  */
1537
- await this.loadMarkets;
1537
+ await this.loadMarkets();
1538
1538
  let paginate = false;
1539
1539
  [paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
1540
1540
  if (paginate) {
@@ -193,6 +193,8 @@ class mexc extends mexc$1 {
193
193
  'rebate/detail/kickback': 1,
194
194
  'rebate/referCode': 1,
195
195
  'rebate/affiliate/commission': 1,
196
+ 'rebate/affiliate/withdraw': 1,
197
+ 'rebate/affiliate/commission/detail': 1,
196
198
  'mxDeduct/enable': 1,
197
199
  'userDataStream': 1,
198
200
  },
@@ -1357,11 +1359,15 @@ class mexc extends mexc$1 {
1357
1359
  /**
1358
1360
  * @method
1359
1361
  * @name mexc3#fetchTrades
1362
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#recent-trades-list
1363
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#compressed-aggregate-trades-list
1364
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-transaction-data
1360
1365
  * @description get the list of most recent trades for a particular symbol
1361
1366
  * @param {string} symbol unified symbol of the market to fetch trades for
1362
1367
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
1363
1368
  * @param {int} [limit] the maximum amount of trades to fetch
1364
1369
  * @param {object} [params] extra parameters specific to the mexc3 api endpoint
1370
+ * @param {int} [params.until] *spot only* *since must be defined* the latest time in ms to fetch entries for
1365
1371
  * @returns {Trade[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#public-trades}
1366
1372
  */
1367
1373
  await this.loadMarkets();
@@ -1372,11 +1378,21 @@ class mexc extends mexc$1 {
1372
1378
  if (limit !== undefined) {
1373
1379
  request['limit'] = limit;
1374
1380
  }
1375
- // if (since !== undefined) {
1376
- // request['startTime'] = since; bug in api, waiting for fix
1377
- // }
1378
1381
  let trades = undefined;
1379
1382
  if (market['spot']) {
1383
+ const until = this.safeIntegerN(params, ['endTime', 'until', 'till']);
1384
+ if (since !== undefined) {
1385
+ request['startTime'] = since;
1386
+ if (until === undefined) {
1387
+ throw new errors.ArgumentsRequired(this.id + ' fetchTrades() requires an until parameter when since is provided');
1388
+ }
1389
+ }
1390
+ if (until !== undefined) {
1391
+ if (since === undefined) {
1392
+ throw new errors.ArgumentsRequired(this.id + ' fetchTrades() requires a since parameter when until is provided');
1393
+ }
1394
+ request['endTime'] = until;
1395
+ }
1380
1396
  let method = this.safeString(this.options, 'fetchTradesMethod', 'spotPublicGetAggTrades');
1381
1397
  method = this.safeString(params, 'method', method); // AggTrades, HistoricalTrades, Trades
1382
1398
  trades = await this[method](this.extend(request, params));
@@ -1607,31 +1623,53 @@ class mexc extends mexc$1 {
1607
1623
  /**
1608
1624
  * @method
1609
1625
  * @name mexc3#fetchOHLCV
1626
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#kline-candlestick-data
1627
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#k-line-data
1610
1628
  * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1611
1629
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1612
1630
  * @param {string} timeframe the length of time each candle represents
1613
1631
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
1614
1632
  * @param {int} [limit] the maximum amount of candles to fetch
1615
1633
  * @param {object} [params] extra parameters specific to the mexc3 api endpoint
1634
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
1635
+ * @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)
1616
1636
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1617
1637
  */
1618
1638
  await this.loadMarkets();
1619
1639
  const market = this.market(symbol);
1640
+ const maxLimit = (market['spot']) ? 1000 : 2000;
1641
+ let paginate = false;
1642
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
1643
+ if (paginate) {
1644
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
1645
+ }
1620
1646
  const options = this.safeValue(this.options, 'timeframes', {});
1621
1647
  const timeframes = this.safeValue(options, market['type'], {});
1622
1648
  const timeframeValue = this.safeString(timeframes, timeframe);
1649
+ const duration = this.parseTimeframe(timeframe) * 1000;
1623
1650
  const request = {
1624
1651
  'symbol': market['id'],
1625
1652
  'interval': timeframeValue,
1626
1653
  };
1627
1654
  let candles = undefined;
1628
1655
  if (market['spot']) {
1656
+ const until = this.safeIntegerN(params, ['until', 'endTime', 'till']);
1629
1657
  if (since !== undefined) {
1630
1658
  request['startTime'] = since;
1659
+ if (until === undefined) {
1660
+ // we have to calculate it assuming we can get at most 2000 entries per request
1661
+ const end = this.sum(since, maxLimit * duration);
1662
+ const now = this.milliseconds();
1663
+ request['endTime'] = Math.min(end, now);
1664
+ }
1631
1665
  }
1632
1666
  if (limit !== undefined) {
1633
1667
  request['limit'] = limit;
1634
1668
  }
1669
+ if (until !== undefined) {
1670
+ params = this.omit(params, ['until', 'till']);
1671
+ request['endTime'] = until;
1672
+ }
1635
1673
  const response = await this.spotPublicGetKlines(this.extend(request, params));
1636
1674
  //
1637
1675
  // [
@@ -1650,9 +1688,14 @@ class mexc extends mexc$1 {
1650
1688
  candles = response;
1651
1689
  }
1652
1690
  else if (market['swap']) {
1691
+ const until = this.safeIntegerProductN(params, ['until', 'endTime', 'till'], 0.001);
1653
1692
  if (since !== undefined) {
1654
1693
  request['start'] = this.parseToInt(since / 1000);
1655
1694
  }
1695
+ if (until !== undefined) {
1696
+ params = this.omit(params, ['until', 'till']);
1697
+ request['end'] = until;
1698
+ }
1656
1699
  const priceType = this.safeString(params, 'price', 'default');
1657
1700
  params = this.omit(params, 'price');
1658
1701
  const method = this.getSupportedMapping(priceType, {
@@ -513,7 +513,7 @@ class exmo extends exmo$1 {
513
513
  const symbol = this.safeSymbol(marketId);
514
514
  const orderBook = this.safeValue(message, 'data', {});
515
515
  const messageHash = 'orderbook:' + symbol;
516
- const timestamp = this.safeNumber(message, 'ts');
516
+ const timestamp = this.safeInteger(message, 'ts');
517
517
  let storedOrderBook = this.safeValue(this.orderbooks, symbol);
518
518
  if (storedOrderBook === undefined) {
519
519
  storedOrderBook = this.orderBook({});
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.1.6";
7
+ declare const version = "4.1.7";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.1.7';
41
+ const version = '4.1.8';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -52,6 +52,7 @@ interface Exchange {
52
52
  privateGetSpotV1MarginIsolatedAccount(params?: {}): Promise<implicitReturnType>;
53
53
  privateGetSpotV1TradeFee(params?: {}): Promise<implicitReturnType>;
54
54
  privateGetSpotV1UserFee(params?: {}): Promise<implicitReturnType>;
55
+ privateGetSpotV1BrokerRebate(params?: {}): Promise<implicitReturnType>;
55
56
  privateGetContractPrivateAssetsDetail(params?: {}): Promise<implicitReturnType>;
56
57
  privateGetContractPrivateOrder(params?: {}): Promise<implicitReturnType>;
57
58
  privateGetContractPrivateOrderHistory(params?: {}): Promise<implicitReturnType>;
@@ -49,6 +49,8 @@ interface Exchange {
49
49
  spotPrivateGetRebateDetailKickback(params?: {}): Promise<implicitReturnType>;
50
50
  spotPrivateGetRebateReferCode(params?: {}): Promise<implicitReturnType>;
51
51
  spotPrivateGetRebateAffiliateCommission(params?: {}): Promise<implicitReturnType>;
52
+ spotPrivateGetRebateAffiliateWithdraw(params?: {}): Promise<implicitReturnType>;
53
+ spotPrivateGetRebateAffiliateCommissionDetail(params?: {}): Promise<implicitReturnType>;
52
54
  spotPrivateGetMxDeductEnable(params?: {}): Promise<implicitReturnType>;
53
55
  spotPrivateGetUserDataStream(params?: {}): Promise<implicitReturnType>;
54
56
  spotPrivatePostOrder(params?: {}): Promise<implicitReturnType>;
@@ -49,6 +49,8 @@ interface mexc {
49
49
  spotPrivateGetRebateDetailKickback(params?: {}): Promise<implicitReturnType>;
50
50
  spotPrivateGetRebateReferCode(params?: {}): Promise<implicitReturnType>;
51
51
  spotPrivateGetRebateAffiliateCommission(params?: {}): Promise<implicitReturnType>;
52
+ spotPrivateGetRebateAffiliateWithdraw(params?: {}): Promise<implicitReturnType>;
53
+ spotPrivateGetRebateAffiliateCommissionDetail(params?: {}): Promise<implicitReturnType>;
52
54
  spotPrivateGetMxDeductEnable(params?: {}): Promise<implicitReturnType>;
53
55
  spotPrivateGetUserDataStream(params?: {}): Promise<implicitReturnType>;
54
56
  spotPrivatePostOrder(params?: {}): Promise<implicitReturnType>;
package/js/src/bitbns.js CHANGED
@@ -441,13 +441,13 @@ export default class bitbns extends Exchange {
441
441
  if (numParts > 1) {
442
442
  let currencyId = this.safeString(parts, 1);
443
443
  // note that "Money" stands for INR - the only fiat in bitbns
444
+ const account = this.account();
445
+ account['free'] = this.safeString(data, key);
446
+ account['used'] = this.safeString(data, 'inorder' + currencyId);
444
447
  if (currencyId === 'Money') {
445
448
  currencyId = 'INR';
446
449
  }
447
450
  const code = this.safeCurrencyCode(currencyId);
448
- const account = this.account();
449
- account['free'] = this.safeString(data, key);
450
- account['used'] = this.safeString(data, 'inorder' + currencyId);
451
451
  result[code] = account;
452
452
  }
453
453
  }
package/js/src/bitmart.js CHANGED
@@ -182,6 +182,8 @@ export default class bitmart extends Exchange {
182
182
  'spot/v1/margin/isolated/account': 6,
183
183
  'spot/v1/trade_fee': 6,
184
184
  'spot/v1/user_fee': 6,
185
+ // broker
186
+ 'spot/v1/broker/rebate': 1,
185
187
  // contract
186
188
  'contract/private/assets-detail': 5,
187
189
  'contract/private/order': 1.2,
@@ -936,9 +936,9 @@ export default class coinfalcon extends Exchange {
936
936
  const amountString = this.safeString(transaction, 'amount');
937
937
  const amount = this.parseNumber(amountString);
938
938
  const feeCostString = this.safeString(transaction, 'fee');
939
- let feeCost = 0;
939
+ let feeCost = '0';
940
940
  if (feeCostString !== undefined) {
941
- feeCost = this.parseNumber(feeCostString);
941
+ feeCost = feeCostString;
942
942
  }
943
943
  return {
944
944
  'info': transaction,
@@ -960,7 +960,7 @@ export default class coinfalcon extends Exchange {
960
960
  'updated': undefined,
961
961
  'fee': {
962
962
  'currency': code,
963
- 'cost': feeCost,
963
+ 'cost': this.parseNumber(feeCost),
964
964
  },
965
965
  };
966
966
  }
package/js/src/kucoin.js CHANGED
@@ -2228,7 +2228,7 @@ export default class kucoin extends Exchange {
2228
2228
  * @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)
2229
2229
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2230
2230
  */
2231
- await this.loadMarkets;
2231
+ await this.loadMarkets();
2232
2232
  let paginate = false;
2233
2233
  [paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
2234
2234
  if (paginate) {
@@ -2261,7 +2261,7 @@ export default class kucoin extends Exchange {
2261
2261
  * @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)
2262
2262
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2263
2263
  */
2264
- await this.loadMarkets;
2264
+ await this.loadMarkets();
2265
2265
  let paginate = false;
2266
2266
  [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'paginate');
2267
2267
  if (paginate) {
@@ -1537,7 +1537,7 @@ export default class kucoinfutures extends kucoin {
1537
1537
  * @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)
1538
1538
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
1539
1539
  */
1540
- await this.loadMarkets;
1540
+ await this.loadMarkets();
1541
1541
  let paginate = false;
1542
1542
  [paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
1543
1543
  if (paginate) {
package/js/src/mexc.d.ts CHANGED
@@ -24,7 +24,7 @@ export default class mexc extends Exchange {
24
24
  fetchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<import("./base/types.js").Trade[]>;
25
25
  parseTrade(trade: any, market?: any): import("./base/types.js").Trade;
26
26
  syntheticTradeId(market?: any, timestamp?: any, side?: any, amount?: any, price?: any, orderType?: any, takerOrMaker?: any): string;
27
- fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<import("./base/types.js").OHLCV[]>;
27
+ fetchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<any>;
28
28
  parseOHLCV(ohlcv: any, market?: any): number[];
29
29
  fetchTickers(symbols?: string[], params?: {}): Promise<import("./base/types.js").Dictionary<import("./base/types.js").Ticker>>;
30
30
  fetchTicker(symbol: string, params?: {}): Promise<import("./base/types.js").Ticker>;
package/js/src/mexc.js CHANGED
@@ -196,6 +196,8 @@ export default class mexc extends Exchange {
196
196
  'rebate/detail/kickback': 1,
197
197
  'rebate/referCode': 1,
198
198
  'rebate/affiliate/commission': 1,
199
+ 'rebate/affiliate/withdraw': 1,
200
+ 'rebate/affiliate/commission/detail': 1,
199
201
  'mxDeduct/enable': 1,
200
202
  'userDataStream': 1,
201
203
  },
@@ -1360,11 +1362,15 @@ export default class mexc extends Exchange {
1360
1362
  /**
1361
1363
  * @method
1362
1364
  * @name mexc3#fetchTrades
1365
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#recent-trades-list
1366
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#compressed-aggregate-trades-list
1367
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-transaction-data
1363
1368
  * @description get the list of most recent trades for a particular symbol
1364
1369
  * @param {string} symbol unified symbol of the market to fetch trades for
1365
1370
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
1366
1371
  * @param {int} [limit] the maximum amount of trades to fetch
1367
1372
  * @param {object} [params] extra parameters specific to the mexc3 api endpoint
1373
+ * @param {int} [params.until] *spot only* *since must be defined* the latest time in ms to fetch entries for
1368
1374
  * @returns {Trade[]} a list of [trade structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#public-trades}
1369
1375
  */
1370
1376
  await this.loadMarkets();
@@ -1375,11 +1381,21 @@ export default class mexc extends Exchange {
1375
1381
  if (limit !== undefined) {
1376
1382
  request['limit'] = limit;
1377
1383
  }
1378
- // if (since !== undefined) {
1379
- // request['startTime'] = since; bug in api, waiting for fix
1380
- // }
1381
1384
  let trades = undefined;
1382
1385
  if (market['spot']) {
1386
+ const until = this.safeIntegerN(params, ['endTime', 'until', 'till']);
1387
+ if (since !== undefined) {
1388
+ request['startTime'] = since;
1389
+ if (until === undefined) {
1390
+ throw new ArgumentsRequired(this.id + ' fetchTrades() requires an until parameter when since is provided');
1391
+ }
1392
+ }
1393
+ if (until !== undefined) {
1394
+ if (since === undefined) {
1395
+ throw new ArgumentsRequired(this.id + ' fetchTrades() requires a since parameter when until is provided');
1396
+ }
1397
+ request['endTime'] = until;
1398
+ }
1383
1399
  let method = this.safeString(this.options, 'fetchTradesMethod', 'spotPublicGetAggTrades');
1384
1400
  method = this.safeString(params, 'method', method); // AggTrades, HistoricalTrades, Trades
1385
1401
  trades = await this[method](this.extend(request, params));
@@ -1610,31 +1626,53 @@ export default class mexc extends Exchange {
1610
1626
  /**
1611
1627
  * @method
1612
1628
  * @name mexc3#fetchOHLCV
1629
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#kline-candlestick-data
1630
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#k-line-data
1613
1631
  * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1614
1632
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1615
1633
  * @param {string} timeframe the length of time each candle represents
1616
1634
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
1617
1635
  * @param {int} [limit] the maximum amount of candles to fetch
1618
1636
  * @param {object} [params] extra parameters specific to the mexc3 api endpoint
1637
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
1638
+ * @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)
1619
1639
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1620
1640
  */
1621
1641
  await this.loadMarkets();
1622
1642
  const market = this.market(symbol);
1643
+ const maxLimit = (market['spot']) ? 1000 : 2000;
1644
+ let paginate = false;
1645
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
1646
+ if (paginate) {
1647
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
1648
+ }
1623
1649
  const options = this.safeValue(this.options, 'timeframes', {});
1624
1650
  const timeframes = this.safeValue(options, market['type'], {});
1625
1651
  const timeframeValue = this.safeString(timeframes, timeframe);
1652
+ const duration = this.parseTimeframe(timeframe) * 1000;
1626
1653
  const request = {
1627
1654
  'symbol': market['id'],
1628
1655
  'interval': timeframeValue,
1629
1656
  };
1630
1657
  let candles = undefined;
1631
1658
  if (market['spot']) {
1659
+ const until = this.safeIntegerN(params, ['until', 'endTime', 'till']);
1632
1660
  if (since !== undefined) {
1633
1661
  request['startTime'] = since;
1662
+ if (until === undefined) {
1663
+ // we have to calculate it assuming we can get at most 2000 entries per request
1664
+ const end = this.sum(since, maxLimit * duration);
1665
+ const now = this.milliseconds();
1666
+ request['endTime'] = Math.min(end, now);
1667
+ }
1634
1668
  }
1635
1669
  if (limit !== undefined) {
1636
1670
  request['limit'] = limit;
1637
1671
  }
1672
+ if (until !== undefined) {
1673
+ params = this.omit(params, ['until', 'till']);
1674
+ request['endTime'] = until;
1675
+ }
1638
1676
  const response = await this.spotPublicGetKlines(this.extend(request, params));
1639
1677
  //
1640
1678
  // [
@@ -1653,9 +1691,14 @@ export default class mexc extends Exchange {
1653
1691
  candles = response;
1654
1692
  }
1655
1693
  else if (market['swap']) {
1694
+ const until = this.safeIntegerProductN(params, ['until', 'endTime', 'till'], 0.001);
1656
1695
  if (since !== undefined) {
1657
1696
  request['start'] = this.parseToInt(since / 1000);
1658
1697
  }
1698
+ if (until !== undefined) {
1699
+ params = this.omit(params, ['until', 'till']);
1700
+ request['end'] = until;
1701
+ }
1659
1702
  const priceType = this.safeString(params, 'price', 'default');
1660
1703
  params = this.omit(params, 'price');
1661
1704
  const method = this.getSupportedMapping(priceType, {
@@ -516,7 +516,7 @@ export default class exmo extends exmoRest {
516
516
  const symbol = this.safeSymbol(marketId);
517
517
  const orderBook = this.safeValue(message, 'data', {});
518
518
  const messageHash = 'orderbook:' + symbol;
519
- const timestamp = this.safeNumber(message, 'ts');
519
+ const timestamp = this.safeInteger(message, 'ts');
520
520
  let storedOrderBook = this.safeValue(this.orderbooks, symbol);
521
521
  if (storedOrderBook === undefined) {
522
522
  storedOrderBook = this.orderBook({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.1.7",
3
+ "version": "4.1.8",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",