ccxt 4.1.83 → 4.1.85

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.
@@ -10689,6 +10689,9 @@ class Exchange {
10689
10689
  async closeAllPositions(params = {}) {
10690
10690
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_3__.NotSupported(this.id + ' closeAllPositions() is not supported yet');
10691
10691
  }
10692
+ async fetchL3OrderBook(symbol, limit = undefined, params = {}) {
10693
+ throw new _errors_js__WEBPACK_IMPORTED_MODULE_3__.BadRequest(this.id + ' fetchL3OrderBook() is not supported yet');
10694
+ }
10692
10695
  parseLastPrice(price, market = undefined) {
10693
10696
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_3__.NotSupported(this.id + ' parseLastPrice() is not supported yet');
10694
10697
  }
@@ -25587,7 +25590,7 @@ class binance extends _abstract_binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
25587
25590
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
25588
25591
  query = this.rawencode(extendedParams);
25589
25592
  const orderidlistLength = orderidlist.length;
25590
- const origclientorderidlistLength = orderidlist.length;
25593
+ const origclientorderidlistLength = origclientorderidlist.length;
25591
25594
  if (orderidlistLength > 0) {
25592
25595
  query = query + '&' + 'orderidlist=[' + orderidlist.join(',') + ']';
25593
25596
  }
@@ -28922,6 +28925,9 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
28922
28925
  const positionSide = this.safeString2(order, 'positionSide', 'ps');
28923
28926
  const marketType = (positionSide === undefined) ? 'spot' : 'swap';
28924
28927
  const marketId = this.safeString2(order, 'symbol', 's');
28928
+ if (market === undefined) {
28929
+ market = this.safeMarket(marketId, undefined, undefined, marketType);
28930
+ }
28925
28931
  const symbol = this.safeSymbol(marketId, market, '-', marketType);
28926
28932
  const orderId = this.safeString2(order, 'orderId', 'i');
28927
28933
  const side = this.safeStringLower2(order, 'side', 'S');
@@ -29287,16 +29293,15 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
29287
29293
  * @param {object} [params] extra parameters specific to the exchange API endpoint
29288
29294
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
29289
29295
  */
29290
- if (symbol === undefined) {
29291
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
29292
- }
29293
29296
  await this.loadMarkets();
29294
- const market = this.market(symbol);
29295
- const request = {
29296
- 'symbol': market['id'],
29297
- };
29297
+ let market = undefined;
29298
+ const request = {};
29299
+ if (symbol !== undefined) {
29300
+ market = this.market(symbol);
29301
+ request['symbol'] = market['id'];
29302
+ }
29298
29303
  let response = undefined;
29299
- const [marketType, query] = this.handleMarketTypeAndParams('fetchOrder', market, params);
29304
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
29300
29305
  if (marketType === 'spot') {
29301
29306
  response = await this.spotV1PrivateGetTradeOpenOrders(this.extend(request, query));
29302
29307
  }
@@ -48325,11 +48330,11 @@ class bithumb extends _abstract_bithumb_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
48325
48330
  };
48326
48331
  return await this.privatePostTradeCancel(this.extend(request, params));
48327
48332
  }
48328
- cancelUnifiedOrder(order, params = {}) {
48333
+ async cancelUnifiedOrder(order, params = {}) {
48329
48334
  const request = {
48330
48335
  'side': order['side'],
48331
48336
  };
48332
- return this.cancelOrder(order['id'], order['symbol'], this.extend(request, params));
48337
+ return await this.cancelOrder(order['id'], order['symbol'], this.extend(request, params));
48333
48338
  }
48334
48339
  async withdraw(code, amount, address, tag = undefined, params = {}) {
48335
48340
  /**
@@ -49814,48 +49819,58 @@ class bitmart extends _abstract_bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
49814
49819
  //
49815
49820
  // public fetchTrades spot ( amount = count * price )
49816
49821
  //
49817
- // {
49818
- // "amount": "818.94",
49819
- // "order_time": "1637601839035", // ETH/USDT
49820
- // "price": "4221.99",
49821
- // "count": "0.19397",
49822
- // "type": "buy"
49823
- // }
49822
+ // {
49823
+ // "amount": "818.94",
49824
+ // "order_time": "1637601839035", // ETH/USDT
49825
+ // "price": "4221.99",
49826
+ // "count": "0.19397",
49827
+ // "type": "buy"
49828
+ // }
49824
49829
  //
49825
49830
  // spot: fetchMyTrades
49826
49831
  //
49827
- // {
49828
- // "tradeId":"182342999769370687",
49829
- // "orderId":"183270218784142990",
49830
- // "clientOrderId":"183270218784142990",
49831
- // "symbol":"ADA_USDT",
49832
- // "side":"buy",
49833
- // "orderMode":"spot",
49834
- // "type":"market",
49835
- // "price":"0.245948",
49836
- // "size":"20.71",
49837
- // "notional":"5.09358308",
49838
- // "fee":"0.00509358",
49839
- // "feeCoinName":"USDT",
49840
- // "tradeRole":"taker",
49841
- // "createTime":1695658457836,
49842
- // }
49832
+ // {
49833
+ // "tradeId":"182342999769370687",
49834
+ // "orderId":"183270218784142990",
49835
+ // "clientOrderId":"183270218784142990",
49836
+ // "symbol":"ADA_USDT",
49837
+ // "side":"buy",
49838
+ // "orderMode":"spot",
49839
+ // "type":"market",
49840
+ // "price":"0.245948",
49841
+ // "size":"20.71",
49842
+ // "notional":"5.09358308",
49843
+ // "fee":"0.00509358",
49844
+ // "feeCoinName":"USDT",
49845
+ // "tradeRole":"taker",
49846
+ // "createTime":1695658457836,
49847
+ // }
49843
49848
  //
49844
49849
  // swap: fetchMyTrades
49845
49850
  //
49846
- // {
49847
- // "order_id": "230930336848609",
49848
- // "trade_id": "6212604014",
49849
- // "symbol": "BTCUSDT",
49850
- // "side": 3,
49851
- // "price": "26910.4",
49852
- // "vol": "1",
49853
- // "exec_type": "Taker",
49854
- // "profit": false,
49855
- // "create_time": 1695961596692,
49856
- // "realised_profit": "-0.0003",
49857
- // "paid_fees": "0.01614624"
49858
- // }
49851
+ // {
49852
+ // "order_id": "230930336848609",
49853
+ // "trade_id": "6212604014",
49854
+ // "symbol": "BTCUSDT",
49855
+ // "side": 3,
49856
+ // "price": "26910.4",
49857
+ // "vol": "1",
49858
+ // "exec_type": "Taker",
49859
+ // "profit": false,
49860
+ // "create_time": 1695961596692,
49861
+ // "realised_profit": "-0.0003",
49862
+ // "paid_fees": "0.01614624"
49863
+ // }
49864
+ //
49865
+ // ws swap
49866
+ //
49867
+ // {
49868
+ // 'fee': '-0.000044502',
49869
+ // 'feeCcy': 'USDT',
49870
+ // 'fillPrice': '74.17',
49871
+ // 'fillQty': '1',
49872
+ // 'lastTradeID': 6802340762
49873
+ // }
49859
49874
  //
49860
49875
  const timestamp = this.safeIntegerN(trade, ['order_time', 'createTime', 'create_time']);
49861
49876
  const isPublicTrade = ('order_time' in trade);
@@ -49869,7 +49884,7 @@ class bitmart extends _abstract_bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
49869
49884
  side = this.safeString(trade, 'type');
49870
49885
  }
49871
49886
  else {
49872
- amount = this.safeString2(trade, 'size', 'vol');
49887
+ amount = this.safeStringN(trade, ['size', 'vol', 'fillQty']);
49873
49888
  cost = this.safeString(trade, 'notional');
49874
49889
  type = this.safeString(trade, 'type');
49875
49890
  side = this.parseOrderSide(this.safeString(trade, 'side'));
@@ -49891,14 +49906,14 @@ class bitmart extends _abstract_bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
49891
49906
  }
49892
49907
  return this.safeTrade({
49893
49908
  'info': trade,
49894
- 'id': this.safeString2(trade, 'tradeId', 'trade_id'),
49909
+ 'id': this.safeStringN(trade, ['tradeId', 'trade_id', 'lastTradeID']),
49895
49910
  'order': this.safeString2(trade, 'orderId', 'order_id'),
49896
49911
  'timestamp': timestamp,
49897
49912
  'datetime': this.iso8601(timestamp),
49898
49913
  'symbol': market['symbol'],
49899
49914
  'type': type,
49900
49915
  'side': side,
49901
- 'price': this.safeString(trade, 'price'),
49916
+ 'price': this.safeString2(trade, 'price', 'fillPrice'),
49902
49917
  'amount': amount,
49903
49918
  'cost': cost,
49904
49919
  'takerOrMaker': this.safeStringLower2(trade, 'tradeRole', 'exec_type'),
@@ -49952,38 +49967,45 @@ class bitmart extends _abstract_bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
49952
49967
  parseOHLCV(ohlcv, market = undefined) {
49953
49968
  //
49954
49969
  // spot
49955
- //
49956
- // [
49957
- // "1699512060", // timestamp
49958
- // "36746.49", // open
49959
- // "36758.71", // high
49960
- // "36736.13", // low
49961
- // "36755.99", // close
49962
- // "2.83965", // base volume
49963
- // "104353.57" // quote volume
49964
- // ]
49970
+ // [
49971
+ // "1699512060", // timestamp
49972
+ // "36746.49", // open
49973
+ // "36758.71", // high
49974
+ // "36736.13", // low
49975
+ // "36755.99", // close
49976
+ // "2.83965", // base volume
49977
+ // "104353.57" // quote volume
49978
+ // ]
49965
49979
  //
49966
49980
  // swap
49967
- //
49968
- // {
49969
- // "low_price": "20090.3",
49970
- // "high_price": "20095.5",
49971
- // "open_price": "20092.6",
49972
- // "close_price": "20091.4",
49973
- // "volume": "8748",
49974
- // "timestamp": 1665002281
49975
- // }
49981
+ // {
49982
+ // "low_price": "20090.3",
49983
+ // "high_price": "20095.5",
49984
+ // "open_price": "20092.6",
49985
+ // "close_price": "20091.4",
49986
+ // "volume": "8748",
49987
+ // "timestamp": 1665002281
49988
+ // }
49976
49989
  //
49977
49990
  // ws
49991
+ // [
49992
+ // 1631056350, // timestamp
49993
+ // "46532.83", // open
49994
+ // "46555.71", // high
49995
+ // "46511.41", // low
49996
+ // "46555.71", // close
49997
+ // "0.25", // volume
49998
+ // ]
49978
49999
  //
49979
- // [
49980
- // 1631056350, // timestamp
49981
- // "46532.83", // open
49982
- // "46555.71", // high
49983
- // "46511.41", // low
49984
- // "46555.71", // close
49985
- // "0.25", // volume
49986
- // ]
50000
+ // ws swap
50001
+ // {
50002
+ // "symbol":"BTCUSDT",
50003
+ // "o":"146.24",
50004
+ // "h":"146.24",
50005
+ // "l":"146.24",
50006
+ // "c":"146.24",
50007
+ // "v":"146"
50008
+ // }
49987
50009
  //
49988
50010
  if (Array.isArray(ohlcv)) {
49989
50011
  return [
@@ -49997,12 +50019,12 @@ class bitmart extends _abstract_bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
49997
50019
  }
49998
50020
  else {
49999
50021
  return [
50000
- this.safeTimestamp(ohlcv, 'timestamp'),
50001
- this.safeNumber(ohlcv, 'open_price'),
50002
- this.safeNumber(ohlcv, 'high_price'),
50003
- this.safeNumber(ohlcv, 'low_price'),
50004
- this.safeNumber(ohlcv, 'close_price'),
50005
- this.safeNumber(ohlcv, 'volume'),
50022
+ this.safeTimestamp2(ohlcv, 'timestamp', 'ts'),
50023
+ this.safeNumber2(ohlcv, 'open_price', 'o'),
50024
+ this.safeNumber2(ohlcv, 'high_price', 'h'),
50025
+ this.safeNumber2(ohlcv, 'low_price', 'l'),
50026
+ this.safeNumber2(ohlcv, 'close_price', 'c'),
50027
+ this.safeNumber2(ohlcv, 'volume', 'v'),
50006
50028
  ];
50007
50029
  }
50008
50030
  }
@@ -56840,11 +56862,11 @@ class bitopro extends _abstract_bitopro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
56840
56862
  //
56841
56863
  return this.parseOrders(orders, market, since, limit);
56842
56864
  }
56843
- fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
56865
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
56844
56866
  const request = {
56845
56867
  'statusKind': 'OPEN',
56846
56868
  };
56847
- return this.fetchOrders(symbol, since, limit, this.extend(request, params));
56869
+ return await this.fetchOrders(symbol, since, limit, this.extend(request, params));
56848
56870
  }
56849
56871
  async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
56850
56872
  /**
@@ -81908,9 +81930,11 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
81908
81930
  else if (symbolsLength === 1) {
81909
81931
  symbol = symbols[0];
81910
81932
  }
81933
+ symbols = this.marketSymbols(symbols);
81911
81934
  }
81912
81935
  else if (symbols !== undefined) {
81913
81936
  symbol = symbols;
81937
+ symbols = [this.symbol(symbol)];
81914
81938
  }
81915
81939
  await this.loadMarkets();
81916
81940
  const [enableUnifiedMargin, enableUnifiedAccount] = await this.isUnifiedEnabled();
@@ -81920,14 +81944,12 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
81920
81944
  let isUsdcSettled = false;
81921
81945
  if (symbol !== undefined) {
81922
81946
  market = this.market(symbol);
81947
+ symbol = market['symbol'];
81923
81948
  request['symbol'] = market['id'];
81924
81949
  isUsdcSettled = market['settle'] === 'USDC';
81925
81950
  }
81926
81951
  let type = undefined;
81927
81952
  [type, params] = this.getBybitType('fetchPositions', market, params);
81928
- if (type === 'spot') {
81929
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' fetchPositions() not support spot market');
81930
- }
81931
81953
  if (type === 'linear' || type === 'inverse') {
81932
81954
  const baseCoin = this.safeString(params, 'baseCoin');
81933
81955
  if (type === 'linear') {
@@ -91561,6 +91583,7 @@ class coinex extends _abstract_coinex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
91561
91583
  // 20 per 2 seconds => 10 per second => weight = 40
91562
91584
  'rateLimit': 2.5,
91563
91585
  'pro': true,
91586
+ 'certified': true,
91564
91587
  'has': {
91565
91588
  'CORS': undefined,
91566
91589
  'spot': true,
@@ -101222,6 +101245,9 @@ class coinsph extends _abstract_coinsph_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
101222
101245
  'closeAllPositions': false,
101223
101246
  'closePosition': false,
101224
101247
  'createDepositAddress': false,
101248
+ 'createMarketBuyOrderWithCost': true,
101249
+ 'createMarketOrderWithCost': false,
101250
+ 'createMarketSellOrderWithCost': false,
101225
101251
  'createOrder': true,
101226
101252
  'createPostOnlyOrder': false,
101227
101253
  'createReduceOnlyOrder': false,
@@ -102249,12 +102275,14 @@ class coinsph extends _abstract_coinsph_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
102249
102275
  * @method
102250
102276
  * @name coinsph#createOrder
102251
102277
  * @description create a trade order
102278
+ * @see https://coins-docs.github.io/rest-api/#new-order--trade
102252
102279
  * @param {string} symbol unified symbol of the market to create an order in
102253
102280
  * @param {string} type 'market', 'limit', 'stop_loss', 'take_profit', 'stop_loss_limit', 'take_profit_limit' or 'limit_maker'
102254
102281
  * @param {string} side 'buy' or 'sell'
102255
102282
  * @param {float} amount how much of currency you want to trade in units of base currency
102256
102283
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
102257
102284
  * @param {object} [params] extra parameters specific to the exchange API endpoint
102285
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount for market buy orders
102258
102286
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
102259
102287
  */
102260
102288
  // todo: add test order low priority
@@ -102290,24 +102318,29 @@ class coinsph extends _abstract_coinsph_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
102290
102318
  request['quantity'] = this.amountToPrecision(symbol, amount);
102291
102319
  }
102292
102320
  else if (orderSide === 'BUY') {
102293
- const quoteOrderQty = this.safeNumber2(params, 'cost', 'quoteOrderQty');
102294
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
102295
- if (quoteOrderQty !== undefined) {
102296
- amount = quoteOrderQty;
102321
+ let quoteAmount = undefined;
102322
+ let createMarketBuyOrderRequiresPrice = true;
102323
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
102324
+ const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
102325
+ params = this.omit(params, 'cost');
102326
+ if (cost !== undefined) {
102327
+ quoteAmount = this.costToPrecision(symbol, cost);
102297
102328
  }
102298
102329
  else if (createMarketBuyOrderRequiresPrice) {
102299
102330
  if (price === undefined) {
102300
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false to supply the cost in the amount argument (the exchange-specific behaviour)");
102331
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
102301
102332
  }
102302
102333
  else {
102303
102334
  const amountString = this.numberToString(amount);
102304
102335
  const priceString = this.numberToString(price);
102305
- const quoteAmount = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString);
102306
- amount = this.parseNumber(quoteAmount);
102336
+ const costRequest = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString);
102337
+ quoteAmount = this.costToPrecision(symbol, costRequest);
102307
102338
  }
102308
102339
  }
102309
- request['quoteOrderQty'] = this.costToPrecision(symbol, amount);
102310
- params = this.omit(params, 'cost', 'quoteOrderQty');
102340
+ else {
102341
+ quoteAmount = this.costToPrecision(symbol, amount);
102342
+ }
102343
+ request['quoteOrderQty'] = quoteAmount;
102311
102344
  }
