ccxt 4.2.9 → 4.2.11

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/README.md +3 -3
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +322 -164
  4. package/dist/ccxt.browser.min.js +7 -7
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +48 -8
  7. package/dist/cjs/src/binance.js +6 -1
  8. package/dist/cjs/src/bingx.js +0 -10
  9. package/dist/cjs/src/bitget.js +14 -5
  10. package/dist/cjs/src/bl3p.js +1 -1
  11. package/dist/cjs/src/btcalpha.js +1 -1
  12. package/dist/cjs/src/bybit.js +1 -1
  13. package/dist/cjs/src/cryptocom.js +3 -1
  14. package/dist/cjs/src/deribit.js +39 -22
  15. package/dist/cjs/src/kraken.js +1 -1
  16. package/dist/cjs/src/kucoin.js +30 -6
  17. package/dist/cjs/src/lykke.js +1 -1
  18. package/dist/cjs/src/ndax.js +1 -1
  19. package/dist/cjs/src/pro/bitmart.js +49 -27
  20. package/dist/cjs/src/pro/blockchaincom.js +2 -28
  21. package/dist/cjs/src/pro/coinbasepro.js +9 -16
  22. package/dist/cjs/src/pro/cryptocom.js +110 -28
  23. package/dist/cjs/src/pro/luno.js +5 -5
  24. package/js/ccxt.d.ts +1 -1
  25. package/js/ccxt.js +1 -1
  26. package/js/src/base/Exchange.d.ts +5 -3
  27. package/js/src/base/Exchange.js +48 -8
  28. package/js/src/binance.js +6 -1
  29. package/js/src/bingx.d.ts +0 -1
  30. package/js/src/bingx.js +0 -10
  31. package/js/src/bitget.js +14 -5
  32. package/js/src/bl3p.d.ts +2 -2
  33. package/js/src/bl3p.js +1 -1
  34. package/js/src/btcalpha.d.ts +2 -2
  35. package/js/src/btcalpha.js +1 -1
  36. package/js/src/bybit.js +1 -1
  37. package/js/src/cryptocom.js +3 -1
  38. package/js/src/deribit.js +39 -22
  39. package/js/src/kraken.d.ts +2 -2
  40. package/js/src/kraken.js +1 -1
  41. package/js/src/kucoin.js +30 -6
  42. package/js/src/lykke.d.ts +2 -2
  43. package/js/src/lykke.js +1 -1
  44. package/js/src/ndax.d.ts +2 -2
  45. package/js/src/ndax.js +1 -1
  46. package/js/src/pro/bitmart.d.ts +1 -0
  47. package/js/src/pro/bitmart.js +49 -27
  48. package/js/src/pro/blockchaincom.d.ts +1 -11
  49. package/js/src/pro/blockchaincom.js +2 -28
  50. package/js/src/pro/coinbasepro.js +9 -16
  51. package/js/src/pro/cryptocom.d.ts +3 -1
  52. package/js/src/pro/cryptocom.js +111 -29
  53. package/js/src/pro/luno.d.ts +4 -4
  54. package/js/src/pro/luno.js +5 -5
  55. package/package.json +11 -11
  56. package/tests-manager.sh +2 -2
@@ -8284,6 +8284,17 @@ class Exchange {
8284
8284
  axolotl(payload, hexKey, ed25519) {
8285
8285
  return (0,_functions_crypto_js__WEBPACK_IMPORTED_MODULE_7__/* .axolotl */ .gC)(payload, hexKey, ed25519);
8286
8286
  }
8287
+ fixStringifiedJsonMembers(content) {
8288
+ // used for instance in bingx
8289
+ // when stringified json has members with their values also stringified, like:
8290
+ // '{"code":0, "data":{"order":{"orderId":1742968678528512345,"symbol":"BTC-USDT", "takeProfit":"{\"type\":\"TAKE_PROFIT\",\"stopPrice\":43320.1}","reduceOnly":false}}}'
8291
+ // we can fix with below manipulations
8292
+ // @ts-ignore
8293
+ let modifiedContent = content.replaceAll('\\', '');
8294
+ modifiedContent = modifiedContent.replaceAll('"{', '{');
8295
+ modifiedContent = modifiedContent.replaceAll('}"', '}');
8296
+ return modifiedContent;
8297
+ }
8287
8298
  /* eslint-enable */
8288
8299
  // ------------------------------------------------------------------------
8289
8300
  // ########################################################################
@@ -9851,11 +9862,11 @@ class Exchange {
9851
9862
  }
9852
9863
  return result;
9853
9864
  }
