ccxt 4.4.59 → 4.4.61

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
@@ -199,7 +199,7 @@ var xt$1 = require('./src/pro/xt.js');
199
199
 
200
200
  //-----------------------------------------------------------------------------
201
201
  // this is updated by vss.js when building
202
- const version = '4.4.59';
202
+ const version = '4.4.61';
203
203
  Exchange["default"].ccxtVersion = version;
204
204
  const exchanges = {
205
205
  'ace': ace,
@@ -1151,10 +1151,10 @@ class alpaca extends alpaca$1 {
1151
1151
  const until = this.safeInteger(params, 'until');
1152
1152
  if (until !== undefined) {
1153
1153
  params = this.omit(params, 'until');
1154
- request['endTime'] = until;
1154
+ request['endTime'] = this.iso8601(until);
1155
1155
  }
1156
1156
  if (since !== undefined) {
1157
- request['after'] = since;
1157
+ request['after'] = this.iso8601(since);
1158
1158
  }
1159
1159
  if (limit !== undefined) {
1160
1160
  request['limit'] = limit;
@@ -1397,6 +1397,7 @@ class alpaca extends alpaca$1 {
1397
1397
  * @param {int} [limit] the maximum number of trade structures to retrieve
1398
1398
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1399
1399
  * @param {int} [params.until] the latest time in ms to fetch trades for
1400
+ * @param {string} [params.page_token] page_token - used for paging
1400
1401
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1401
1402
  */
1402
1403
  async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1408,8 +1409,13 @@ class alpaca extends alpaca$1 {
1408
1409
  if (symbol !== undefined) {
1409
1410
  market = this.market(symbol);
1410
1411
  }
1412
+ const until = this.safeInteger(params, 'until');
1413
+ if (until !== undefined) {
1414
+ params = this.omit(params, 'until');
1415
+ request['until'] = this.iso8601(until);
1416
+ }
1411
1417
  if (since !== undefined) {
1412
- request['after'] = since;
1418
+ request['after'] = this.iso8601(since);
1413
1419
  }
1414
1420
  if (limit !== undefined) {
1415
1421
  request['page_size'] = limit;
@@ -1376,6 +1376,7 @@ class Exchange {
1376
1376
  'createTriggerOrderWs': undefined,
1377
1377
  'deposit': undefined,
1378
1378
  'editOrder': 'emulated',
1379
+ 'editOrders': undefined,
1379
1380
  'editOrderWs': undefined,
1380
1381
  'fetchAccounts': undefined,
1381
1382
  'fetchBalance': true,
@@ -5226,6 +5227,9 @@ class Exchange {
5226
5227
  async createOrders(orders, params = {}) {
5227
5228
  throw new errors.NotSupported(this.id + ' createOrders() is not supported yet');
5228
5229
  }
5230
+ async editOrders(orders, params = {}) {
5231
+ throw new errors.NotSupported(this.id + ' editOrders() is not supported yet');
5232
+ }
5229
5233
  async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
5230
5234
  throw new errors.NotSupported(this.id + ' createOrderWs() is not supported yet');
5231
5235
  }
@@ -62,6 +62,7 @@ class binance extends binance$1 {
62
62
  'createTrailingPercentOrder': true,
63
63
  'createTriggerOrder': true,
64
64
  'editOrder': true,
65
+ 'editOrders': true,
65
66
  'fetchAccounts': undefined,
66
67
  'fetchBalance': true,
67
68
  'fetchBidsAsks': true,
@@ -5605,6 +5606,90 @@ class binance extends binance$1 {
5605
5606
  return await this.editContractOrder(id, symbol, type, side, amount, price, params);
5606
5607
  }
5607
5608
  }
5609
+ /**
5610
+ * @method
5611
+ * @name binance#editOrders
5612
+ * @description edit a list of trade orders
5613
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Modify-Multiple-Orders
5614
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/Modify-Multiple-Orders
5615
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
5616
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5617
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5618
+ */
5619
+ async editOrders(orders, params = {}) {
5620
+ await this.loadMarkets();
5621
+ const ordersRequests = [];
5622
+ let orderSymbols = [];
5623
+ for (let i = 0; i < orders.length; i++) {
5624
+ const rawOrder = orders[i];
5625
+ const marketId = this.safeString(rawOrder, 'symbol');
5626
+ orderSymbols.push(marketId);
5627
+ const id = this.safeString(rawOrder, 'id');
5628
+ const type = this.safeString(rawOrder, 'type');
5629
+ const side = this.safeString(rawOrder, 'side');
5630
+ const amount = this.safeValue(rawOrder, 'amount');
5631
+ const price = this.safeValue(rawOrder, 'price');
5632
+ let orderParams = this.safeDict(rawOrder, 'params', {});
5633
+ let isPortfolioMargin = undefined;
5634
+ [isPortfolioMargin, orderParams] = this.handleOptionAndParams2(orderParams, 'editOrders', 'papi', 'portfolioMargin', false);
5635
+ if (isPortfolioMargin) {
5636
+ throw new errors.NotSupported(this.id + ' editOrders() does not support portfolio margin orders');
5637
+ }
5638
+ const orderRequest = this.editContractOrderRequest(id, marketId, type, side, amount, price, orderParams);
5639
+ ordersRequests.push(orderRequest);
5640
+ }
5641
+ orderSymbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
5642
+ const market = this.market(orderSymbols[0]);
5643
+ if (market['spot'] || market['option']) {
5644
+ throw new errors.NotSupported(this.id + ' editOrders() does not support ' + market['type'] + ' orders');
5645
+ }
5646
+ let response = undefined;
5647
+ let request = {
5648
+ 'batchOrders': ordersRequests,
5649
+ };
5650
+ request = this.extend(request, params);
5651
+ if (market['linear']) {
5652
+ response = await this.fapiPrivatePutBatchOrders(request);
5653
+ }
5654
+ else if (market['inverse']) {
5655
+ response = await this.dapiPrivatePutBatchOrders(request);
5656
+ }
5657
+ //
5658
+ // [
5659
+ // {
5660
+ // "code": -4005,
5661
+ // "msg": "Quantity greater than max quantity."
5662
+ // },
5663
+ // {
5664
+ // "orderId": 650640530,
5665
+ // "symbol": "LTCUSDT",
5666
+ // "status": "NEW",
5667
+ // "clientOrderId": "x-xcKtGhcu32184eb13585491289bbaf",
5668
+ // "price": "54.00",
5669
+ // "avgPrice": "0.00",
5670
+ // "origQty": "0.100",
5671
+ // "executedQty": "0.000",
5672
+ // "cumQty": "0.000",
5673
+ // "cumQuote": "0.00000",
5674
+ // "timeInForce": "GTC",
5675
+ // "type": "LIMIT",
5676
+ // "reduceOnly": false,
5677
+ // "closePosition": false,
5678
+ // "side": "BUY",
5679
+ // "positionSide": "BOTH",
5680
+ // "stopPrice": "0.00",
5681
+ // "workingType": "CONTRACT_PRICE",
5682
+ // "priceProtect": false,
5683
+ // "origType": "LIMIT",
5684
+ // "priceMatch": "NONE",
5685
+ // "selfTradePreventionMode": "NONE",
5686
+ // "goodTillDate": 0,
5687
+ // "updateTime": 1698073926929
5688
+ // }
5689
+ // ]
5690
+ //
5691
+ return this.parseOrders(response);
5692
+ }
5608
5693
  parseOrderStatus(status) {
5609
5694
  const statuses = {
5610
5695
  'NEW': 'open',
@@ -12029,7 +12114,7 @@ class binance extends binance$1 {
12029
12114
  }
12030
12115
  let query = undefined;
12031
12116
  // handle batchOrders
12032
- if ((path === 'batchOrders') && (method === 'POST')) {
12117
+ if ((path === 'batchOrders') && ((method === 'POST') || (method === 'PUT'))) {
12033
12118
  const batchOrders = this.safeValue(params, 'batchOrders');
12034
12119
  const queryBatch = (this.json(batchOrders));
12035
12120
  params['batchOrders'] = queryBatch;
@@ -9373,7 +9373,8 @@ class bitget extends bitget$1 {
9373
9373
  }
9374
9374
  }
9375
9375
  const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
9376
- if (sandboxMode) {
9376
+ if (sandboxMode && (path !== 'v2/public/time')) {
9377
+ // https://github.com/ccxt/ccxt/issues/25252#issuecomment-2662742336
9377
9378
  if (headers === undefined) {
9378
9379
  headers = {};
9379
9380
  }
@@ -6917,10 +6917,13 @@ class bybit extends bybit$1 {
6917
6917
  // }
6918
6918
  //
6919
6919
  const timestamp = this.safeInteger(interest, 'timestamp');
6920
- const value = this.safeNumber2(interest, 'open_interest', 'openInterest');
6920
+ const openInterest = this.safeNumber2(interest, 'open_interest', 'openInterest');
6921
+ // the openInterest is in the base asset for linear and quote asset for inverse
6922
+ const amount = market['linear'] ? openInterest : undefined;
6923
+ const value = market['inverse'] ? openInterest : undefined;
6921
6924
  return this.safeOpenInterest({
6922
6925
  'symbol': market['symbol'],
6923
- 'openInterestAmount': undefined,
6926
+ 'openInterestAmount': amount,
6924
6927
  'openInterestValue': value,
6925
6928
  'timestamp': timestamp,
6926
6929
  'datetime': this.iso8601(timestamp),
@@ -656,23 +656,67 @@ class gate extends gate$1 {
656
656
  },
657
657
  'createMarketBuyOrderRequiresPrice': true,
658
658
  'networks': {
659
- 'LINEA': 'LINEAETH',
660
- 'KON': 'KONET',
661
- 'AVAXC': 'AVAX_C',
659
+ 'BTC': 'BTC',
660
+ 'BRC20': 'BTCBRC',
661
+ 'ETH': 'ETH',
662
+ 'ERC20': 'ETH',
663
+ 'TRX': 'TRX',
664
+ 'TRC20': 'TRX',
665
+ 'HECO': 'HT',
666
+ 'HRC20': 'HT',
667
+ 'BSC': 'BSC',
662
668
  'BEP20': 'BSC',
669
+ 'SOL': 'SOL',
670
+ 'POLYGON': 'POL',
671
+ 'MATIC': 'POL',
672
+ 'OP': 'OPETH',
673
+ 'OPTIMISM': 'OPETH',
674
+ 'ADA': 'ADA',
675
+ 'AVAXC': 'AVAX_C',
676
+ 'NEAR': 'NEAR',
677
+ 'ARBONE': 'ARBEVM',
678
+ 'BASE': 'BASEEVM',
679
+ 'SUI': 'SUI',
680
+ 'CRONOS': 'CRO',
681
+ 'CRO': 'CRO',
682
+ 'APT': 'APT',
683
+ 'SCROLL': 'SCROLLETH',
684
+ 'TAIKO': 'TAIKOETH',
685
+ 'HYPE': 'HYPE',
686
+ 'ALGO': 'ALGO',
687
+ // KAVA: ['KAVA', 'KAVAEVM']
688
+ // SEI: ['SEI', 'SEIEVM']
689
+ 'LINEA': 'LINEAETH',
690
+ 'BLAST': 'BLASTETH',
691
+ 'XLM': 'XLM',
692
+ 'RSK': 'RBTC',
693
+ 'TON': 'TON',
694
+ 'MNT': 'MNT',
695
+ // 'RUNE': 'BTCRUNES', probably, cant verify atm
696
+ 'CELO': 'CELO',
697
+ 'HBAR': 'HBAR',
698
+ // 'FTM': SONIC REBRAND, todo
699
+ 'ZKSERA': 'ZKSERA',
700
+ 'KLAY': 'KLAY',
663
701
  'EOS': 'EOS',
664
- 'ERC20': 'ETH',
702
+ 'ACA': 'ACA',
703
+ // TLOS: ['TLOS', 'TLOSEVM']
704
+ // ASTR: ['ASTR', 'ASTREVM']
705
+ // CFX: ['CFX', 'CFXEVM']
706
+ 'XTZ': 'XTZ',
707
+ 'EGLD': 'EGLD',
708
+ 'GLMR': 'GLMR',
709
+ 'AURORA': 'AURORAEVM',
710
+ // others
711
+ 'KON': 'KONET',
665
712
  'GATECHAIN': 'GTEVM',
666
- 'HRC20': 'HT',
667
713
  'KUSAMA': 'KSMSM',
668
- 'NEAR': 'NEAR',
669
714
  'OKC': 'OKT',
670
- 'OPTIMISM': 'OPETH',
671
715
  'POLKADOT': 'DOTSM',
672
- 'TRC20': 'TRX',
673
716
  'LUNA': 'LUNC',
674
- 'BASE': 'BASEEVM',
675
- 'BRC20': 'BTCBRC',
717
+ },
718
+ 'networksById': {
719
+ 'OPETH': 'OP',
676
720
  },
677
721
  'timeInForce': {
678
722
  'GTC': 'gtc',
@@ -3675,6 +3719,7 @@ class gate extends gate$1 {
3675
3719
  //
3676
3720
  // public
3677
3721
  //
3722
+ // spot:
3678
3723
  // {
3679
3724
  // "id": "1334253759",
3680
3725
  // "create_time": "1626342738",
@@ -3685,6 +3730,18 @@ class gate extends gate$1 {
3685
3730
  // "price": "32452.16"
3686
3731
  // }
3687
3732
  //
3733
+ // swap:
3734
+ //
3735
+ // {
3736
+ // "id": "442288327",
3737
+ // "contract": "BTC_USDT",
3738
+ // "create_time": "1739814676.707",
3739
+ // "create_time_ms": "1739814676.707",
3740
+ // "size": "-105",
3741
+ // "price": "95594.8"
3742
+ // }
3743
+ //
3744
+ //
3688
3745
  // public ws
3689
3746
  //
3690
3747
  // {
@@ -3761,8 +3818,16 @@ class gate extends gate$1 {
3761
3818
  // }
3762
3819
  //
3763
3820
  const id = this.safeString2(trade, 'id', 'trade_id');
3764
- let timestamp = this.safeTimestamp2(trade, 'time', 'create_time');
3765
- timestamp = this.safeInteger(trade, 'create_time_ms', timestamp);
3821
+ let timestamp = undefined;
3822
+ let msString = this.safeString(trade, 'create_time_ms');
3823
+ if (msString !== undefined) {
3824
+ msString = Precise["default"].stringMul(msString, '1000');
3825
+ msString = msString.slice(0, 13);
3826
+ timestamp = this.parseToInt(msString);
3827
+ }
3828
+ else {
3829
+ timestamp = this.safeTimestamp2(trade, 'time', 'create_time');
3830
+ }
3766
3831
  const marketId = this.safeString2(trade, 'currency_pair', 'contract');
3767
3832
  const marketType = ('contract' in trade) ? 'contract' : 'spot';
3768
3833
  market = this.safeMarket(marketId, market, '_', marketType);
@@ -1914,7 +1914,7 @@ class hollaex extends hollaex$1 {
1914
1914
  // "network":"https://api.hollaex.network"
1915
1915
  // }
1916
1916
  //
1917
- const coins = this.safeList(response, 'coins');
1917
+ const coins = this.safeDict(response, 'coins', {});
1918
1918
  return this.parseDepositWithdrawFees(coins, codes, 'symbol');
1919
1919
  }
1920
1920
  normalizeNumberIfNeeded(number) {
@@ -2947,7 +2947,7 @@ class oxfun extends oxfun$1 {
2947
2947
  'AccessKey': this.apiKey,
2948
2948
  'Timestamp': datetime,
2949
2949
  'Signature': signature,
2950
- 'Nonce': nonce,
2950
+ 'Nonce': nonce.toString(),
2951
2951
  };
2952
2952
  }
2953
2953
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };
@@ -1067,7 +1067,7 @@ class phemex extends phemex$1 {
1067
1067
  for (let i = 0; i < products.length; i++) {
1068
1068
  let market = products[i];
1069
1069
  const type = this.safeStringLower(market, 'type');
1070
- if ((type === 'perpetual') || (type === 'perpetualv2')) {
1070
+ if ((type === 'perpetual') || (type === 'perpetualv2') || (type === 'PerpetualPilot')) {
1071
1071
  const id = this.safeString(market, 'symbol');
1072
1072
  const riskLimitValues = this.safeValue(riskLimitsById, id, {});
1073
1073
  market = this.extend(market, riskLimitValues);
@@ -1577,6 +1577,27 @@ class gate extends gate$1 {
1577
1577
  // data: { errs: { label: 'AUTHENTICATION_FAILED', message: 'Not login' } },
1578
1578
  // request_id: '10406147'
1579
1579
  // }
1580
+ // {
1581
+ // "time": 1739853211,
1582
+ // "time_ms": 1739853211201,
1583
+ // "id": 1,
1584
+ // "conn_id": "62f2c1dabbe186d7",
1585
+ // "trace_id": "cdb02a8c0b61086b2fe6f8fad2f98c54",
1586
+ // "channel": "spot.trades",
1587
+ // "event": "subscribe",
1588
+ // "payload": [
1589
+ // "LUNARLENS_USDT",
1590
+ // "ETH_USDT"
1591
+ // ],
1592
+ // "error": {
1593
+ // "code": 2,
1594
+ // "message": "unknown currency pair: LUNARLENS_USDT"
1595
+ // },
1596
+ // "result": {
1597
+ // "status": "fail"
1598
+ // },
1599
+ // "requestId": "cdb02a8c0b61086b2fe6f8fad2f98c54"
1600
+ // }
1580
1601
  //
1581
1602
  const data = this.safeDict(message, 'data');
1582
1603
  const errs = this.safeDict(data, 'errs');
@@ -1597,6 +1618,20 @@ class gate extends gate$1 {
1597
1618
  if ((messageHash !== undefined) && (messageHash in client.subscriptions)) {
1598
1619
  delete client.subscriptions[messageHash];
1599
1620
  }
1621
+ // remove subscriptions for watchSymbols
1622
+ const channel = this.safeString(message, 'channel');
1623
+ if ((channel !== undefined) && (channel.indexOf('.') > 0)) {
1624
+ const parsedChannel = channel.split('.');
1625
+ const payload = this.safeList(message, 'payload', []);
1626
+ for (let i = 0; i < payload.length; i++) {
1627
+ const marketType = parsedChannel[0] === 'futures' ? 'swap' : parsedChannel[0];
1628
+ const symbol = this.safeSymbol(payload[i], undefined, '_', marketType);
1629
+ const messageHashSymbol = parsedChannel[1] + ':' + symbol;
1630
+ if ((messageHashSymbol !== undefined) && (messageHashSymbol in client.subscriptions)) {
1631
+ delete client.subscriptions[messageHashSymbol];
1632
+ }
1633
+ }
1634
+ }
1600
1635
  }
1601
1636
  if ((id !== undefined) && (id in client.subscriptions)) {
1602
1637
  delete client.subscriptions[id];
@@ -19,7 +19,7 @@ class xt extends xt$1 {
19
19
  'watchBalance': true,
20
20
  'watchOrders': true,
21
21
  'watchMyTrades': true,
22
- 'watchPositions': undefined, // TODO https://doc.xt.com/#futures_user_websocket_v2position
22
+ 'watchPositions': true,
23
23
  },
24
24
  'urls': {
25
25
  'api': {
@@ -39,6 +39,11 @@ class xt extends xt$1 {
39
39
  'watchTickers': {
40
40
  'method': 'tickers', // agg_tickers (contract only)
41
41
  },
42
+ 'watchPositions': {
43
+ 'type': 'swap',
44
+ 'fetchPositionsSnapshot': true,
45
+ 'awaitPositionsSnapshot': true,
46
+ },
42
47
  },
43
48
  'streaming': {
44
49
  'keepAlive': 20000,
@@ -368,6 +373,116 @@ class xt extends xt$1 {
368
373
  const name = 'balance';
369
374
  return await this.subscribe(name, 'private', 'watchBalance', undefined, undefined, params);
370
375
  }
376
+ /**
377
+ * @method
378
+ * @name xt#watchPositions
379
+ * @see https://doc.xt.com/#futures_user_websocket_v2position
380
+ * @description watch all open positions
381
+ * @param {string[]|undefined} symbols list of unified market symbols
382
+ * @param {number} [since] since timestamp
383
+ * @param {number} [limit] limit
384
+ * @param {object} params extra parameters specific to the exchange API endpoint
385
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
386
+ */
387
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
388
+ await this.loadMarkets();
389
+ const url = this.urls['api']['ws']['contract'] + '/' + 'user';
390
+ const client = this.client(url);
391
+ this.setPositionsCache(client);
392
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
393
+ const awaitPositionsSnapshot = this.handleOption('watchPositions', 'awaitPositionsSnapshot', true);
394
+ const cache = this.positions;
395
+ if (fetchPositionsSnapshot && awaitPositionsSnapshot && this.isEmpty(cache)) {
396
+ const snapshot = await client.future('fetchPositionsSnapshot');
397
+ return this.filterBySymbolsSinceLimit(snapshot, symbols, since, limit, true);
398
+ }
399
+ const name = 'position';
400
+ const newPositions = await this.subscribe(name, 'private', 'watchPositions', undefined, undefined, params);
401
+ if (this.newUpdates) {
402
+ return newPositions;
403
+ }
404
+ return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
405
+ }
406
+ setPositionsCache(client) {
407
+ if (this.positions === undefined) {
408
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
409
+ }
410
+ const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot');
411
+ if (fetchPositionsSnapshot) {
412
+ const messageHash = 'fetchPositionsSnapshot';
413
+ if (!(messageHash in client.futures)) {
414
+ client.future(messageHash);
415
+ this.spawn(this.loadPositionsSnapshot, client, messageHash);
416
+ }
417
+ }
418
+ }
419
+ async loadPositionsSnapshot(client, messageHash) {
420
+ const positions = await this.fetchPositions(undefined);
421
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
422
+ const cache = this.positions;
423
+ for (let i = 0; i < positions.length; i++) {
424
+ const position = positions[i];
425
+ const contracts = this.safeNumber(position, 'contracts', 0);
426
+ if (contracts > 0) {
427
+ cache.append(position);
428
+ }
429
+ }
430
+ // don't remove the future from the .futures cache
431
+ const future = client.futures[messageHash];
432
+ future.resolve(cache);
433
+ client.resolve(cache, 'position::contract');
434
+ }
435
+ handlePosition(client, message) {
436
+ //
437
+ // {
438
+ // topic: 'position',
439
+ // event: 'position',
440
+ // data: {
441
+ // accountId: 245296,
442
+ // accountType: 0,
443
+ // symbol: 'eth_usdt',
444
+ // contractType: 'PERPETUAL',
445
+ // positionType: 'CROSSED',
446
+ // positionSide: 'LONG',
447
+ // positionSize: '1',
448
+ // closeOrderSize: '0',
449
+ // availableCloseSize: '1',
450
+ // realizedProfit: '-0.0121',
451
+ // entryPrice: '2637.87',
452
+ // openOrderSize: '1',
453
+ // isolatedMargin: '2.63787',
454
+ // openOrderMarginFrozen: '2.78832014',
455
+ // underlyingType: 'U_BASED',
456
+ // leverage: 10,
457
+ // welfareAccount: false,
458
+ // profitFixedLatest: {},
459
+ // closeProfit: '0.0000',
460
+ // totalFee: '-0.0158',
461
+ // totalFundFee: '0.0037',
462
+ // markPrice: '2690.96'
463
+ // }
464
+ // }
465
+ //
466
+ if (this.positions === undefined) {
467
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
468
+ }
469
+ const cache = this.positions;
470
+ const data = this.safeDict(message, 'data', {});
471
+ const position = this.parsePosition(data);
472
+ cache.append(position);
473
+ const messageHashes = this.findMessageHashes(client, 'position::contract');
474
+ for (let i = 0; i < messageHashes.length; i++) {
475
+ const messageHash = messageHashes[i];
476
+ const parts = messageHash.split('::');
477
+ const symbolsString = parts[1];
478
+ const symbols = symbolsString.split(',');
479
+ const positions = this.filterByArray([position], 'symbol', symbols, false);
480
+ if (!this.isEmpty(positions)) {
481
+ client.resolve(positions, messageHash);
482
+ }
483
+ }
484
+ client.resolve([position], 'position::contract');
485
+ }
371
486
  handleTicker(client, message) {
372
487
  //
373
488
  // spot
@@ -1072,6 +1187,7 @@ class xt extends xt$1 {
1072
1187
  'agg_tickers': this.handleTickers,
1073
1188
  'balance': this.handleBalance,
1074
1189
  'order': this.handleOrder,
1190
+ 'position': this.handlePosition,
1075
1191
  };
1076
1192
  let method = this.safeValue(methods, topic);
1077
1193
  if (topic === 'trade') {
@@ -1397,10 +1397,17 @@ class xt extends xt$1 {
1397
1397
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
1398
1398
  * @param {int} [limit] the maximum amount of candles to fetch
1399
1399
  * @param {object} params extra parameters specific to the xt api endpoint
1400
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
1401
+ * @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)
1400
1402
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1401
1403
  */
1402
1404
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1403
1405
  await this.loadMarkets();
1406
+ let paginate = false;
1407
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
1408
+ if (paginate) {
1409
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
1410
+ }
1404
1411
  const market = this.market(symbol);
1405
1412
  const request = {
1406
1413
  'symbol': market['id'],
@@ -1412,6 +1419,14 @@ class xt extends xt$1 {
1412
1419
  if (limit !== undefined) {
1413
1420
  request['limit'] = limit;
1414
1421
  }
1422
+ else {
1423
+ request['limit'] = 1000;
1424
+ }
1425
+ const until = this.safeInteger(params, 'until');
1426
+ params = this.omit(params, ['until']);
1427
+ if (until !== undefined) {
1428
+ request['endTime'] = until;
1429
+ }
1415
1430
  let response = undefined;
1416
1431
  if (market['linear']) {
1417
1432
  response = await this.publicLinearGetFutureMarketV1PublicQKline(this.extend(request, params));
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 type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarketMarginModes, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, LongShortRatio, OrderBooks, OpenInterests } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
7
- declare const version = "4.4.58";
7
+ declare const version = "4.4.60";
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, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.4.59';
41
+ const version = '4.4.61';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -243,6 +243,7 @@ export default class alpaca extends Exchange {
243
243
  * @param {int} [limit] the maximum number of trade structures to retrieve
244
244
  * @param {object} [params] extra parameters specific to the exchange API endpoint
245
245
  * @param {int} [params.until] the latest time in ms to fetch trades for
246
+ * @param {string} [params.page_token] page_token - used for paging
246
247
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
247
248
  */
248
249
  fetchMyTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
package/js/src/alpaca.js CHANGED
@@ -1154,10 +1154,10 @@ export default class alpaca extends Exchange {
1154
1154
  const until = this.safeInteger(params, 'until');
1155
1155
  if (until !== undefined) {
1156
1156
  params = this.omit(params, 'until');
1157
- request['endTime'] = until;
1157
+ request['endTime'] = this.iso8601(until);
1158
1158
  }
1159
1159
  if (since !== undefined) {
1160
- request['after'] = since;
1160
+ request['after'] = this.iso8601(since);
1161
1161
  }
1162
1162
  if (limit !== undefined) {
1163
1163
  request['limit'] = limit;
@@ -1400,6 +1400,7 @@ export default class alpaca extends Exchange {
1400
1400
  * @param {int} [limit] the maximum number of trade structures to retrieve
1401
1401
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1402
1402
  * @param {int} [params.until] the latest time in ms to fetch trades for
1403
+ * @param {string} [params.page_token] page_token - used for paging
1403
1404
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1404
1405
  */
1405
1406
  async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1411,8 +1412,13 @@ export default class alpaca extends Exchange {
1411
1412
  if (symbol !== undefined) {
1412
1413
  market = this.market(symbol);
1413
1414
  }
1415
+ const until = this.safeInteger(params, 'until');
1416
+ if (until !== undefined) {
1417
+ params = this.omit(params, 'until');
1418
+ request['until'] = this.iso8601(until);
1419
+ }
1414
1420
  if (since !== undefined) {
1415
- request['after'] = since;
1421
+ request['after'] = this.iso8601(since);
1416
1422
  }
1417
1423
  if (limit !== undefined) {
1418
1424
  request['page_size'] = limit;