102312
102345
  }
102313
102346
  if (orderType === 'STOP_LOSS' || orderType === 'STOP_LOSS_LIMIT' || orderType === 'TAKE_PROFIT' || orderType === 'TAKE_PROFIT_LIMIT') {
@@ -136645,6 +136678,9 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
136645
136678
  'cancelOrder': true,
136646
136679
  'cancelOrders': true,
136647
136680
  'createDepositAddress': undefined,
136681
+ 'createMarketBuyOrderWithCost': true,
136682
+ 'createMarketOrderWithCost': false,
136683
+ 'createMarketSellOrderWithCost': false,
136648
136684
  'createOrder': true,
136649
136685
  'createOrders': true,
136650
136686
  'createReduceOnlyOrder': false,
@@ -141447,6 +141483,25 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
141447
141483
  'trades': trades,
141448
141484
  }, market);
141449
141485
  }
141486
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
141487
+ /**
141488
+ * @method
141489
+ * @name htx#createMarketBuyOrderWithCost
141490
+ * @description create a market buy order by providing the symbol and cost
141491
+ * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
141492
+ * @param {string} symbol unified symbol of the market to create an order in
141493
+ * @param {float} cost how much you want to trade in units of the quote currency
141494
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
141495
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
141496
+ */
141497
+ await this.loadMarkets();
141498
+ const market = this.market(symbol);
141499
+ if (!market['spot']) {
141500
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
141501
+ }
141502
+ params['createMarketBuyOrderRequiresPrice'] = false;
141503
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
141504
+ }
141450
141505
  async createSpotOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
141451
141506
  /**
141452
141507
  * @method
@@ -141460,6 +141515,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
141460
141515
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
141461
141516
  * @param {object} [params] extra parameters specific to the exchange API endpoint
141462
141517
  * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
141518
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount for market buy orders
141463
141519
  * @returns {object} request to be sent to the exchange
141464
141520
  */
141465
141521
  await this.loadMarkets();
@@ -141534,9 +141590,17 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
141534
141590
  request['source'] = 'c2c-margin-api';
141535
141591
  }
141536
141592
  if ((orderType === 'market') && (side === 'buy')) {
141537
- if (this.options['createMarketBuyOrderRequiresPrice']) {
141593
+ let quoteAmount = undefined;
141594
+ let createMarketBuyOrderRequiresPrice = true;
141595
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
141596
+ const cost = this.safeNumber(params, 'cost');
141597
+ params = this.omit(params, 'cost');
141598
+ if (cost !== undefined) {
141599
+ quoteAmount = this.amountToPrecision(symbol, cost);
141600
+ }
141601
+ else if (createMarketBuyOrderRequiresPrice) {
141538
141602
  if (price === undefined) {
141539
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + " market buy order requires price argument to calculate cost (total amount of quote currency to spend for buying, amount * price). To switch off this warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = false. Make sure you know what you're doing.");
141603
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
141540
141604
  }
141541
141605
  else {
141542
141606
  // despite that cost = amount * price is in quote currency and should have quote precision
@@ -141547,12 +141611,13 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
141547
141611
  // we use amountToPrecision here because the exchange requires cost in base precision
141548
141612
  const amountString = this.numberToString(amount);
141549
141613
  const priceString = this.numberToString(price);
141550
- request['amount'] = this.costToPrecision(symbol, _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString));
141614
+ quoteAmount = this.amountToPrecision(symbol, _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString));
141551
141615
  }
141552
141616
  }
141553
141617
  else {
141554
- request['amount'] = this.costToPrecision(symbol, amount);
141618
+ quoteAmount = this.amountToPrecision(symbol, amount);
141555
141619
  }
141620
+ request['amount'] = quoteAmount;
141556
141621
  }
141557
141622
  else {
141558
141623
  request['amount'] = this.amountToPrecision(symbol, amount);
@@ -141684,6 +141749,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
141684
141749
  * @param {bool} [params.postOnly] *contract only* true or false
141685
141750
  * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
141686
141751
  * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
141752
+ * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
141687
141753
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
141688
141754
  */
141689
141755
  await this.loadMarkets();
@@ -145403,6 +145469,9 @@ class huobijp extends _abstract_huobijp_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
145403
145469
  'cancelAllOrders': true,
145404
145470
  'cancelOrder': true,
145405
145471
  'cancelOrders': true,
145472
+ 'createMarketBuyOrderWithCost': true,
145473
+ 'createMarketOrderWithCost': false,
145474
+ 'createMarketSellOrderWithCost': false,
145406
145475
  'createOrder': true,
145407
145476
  'createStopLimitOrder': false,
145408
145477
  'createStopMarketOrder': false,
@@ -146727,6 +146796,24 @@ class huobijp extends _abstract_huobijp_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
146727
146796
  'trades': undefined,
146728
146797
  }, market);
146729
146798
  }