9854
- parseBidsAsks(bidasks, priceKey = 0, amountKey = 1) {
9865
+ parseBidsAsks(bidasks, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
9855
9866
  bidasks = this.toArray(bidasks);
9856
9867
  const result = [];
9857
9868
  for (let i = 0; i < bidasks.length; i++) {
9858
- result.push(this.parseBidAsk(bidasks[i], priceKey, amountKey));
9869
+ result.push(this.parseBidAsk(bidasks[i], priceKey, amountKey, countOrIdKey));
9859
9870
  }
9860
9871
  return result;
9861
9872
  }
@@ -10024,9 +10035,9 @@ class Exchange {
10024
10035
  const value = this.safeString2(dictionary, key1, key2);
10025
10036
  return this.parseNumber(value, d);
10026
10037
  }
10027
- parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 0, amountKey = 1) {
10028
- const bids = this.parseBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey);
10029
- const asks = this.parseBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey);
10038
+ parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 0, amountKey = 1, countOrIdKey = 2) {
10039
+ const bids = this.parseBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, countOrIdKey);
10040
+ const asks = this.parseBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, countOrIdKey);
10030
10041
  return {
10031
10042
  'symbol': symbol,
10032
10043
  'bids': this.sortBy(bids, 0, true),
@@ -10341,10 +10352,15 @@ class Exchange {
10341
10352
  async fetchBidsAsks(symbols = undefined, params = {}) {
10342
10353
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_3__.NotSupported(this.id + ' fetchBidsAsks() is not supported yet');
10343
10354
  }
10344
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
10355
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
10345
10356
  const price = this.safeNumber(bidask, priceKey);
10346
10357
  const amount = this.safeNumber(bidask, amountKey);
10347
- return [price, amount];
10358
+ const countOrId = this.safeInteger(bidask, countOrIdKey);
10359
+ const bidAsk = [price, amount];
10360
+ if (countOrId !== undefined) {
10361
+ bidAsk.push(countOrId);
10362
+ }
10363
+ return bidAsk;
10348
10364
  }
10349
10365
  safeCurrency(currencyId, currency = undefined) {
10350
10366
  if ((currencyId === undefined) && (currency !== undefined)) {
@@ -10392,7 +10408,7 @@ class Exchange {
10392
10408
  }
10393
10409
  }
10394
10410
  }
10395
- else if (delimiter !== undefined) {
10411
+ else if (delimiter !== undefined && delimiter !== '') {
10396
10412
  const parts = marketId.split(delimiter);
10397
10413
  const partsLength = parts.length;
10398
10414
  if (partsLength === 2) {
@@ -10553,6 +10569,30 @@ class Exchange {
10553
10569
  }
10554
10570
  return [value, params];
10555
10571
  }
10572
+ handleOptionAndParams2(params, methodName, methodName2, optionName, defaultValue = undefined) {
10573
+ // This method can be used to obtain method specific properties, i.e: this.handleOptionAndParams (params, 'fetchPosition', 'marginMode', 'isolated')
10574
+ const defaultOptionName = 'default' + this.capitalize(optionName); // we also need to check the 'defaultXyzWhatever'
10575
+ // check if params contain the key
10576
+ let value = this.safeValue2(params, optionName, defaultOptionName);
10577
+ if (value !== undefined) {
10578
+ params = this.omit(params, [optionName, defaultOptionName]);
10579
+ }
10580
+ else {
10581
+ // check if exchange has properties for this method
10582
+ const exchangeWideMethodOptions = this.safeValue2(this.options, methodName, methodName2);
10583
+ if (exchangeWideMethodOptions !== undefined) {
10584
+ // check if the option is defined inside this method's props
10585
+ value = this.safeValue2(exchangeWideMethodOptions, optionName, defaultOptionName);
10586
+ }
10587
+ if (value === undefined) {
10588
+ // if it's still undefined, check if global exchange-wide option exists
10589
+ value = this.safeValue2(this.options, optionName, defaultOptionName);
10590
+ }
10591
+ // if it's still undefined, use the default value
10592
+ value = (value !== undefined) ? value : defaultValue;
10593
+ }
10594
+ return [value, params];
10595
+ }
10556
10596
  handleOption(methodName, optionName, defaultValue = undefined) {
10557
10597
  // eslint-disable-next-line no-unused-vars
10558
10598
  const [result, empty] = this.handleOptionAndParams({}, methodName, optionName, defaultValue);
@@ -20305,7 +20345,12 @@ class binance extends _abstract_binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
20305
20345
  response = await this.dapiPublicGetTickerBookTicker(params);
20306
20346
  }
20307
20347
  else {
20308
- response = await this.publicGetTickerBookTicker(params);
20348
+ const request = {};
20349
+ if (symbols !== undefined) {
20350
+ const marketIds = this.marketIds(symbols);
20351
+ request['symbols'] = this.json(marketIds);
20352
+ }
20353
+ response = await this.publicGetTickerBookTicker(this.extend(request, params));
20309
20354
  }
20310
20355
  return this.parseTickers(response, symbols);
20311
20356
  }
@@ -28999,16 +29044,6 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
28999
29044
  const order = this.safeValue(data, 'order', data);
29000
29045
  return this.parseOrder(order, market);
29001
29046
  }
29002
- fixStringifiedJsonMembers(content) {
29003
- // when stringified json has members with their values also stringified, like:
29004
- // '{"code":0, "data":{"order":{"orderId":1742968678528512345,"symbol":"BTC-USDT", "takeProfit":"{\"type\":\"TAKE_PROFIT\",\"stopPrice\":43320.1}","reduceOnly":false}}}'
29005
- // we can fix with below manipulations
29006
- // @ts-ignore
29007
- let modifiedContent = content.replaceAll('\\', '');
29008
- modifiedContent = modifiedContent.replaceAll('"{', '{');
29009
- modifiedContent = modifiedContent.replaceAll('}"', '}');
29010
- return modifiedContent;
29011
- }
29012
29047
  async createOrders(orders, params = {}) {
29013
29048
  /**
29014
29049
  * @method
@@ -44659,6 +44694,7 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
44659
44694
  * @param {string} [params.trailingPercent] *swap and future only* the percent to trail away from the current market price, rate can not be greater than 10
44660
44695
  * @param {string} [params.trailingTriggerPrice] *swap and future only* the price to trigger a trailing stop order, default uses the price argument
44661
44696
  * @param {string} [params.triggerType] *swap and future only* 'fill_price', 'mark_price' or 'index_price'
44697
+ * @param {boolean} [params.oneWayMode] *swap and future only* required to set this to true in one_way_mode and you can leave this as undefined in hedge_mode, can adjust the mode using the setPositionMode() method
44662
44698
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
44663
44699
  */
44664
44700
  await this.loadMarkets();
@@ -44852,15 +44888,23 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
44852
44888
  }
44853
44889
  const marginModeRequest = (marginMode === 'cross') ? 'crossed' : 'isolated';
44854
44890
  request['marginMode'] = marginModeRequest;
44891
+ const oneWayMode = this.safeValue(params, 'oneWayMode', false);
44892
+ params = this.omit(params, 'oneWayMode');
44855
44893
  let requestSide = side;
44856
44894
  if (reduceOnly) {
44857
- request['reduceOnly'] = 'YES';
44858
- request['tradeSide'] = 'Close';
44859
- // on bitget if the position is long the side is always buy, and if the position is short the side is always sell
44860
- requestSide = (side === 'buy') ? 'sell' : 'buy';
44895
+ if (oneWayMode) {
44896
+ request['reduceOnly'] = 'YES';
44897
+ }
44898
+ else {
44899
+ // on bitget hedge mode if the position is long the side is always buy, and if the position is short the side is always sell
44900
+ requestSide = (side === 'buy') ? 'sell' : 'buy';
44901
+ request['tradeSide'] = 'Close';
44902
+ }
44861
44903
  }
44862
44904
  else {
44863
- request['tradeSide'] = 'Open';
44905
+ if (!oneWayMode) {
44906
+ request['tradeSide'] = 'Open';
44907
+ }
44864
44908
  }
44865
44909
  request['side'] = requestSide;
44866
44910
  }
@@ -72790,7 +72834,7 @@ class bl3p extends _abstract_bl3p_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
72790
72834
  const response = await this.privatePostGENMKTMoneyInfo(params);
72791
72835
  return this.parseBalance(response);
72792
72836
  }
72793
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
72837
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
72794
72838
  const price = this.safeString(bidask, priceKey);
72795
72839
  const size = this.safeString(bidask, amountKey);
72796
72840
  return [
@@ -74629,7 +74673,7 @@ class btcalpha extends _abstract_btcalpha_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
74629
74673
  const response = await this.publicGetOrderbookPairName(this.extend(request, params));
74630
74674
  return this.parseOrderBook(response, market['symbol'], undefined, 'buy', 'sell', 'price', 'amount');
74631
74675
  }
74632
- parseBidsAsks(bidasks, priceKey = 0, amountKey = 1) {
74676
+ parseBidsAsks(bidasks, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
74633
74677
  const result = [];
74634
74678
  for (let i = 0; i < bidasks.length; i++) {
74635
74679
  const bidask = bidasks[i];
@@ -78287,7 +78331,7 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
78287
78331
  'v5/asset/deposit/query-internal-record': 5,
78288
78332
  'v5/asset/deposit/query-address': 10,
78289
78333
  'v5/asset/deposit/query-sub-member-address': 10,
78290
- 'v5/asset/coin/query-info': 25,
78334
+ 'v5/asset/coin/query-info': 28,
78291
78335
  'v5/asset/withdraw/query-record': 10,
78292
78336
  'v5/asset/withdraw/withdrawable-amount': 5,
78293
78337
  // user
@@ -106575,6 +106619,7 @@ class cryptocom extends _abstract_cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["
106575
106619
  // "p": "26386.00",
106576
106620
  // "q": "0.00453",
106577
106621
  // "t": 1686944282062,
106622
+ // "tn" : 1704476468851524373,
106578
106623
  // "d": "4611686018455979970",
106579
106624
  // "i": "BTC_USD"
106580
106625
  // },
@@ -107745,7 +107790,8 @@ class cryptocom extends _abstract_cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["
107745
107790
  // "s": "sell",
107746
107791
  // "p": "26386.00",
107747
107792
  // "q": "0.00453",
107748
- // "t": 1686944282062,
107793
+ // "tn": 1686944282062,
107794
+ // "tn": 1704476468851524373,
107749
107795
  // "d": "4611686018455979970",
107750
107796
  // "i": "BTC_USD"
107751
107797
  // }
@@ -115835,27 +115881,18 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
115835
115881
  * @param {string} symbol unified symbol of the market to create an order in
115836
115882
  * @param {string} type 'market' or 'limit'
115837
115883
  * @param {string} side 'buy' or 'sell'
115838
- * @param {float} amount how much of currency you want to trade. For perpetual and futures the amount is in USD. For options it is in corresponding cryptocurrency contracts currency.
115884
+ * @param {float} amount how much you want to trade in units of the base currency. For inverse perpetual and futures the amount is in the quote currency USD. For options it is in the underlying assets base currency.
115839
115885
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
115840
115886
  * @param {object} [params] extra parameters specific to the exchange API endpoint
115887
+ * @param {string} [params.trigger] the trigger type 'index_price', 'mark_price', or 'last_price', default is 'last_price'
115888
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
115841
115889
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
115842
115890
  */
115843
115891
  await this.loadMarkets();
115844
115892
  const market = this.market(symbol);
115845
- if (market['inverse']) {
115846
- amount = this.amountToPrecision(symbol, amount);
115847
- }
115848
- else if (market['settle'] === 'USDC') {
115849
- amount = this.amountToPrecision(symbol, amount);
115850
- }
115851
- else {
115852
- amount = this.currencyToPrecision(symbol, amount);
115853
- }
115854
115893
  const request = {
115855
115894
  'instrument_name': market['id'],
115856
- // for perpetual and futures the amount is in USD
115857
- // for options it is in corresponding cryptocurrency contracts, e.g., BTC or ETH
115858
- 'amount': amount,
115895
+ 'amount': this.amountToPrecision(symbol, amount),
115859
115896
  'type': type, // limit, stop_limit, market, stop_market, default is limit
115860
115897
  // 'label': 'string', // user-defined label for the order (maximum 64 characters)
115861
115898
  // 'price': this.priceToPrecision (symbol, 123.45), // only for limit and stop_limit orders
@@ -115868,12 +115905,15 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
115868
115905
  // 'trigger': 'index_price', // mark_price, last_price, required for stop_limit orders
115869
115906
  // 'advanced': 'usd', // 'implv', advanced option order type, options only
115870
115907
  };
115908
+ const trigger = this.safeString(params, 'trigger', 'last_price');
115871
115909
  const timeInForce = this.safeStringUpper(params, 'timeInForce');
115872
115910
  const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
115873
115911
  // only stop loss sell orders are allowed when price crossed from above
115874
115912
  const stopLossPrice = this.safeValue(params, 'stopLossPrice');
115875
115913
  // only take profit buy orders are allowed when price crossed from below
115876
115914
  const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
115915
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trigger_offset');
115916
+ const isTrailingAmountOrder = trailingAmount !== undefined;
115877
115917
  const isStopLimit = type === 'stop_limit';
115878
115918
  const isStopMarket = type === 'stop_market';
115879
115919
  const isTakeLimit = type === 'take_limit';
@@ -115895,10 +115935,15 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
115895
115935
  else {
115896
115936
  request['type'] = 'market';
115897
115937
  }
115898
- if (isStopOrder) {
115938
+ if (isTrailingAmountOrder) {
115939
+ request['trigger'] = trigger;
115940
+ request['type'] = 'trailing_stop';
115941
+ request['trigger_offset'] = this.parseToNumeric(trailingAmount);
115942
+ }
115943
+ else if (isStopOrder) {
115899
115944
  const triggerPrice = (stopLossPrice !== undefined) ? stopLossPrice : takeProfitPrice;
115900
115945
  request['trigger_price'] = this.priceToPrecision(symbol, triggerPrice);
115901
- request['trigger'] = 'last_price'; // required
115946
+ request['trigger'] = trigger;
115902
115947
  if (isStopLossOrder) {
115903
115948
  if (isMarketOrder) {
115904
115949
  // stop_market (sell only)
@@ -115938,7 +115983,7 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
115938
115983
  request['time_in_force'] = 'fill_or_kill';
115939
115984
  }
115940
115985
  }
115941
- params = this.omit(params, ['timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'reduceOnly']);
115986
+ params = this.omit(params, ['timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'reduceOnly', 'trailingAmount']);
115942
115987
  let response = undefined;
115943
115988
  if (this.capitalize(side) === 'Buy') {
115944
115989
  response = await this.privateGetBuy(this.extend(request, params));
@@ -116005,25 +116050,43 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
116005
116050
  return this.parseOrder(order, market);
116006
116051
  }
116007
116052
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
116053
+ /**
116054
+ * @method
116055
+ * @name deribit#editOrder
116056
+ * @description edit a trade order
116057
+ * @see https://docs.deribit.com/#private-edit
116058
+ * @param {string} id edit order id
116059
+ * @param {string} [symbol] unified symbol of the market to edit an order in
116060
+ * @param {string} [type] 'market' or 'limit'
116061
+ * @param {string} [side] 'buy' or 'sell'
116062
+ * @param {float} amount how much you want to trade in units of the base currency, inverse swap and future use the quote currency
116063
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
116064
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
116065
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
116066
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
116067
+ */
116008
116068
  if (amount === undefined) {
116009
116069
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' editOrder() requires an amount argument');
116010
116070
  }
116011
- if (price === undefined) {
116012
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' editOrder() requires a price argument');
116013
- }
116014
116071
  await this.loadMarkets();
116015
116072
  const request = {
116016
116073
  'order_id': id,
116017
- // for perpetual and futures the amount is in USD
116018
- // for options it is in corresponding cryptocurrency contracts, e.g., BTC or ETH
116019
116074
  'amount': this.amountToPrecision(symbol, amount),
116020
- 'price': this.priceToPrecision(symbol, price), // required
116021
116075
  // 'post_only': false, // if the new price would cause the order to be filled immediately (as taker), the price will be changed to be just below the spread.
116022
116076
  // 'reject_post_only': false, // if true the order is put to order book unmodified or request is rejected
116023
116077
  // 'reduce_only': false, // if true, the order is intended to only reduce a current position
116024
116078
  // 'stop_price': false, // stop price, required for stop_limit orders
116025
116079
  // 'advanced': 'usd', // 'implv', advanced option order type, options only
116026
116080
  };
116081
+ if (price !== undefined) {
116082
+ request['price'] = this.priceToPrecision(symbol, price);
116083
+ }
116084
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trigger_offset');
116085
+ const isTrailingAmountOrder = trailingAmount !== undefined;
116086
+ if (isTrailingAmountOrder) {
116087
+ request['trigger_offset'] = this.parseToNumeric(trailingAmount);
116088
+ params = this.omit(params, 'trigger_offset');
116089
+ }
116027
116090
  const response = await this.privateGetEdit(this.extend(request, params));
116028
116091
  const result = this.safeValue(response, 'result', {});
116029
116092
  const order = this.safeValue(result, 'order');
@@ -154284,7 +154347,7 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
154284
154347
  'tierBased': true,
154285
154348
  };
154286
154349
  }
154287
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
154350
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
154288
154351
  const price = this.safeNumber(bidask, priceKey);
154289
154352
  const amount = this.safeNumber(bidask, amountKey);
154290
154353
  const timestamp = this.safeInteger(bidask, 2);
@@ -161240,7 +161303,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
161240
161303
  // }
161241
161304
  // }
161242
161305
  const responseData = this.safeValue(response, 'data', {});
161243
- const orders = this.safeValue(responseData, 'items', []);
161306
+ const orders = this.safeValue(responseData, 'items', responseData);
161244
161307
  return this.parseOrders(orders, market, since, limit);
161245
161308
  }
161246
161309
  async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -162266,10 +162329,12 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162266
162329
  * @name kucoin#fetchBalance
162267
162330
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
162268
162331
  * @see https://docs.kucoin.com/#list-accounts
162332
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
162269
162333
  * @see https://docs.kucoin.com/#query-isolated-margin-account-info
162270
162334
  * @param {object} [params] extra parameters specific to the exchange API endpoint
162271
162335
  * @param {object} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance
162272
162336
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
162337
+ * @param {object} [params.hf] *default if false* if true, the result includes the balance of the high frequency account
162273
162338
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
162274
162339
  */
162275
162340
  await this.loadMarkets();
@@ -162281,8 +162346,13 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162281
162346
  const defaultType = this.safeString2(this.options, 'fetchBalance', 'defaultType', 'spot');
162282
162347
  const requestedType = this.safeString(params, 'type', defaultType);
162283
162348
  const accountsByType = this.safeValue(this.options, 'accountsByType');
162284
- const type = this.safeString(accountsByType, requestedType, requestedType);
162349
+ let type = this.safeString(accountsByType, requestedType, requestedType);
162285
162350
  params = this.omit(params, 'type');
162351
+ const isHf = this.safeValue(params, 'hf', false);
162352
+ if (isHf) {
162353
+ type = 'trade_hf';
162354
+ }
162355
+ params = this.omit(params, 'hf');
162286
162356
  const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
162287
162357
  let response = undefined;
162288
162358
  const request = {};
@@ -162364,7 +162434,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162364
162434
  'datetime': undefined,
162365
162435
  };
162366
162436
  if (isolated) {
162367
- const assets = this.safeValue(data, 'assets', []);
162437
+ const assets = this.safeValue(data, 'assets', data);
162368
162438
  for (let i = 0; i < assets.length; i++) {
162369
162439
  const entry = assets[i];
162370
162440
  const marketId = this.safeString(entry, 'symbol');
@@ -162695,12 +162765,14 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162695
162765
  * @method
162696
162766
  * @name kucoin#fetchLedger
162697
162767
  * @see https://docs.kucoin.com/#get-account-ledgers
162768
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
162769
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
162698
162770
  * @description fetch the history of changes, actions done by the user or operations that altered balance of the user
162699
- * @see https://docs.kucoin.com/#get-account-ledgers
162700
162771
  * @param {string} code unified currency code, default is undefined
162701
162772
  * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
162702
162773
  * @param {int} [limit] max number of ledger entrys to return, default is undefined
162703
162774
  * @param {object} [params] extra parameters specific to the exchange API endpoint
162775
+ * @param {boolean} [params.hf] default false, when true will fetch ledger entries for the high frequency trading account
162704
162776
  * @param {int} [params.until] the latest time in ms to fetch entries for
162705
162777
  * @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)
162706
162778
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
@@ -162709,6 +162781,8 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162709
162781
  await this.loadAccounts();
162710
162782
  let paginate = false;
162711
162783
  [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
162784
+ const isHf = this.safeValue(params, 'hf');
162785
+ params = this.omit(params, 'hf');
162712
162786
  if (paginate) {
162713
162787
  return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
162714
162788
  }
@@ -162729,7 +162803,20 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162729
162803
  request['currency'] = currency['id'];
162730
162804
  }
162731
162805
  [request, params] = this.handleUntilOption('endAt', request, params);
162732
- const response = await this.privateGetAccountsLedgers(this.extend(request, params));
162806
+ let marginMode = undefined;
162807
+ [marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
162808
+ let response = undefined;
162809
+ if (isHf) {
162810
+ if (marginMode !== undefined) {
162811
+ response = await this.privateGetHfMarginAccountLedgers(this.extend(request, params));
162812
+ }
162813
+ else {
162814
+ response = await this.privateGetHfAccountsLedgers(this.extend(request, params));
162815
+ }
162816
+ }
162817
+ else {
162818
+ response = await this.privateGetAccountsLedgers(this.extend(request, params));
162819
+ }
162733
162820
  //
162734
162821
  // {
162735
162822
  // "code":"200000",
@@ -162768,7 +162855,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
162768
162855
  // }
162769
162856
  //
162770
162857
  const data = this.safeValue(response, 'data');
162771
- const items = this.safeValue(data, 'items');
162858
+ const items = this.safeValue(data, 'items', data);
162772
162859
  return this.parseLedger(items, currency, since, limit);
162773
162860
  }
162774
162861
  calculateRateLimiterCost(api, method, path, params, config = {}) {
@@ -174445,7 +174532,7 @@ class lykke extends _abstract_lykke_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
174445
174532
  //
174446
174533
  return this.parseTrades(payload, market, since, limit);
174447
174534
  }
174448
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
174535
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
174449
174536
  const price = this.safeString(bidask, priceKey);
174450
174537
  const amount = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringAbs(this.safeString(bidask, amountKey));
174451
174538
  return [this.parseNumber(price), this.parseNumber(amount)];
@@ -181522,7 +181609,7 @@ class ndax extends _abstract_ndax_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
181522
181609
  'info': market,
181523
181610
  };
181524
181611
  }
181525
- parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 6, amountKey = 8) {
181612
+ parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 6, amountKey = 8, countOrIdKey = 2) {
181526
181613
  let nonce = undefined;
181527
181614
  const result = {
181528
181615
  'symbol': symbol,
@@ -216710,25 +216797,39 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
216710
216797
  const market = this.getMarketFromSymbols(symbols);
216711
216798
  let type = 'spot';
216712
216799
  [type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
216713
- symbols = this.marketSymbols(symbols);
216714
- if (type === 'spot') {
216715
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchTickers() does not support ' + type + ' markets. Use watchTicker() instead');
216716
- }
216717
216800
  const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
216718
- if (type === 'swap') {
216719
- type = 'futures';
216720
- }
216721
- let messageHash = 'tickers';
216801
+ symbols = this.marketSymbols(symbols);
216802
+ let messageHash = 'tickers::' + type;
216722
216803
  if (symbols !== undefined) {
216723
216804
  messageHash += '::' + symbols.join(',');
216724
216805
  }
216725
- const request = {
216726
- 'action': 'subscribe',
216727
- 'args': ['futures/ticker'],
216728
- };
216729
- const newTickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
216806
+ let request = undefined;
216807
+ let tickers = undefined;
216808
+ const isSpot = (type === 'spot');
216809
+ if (isSpot) {
216810
+ if (symbols === undefined) {
216811
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTickers() for ' + type + ' market type requires symbols argument to be provided');
216812
+ }
216813
+ const marketIds = this.marketIds(symbols);
216814
+ const finalArray = [];
216815
+ for (let i = 0; i < marketIds.length; i++) {
216816
+ finalArray.push('spot/ticker:' + marketIds[i]);
216817
+ }
216818
+ request = {
216819
+ 'op': 'subscribe',
216820
+ 'args': finalArray,
216821
+ };
216822
+ tickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
216823
+ }
216824
+ else {
216825
+ request = {
216826
+ 'action': 'subscribe',
216827
+ 'args': ['futures/ticker'],
216828
+ };
216829
+ tickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
216830
+ }
216730
216831
  if (this.newUpdates) {
216731
- return newTickers;
216832
+ return tickers;
216732
216833
  }
216733
216834
  return this.filterByArray(this.tickers, 'symbol', symbols);
216734
216835
  }
@@ -217313,28 +217414,36 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
217313
217414
  const messageHash = table + ':' + marketId;
217314
217415
  this.tickers[symbol] = ticker;
217315
217416
  client.resolve(ticker, messageHash);
217417
+ this.resolveMessageHashesForSymbol(client, symbol, ticker, 'tickers::');
217316
217418
  }
217317
217419
  }
217318
217420
  else {
217421
+ // on each update for contract markets, single ticker is provided
217319
217422
  const ticker = this.parseWsSwapTicker(data);
217320
217423
  const symbol = this.safeString(ticker, 'symbol');
217321
217424
  this.tickers[symbol] = ticker;
217322
- client.resolve(ticker, 'tickers');
217323
- const messageHashes = this.findMessageHashes(client, 'tickers::');
217324
- for (let i = 0; i < messageHashes.length; i++) {
217325
- const messageHash = messageHashes[i];
217326
- const parts = messageHash.split('::');
217327
- const symbolsString = parts[1];
217328
- const symbols = symbolsString.split(',');
217329
- if (this.inArray(symbol, symbols)) {
217330
- const response = {};
217331
- response[symbol] = ticker;
217332
- client.resolve(response, messageHash);
217333
- }
217334
- }
217425
+ client.resolve(ticker, 'tickers::swap');
217426
+ this.resolveMessageHashesForSymbol(client, symbol, ticker, 'tickers::');
217335
217427
  }
217336
217428
  return message;
217337
217429
  }
217430
+ resolveMessageHashesForSymbol(client, symbol, result, prexif) {
217431
+ const prefixSeparator = '::';
217432
+ const symbolsSeparator = ',';
217433
+ const messageHashes = this.findMessageHashes(client, prexif);
217434
+ for (let i = 0; i < messageHashes.length; i++) {
217435
+ const messageHash = messageHashes[i];
217436
+ const parts = messageHash.split(prefixSeparator);
217437
+ const length = parts.length;
217438
+ const symbolsString = parts[length - 1];
217439
+ const symbols = symbolsString.split(symbolsSeparator);
217440
+ if (this.inArray(symbol, symbols)) {
217441
+ const response = {};
217442
+ response[symbol] = result;
217443
+ client.resolve(response, messageHash);
217444
+ }
217445
+ }
217446
+ }
217338
217447
  parseWsSwapTicker(ticker, market = undefined) {
217339
217448
  //
217340
217449
  // {
@@ -223594,7 +223703,7 @@ class blockchaincom extends _blockchaincom_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
223594
223703
  return message;
223595
223704
  }
223596
223705
  else if (event === 'snapshot') {
223597
- const snapshot = this.parseCountedOrderBook(message, symbol, timestamp, 'bids', 'asks', 'px', 'qty', 'num');
223706
+ const snapshot = this.parseOrderBook(message, symbol, timestamp, 'bids', 'asks', 'px', 'qty', 'num');
223598
223707
  storedOrderBook.reset(snapshot);
223599
223708
  }
223600
223709
  else if (event === 'updated') {
@@ -223610,34 +223719,8 @@ class blockchaincom extends _blockchaincom_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
223610
223719
  }
223611
223720
  client.resolve(storedOrderBook, messageHash);
223612
223721
  }
223613
- parseCountedBidAsk(bidAsk, priceKey = 0, amountKey = 1, countKey = 2) {
223614
- const price = this.safeNumber(bidAsk, priceKey);
223615
- const amount = this.safeNumber(bidAsk, amountKey);
223616
- const count = this.safeNumber(bidAsk, countKey);
223617
- return [price, amount, count];
223618
- }
223619
- parseCountedBidsAsks(bidasks, priceKey = 0, amountKey = 1, countKey = 2) {
223620
- bidasks = this.toArray(bidasks);
223621
- const result = [];
223622
- for (let i = 0; i < bidasks.length; i++) {
223623
- result.push(this.parseCountedBidAsk(bidasks[i], priceKey, amountKey, countKey));
223624
- }
223625
- return result;
223626
- }
223627
- parseCountedOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 0, amountKey = 1, countKey = 2) {
223628
- const bids = this.parseCountedBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, countKey);
223629
- const asks = this.parseCountedBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, countKey);
223630
- return {
223631
- 'symbol': symbol,
223632
- 'bids': this.sortBy(bids, 0, true),
223633
- 'asks': this.sortBy(asks, 0),
223634
- 'timestamp': timestamp,
223635
- 'datetime': this.iso8601(timestamp),
223636
- 'nonce': undefined,
223637
- };
223638
- }
223639
223722
  handleDelta(bookside, delta) {
223640
- const bookArray = this.parseCountedBidAsk(delta, 'px', 'qty', 'num');
223723
+ const bookArray = this.parseBidAsk(delta, 'px', 'qty', 'num');
223641
223724
  bookside.storeArray(bookArray);
223642
223725
  }