146799
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
146800
+ /**
146801
+ * @method
146802
+ * @name huobijp#createMarketBuyOrderWithCost
146803
+ * @description create a market buy order by providing the symbol and cost
146804
+ * @param {string} symbol unified symbol of the market to create an order in
146805
+ * @param {float} cost how much you want to trade in units of the quote currency
146806
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
146807
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
146808
+ */
146809
+ await this.loadMarkets();
146810
+ const market = this.market(symbol);
146811
+ if (!market['spot']) {
146812
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
146813
+ }
146814
+ params['createMarketBuyOrderRequiresPrice'] = false;
146815
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
146816
+ }
146730
146817
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
146731
146818
  /**
146732
146819
  * @method
@@ -146759,9 +146846,17 @@ class huobijp extends _abstract_huobijp_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
146759
146846
  }
146760
146847
  params = this.omit(params, ['clientOrderId', 'client-order-id']);
146761
146848
  if ((type === 'market') && (side === 'buy')) {
146762
- if (this.options['createMarketBuyOrderRequiresPrice']) {
146849
+ let quoteAmount = undefined;
146850
+ let createMarketBuyOrderRequiresPrice = true;
146851
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
146852
+ const cost = this.safeNumber(params, 'cost');
146853
+ params = this.omit(params, 'cost');
146854
+ if (cost !== undefined) {
146855
+ quoteAmount = this.amountToPrecision(symbol, cost);
146856
+ }
146857
+ else if (createMarketBuyOrderRequiresPrice) {
146763
146858
  if (price === undefined) {
146764
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + " market buy order requires price argument to calculate cost (total amount of quote currency to spend for buying, amount * price). To switch off this warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = false. Make sure you know what you're doing.");
146859
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
146765
146860
  }
146766
146861
  else {
146767
146862
  // despite that cost = amount * price is in quote currency and should have quote precision
@@ -146772,13 +146867,13 @@ class huobijp extends _abstract_huobijp_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
146772
146867
  // we use amountToPrecision here because the exchange requires cost in base precision
146773
146868
  const amountString = this.numberToString(amount);
146774
146869
  const priceString = this.numberToString(price);
146775
- const baseAmount = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString);
146776
- request['amount'] = this.costToPrecision(symbol, baseAmount);
146870
+ quoteAmount = this.amountToPrecision(symbol, _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMul(amountString, priceString));
146777
146871
  }
146778
146872
  }
146779
146873
  else {
146780
- request['amount'] = this.costToPrecision(symbol, amount);
146874
+ quoteAmount = this.amountToPrecision(symbol, amount);
146781
146875
  }
146876
+ request['amount'] = quoteAmount;
146782
146877
  }
146783
146878
  else {
146784
146879
  request['amount'] = this.amountToPrecision(symbol, amount);
@@ -161265,9 +161360,6 @@ class kucoinfutures extends _abstract_kucoinfutures_js__WEBPACK_IMPORTED_MODULE_
161265
161360
  orderbook['nonce'] = this.safeInteger(data, 'sequence');
161266
161361
  return orderbook;
161267
161362
  }
161268
- async fetchL3OrderBook(symbol, limit = undefined, params = {}) {
161269
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' fetchL3OrderBook() is not supported yet');
161270
- }
161271
161363
  async fetchTicker(symbol, params = {}) {
161272
161364
  /**
161273
161365
  * @method
@@ -213296,12 +213388,14 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
213296
213388
  /* harmony import */ var _bitmart_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3718);
213297
213389
  /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6689);
213298
213390
  /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3020);
213299
- /* harmony import */ var _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1372);
213391
+ /* harmony import */ var _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1372);
213392
+ /* harmony import */ var _base_ws_OrderBookSide_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(416);
213300
213393
  // ---------------------------------------------------------------------------
213301
213394
 
213302
213395
 
213303
213396
 
213304
213397
 
213398
+
213305
213399
  // ---------------------------------------------------------------------------
213306
213400
  class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
213307
213401
  describe() {
@@ -213315,24 +213409,38 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213315
213409
  'cancelOrdersWs': false,
213316
213410
  'cancelAllOrdersWs': false,
213317
213411
  'ws': true,
213412
+ 'watchBalance': true,
213318
213413
  'watchTicker': true,
213414
+ 'watchTickers': true,
213319
213415
  'watchOrderBook': true,
213320
213416
  'watchOrders': true,
213321
213417
  'watchTrades': true,
213322
213418
  'watchOHLCV': true,
213419
+ 'watchPosition': 'emulated',
213420
+ 'watchPositions': true,
213323
213421
  },
213324
213422
  'urls': {
213325
213423
  'api': {
213326
213424
  'ws': {
213327
- 'public': 'wss://ws-manager-compress.{hostname}/api?protocol=1.1',
213328
- 'private': 'wss://ws-manager-compress.{hostname}/user?protocol=1.1',
213425
+ 'spot': {
213426
+ 'public': 'wss://ws-manager-compress.{hostname}/api?protocol=1.1',
213427
+ 'private': 'wss://ws-manager-compress.{hostname}/user?protocol=1.1',
213428
+ },
213429
+ 'swap': {
213430
+ 'public': 'wss://openapi-ws.{hostname}/api?protocol=1.1',
213431
+ 'private': 'wss://openapi-ws.{hostname}/user?protocol=1.1',
213432
+ },
213329
213433
  },
213330
213434
  },
213331
213435
  },
213332
213436
  'options': {
213333
213437
  'defaultType': 'spot',
213438
+ 'watchBalance': {
213439
+ 'fetchBalanceSnapshot': true,
213440
+ 'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
213441
+ },
213334
213442
  'watchOrderBook': {
213335
- 'depth': 'depth5', // depth5, depth20, depth50
213443
+ 'depth': 'depth50', // depth5, depth20, depth50
213336
213444
  },
213337
213445
  'ws': {
213338
213446
  'inflate': true,
@@ -213358,33 +213466,166 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213358
213466
  },
213359
213467
  });
213360
213468
  }