223643
223726
  handleDeltas(bookside, deltas) {
@@ -227756,7 +227839,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
227756
227839
  const symbol = symbols[i];
227757
227840
  market = this.market(symbol);
227758
227841
  productIds.push(market['id']);
227759
- messageHashes.push(messageHashStart + ':' + market['id']);
227842
+ messageHashes.push(messageHashStart + ':' + market['symbol']);
227760
227843
  }
227761
227844
  let url = this.urls['api']['ws'];
227762
227845
  if ('signature' in params) {
@@ -227801,10 +227884,12 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
227801
227884
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadSymbol(this.id + ' watchTickers requires a non-empty symbols array');
227802
227885
  }
227803
227886
  const channel = 'ticker';
227804
- const messageHash = 'tickers::';
227805
- const newTickers = await this.subscribeMultiple(channel, symbols, messageHash, params);
227887
+ const messageHash = 'ticker';
227888
+ const ticker = await this.subscribeMultiple(channel, symbols, messageHash, params);
227806
227889
  if (this.newUpdates) {
227807
- return newTickers;
227890
+ const result = {};
227891
+ result[ticker['symbol']] = ticker;
227892
+ return result;
227808
227893
  }
227809
227894
  return this.filterByArray(this.tickers, 'symbol', symbols);
227810
227895
  }