213361
- async subscribe(channel, symbol, params = {}) {
213362
- await this.loadMarkets();
213469
+ async subscribe(channel, symbol, type, params = {}) {
213363
213470
  const market = this.market(symbol);
213364
- const url = this.implodeHostname(this.urls['api']['ws']['public']);
213365
- const messageHash = market['type'] + '/' + channel + ':' + market['id'];
213366
- const request = {
213367
- 'op': 'subscribe',
213368
- 'args': [messageHash],
213369
- };
213471
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
213472
+ let request = {};
213473
+ let messageHash = undefined;
213474
+ if (type === 'spot') {
213475
+ messageHash = 'spot/' + channel + ':' + market['id'];
213476
+ request = {
213477
+ 'op': 'subscribe',
213478
+ 'args': [messageHash],
213479
+ };
213480
+ }
213481
+ else {
213482
+ messageHash = 'futures/' + channel + ':' + market['id'];
213483
+ request = {
213484
+ 'action': 'subscribe',
213485
+ 'args': [messageHash],
213486
+ };
213487
+ }
213370
213488
  return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213371
213489
  }
213372
- async subscribePrivate(channel, symbol, params = {}) {
213490
+ async watchBalance(params = {}) {
213491
+ /**
213492
+ * @method
213493
+ * @name bitmart#watchBalance
213494
+ * @see https://developer-pro.bitmart.com/en/spot/#private-balance-change
213495
+ * @see https://developer-pro.bitmart.com/en/futures/#private-assets-channel
213496
+ * @description watch balance and get the amount of funds available for trading or funds locked in orders
213497
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
213498
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
213499
+ */
213373
213500
  await this.loadMarkets();
213374
- const market = this.market(symbol);
213375
- const url = this.implodeHostname(this.urls['api']['ws']['private']);
213376
- const messageHash = channel + ':' + market['id'];
213377
- await this.authenticate();
213378
- const request = {
213379
- 'op': 'subscribe',
213380
- 'args': [messageHash],
213381
- };
213501
+ let type = 'spot';
213502
+ [type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
213503
+ await this.authenticate(type, params);
213504
+ let request = {};
213505
+ if (type === 'spot') {
213506
+ request = {
213507
+ 'op': 'subscribe',
213508
+ 'args': ['spot/user/balance:BALANCE_UPDATE'],
213509
+ };
213510
+ }
213511
+ else {
213512
+ request = {
213513
+ 'action': 'subscribe',
213514
+ 'args': ['futures/asset:USDT', 'futures/asset:BTC', 'futures/asset:ETH'],
213515
+ };
213516
+ }
213517
+ const messageHash = 'balance:' + type;
213518
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
213519
+ const client = this.client(url);
213520
+ this.setBalanceCache(client, type);
213521
+ const fetchBalanceSnapshot = this.handleOptionAndParams(this.options, 'watchBalance', 'fetchBalanceSnapshot', true);
213522
+ const awaitBalanceSnapshot = this.handleOptionAndParams(this.options, 'watchBalance', 'awaitBalanceSnapshot', false);
213523
+ if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
213524
+ await client.future(type + ':fetchBalanceSnapshot');
213525
+ }
213382
213526
  return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213383
213527
  }
213528
+ setBalanceCache(client, type) {
213529
+ if (type in client.subscriptions) {
213530
+ return undefined;
213531
+ }
213532
+ const options = this.safeValue(this.options, 'watchBalance');
213533
+ const fetchBalanceSnapshot = this.handleOptionAndParams(options, 'watchBalance', 'fetchBalanceSnapshot', true);
213534
+ if (fetchBalanceSnapshot) {
213535
+ const messageHash = type + ':fetchBalanceSnapshot';
213536
+ if (!(messageHash in client.futures)) {
213537
+ client.future(messageHash);
213538
+ this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
213539
+ }
213540
+ }
213541
+ else {
213542
+ this.balance[type] = {};
213543
+ }
213544
+ }
213545
+ async loadBalanceSnapshot(client, messageHash, type) {
213546
+ const response = await this.fetchBalance({ 'type': type });
213547
+ this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
213548
+ // don't remove the future from the .futures cache
213549
+ const future = client.futures[messageHash];
213550
+ future.resolve();
213551
+ client.resolve(this.balance[type], 'balance:' + type);
213552
+ }
213553
+ handleBalance(client, message) {
213554
+ //
213555
+ // spot
213556
+ // {
213557
+ // "data":[
213558
+ // {
213559
+ // "balance_details":[
213560
+ // {
213561
+ // "av_bal":"0.206000000000000000000000000000",
213562
+ // "ccy":"LTC",
213563
+ // "fz_bal":"0.100000000000000000000000000000"
213564
+ // }
213565
+ // ],
213566
+ // "event_time":"1701632345415",
213567
+ // "event_type":"TRANSACTION_COMPLETED"
213568
+ // }
213569
+ // ],
213570
+ // "table":"spot/user/balance"
213571
+ // }
213572
+ // swap
213573
+ // {
213574
+ // group: 'futures/asset:USDT',
213575
+ // data: {
213576
+ // currency: 'USDT',
213577
+ // available_balance: '37.19688649135',
213578
+ // position_deposit: '0.788687546',
213579
+ // frozen_balance: '0'
213580
+ // }
213581
+ // }
213582
+ //
213583
+ const channel = this.safeString2(message, 'table', 'group');
213584
+ const data = this.safeValue(message, 'data');
213585
+ if (data === undefined) {
213586
+ return;
213587
+ }
213588
+ const isSpot = (channel.indexOf('spot') >= 0);
213589
+ const type = isSpot ? 'spot' : 'swap';
213590
+ this.balance['info'] = message;
213591
+ if (isSpot) {
213592
+ if (!Array.isArray(data)) {
213593
+ return;
213594
+ }
213595
+ for (let i = 0; i < data.length; i++) {
213596
+ const timestamp = this.safeInteger(message, 'event_time');
213597
+ this.balance['timestamp'] = timestamp;
213598
+ this.balance['datetime'] = this.iso8601(timestamp);
213599
+ const balanceDetails = this.safeValue(data[i], 'balance_details', []);
213600
+ for (let ii = 0; ii < balanceDetails.length; ii++) {
213601
+ const rawBalance = balanceDetails[i];
213602
+ const account = this.account();
213603
+ const currencyId = this.safeString(rawBalance, 'ccy');
213604
+ const code = this.safeCurrencyCode(currencyId);
213605
+ account['free'] = this.safeString(rawBalance, 'av_bal');
213606
+ account['total'] = this.safeString(rawBalance, 'fz_bal');
213607
+ this.balance[code] = account;
213608
+ }
213609
+ }
213610
+ }
213611
+ else {
213612
+ const currencyId = this.safeString(data, 'currency');
213613
+ const code = this.safeCurrencyCode(currencyId);
213614
+ const account = this.account();
213615
+ account['free'] = this.safeString(data, 'available_balance');
213616
+ account['used'] = this.safeString(data, 'frozen_balance');
213617
+ this.balance[type][code] = account;
213618
+ }
213619
+ this.balance[type] = this.safeBalance(this.balance[type]);
213620
+ const messageHash = 'balance:' + type;
213621
+ client.resolve(this.balance[type], messageHash);
213622
+ }
213384
213623
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
213385
213624
  /**
213386
213625
  * @method
213387
213626
  * @name bitmart#watchTrades
213627
+ * @see https://developer-pro.bitmart.com/en/spot/#public-trade-channel
213628
+ * @see https://developer-pro.bitmart.com/en/futures/#public-trade-channel
213388
213629
  * @description get the list of most recent trades for a particular symbol
213389
213630
  * @param {string} symbol unified symbol of the market to fetch trades for
213390
213631
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
@@ -213394,7 +213635,10 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213394
213635
  */
213395
213636
  await this.loadMarkets();
213396
213637
  symbol = this.symbol(symbol);
213397
- const trades = await this.subscribe('trade', symbol, params);
213638
+ const market = this.market(symbol);
213639
+ let type = 'spot';
213640
+ [type, params] = this.handleMarketTypeAndParams('watchTrades', market, params);
213641
+ const trades = await this.subscribe('trade', symbol, type, params);
213398
213642
  if (this.newUpdates) {
213399
213643
  limit = trades.getLimit(symbol, limit);
213400
213644
  }
@@ -213404,17 +213648,64 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213404
213648
  /**
213405
213649
  * @method
213406
213650
  * @name bitmart#watchTicker
213651
+ * @see https://developer-pro.bitmart.com/en/spot/#public-ticker-channel
213407
213652
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
213408
213653
  * @param {string} symbol unified symbol of the market to fetch the ticker for
213409
213654
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213410
213655
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
213411
213656
  */
213412
- return await this.subscribe('ticker', symbol, params);
213657
+ await this.loadMarkets();
213658
+ symbol = this.symbol(symbol);
213659
+ const market = this.market(symbol);
213660
+ let type = 'spot';
213661
+ [type, params] = this.handleMarketTypeAndParams('watchTicker', market, params);
213662
+ if (type === 'swap') {
213663
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchTicker() does not support ' + type + ' markets. Use watchTickers() instead');
213664
+ }
213665
+ return await this.subscribe('ticker', symbol, type, params);
213666
+ }
213667
+ async watchTickers(symbols = undefined, params = {}) {
213668
+ /**
213669
+ * @method
213670
+ * @name bitmart#watchTickers
213671
+ * @see https://developer-pro.bitmart.com/en/futures/#overview
213672
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
213673
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
213674
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
213675
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
213676
+ */
213677
+ await this.loadMarkets();
213678
+ const market = this.getMarketFromSymbols(symbols);
213679
+ let type = 'spot';
213680
+ [type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
213681
+ symbols = this.marketSymbols(symbols);
213682
+ if (type === 'spot') {
213683
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchTickers() does not support ' + type + ' markets. Use watchTicker() instead');
213684
+ }
213685
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
213686
+ if (type === 'swap') {
213687
+ type = 'futures';
213688
+ }
213689
+ let messageHash = 'tickers';
213690
+ if (symbols !== undefined) {
213691
+ messageHash += '::' + symbols.join(',');
213692
+ }
213693
+ const request = {
213694
+ 'action': 'subscribe',
213695
+ 'args': ['futures/ticker'],
213696
+ };
213697
+ const newTickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213698
+ if (this.newUpdates) {
213699
+ return newTickers;
213700
+ }
213701
+ return this.filterByArray(this.tickers, 'symbol', symbols);
213413
213702
  }
213414
213703
  async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
213415
213704
  /**
213416
213705
  * @method
213417
213706
  * @name bitmart#watchOrders
213707
+ * @see https://developer-pro.bitmart.com/en/spot/#private-order-channel
213708
+ * @see https://developer-pro.bitmart.com/en/futures/#private-order-channel
213418
213709
  * @description watches information on multiple orders made by the user
213419
213710
  * @param {string} symbol unified market symbol of the market orders were made in
213420
213711
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -213422,196 +213713,626 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213422
213713
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213423
213714
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
213424
213715
  */
213425
- if (symbol === undefined) {
213426
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrders() requires a symbol argument');
213427
- }
213428
213716
  await this.loadMarkets();
213429
- const market = this.market(symbol);
213430
- symbol = market['symbol'];
213431
- if (market['type'] !== 'spot') {
213432
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrders supports spot markets only');
213717
+ let market = undefined;
213718
+ let messageHash = 'orders';
213719
+ if (symbol !== undefined) {
213720
+ symbol = this.symbol(symbol);
213721
+ market = this.market(symbol);
213722
+ messageHash = 'orders::' + symbol;
213723
+ }
213724
+ let type = 'spot';
213725
+ [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
213726
+ await this.authenticate(type, params);
213727
+ let request = undefined;
213728
+ if (type === 'spot') {
213729
+ if (symbol === undefined) {
213730
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrders() requires a symbol argument for spot markets');
213731
+ }
213732
+ request = {
213733
+ 'op': 'subscribe',
213734
+ 'args': ['spot/user/order:' + market['id']],
213735
+ };
213736
+ }
213737
+ else {
213738
+ request = {
213739
+ 'action': 'subscribe',
213740
+ 'args': ['futures/order'],
213741
+ };
213433
213742
  }
213434
- const channel = 'spot/user/order';
213435
- const orders = await this.subscribePrivate(channel, symbol, params);
213743
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
213744
+ const newOrders = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213436
213745
  if (this.newUpdates) {
213437
- limit = orders.getLimit(symbol, limit);
213746
+ return newOrders;
213438
213747
  }
213439
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
213748
+ return this.filterBySymbolSinceLimit(this.orders, symbol, since, limit, true);
213440
213749
  }
213441
213750
  handleOrders(client, message) {
213442
213751
  //
213443
- // {
213444
- // "data":[
213445
- // {
213446
- // "symbol": "LTC_USDT",
213447
- // "notional": '',
213448
- // "side": "buy",
213449
- // "last_fill_time": "0",
213450
- // "ms_t": "1646216634000",
213451
- // "type": "limit",
213452
- // "filled_notional": "0.000000000000000000000000000000",
213453
- // "last_fill_price": "0",
213454
- // "size": "0.500000000000000000000000000000",
213455
- // "price": "50.000000000000000000000000000000",
213456
- // "last_fill_count": "0",
213457
- // "filled_size": "0.000000000000000000000000000000",
213458
- // "margin_trading": "0",
213459
- // "state": "8",
213460
- // "order_id": "24807076628",
213461
- // "order_type": "0"
213752
+ // spot
213753
+ // {
213754
+ // "data":[
213755
+ // {
213756
+ // "symbol": "LTC_USDT",
213757
+ // "notional": '',
213758
+ // "side": "buy",
213759
+ // "last_fill_time": "0",
213760
+ // "ms_t": "1646216634000",
213761
+ // "type": "limit",
213762
+ // "filled_notional": "0.000000000000000000000000000000",
213763
+ // "last_fill_price": "0",
213764
+ // "size": "0.500000000000000000000000000000",
213765
+ // "price": "50.000000000000000000000000000000",
213766
+ // "last_fill_count": "0",
213767
+ // "filled_size": "0.000000000000000000000000000000",
213768
+ // "margin_trading": "0",
213769
+ // "state": "8",
213770
+ // "order_id": "24807076628",
213771
+ // "order_type": "0"
213772
+ // }
213773
+ // ],
213774
+ // "table":"spot/user/order"
213775
+ // }
213776
+ // swap
213777
+ // {
213778
+ // "group":"futures/order",
213779
+ // "data":[
213780
+ // {
213781
+ // "action":2,
213782
+ // "order":{
213783
+ // "order_id":"2312045036986775",
213784
+ // "client_order_id":"",
213785
+ // "price":"71.61707928",
213786
+ // "size":"1",
213787
+ // "symbol":"LTCUSDT",
213788
+ // "state":1,
213789
+ // "side":4,
213790
+ // "type":"market",
213791
+ // "leverage":"1",
213792
+ // "open_type":"cross",
213793
+ // "deal_avg_price":"0",
213794
+ // "deal_size":"0",
213795
+ // "create_time":1701625324646,
213796
+ // "update_time":1701625324640,
213797
+ // "plan_order_id":"",
213798
+ // "last_trade":null
213799
+ // }
213462
213800
  // }
213463
- // ],
213464
- // "table":"spot/user/order"
213465
- // }
213801
+ // ]
213802
+ // }
213466
213803
  //
213467
- const channel = this.safeString(message, 'table');
213468
- const orders = this.safeValue(message, 'data', []);
213804
+ const orders = this.safeValue(message, 'data');
213805
+ if (orders === undefined) {
213806
+ return;
213807
+ }
213469
213808
  const ordersLength = orders.length;
213809
+ const newOrders = [];
213810
+ const symbols = {};
213470
213811
  if (ordersLength > 0) {
213471
213812
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
213472
213813
  if (this.orders === undefined) {
213473
213814
  this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
213474
213815
  }
213475
213816
  const stored = this.orders;
213476
- const marketIds = [];
213477
213817
  for (let i = 0; i < orders.length; i++) {
213478
213818
  const order = this.parseWsOrder(orders[i]);
213479
213819
  stored.append(order);
213820
+ newOrders.push(order);
213480
213821
  const symbol = order['symbol'];
213481
- const market = this.market(symbol);
213482
- marketIds.push(market['id']);
213483
- }
213484
- for (let i = 0; i < marketIds.length; i++) {
213485
- const messageHash = channel + ':' + marketIds[i];
213486
- client.resolve(this.orders, messageHash);
213822
+ symbols[symbol] = true;
213487
213823
  }
213488
213824
  }
213825
+ const newOrderSymbols = Object.keys(symbols);
213826
+ for (let i = 0; i < newOrderSymbols.length; i++) {
213827
+ const symbol = newOrderSymbols[i];
213828
+ this.resolvePromiseIfMessagehashMatches(client, 'orders::', symbol, newOrders);
213829
+ }
213830
+ client.resolve(newOrders, 'orders');
213489
213831
  }
213490
213832
  parseWsOrder(order, market = undefined) {
213491
213833
  //
213492
- // {
213493
- // "symbol": "LTC_USDT",
213494
- // "notional": '',
213495
- // "side": "buy",
213496
- // "last_fill_time": "0",
213497
- // "ms_t": "1646216634000",
213498
- // "type": "limit",
213499
- // "filled_notional": "0.000000000000000000000000000000",
213500
- // "last_fill_price": "0",
213501
- // "size": "0.500000000000000000000000000000",
213502
- // "price": "50.000000000000000000000000000000",
213503
- // "last_fill_count": "0",
213504
- // "filled_size": "0.000000000000000000000000000000",
213505
- // "margin_trading": "0",
213506
- // "state": "8",
213507
- // "order_id": "24807076628",
213508
- // "order_type": "0"
213509
- // }
213834
+ // spot
213835
+ // {
213836
+ // "symbol": "LTC_USDT",
213837
+ // "notional": '',
213838
+ // "side": "buy",
213839
+ // "last_fill_time": "0",
213840
+ // "ms_t": "1646216634000",
213841
+ // "type": "limit",
213842
+ // "filled_notional": "0.000000000000000000000000000000",
213843
+ // "last_fill_price": "0",
213844
+ // "size": "0.500000000000000000000000000000",
213845
+ // "price": "50.000000000000000000000000000000",
213846
+ // "last_fill_count": "0",
213847
+ // "filled_size": "0.000000000000000000000000000000",
213848
+ // "margin_trading": "0",
213849
+ // "state": "8",
213850
+ // "order_id": "24807076628",
213851
+ // "order_type": "0"
213852
+ // }
213853
+ // swap
213854
+ // {
213855
+ // "action":2,
213856
+ // "order":{
213857
+ // "order_id":"2312045036986775",
213858
+ // "client_order_id":"",
213859
+ // "price":"71.61707928",
213860
+ // "size":"1",
213861
+ // "symbol":"LTCUSDT",
213862
+ // "state":1,
213863
+ // "side":4,
213864
+ // "type":"market",
213865
+ // "leverage":"1",
213866
+ // "open_type":"cross",
213867
+ // "deal_avg_price":"0",
213868
+ // "deal_size":"0",
213869
+ // "create_time":1701625324646,
213870
+ // "update_time":1701625324640,
213871
+ // "plan_order_id":"",
213872
+ // "last_trade":null
213873
+ // }
213874
+ // }
213510
213875
  //
213511
- const marketId = this.safeString(order, 'symbol');
213512
- market = this.safeMarket(marketId, market);
213513
- const id = this.safeString(order, 'order_id');
213514
- const clientOrderId = this.safeString(order, 'clientOid');
213515
- const price = this.safeString(order, 'price');
213516
- const filled = this.safeString(order, 'filled_size');
213517
- const amount = this.safeString(order, 'size');
213518
- const type = this.safeString(order, 'type');
213519
- const rawState = this.safeString(order, 'state');
213520
- const status = this.parseOrderStatusByType(market['type'], rawState);
213521
- const timestamp = this.safeInteger(order, 'ms_t');
213876
+ const action = this.safeNumber(order, 'action');
213877
+ const isSpot = (action === undefined);
213878
+ if (isSpot) {
213879
+ const marketId = this.safeString(order, 'symbol');
213880
+ market = this.safeMarket(marketId, market, '_', 'spot');
213881
+ const id = this.safeString(order, 'order_id');
213882
+ const clientOrderId = this.safeString(order, 'clientOid');
213883
+ const price = this.safeString(order, 'price');
213884
+ const filled = this.safeString(order, 'filled_size');
213885
+ const amount = this.safeString(order, 'size');
213886
+ const type = this.safeString(order, 'type');
213887
+ const rawState = this.safeString(order, 'state');
213888
+ const status = this.parseOrderStatusByType(market['type'], rawState);
213889
+ const timestamp = this.safeInteger(order, 'ms_t');
213890
+ const symbol = market['symbol'];
213891
+ const side = this.safeStringLower(order, 'side');
213892
+ return this.safeOrder({
213893
+ 'info': order,
213894
+ 'symbol': symbol,
213895
+ 'id': id,
213896
+ 'clientOrderId': clientOrderId,
213897
+ 'timestamp': undefined,
213898
+ 'datetime': undefined,
213899
+ 'lastTradeTimestamp': timestamp,
213900
+ 'type': type,
213901
+ 'timeInForce': undefined,
213902
+ 'postOnly': undefined,
213903
+ 'side': side,
213904
+ 'price': price,
213905
+ 'stopPrice': undefined,
213906
+ 'triggerPrice': undefined,
213907
+ 'amount': amount,
213908
+ 'cost': undefined,
213909
+ 'average': undefined,
213910
+ 'filled': filled,
213911
+ 'remaining': undefined,
213912
+ 'status': status,
213913
+ 'fee': undefined,
213914
+ 'trades': undefined,
213915
+ }, market);
213916
+ }
213917
+ else {
213918
+ const orderInfo = this.safeValue(order, 'order');
213919
+ const marketId = this.safeString(orderInfo, 'symbol');
213920
+ const symbol = this.safeSymbol(marketId, market, '', 'swap');
213921
+ const orderId = this.safeString(orderInfo, 'order_id');
213922
+ const timestamp = this.safeInteger(orderInfo, 'create_time');
213923
+ const updatedTimestamp = this.safeInteger(orderInfo, 'update_time');
213924
+ const lastTrade = this.safeValue(orderInfo, 'last_trade');
213925
+ const cachedOrders = this.orders;
213926
+ const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
213927
+ const cachedOrder = this.safeValue(orders, orderId);
213928
+ let trades = undefined;
213929
+ if (cachedOrder !== undefined) {
213930
+ trades = this.safeValue(order, 'trades');
213931
+ }
213932
+ if (lastTrade !== undefined) {
213933
+ if (trades === undefined) {
213934
+ trades = [];
213935
+ }
213936
+ trades.push(lastTrade);
213937
+ }
213938
+ return this.safeOrder({
213939
+ 'info': order,
213940
+ 'symbol': symbol,
213941
+ 'id': orderId,
213942
+ 'clientOrderId': this.safeString(orderInfo, 'client_order_id'),
213943
+ 'timestamp': timestamp,
213944
+ 'datetime': this.iso8601(timestamp),
213945
+ 'lastTradeTimestamp': updatedTimestamp,
213946
+ 'type': this.safeString(orderInfo, 'type'),
213947
+ 'timeInForce': undefined,
213948
+ 'postOnly': undefined,
213949
+ 'side': this.parseWsOrderSide(this.safeString(orderInfo, 'side')),
213950
+ 'price': this.safeString(orderInfo, 'price'),
213951
+ 'stopPrice': undefined,
213952
+ 'triggerPrice': undefined,
213953
+ 'amount': this.safeString(orderInfo, 'size'),
213954
+ 'cost': undefined,
213955
+ 'average': this.safeString(orderInfo, 'deal_avg_price'),
213956
+ 'filled': this.safeString(orderInfo, 'deal_size'),
213957
+ 'remaining': undefined,
213958
+ 'status': this.parseWsOrderStatus(this.safeString(order, 'action')),
213959
+ 'fee': undefined,
213960
+ 'trades': trades,
213961
+ }, market);
213962
+ }
213963
+ }
213964
+ parseWsOrderStatus(statusId) {
213965
+ const statuses = {
213966
+ '1': 'closed',
213967
+ '2': 'open',
213968
+ '3': 'canceled',
213969
+ '4': 'closed',
213970
+ '5': 'canceled',
213971
+ '6': 'open',
213972
+ '7': 'open',
213973
+ '8': 'closed',
213974
+ '9': 'closed', // active adl match deal
213975
+ };
213976
+ return this.safeString(statuses, statusId, statusId);
213977
+ }
213978
+ parseWsOrderSide(sideId) {
213979
+ const sides = {
213980
+ '1': 'buy',
213981
+ '2': 'buy',
213982
+ '3': 'sell',
213983
+ '4': 'sell', // sell_open_short
213984
+ };
213985
+ return this.safeString(sides, sideId, sideId);
213986
+ }
213987
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
213988
+ /**
213989
+ * @method
213990
+ * @name bitmart#watchPositions
213991
+ * @see https://developer-pro.bitmart.com/en/futures/#private-position-channel
213992
+ * @description watch all open positions
213993
+ * @param {string[]|undefined} symbols list of unified market symbols
213994
+ * @param {object} params extra parameters specific to the exchange API endpoint
213995
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
213996
+ */
213997
+ await this.loadMarkets();
213998
+ const type = 'swap';
213999
+ await this.authenticate(type, params);
214000
+ symbols = this.marketSymbols(symbols, 'swap', true, true, false);
214001
+ let messageHash = 'positions';
214002
+ if (symbols !== undefined) {
214003
+ messageHash += '::' + symbols.join(',');
214004
+ }
214005
+ const subscriptionHash = 'futures/position';
214006
+ const request = {
214007
+ 'action': 'subscribe',
214008
+ 'args': ['futures/position'],
214009
+ };
214010
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
214011
+ const newPositions = await this.watch(url, messageHash, this.deepExtend(request, params), subscriptionHash);
214012
+ if (this.newUpdates) {
214013
+ return newPositions;
214014
+ }
214015
+ return this.filterBySymbolsSinceLimit(this.positions, symbols, since, limit);
214016
+ }
214017
+ handlePositions(client, message) {
214018
+ //
214019
+ // {
214020
+ // "group":"futures/position",
214021
+ // "data":[
214022
+ // {
214023
+ // "symbol":"LTCUSDT",
214024
+ // "hold_volume":"5",
214025
+ // "position_type":2,
214026
+ // "open_type":2,
214027
+ // "frozen_volume":"0",
214028
+ // "close_volume":"0",
214029
+ // "hold_avg_price":"71.582",
214030
+ // "close_avg_price":"0",
214031
+ // "open_avg_price":"71.582",
214032
+ // "liquidate_price":"0",
214033
+ // "create_time":1701623327513,
214034
+ // "update_time":1701627620439
214035
+ // },
214036
+ // {
214037
+ // "symbol":"LTCUSDT",
214038
+ // "hold_volume":"6",
214039
+ // "position_type":1,
214040
+ // "open_type":2,
214041
+ // "frozen_volume":"0",
214042
+ // "close_volume":"0",
214043
+ // "hold_avg_price":"71.681666666666666667",
214044
+ // "close_avg_price":"0",
214045
+ // "open_avg_price":"71.681666666666666667",
214046
+ // "liquidate_price":"0",
214047
+ // "create_time":1701621167225,
214048
+ // "update_time":1701628152614
214049
+ // }
214050
+ // ]
214051
+ // }
214052
+ //
214053
+ const data = this.safeValue(message, 'data', []);
214054
+ const cache = this.positions;
214055
+ if (this.positions === undefined) {
214056
+ this.positions = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolBySide */ .tU();
214057
+ }
214058
+ const newPositions = [];
214059
+ for (let i = 0; i < data.length; i++) {
214060
+ const rawPosition = data[i];
214061
+ const position = this.parseWsPosition(rawPosition);
214062
+ newPositions.push(position);
214063
+ cache.append(position);
214064
+ }
214065
+ const messageHashes = this.findMessageHashes(client, 'positions::');
214066
+ for (let i = 0; i < messageHashes.length; i++) {
214067
+ const messageHash = messageHashes[i];
214068
+ const parts = messageHash.split('::');
214069
+ const symbolsString = parts[1];
214070
+ const symbols = symbolsString.split(',');
214071
+ const positions = this.filterByArray(newPositions, 'symbol', symbols, false);
214072
+ if (!this.isEmpty(positions)) {
214073
+ client.resolve(positions, messageHash);
214074
+ }
214075
+ }
214076
+ client.resolve(newPositions, 'positions');
214077
+ }
214078
+ parseWsPosition(position, market = undefined) {
214079
+ //
214080
+ // {
214081
+ // "symbol":"LTCUSDT",
214082
+ // "hold_volume":"6",
214083
+ // "position_type":1,
214084
+ // "open_type":2,
214085
+ // "frozen_volume":"0",
214086
+ // "close_volume":"0",
214087
+ // "hold_avg_price":"71.681666666666666667",
214088
+ // "close_avg_price":"0",
214089
+ // "open_avg_price":"71.681666666666666667",
214090
+ // "liquidate_price":"0",
214091
+ // "create_time":1701621167225,
214092
+ // "update_time":1701628152614
214093
+ // }
214094
+ //
214095
+ const marketId = this.safeString(position, 'symbol');
214096
+ market = this.safeMarket(marketId, market, '', 'swap');
213522
214097
  const symbol = market['symbol'];
213523
- const side = this.safeStringLower(order, 'side');
213524
- return this.safeOrder({
213525
- 'info': order,
214098
+ const openTimestamp = this.safeInteger(position, 'create_time');
214099
+ const timestamp = this.safeInteger(position, 'update_time');
214100
+ const side = this.safeNumber(position, 'position_type');
214101
+ const marginModeId = this.safeNumber(position, 'open_type');
214102
+ return this.safePosition({
214103
+ 'info': position,
214104
+ 'id': undefined,
213526
214105
  'symbol': symbol,
213527
- 'id': id,
213528
- 'clientOrderId': clientOrderId,
213529
- 'timestamp': undefined,
213530
- 'datetime': undefined,
213531
- 'lastTradeTimestamp': timestamp,
213532
- 'type': type,
213533
- 'timeInForce': undefined,
213534
- 'postOnly': undefined,
213535
- 'side': side,
213536
- 'price': price,
213537
- 'stopPrice': undefined,
213538
- 'triggerPrice': undefined,
213539
- 'amount': amount,
213540
- 'cost': undefined,
213541
- 'average': undefined,
213542
- 'filled': filled,
213543
- 'remaining': undefined,
213544
- 'status': status,
213545
- 'fee': undefined,
213546
- 'trades': undefined,
213547
- }, market);
214106
+ 'timestamp': openTimestamp,
214107
+ 'datetime': this.iso8601(openTimestamp),
214108
+ 'lastUpdateTimestamp': timestamp,
214109
+ 'hedged': undefined,
214110
+ 'side': (side === 1) ? 'long' : 'short',
214111
+ 'contracts': this.safeNumber(position, 'hold_volume'),
214112
+ 'contractSize': this.safeNumber(market, 'contractSize'),
214113
+ 'entryPrice': this.safeNumber(position, 'open_avg_price'),
214114
+ 'markPrice': this.safeNumber(position, 'hold_avg_price'),
214115
+ 'lastPrice': undefined,
214116
+ 'notional': undefined,
214117
+ 'leverage': undefined,
214118
+ 'collateral': undefined,
214119
+ 'initialMargin': undefined,
214120
+ 'initialMarginPercentage': undefined,
214121
+ 'maintenanceMargin': undefined,
214122
+ 'maintenanceMarginPercentage': undefined,
214123
+ 'unrealizedPnl': undefined,
214124
+ 'realizedPnl': undefined,
214125
+ 'liquidationPrice': this.safeNumber(position, 'liquidate_price'),
214126
+ 'marginMode': (marginModeId === 1) ? 'isolated' : 'cross',
214127
+ 'percentage': undefined,
214128
+ 'marginRatio': undefined,
214129
+ 'stopLossPrice': undefined,
214130
+ 'takeProfitPrice': undefined,
214131
+ });
213548
214132
  }
213549
214133
  handleTrade(client, message) {
213550
214134
  //
213551
- // {
213552
- // "table": "spot/trade",
213553
- // "data": [
213554
- // {
213555
- // "price": "52700.50",
213556
- // "s_t": 1630982050,
213557
- // "side": "buy",
213558
- // "size": "0.00112",
213559
- // "symbol": "BTC_USDT"
213560
- // },
213561
- // ]
213562
- // }
214135
+ // spot
214136
+ // {
214137
+ // "table": "spot/trade",
214138
+ // "data": [
214139
+ // {
214140
+ // "price": "52700.50",
214141
+ // "s_t": 1630982050,
214142
+ // "side": "buy",
214143
+ // "size": "0.00112",
214144
+ // "symbol": "BTC_USDT"
214145
+ // },
214146
+ // ]
214147
+ // }
213563
214148
  //
213564
- const table = this.safeString(message, 'table');
213565
- const data = this.safeValue(message, 'data', []);
213566
- const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
214149
+ // swap
214150
+ // {
214151
+ // "group":"futures/trade:BTCUSDT",
214152
+ // "data":[
214153
+ // {
214154
+ // "trade_id":6798697637,
214155
+ // "contract_id":1,
214156
+ // "symbol":"BTCUSDT",
214157
+ // "deal_price":"39735.8",
214158
+ // "deal_vol":"2",
214159
+ // "type":0,
214160
+ // "way":1,
214161
+ // "create_time":1701618503,
214162
+ // "create_time_mill":1701618503517,
214163
+ // "created_at":"2023-12-03T15:48:23.517518538Z"
214164
+ // }
214165
+ // ]
214166
+ // }
214167
+ //
214168
+ const channel = this.safeString2(message, 'table', 'group');
214169
+ const isSpot = (channel.indexOf('spot') >= 0);
214170
+ const data = this.safeValue(message, 'data');
214171
+ if (data === undefined) {
214172
+ return;
214173
+ }
214174
+ let stored = undefined;
213567
214175
  for (let i = 0; i < data.length; i++) {
213568
- const trade = this.parseTrade(data[i]);
214176
+ const trade = this.parseWsTrade(data[i]);
213569
214177
  const symbol = trade['symbol'];
213570
- const marketId = this.safeString(trade['info'], 'symbol');
213571
- const messageHash = table + ':' + marketId;
213572
- let stored = this.safeValue(this.trades, symbol);
214178
+ const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
214179
+ stored = this.safeValue(this.trades, symbol);
213573
214180
  if (stored === undefined) {
213574
214181
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCache */ .ZL(tradesLimit);
213575
214182
  this.trades[symbol] = stored;
213576
214183
  }
213577
214184
  stored.append(trade);
213578
- client.resolve(stored, messageHash);
213579
214185
  }
214186
+ let messageHash = channel;
214187
+ if (isSpot) {
214188
+ messageHash += ':' + this.safeString(data[0], 'symbol');
214189
+ }
214190
+ client.resolve(stored, messageHash);
213580
214191
  return message;
213581
214192
  }
214193
+ parseWsTrade(trade, market = undefined) {
214194
+ // spot
214195
+ // {
214196
+ // "price": "52700.50",
214197
+ // "s_t": 1630982050,
214198
+ // "side": "buy",
214199
+ // "size": "0.00112",
214200
+ // "symbol": "BTC_USDT"
214201
+ // }
214202
+ // swap
214203
+ // {
214204
+ // "trade_id":6798697637,
214205
+ // "contract_id":1,
214206
+ // "symbol":"BTCUSDT",
214207
+ // "deal_price":"39735.8",
214208
+ // "deal_vol":"2",
214209
+ // "type":0,
214210
+ // "way":1,
214211
+ // "create_time":1701618503,
214212
+ // "create_time_mill":1701618503517,
214213
+ // "created_at":"2023-12-03T15:48:23.517518538Z"
214214
+ // }
214215
+ //
214216
+ const contractId = this.safeString(trade, 'contract_id');
214217
+ const marketType = (contractId === undefined) ? 'spot' : 'swap';
214218
+ const marketDelimiter = (marketType === 'spot') ? '_' : '';
214219
+ const timestamp = this.safeInteger(trade, 'create_time_mill', this.safeTimestamp(trade, 's_t'));
214220
+ const marketId = this.safeString(trade, 'symbol');
214221
+ return this.safeTrade({
214222
+ 'info': trade,
214223
+ 'id': this.safeString(trade, 'trade_id'),
214224
+ 'order': undefined,
214225
+ 'timestamp': timestamp,
214226
+ 'datetime': this.iso8601(timestamp),
214227
+ 'symbol': this.safeSymbol(marketId, market, marketDelimiter, marketType),
214228
+ 'type': undefined,
214229
+ 'side': this.safeString(trade, 'side'),
214230
+ 'price': this.safeString2(trade, 'price', 'deal_price'),
214231
+ 'amount': this.safeString2(trade, 'size', 'deal_vol'),
214232
+ 'cost': undefined,
214233
+ 'takerOrMaker': undefined,
214234
+ 'fee': undefined,
214235
+ }, market);
214236
+ }
213582
214237
  handleTicker(client, message) {
213583
214238
  //
213584
- // {
213585
- // "data": [
213586
- // {
213587
- // "base_volume_24h": "78615593.81",
213588
- // "high_24h": "52756.97",
213589
- // "last_price": "52638.31",
213590
- // "low_24h": "50991.35",
213591
- // "open_24h": "51692.03",
213592
- // "s_t": 1630981727,
213593
- // "symbol": "BTC_USDT"
213594
- // }
213595
- // ],
213596
- // "table": "spot/ticker"
213597
- // }
214239
+ // {
214240
+ // "data": [
214241
+ // {
214242
+ // "base_volume_24h": "78615593.81",
214243
+ // "high_24h": "52756.97",
214244
+ // "last_price": "52638.31",
214245
+ // "low_24h": "50991.35",
214246
+ // "open_24h": "51692.03",
214247
+ // "s_t": 1630981727,
214248
+ // "symbol": "BTC_USDT"
214249
+ // }
214250
+ // ],
214251
+ // "table": "spot/ticker"
214252
+ // }
214253
+ // {
214254
+ // "group":"futures/ticker",
214255
+ // "data":{
214256
+ // "symbol":"BTCUSDT",
214257
+ // "volume_24":"117387.58",
214258
+ // "fair_price":"146.24",
214259
+ // "last_price":"146.24",
214260
+ // "range":"147.17",
214261
+ // "ask_price": "147.11",
214262
+ // "ask_vol": "1",
214263
+ // "bid_price": "142.11",
214264
+ // "bid_vol": "1"
214265
+ // }
214266
+ // }
213598
214267
  //
213599
214268
  const table = this.safeString(message, 'table');
213600
- const data = this.safeValue(message, 'data', []);
213601
- for (let i = 0; i < data.length; i++) {
213602
- const ticker = this.parseTicker(data[i]);
213603
- const symbol = ticker['symbol'];
213604
- const marketId = this.safeString(ticker['info'], 'symbol');
213605
- const messageHash = table + ':' + marketId;
214269
+ const isSpot = (table !== undefined);
214270
+ const data = this.safeValue(message, 'data');
214271
+ if (data === undefined) {
214272
+ return;
214273
+ }
214274
+ if (isSpot) {
214275
+ for (let i = 0; i < data.length; i++) {
214276
+ const ticker = this.parseTicker(data[i]);
214277
+ const symbol = ticker['symbol'];
214278
+ const marketId = this.safeString(ticker['info'], 'symbol');
214279
+ const messageHash = table + ':' + marketId;
214280
+ this.tickers[symbol] = ticker;
214281
+ client.resolve(ticker, messageHash);
214282
+ }
214283
+ }
214284
+ else {
214285
+ const ticker = this.parseWsSwapTicker(data);
214286
+ const symbol = this.safeString(ticker, 'symbol');
213606
214287
  this.tickers[symbol] = ticker;
213607
- client.resolve(ticker, messageHash);
214288
+ client.resolve(ticker, 'tickers');
214289
+ this.resolvePromiseIfMessagehashMatches(client, 'tickers::', symbol, ticker);
213608
214290
  }
213609
214291
  return message;
213610
214292
  }
214293
+ parseWsSwapTicker(ticker, market = undefined) {
214294
+ //
214295
+ // {
214296
+ // "symbol":"BTCUSDT",
214297
+ // "volume_24":"117387.58",
214298
+ // "fair_price":"146.24",
214299
+ // "last_price":"146.24",
214300
+ // "range":"147.17",
214301
+ // "ask_price": "147.11",
214302
+ // "ask_vol": "1",
214303
+ // "bid_price": "142.11",
214304
+ // "bid_vol": "1"
214305
+ // }
214306
+ const marketId = this.safeString(ticker, 'symbol');
214307
+ return this.safeTicker({
214308
+ 'symbol': this.safeSymbol(marketId, market, '', 'swap'),
214309
+ 'timestamp': undefined,
214310
+ 'datetime': undefined,
214311
+ 'high': undefined,
214312
+ 'low': undefined,
214313
+ 'bid': this.safeString(ticker, 'bid_price'),
214314
+ 'bidVolume': this.safeString(ticker, 'bid_vol'),
214315
+ 'ask': this.safeString(ticker, 'ask_price'),
214316
+ 'askVolume': this.safeString(ticker, 'ask_vol'),
214317
+ 'vwap': undefined,
214318
+ 'open': undefined,
214319
+ 'close': undefined,
214320
+ 'last': this.safeString(ticker, 'last_price'),
214321
+ 'previousClose': undefined,
214322
+ 'change': undefined,
214323
+ 'percentage': undefined,
214324
+ 'average': this.safeString(ticker, 'fair_price'),
214325
+ 'baseVolume': undefined,
214326
+ 'quoteVolume': this.safeString(ticker, 'volume_24'),
214327
+ 'info': ticker,
214328
+ }, market);
214329
+ }
213611
214330
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
213612
214331
  /**
213613
214332
  * @method
213614
214333
  * @name bitmart#watchOHLCV
214334
+ * @see https://developer-pro.bitmart.com/en/spot/#public-kline-channel
214335
+ * @see https://developer-pro.bitmart.com/en/futures/#public-klinebin-channel
213615
214336
  * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
213616
214337
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
213617
214338
  * @param {string} timeframe the length of time each candle represents
@@ -213622,10 +214343,19 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213622
214343
  */
213623
214344
  await this.loadMarkets();
213624
214345
  symbol = this.symbol(symbol);
214346
+ const market = this.market(symbol);
214347
+ let type = 'spot';
214348
+ [type, params] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
213625
214349
  const timeframes = this.safeValue(this.options, 'timeframes', {});
213626
214350
  const interval = this.safeString(timeframes, timeframe);
213627
- const name = 'kline' + interval;
213628
- const ohlcv = await this.subscribe(name, symbol, params);
214351
+ let name = undefined;
214352
+ if (type === 'spot') {
214353
+ name = 'kline' + interval;
214354
+ }
214355
+ else {
214356
+ name = 'klineBin' + interval;
214357
+ }
214358
+ const ohlcv = await this.subscribe(name, symbol, type, params);
213629
214359
  if (this.newUpdates) {
213630
214360
  limit = ohlcv.getLimit(symbol, limit);
213631
214361
  }
@@ -213633,40 +214363,82 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213633
214363
  }
213634
214364
  handleOHLCV(client, message) {
213635
214365
  //
213636
- // {
213637
- // "data": [
213638
- // {
213639
- // "candle": [
213640
- // 1631056350,
213641
- // "46532.83",
213642
- // "46555.71",
213643
- // "46511.41",
213644
- // "46555.71",
213645
- // "0.25"
213646
- // ],
213647
- // "symbol": "BTC_USDT"
213648
- // }
213649
- // ],
213650
- // "table": "spot/kline1m"
213651
- // }
214366
+ // {
214367
+ // "data": [
214368
+ // {
214369
+ // "candle": [
214370
+ // 1631056350,
214371
+ // "46532.83",
214372
+ // "46555.71",
214373
+ // "46511.41",
214374
+ // "46555.71",
214375
+ // "0.25"
214376
+ // ],
214377
+ // "symbol": "BTC_USDT"
214378
+ // }
214379
+ // ],
214380
+ // "table": "spot/kline1m"
214381
+ // }
214382
+ // swap
214383
+ // {
214384
+ // "group":"futures/klineBin1m:BTCUSDT",
214385
+ // "data":{
214386
+ // "symbol":"BTCUSDT",
214387
+ // "items":[
214388
+ // {
214389
+ // "o":"39635.8",
214390
+ // "h":"39636",
214391
+ // "l":"39614.4",
214392
+ // "c":"39629.7",
214393
+ // "v":"31852",
214394
+ // "ts":1701617761
214395
+ // }
214396
+ // ]
214397
+ // }
214398
+ // }
213652
214399
  //
213653
- const table = this.safeString(message, 'table');
213654
- const data = this.safeValue(message, 'data', []);
213655
- const parts = table.split('/');
213656
- const part1 = this.safeString(parts, 1);
213657
- const interval = part1.replace('kline', '');
214400
+ const channel = this.safeString2(message, 'table', 'group');
214401
+ const isSpot = (channel.indexOf('spot') >= 0);
214402
+ const data = this.safeValue(message, 'data');
214403
+ if (data === undefined) {
214404
+ return;
214405
+ }
214406
+ const parts = channel.split('/');
214407
+ const part1 = this.safeString(parts, 1, '');
214408
+ let interval = part1.replace('kline', '');
214409
+ interval = interval.replace('Bin', '');
214410
+ const intervalParts = interval.split(':');
214411
+ interval = this.safeString(intervalParts, 0);
213658
214412
  // use a reverse lookup in a static map instead
213659
214413
  const timeframes = this.safeValue(this.options, 'timeframes', {});
213660
214414
  const timeframe = this.findTimeframe(interval, timeframes);
213661
214415
  const duration = this.parseTimeframe(timeframe);
213662
214416
  const durationInMs = duration * 1000;
213663
- for (let i = 0; i < data.length; i++) {
213664
- const marketId = this.safeString(data[i], 'symbol');
213665
- const candle = this.safeValue(data[i], 'candle');
213666
- const market = this.safeMarket(marketId);
214417
+ if (isSpot) {
214418
+ for (let i = 0; i < data.length; i++) {
214419
+ const marketId = this.safeString(data[i], 'symbol');
214420
+ const market = this.safeMarket(marketId);
214421
+ const symbol = market['symbol'];
214422
+ const rawOHLCV = this.safeValue(data[i], 'candle');
214423
+ const parsed = this.parseOHLCV(rawOHLCV, market);
214424
+ parsed[0] = this.parseToInt(parsed[0] / durationInMs) * durationInMs;
214425
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
214426
+ let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
214427
+ if (stored === undefined) {
214428
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
214429
+ stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
214430
+ this.ohlcvs[symbol][timeframe] = stored;
214431
+ }
214432
+ stored.append(parsed);
214433
+ const messageHash = channel + ':' + marketId;
214434
+ client.resolve(stored, messageHash);
214435
+ }
214436
+ }
214437
+ else {
214438
+ const marketId = this.safeString(data, 'symbol');
214439
+ const market = this.safeMarket(marketId, undefined, '', 'swap');
213667
214440
  const symbol = market['symbol'];
213668
- const parsed = this.parseOHLCV(candle, market);
213669
- parsed[0] = this.parseToInt(parsed[0] / durationInMs) * durationInMs;
214441
+ const items = this.safeValue(data, 'items', []);
213670
214442
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
213671
214443
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
213672
214444
  if (stored === undefined) {
@@ -213674,24 +214446,34 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213674
214446
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
213675
214447
  this.ohlcvs[symbol][timeframe] = stored;
213676
214448
  }
213677
- stored.append(parsed);
213678
- const messageHash = table + ':' + marketId;
213679
- client.resolve(stored, messageHash);
214449
+ for (let i = 0; i < items.length; i++) {
214450
+ const candle = items[i];
214451
+ const parsed = this.parseOHLCV(candle, market);
214452
+ stored.append(parsed);
214453
+ }
214454
+ client.resolve(stored, channel);
213680
214455
  }
213681
214456
  }
213682
214457
  async watchOrderBook(symbol, limit = undefined, params = {}) {
213683
214458
  /**
213684
214459
  * @method
213685
214460
  * @name bitmart#watchOrderBook
214461
+ * @see https://developer-pro.bitmart.com/en/spot/#public-depth-all-channel
214462
+ * @see https://developer-pro.bitmart.com/en/futures/#public-depth-channel
213686
214463
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
213687
214464
  * @param {string} symbol unified symbol of the market to fetch the order book for
213688
214465
  * @param {int} [limit] the maximum amount of order book entries to return
213689
214466
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213690
214467
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
213691
214468
  */
214469
+ await this.loadMarkets();
213692
214470
  const options = this.safeValue(this.options, 'watchOrderBook', {});
213693
214471
  const depth = this.safeString(options, 'depth', 'depth50');
213694
- const orderbook = await this.subscribe(depth, symbol, params);
214472
+ symbol = this.symbol(symbol);
214473
+ const market = this.market(symbol);
214474
+ let type = 'spot';
214475
+ [type, params] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
214476
+ const orderbook = await this.subscribe(depth, symbol, type, params);
213695
214477
  return orderbook.limit();
213696
214478
  }
213697
214479
  handleDelta(bookside, delta) {
@@ -213739,22 +214521,19 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213739
214521
  }
213740
214522
  handleOrderBook(client, message) {
213741
214523
  //
214524
+ // spot
213742
214525
  // {
213743
214526
  // "data": [
213744
214527
  // {
213745
214528
  // "asks": [
213746
214529
  // [ '46828.38', "0.21847" ],
213747
214530
  // [ '46830.68', "0.08232" ],
213748
- // [ '46832.08', "0.09285" ],
213749
- // [ '46837.82', "0.02028" ],
213750
- // [ '46839.43', "0.15068" ]
214531
+ // ...
213751
214532
  // ],
213752
214533
  // "bids": [
213753
214534
  // [ '46820.78', "0.00444" ],
213754
214535
  // [ '46814.33', "0.00234" ],
213755
- // [ '46813.50', "0.05021" ],
213756
- // [ '46808.14', "0.00217" ],
213757
- // [ '46808.04', "0.00013" ]
214536
+ // ...
213758
214537
  // ],
213759
214538
  // "ms_t": 1631044962431,
213760
214539
  // "symbol": "BTC_USDT"
@@ -213762,32 +214541,99 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213762
214541
  // ],
213763
214542
  // "table": "spot/depth5"
213764
214543
  // }
214544
+ // swap
214545
+ // {
214546
+ // "group":"futures/depth50:BTCUSDT",
214547
+ // "data":{
214548
+ // "symbol":"BTCUSDT",
214549
+ // "way":1,
214550
+ // "depths":[
214551
+ // {
214552
+ // "price":"39509.8",
214553
+ // "vol":"2379"
214554
+ // },
214555
+ // {
214556
+ // "price":"39509.6",
214557
+ // "vol":"6815"
214558
+ // },
214559
+ // ...
214560
+ // ],
214561
+ // "ms_t":1701566021194
214562
+ // }
214563
+ // }
213765
214564
  //
213766
- const data = this.safeValue(message, 'data', []);
213767
- const table = this.safeString(message, 'table');
214565
+ const data = this.safeValue(message, 'data');
214566
+ if (data === undefined) {
214567
+ return;
214568
+ }
214569
+ const depths = this.safeValue(data, 'depths');
214570
+ const isSpot = (depths === undefined);
214571
+ const table = this.safeString2(message, 'table', 'group');
213768
214572
  const parts = table.split('/');
213769
214573
  const lastPart = this.safeString(parts, 1);
213770
- const limitString = lastPart.replace('depth', '');
213771
- const limit = parseInt(limitString);
213772
- for (let i = 0; i < data.length; i++) {
213773
- const update = data[i];
213774
- const marketId = this.safeString(update, 'symbol');
214574
+ let limitString = lastPart.replace('depth', '');
214575
+ const dotsIndex = limitString.indexOf(':');
214576
+ limitString = limitString.slice(0, dotsIndex);
214577
+ const limit = this.parseToInt(limitString);
214578
+ if (isSpot) {
214579
+ for (let i = 0; i < data.length; i++) {
214580
+ const update = data[i];
214581
+ const marketId = this.safeString(update, 'symbol');
214582
+ const symbol = this.safeSymbol(marketId);
214583
+ let orderbook = this.safeValue(this.orderbooks, symbol);
214584
+ if (orderbook === undefined) {
214585
+ orderbook = this.orderBook({}, limit);
214586
+ orderbook['symbol'] = symbol;
214587
+ this.orderbooks[symbol] = orderbook;
214588
+ }
214589
+ orderbook.reset({});
214590
+ this.handleOrderBookMessage(client, update, orderbook);
214591
+ const timestamp = this.safeInteger(update, 'ms_t');
214592
+ orderbook['timestamp'] = timestamp;
214593
+ orderbook['datetime'] = this.iso8601(timestamp);
214594
+ const messageHash = table + ':' + marketId;
214595
+ client.resolve(orderbook, messageHash);
214596
+ }
214597
+ }
214598
+ else {
214599
+ const marketId = this.safeString(data, 'symbol');
213775
214600
  const symbol = this.safeSymbol(marketId);
213776
214601
  let orderbook = this.safeValue(this.orderbooks, symbol);
213777
214602
  if (orderbook === undefined) {
213778
214603
  orderbook = this.orderBook({}, limit);
214604
+ orderbook['symbol'] = symbol;
213779
214605
  this.orderbooks[symbol] = orderbook;
213780
214606
  }
213781
- orderbook.reset({});
213782
- this.handleOrderBookMessage(client, update, orderbook);
213783
- const messageHash = table + ':' + marketId;
214607
+ const way = this.safeNumber(data, 'way');
214608
+ const side = (way === 1) ? 'bids' : 'asks';
214609
+ if (way === 1) {
214610
+ orderbook[side] = new _base_ws_OrderBookSide_js__WEBPACK_IMPORTED_MODULE_3__/* .Bids */ .T8([], limit);
214611
+ }
214612
+ else {
214613
+ orderbook[side] = new _base_ws_OrderBookSide_js__WEBPACK_IMPORTED_MODULE_3__/* .Asks */ .lB([], limit);
214614
+ }
214615
+ for (let i = 0; i < depths.length; i++) {
214616
+ const depth = depths[i];
214617
+ const price = this.safeNumber(depth, 'price');
214618
+ const amount = this.safeNumber(depth, 'vol');
214619
+ const orderbookSide = this.safeValue(orderbook, side);
214620
+ orderbookSide.store(price, amount);
214621
+ }
214622
+ const bidsLength = orderbook['bids'].length;
214623
+ const asksLength = orderbook['asks'].length;
214624
+ if ((bidsLength === 0) || (asksLength === 0)) {
214625
+ return;
214626
+ }
214627
+ const timestamp = this.safeInteger(data, 'ms_t');
214628
+ orderbook['timestamp'] = timestamp;
214629
+ orderbook['datetime'] = this.iso8601(timestamp);
214630
+ const messageHash = table;
213784
214631
  client.resolve(orderbook, messageHash);
213785
214632
  }
213786
- return message;
213787
214633
  }
213788
- async authenticate(params = {}) {
214634
+ async authenticate(type, params = {}) {
213789
214635
  this.checkRequiredCredentials();
213790
- const url = this.implodeHostname(this.urls['api']['ws']['private']);
214636
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
213791
214637
  const messageHash = 'authenticated';
213792
214638
  const client = this.client(url);
213793
214639
  const future = client.future(messageHash);
@@ -213797,16 +214643,29 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213797
214643
  const memo = this.uid;
213798
214644
  const path = 'bitmart.WebSocket';
213799
214645
  const auth = timestamp + '#' + memo + '#' + path;
213800
- const signature = this.hmac(this.encode(auth), this.encode(this.secret), _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_3__/* .sha256 */ .J);
213801
- const operation = 'login';
213802
- const request = {
213803
- 'op': operation,
213804
- 'args': [
213805
- this.apiKey,
213806
- timestamp,
213807
- signature,
213808
- ],
213809
- };
214646
+ const signature = this.hmac(this.encode(auth), this.encode(this.secret), _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_4__/* .sha256 */ .J);
214647
+ let request = undefined;
214648
+ if (type === 'spot') {
214649
+ request = {
214650
+ 'op': 'login',
214651
+ 'args': [
214652
+ this.apiKey,
214653
+ timestamp,
214654
+ signature,
214655
+ ],
214656
+ };
214657
+ }
214658
+ else {
214659
+ request = {
214660
+ 'action': 'access',
214661
+ 'args': [
214662
+ this.apiKey,
214663
+ timestamp,
214664
+ signature,
214665
+ 'web',
214666
+ ],
214667
+ };
214668
+ }
213810
214669
  const message = this.extend(request, params);
213811
214670
  this.watch(url, messageHash, message, messageHash);
213812
214671
  }
@@ -213814,13 +214673,16 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213814
214673
  }
213815
214674
  handleSubscriptionStatus(client, message) {
213816
214675
  //
213817
- // {"event":"subscribe","channel":"spot/depth:BTC-USDT"}
214676
+ // {"event":"subscribe","channel":"spot/depth:BTC-USDT"}
213818
214677
  //
213819
214678
  return message;
213820
214679
  }
213821
214680
  handleAuthenticate(client, message) {
213822
214681
  //
213823
- // { event: "login" }
214682
+ // spot
214683
+ // { event: "login" }
214684
+ // swap
214685
+ // { action: 'access', success: true }
213824
214686
  //
213825
214687
  const messageHash = 'authenticated';
213826
214688
  const future = this.safeValue(client.futures, messageHash);
@@ -213828,29 +214690,41 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213828
214690
  }
213829
214691
  handleErrorMessage(client, message) {
213830
214692
  //
213831
- // { event: "error", message: "Invalid sign", errorCode: 30013 }
213832
- // {"event":"error","message":"Unrecognized request: {\"event\":\"subscribe\",\"channel\":\"spot/depth:BTC-USDT\"}","errorCode":30039}
214693
+ // { event: "error", message: "Invalid sign", errorCode: 30013 }
214694
+ // {"event":"error","message":"Unrecognized request: {\"event\":\"subscribe\",\"channel\":\"spot/depth:BTC-USDT\"}","errorCode":30039}
214695
+ // {
214696
+ // action: '',
214697
+ // group: 'futures/trade:BTCUSDT',
214698
+ // success: false,
214699
+ // request: { action: '', args: [ 'futures/trade:BTCUSDT' ] },
214700
+ // error: 'Invalid action [] for group [futures/trade:BTCUSDT]'
214701
+ // }
213833
214702
  //
213834
214703
  const errorCode = this.safeString(message, 'errorCode');
214704
+ const error = this.safeString(message, 'error');
213835
214705
  try {
213836
- if (errorCode !== undefined) {
214706
+ if (errorCode !== undefined || error !== undefined) {
213837
214707
  const feedback = this.id + ' ' + this.json(message);
213838
214708
  this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
213839
- const messageString = this.safeValue(message, 'message');
213840
- if (messageString !== undefined) {
213841
- this.throwBroadlyMatchedException(this.exceptions['broad'], messageString, feedback);
214709
+ const messageString = this.safeValue(message, 'message', error);
214710
+ this.throwBroadlyMatchedException(this.exceptions['broad'], messageString, feedback);
214711
+ const action = this.safeString(message, 'action');
214712
+ if (action === 'access') {
214713
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError(feedback);
213842
214714
  }
214715
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(feedback);
213843
214716
  }
213844
214717
  return false;
213845
214718
  }
213846
214719
  catch (e) {
213847
- if (e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError) {
214720
+ if ((e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError)) {
213848
214721
  const messageHash = 'authenticated';
213849
214722
  client.reject(e, messageHash);
213850
214723
  if (messageHash in client.subscriptions) {
213851
214724
  delete client.subscriptions[messageHash];
213852
214725
  }
213853
214726
  }
214727
+ client.reject(e);
213854
214728
  return true;
213855
214729
  }
213856
214730
  }
@@ -213883,14 +214757,14 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213883
214757
  //
213884
214758
  // { data: '', table: "spot/user/order" }
213885
214759
  //
213886
- const table = this.safeString(message, 'table');
213887
- if (table === undefined) {
213888
- const event = this.safeString(message, 'event');
214760
+ const channel = this.safeString2(message, 'table', 'group');
214761
+ if (channel === undefined) {
214762
+ const event = this.safeString2(message, 'event', 'action');
213889
214763
  if (event !== undefined) {
213890
214764
  const methods = {
213891
214765
  // 'info': this.handleSystemStatus,
213892
- // 'book': 'handleOrderBook',
213893
214766
  'login': this.handleAuthenticate,
214767
+ 'access': this.handleAuthenticate,
213894
214768
  'subscribe': this.handleSubscriptionStatus,
213895
214769
  };
213896
214770
  const method = this.safeValue(methods, event);
@@ -213903,30 +214777,25 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213903
214777
  }
213904
214778
  }
213905
214779
  else {
213906
- const parts = table.split('/');
213907
- const name = this.safeString(parts, 1);
213908
214780
  const methods = {
213909
- 'depth': this.handleOrderBook,
213910
214781
  'depth5': this.handleOrderBook,
213911
214782
  'depth20': this.handleOrderBook,
213912
214783
  'depth50': this.handleOrderBook,
213913
214784
  'ticker': this.handleTicker,
213914
214785
  'trade': this.handleTrade,
213915
- // ...
214786
+ 'kline': this.handleOHLCV,
214787
+ 'order': this.handleOrders,
214788
+ 'position': this.handlePositions,
214789
+ 'balance': this.handleBalance,
214790
+ 'asset': this.handleBalance,
213916
214791
  };
213917
- let method = this.safeValue(methods, name);
213918
- if (name.indexOf('kline') >= 0) {
213919
- method = this.handleOHLCV;
213920
- }
213921
- const privateName = this.safeString(parts, 2);
213922
- if (privateName === 'order') {
213923
- method = this.handleOrders;
213924
- }
213925
- if (method === undefined) {
213926
- return message;
213927
- }
213928
- else {
213929
- return method.call(this, client, message);
214792
+ const keys = Object.keys(methods);
214793
+ for (let i = 0; i < keys.length; i++) {
214794
+ const key = keys[i];
214795
+ if (channel.indexOf(key) >= 0) {
214796
+ const method = this.safeValue(methods, key);
214797
+ return method.call(this, client, message);
214798
+ }
213930
214799
  }
213931
214800
  }
213932
214801
  }
@@ -288967,7 +289836,7 @@ SOFTWARE.
288967
289836
 
288968
289837
  //-----------------------------------------------------------------------------
288969
289838
  // this is updated by vss.js when building
288970
- const version = '4.1.83';
289839
+ const version = '4.1.85';
288971
289840
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
288972
289841
  //-----------------------------------------------------------------------------
288973
289842