@@ -228416,19 +228501,10 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
228416
228501
  const ticker = this.parseTicker(message);
228417
228502
  const symbol = ticker['symbol'];
228418
228503
  this.tickers[symbol] = ticker;
228419
- const type = this.safeString(message, 'type');
228420
- const messageHash = type + ':' + marketId;
228504
+ const messageHash = 'ticker:' + symbol;
228505
+ const idMessageHash = 'ticker:' + marketId;
228421
228506
  client.resolve(ticker, messageHash);
228422
- const messageHashes = this.findMessageHashes(client, 'tickers::');
228423
- for (let i = 0; i < messageHashes.length; i++) {
228424
- const currentMessageHash = messageHashes[i];
228425
- const parts = currentMessageHash.split('::');
228426
- const symbolsString = parts[1];
228427
- const symbols = symbolsString.split(',');
228428
- if (this.inArray(symbol, symbols)) {
228429
- client.resolve(ticker, currentMessageHash);
228430
- }
228431
- }
228507
+ client.resolve(ticker, idMessageHash);
228432
228508
  }
228433
228509
  return message;
228434
228510
  }
@@ -229828,6 +229904,8 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
229828
229904
  * @param {string} symbol unified symbol of the market to fetch the order book for
229829
229905
  * @param {int} [limit] the maximum amount of order book entries to return
229830
229906
  * @param {object} [params] extra parameters specific to the exchange API endpoint
229907
+ * @param {string} [params.bookSubscriptionType] The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
229908
+ * @param {int} [params.bookUpdateFrequency] Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
229831
229909
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
229832
229910
  */
229833
229911
  return await this.watchOrderBookForSymbols([symbol], limit, params);
@@ -229841,6 +229919,8 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
229841
229919
  * @param {string[]} symbols unified array of symbols
229842
229920
  * @param {int} [limit] the maximum amount of order book entries to return
229843
229921
  * @param {object} [params] extra parameters specific to the exchange API endpoint
229922
+ * @param {string} [params.bookSubscriptionType] The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
229923
+ * @param {int} [params.bookUpdateFrequency] Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
229844
229924
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
229845
229925
  */
229846
229926
  await this.loadMarkets();
@@ -229848,12 +229928,26 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
229848
229928
  const topics = [];
229849
229929
  const messageHashes = [];
229850
229930
  if (!limit) {
229851
- limit = 150;
229931
+ limit = 50;
229932
+ }
229933
+ const topicParams = this.safeValue(params, 'params');
229934
+ if (topicParams === undefined) {
229935
+ params['params'] = {};
229936
+ }
229937
+ let bookSubscriptionType = undefined;
229938
+ [bookSubscriptionType, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE');
229939
+ if (bookSubscriptionType !== undefined) {
229940
+ params['params']['bookSubscriptionType'] = bookSubscriptionType;
229941
+ }
229942
+ let bookUpdateFrequency = undefined;
229943
+ [bookUpdateFrequency, params] = this.handleOptionAndParams2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookUpdateFrequency');
229944
+ if (bookUpdateFrequency !== undefined) {
229945
+ params['params']['bookSubscriptionType'] = bookSubscriptionType;
229852
229946
  }
229853
229947
  for (let i = 0; i < symbols.length; i++) {
229854
229948
  const symbol = symbols[i];
229855
229949
  const market = this.market(symbol);
229856
- const currentTopic = 'book' + '.' + market['id'] + '.' + limit;
229950
+ const currentTopic = 'book' + '.' + market['id'] + '.' + limit.toString();
229857
229951
  const messageHash = 'orderbook:' + market['symbol'];
229858
229952
  messageHashes.push(messageHash);
229859
229953
  topics.push(currentTopic);
@@ -229861,27 +229955,72 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
229861
229955
  const orderbook = await this.watchPublicMultiple(messageHashes, topics, params);
229862
229956
  return orderbook.limit();
229863
229957
  }
229864
- handleOrderBookSnapshot(client, message) {
229865
- // full snapshot
229958
+ handleDelta(bookside, delta) {
229959
+ const price = this.safeFloat(delta, 0);
229960
+ const amount = this.safeFloat(delta, 1);
229961
+ const count = this.safeInteger(delta, 2);
229962
+ bookside.store(price, amount, count);
229963
+ }
229964
+ handleDeltas(bookside, deltas) {
229965
+ for (let i = 0; i < deltas.length; i++) {
229966
+ this.handleDelta(bookside, deltas[i]);
229967
+ }
229968
+ }
229969
+ handleOrderBook(client, message) {
229866
229970
  //
229867
- // {
229868
- // "instrument_name":"LTC_USDT",
229869
- // "subscription":"book.LTC_USDT.150",
229870
- // "channel":"book",
229871
- // "depth":150,
229872
- // "data": [
229873
- // {
229874
- // "bids": [
229875
- // [122.21, 0.74041, 4]
229876
- // ],
229877
- // "asks": [
229878
- // [122.29, 0.00002, 1]
229879
- // ]
229880
- // "t": 1648123943803,
229881
- // "s":754560122
229882
- // }
229883
- // ]
229884
- // }
229971
+ // snapshot
229972
+ // {
229973
+ // "instrument_name":"LTC_USDT",
229974
+ // "subscription":"book.LTC_USDT.150",
229975
+ // "channel":"book",
229976
+ // "depth":150,
229977
+ // "data": [
229978
+ // {
229979
+ // "bids": [
229980
+ // [122.21, 0.74041, 4]
229981
+ // ],
229982
+ // "asks": [
229983
+ // [122.29, 0.00002, 1]
229984
+ // ]
229985
+ // "t": 1648123943803,
229986
+ // "s":754560122
229987
+ // }
229988
+ // ]
229989
+ // }
229990
+ // update
229991
+ // {
229992
+ // "instrument_name":"BTC_USDT",
229993
+ // "subscription":"book.BTC_USDT.50",
229994
+ // "channel":"book.update",
229995
+ // "depth":50,
229996
+ // "data":[
229997
+ // {
229998
+ // "update":{
229999
+ // "asks":[
230000
+ // [
230001
+ // "43755.46",
230002
+ // "0.10000",
230003
+ // "1"
230004
+ // ],
230005
+ // ...
230006
+ // ],
230007
+ // "bids":[
230008
+ // [
230009
+ // "43737.46",
230010
+ // "0.14096",
230011
+ // "1"
230012
+ // ],
230013
+ // ...
230014
+ // ]
230015
+ // },
230016
+ // "t":1704484068898,
230017
+ // "tt":1704484068892,
230018
+ // "u":78795598253024,
230019
+ // "pu":78795598162080,
230020
+ // "cs":-781431132
230021
+ // }
230022
+ // ]
230023
+ // }
229885
230024
  //
229886
230025
  const marketId = this.safeString(message, 'instrument_name');
229887
230026
  const market = this.safeMarket(marketId);
@@ -229889,14 +230028,32 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
229889
230028
  let data = this.safeValue(message, 'data');
229890
230029
  data = this.safeValue(data, 0);
229891
230030
  const timestamp = this.safeInteger(data, 't');
229892
- const snapshot = this.parseOrderBook(data, symbol, timestamp);
229893
- snapshot['nonce'] = this.safeInteger(data, 's');
229894
230031
  let orderbook = this.safeValue(this.orderbooks, symbol);
229895
230032
  if (orderbook === undefined) {
229896
230033
  const limit = this.safeInteger(message, 'depth');
229897
- orderbook = this.orderBook({}, limit);
230034
+ orderbook = this.countedOrderBook({}, limit);
229898
230035
  }
229899
- orderbook.reset(snapshot);
230036
+ const channel = this.safeString(message, 'channel');
230037
+ const nonce = this.safeInteger2(data, 'u', 's');
230038
+ let books = data;
230039
+ if (channel === 'book') { // snapshot
230040
+ orderbook.reset({});
230041
+ orderbook['symbol'] = symbol;
230042
+ orderbook['timestamp'] = timestamp;
230043
+ orderbook['datetime'] = this.iso8601(timestamp);
230044
+ orderbook['nonce'] = nonce;
230045
+ }
230046
+ else {
230047
+ books = this.safeValue(data, 'update', {});
230048
+ const previousNonce = this.safeInteger(data, 'pu');
230049
+ const currentNonce = orderbook['nonce'];
230050
+ if (currentNonce !== previousNonce) {
230051
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidNonce(this.id + ' watchOrderBook() ' + symbol + ' ' + previousNonce + ' != ' + nonce);
230052
+ }
230053
+ }
230054
+ this.handleDeltas(orderbook['asks'], this.safeValue(books, 'asks', []));
230055
+ this.handleDeltas(orderbook['bids'], this.safeValue(books, 'bids', []));
230056
+ orderbook['nonce'] = nonce;
229900
230057
  this.orderbooks[symbol] = orderbook;
229901
230058
  const messageHash = 'orderbook:' + symbol;
229902
230059
  client.resolve(orderbook, messageHash);
@@ -230518,7 +230675,7 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
230518
230675
  },
230519
230676
  'nonce': id,
230520
230677
  };
230521
- const message = this.extend(request, params);
230678
+ const message = this.deepExtend(request, params);
230522
230679
  return await this.watchMultiple(url, messageHashes, message, messageHashes);
230523
230680
  }
230524
230681
  async watchPrivateRequest(nonce, params = {}) {
@@ -230585,7 +230742,8 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
230585
230742
  'candlestick': this.handleOHLCV,
230586
230743
  'ticker': this.handleTicker,
230587
230744
  'trade': this.handleTrades,
230588
- 'book': this.handleOrderBookSnapshot,
230745
+ 'book': this.handleOrderBook,
230746
+ 'book.update': this.handleOrderBook,
230589
230747
  'user.order': this.handleOrders,
230590
230748
  'user.trade': this.handleTrades,
230591
230749
  'user.balance': this.handleBalance,
@@ -245872,9 +246030,9 @@ class luno extends _luno_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
245872
246030
  storedOrderBook['nonce'] = nonce;
245873
246031
  client.resolve(storedOrderBook, messageHash);
245874
246032
  }
245875
- customParseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 'price', amountKey = 'volume', thirdKey = undefined) {
245876
- const bids = this.parseBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, thirdKey);
245877
- const asks = this.parseBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, thirdKey);
246033
+ customParseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 'price', amountKey = 'volume', countOrIdKey = 2) {
246034
+ const bids = this.parseBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, countOrIdKey);
246035
+ const asks = this.parseBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, countOrIdKey);
245878
246036
  return {
245879
246037
  'symbol': symbol,
245880
246038
  'bids': this.sortBy(bids, 0, true),
@@ -245884,7 +246042,7 @@ class luno extends _luno_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
245884
246042
  'nonce': undefined,
245885
246043
  };
245886
246044
  }
245887
- parseBidsAsks(bidasks, priceKey = 'price', amountKey = 'volume', thirdKey = undefined) {
246045
+ parseBidsAsks(bidasks, priceKey = 'price', amountKey = 'volume', thirdKey = 2) {
245888
246046
  bidasks = this.toArray(bidasks);
245889
246047
  const result = [];
245890
246048
  for (let i = 0; i < bidasks.length; i++) {
@@ -245892,7 +246050,7 @@ class luno extends _luno_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
245892
246050
  }
245893
246051
  return result;
245894
246052
  }
245895
- customParseBidAsk(bidask, priceKey = 'price', amountKey = 'volume', thirdKey = undefined) {
246053
+ customParseBidAsk(bidask, priceKey = 'price', amountKey = 'volume', thirdKey = 2) {
245896
246054
  const price = this.safeNumber(bidask, priceKey);
245897
246055
  const amount = this.safeNumber(bidask, amountKey);
245898
246056
  const result = [price, amount];
@@ -292117,7 +292275,7 @@ SOFTWARE.
292117
292275
 
292118
292276
  //-----------------------------------------------------------------------------
292119
292277
  // this is updated by vss.js when building
292120
- const version = '4.2.9';
292278
+ const version = '4.2.11';
292121
292279
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
292122
292280
  //-----------------------------------------------------------------------------
292123
292281