ccxt 4.1.84 → 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
  }
@@ -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
  /**
@@ -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,
@@ -161337,9 +161360,6 @@ class kucoinfutures extends _abstract_kucoinfutures_js__WEBPACK_IMPORTED_MODULE_
161337
161360
  orderbook['nonce'] = this.safeInteger(data, 'sequence');
161338
161361
  return orderbook;
161339
161362
  }
161340
- async fetchL3OrderBook(symbol, limit = undefined, params = {}) {
161341
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' fetchL3OrderBook() is not supported yet');
161342
- }
161343
161363
  async fetchTicker(symbol, params = {}) {
161344
161364
  /**
161345
161365
  * @method
@@ -213368,12 +213388,14 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
213368
213388
  /* harmony import */ var _bitmart_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3718);
213369
213389
  /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6689);
213370
213390
  /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3020);
213371
- /* 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);
213372
213393
  // ---------------------------------------------------------------------------
213373
213394
 
213374
213395
 
213375
213396
 
213376
213397
 
213398
+
213377
213399
  // ---------------------------------------------------------------------------
213378
213400
  class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
213379
213401
  describe() {
@@ -213387,24 +213409,38 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213387
213409
  'cancelOrdersWs': false,
213388
213410
  'cancelAllOrdersWs': false,
213389
213411
  'ws': true,
213412
+ 'watchBalance': true,
213390
213413
  'watchTicker': true,
213414
+ 'watchTickers': true,
213391
213415
  'watchOrderBook': true,
213392
213416
  'watchOrders': true,
213393
213417
  'watchTrades': true,
213394
213418
  'watchOHLCV': true,
213419
+ 'watchPosition': 'emulated',
213420
+ 'watchPositions': true,
213395
213421
  },
213396
213422
  'urls': {
213397
213423
  'api': {
213398
213424
  'ws': {
213399
- 'public': 'wss://ws-manager-compress.{hostname}/api?protocol=1.1',
213400
- '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
+ },
213401
213433
  },
213402
213434
  },
213403
213435
  },
213404
213436
  'options': {
213405
213437
  'defaultType': 'spot',
213438
+ 'watchBalance': {
213439
+ 'fetchBalanceSnapshot': true,
213440
+ 'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
213441
+ },
213406
213442
  'watchOrderBook': {
213407
- 'depth': 'depth5', // depth5, depth20, depth50
213443
+ 'depth': 'depth50', // depth5, depth20, depth50
213408
213444
  },
213409
213445
  'ws': {
213410
213446
  'inflate': true,
@@ -213430,33 +213466,166 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213430
213466
  },
213431
213467
  });
213432
213468
  }
213433
- async subscribe(channel, symbol, params = {}) {
213434
- await this.loadMarkets();
213469
+ async subscribe(channel, symbol, type, params = {}) {
213435
213470
  const market = this.market(symbol);
213436
- const url = this.implodeHostname(this.urls['api']['ws']['public']);
213437
- const messageHash = market['type'] + '/' + channel + ':' + market['id'];
213438
- const request = {
213439
- 'op': 'subscribe',
213440
- 'args': [messageHash],
213441
- };
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
+ }
213442
213488
  return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213443
213489
  }
213444
- 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
+ */
213445
213500
  await this.loadMarkets();
213446
- const market = this.market(symbol);
213447
- const url = this.implodeHostname(this.urls['api']['ws']['private']);
213448
- const messageHash = channel + ':' + market['id'];
213449
- await this.authenticate();
213450
- const request = {
213451
- 'op': 'subscribe',
213452
- 'args': [messageHash],
213453
- };
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
+ }
213454
213526
  return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213455
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
+ }
213456
213623
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
213457
213624
  /**
213458
213625
  * @method
213459
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
213460
213629
  * @description get the list of most recent trades for a particular symbol
213461
213630
  * @param {string} symbol unified symbol of the market to fetch trades for
213462
213631
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
@@ -213466,7 +213635,10 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213466
213635
  */
213467
213636
  await this.loadMarkets();
213468
213637
  symbol = this.symbol(symbol);
213469
- 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);
213470
213642
  if (this.newUpdates) {
213471
213643
  limit = trades.getLimit(symbol, limit);
213472
213644
  }
@@ -213476,17 +213648,64 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213476
213648
  /**
213477
213649
  * @method
213478
213650
  * @name bitmart#watchTicker
213651
+ * @see https://developer-pro.bitmart.com/en/spot/#public-ticker-channel
213479
213652
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
213480
213653
  * @param {string} symbol unified symbol of the market to fetch the ticker for
213481
213654
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213482
213655
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
213483
213656
  */
213484
- 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);
213485
213702
  }
213486
213703
  async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
213487
213704
  /**
213488
213705
  * @method
213489
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
213490
213709
  * @description watches information on multiple orders made by the user
213491
213710
  * @param {string} symbol unified market symbol of the market orders were made in
213492
213711
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -213494,196 +213713,626 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213494
213713
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213495
213714
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
213496
213715
  */
213497
- if (symbol === undefined) {
213498
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrders() requires a symbol argument');
213499
- }
213500
213716
  await this.loadMarkets();
213501
- const market = this.market(symbol);
213502
- symbol = market['symbol'];
213503
- if (market['type'] !== 'spot') {
213504
- 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
+ };
213505
213736
  }
213506
- const channel = 'spot/user/order';
213507
- const orders = await this.subscribePrivate(channel, symbol, params);
213737
+ else {
213738
+ request = {
213739
+ 'action': 'subscribe',
213740
+ 'args': ['futures/order'],
213741
+ };
213742
+ }
213743
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
213744
+ const newOrders = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
213508
213745
  if (this.newUpdates) {
213509
- limit = orders.getLimit(symbol, limit);
213746
+ return newOrders;
213510
213747
  }
213511
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
213748
+ return this.filterBySymbolSinceLimit(this.orders, symbol, since, limit, true);
213512
213749
  }
213513
213750
  handleOrders(client, message) {
213514
213751
  //
213515
- // {
213516
- // "data":[
213517
- // {
213518
- // "symbol": "LTC_USDT",
213519
- // "notional": '',
213520
- // "side": "buy",
213521
- // "last_fill_time": "0",
213522
- // "ms_t": "1646216634000",
213523
- // "type": "limit",
213524
- // "filled_notional": "0.000000000000000000000000000000",
213525
- // "last_fill_price": "0",
213526
- // "size": "0.500000000000000000000000000000",
213527
- // "price": "50.000000000000000000000000000000",
213528
- // "last_fill_count": "0",
213529
- // "filled_size": "0.000000000000000000000000000000",
213530
- // "margin_trading": "0",
213531
- // "state": "8",
213532
- // "order_id": "24807076628",
213533
- // "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
+ // }
213534
213800
  // }
213535
- // ],
213536
- // "table":"spot/user/order"
213537
- // }
213801
+ // ]
213802
+ // }
213538
213803
  //
213539
- const channel = this.safeString(message, 'table');
213540
- const orders = this.safeValue(message, 'data', []);
213804
+ const orders = this.safeValue(message, 'data');
213805
+ if (orders === undefined) {
213806
+ return;
213807
+ }
213541
213808
  const ordersLength = orders.length;
213809
+ const newOrders = [];
213810
+ const symbols = {};
213542
213811
  if (ordersLength > 0) {
213543
213812
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
213544
213813
  if (this.orders === undefined) {
213545
213814
  this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
213546
213815
  }
213547
213816
  const stored = this.orders;
213548
- const marketIds = [];
213549
213817
  for (let i = 0; i < orders.length; i++) {
213550
213818
  const order = this.parseWsOrder(orders[i]);
213551
213819
  stored.append(order);
213820
+ newOrders.push(order);
213552
213821
  const symbol = order['symbol'];
213553
- const market = this.market(symbol);
213554
- marketIds.push(market['id']);
213555
- }
213556
- for (let i = 0; i < marketIds.length; i++) {
213557
- const messageHash = channel + ':' + marketIds[i];
213558
- client.resolve(this.orders, messageHash);
213822
+ symbols[symbol] = true;
213559
213823
  }
213560
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');
213561
213831
  }
213562
213832
  parseWsOrder(order, market = undefined) {
213563
213833
  //
213564
- // {
213565
- // "symbol": "LTC_USDT",
213566
- // "notional": '',
213567
- // "side": "buy",
213568
- // "last_fill_time": "0",
213569
- // "ms_t": "1646216634000",
213570
- // "type": "limit",
213571
- // "filled_notional": "0.000000000000000000000000000000",
213572
- // "last_fill_price": "0",
213573
- // "size": "0.500000000000000000000000000000",
213574
- // "price": "50.000000000000000000000000000000",
213575
- // "last_fill_count": "0",
213576
- // "filled_size": "0.000000000000000000000000000000",
213577
- // "margin_trading": "0",
213578
- // "state": "8",
213579
- // "order_id": "24807076628",
213580
- // "order_type": "0"
213581
- // }
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
+ // }
213582
213875
  //
213583
- const marketId = this.safeString(order, 'symbol');
213584
- market = this.safeMarket(marketId, market);
213585
- const id = this.safeString(order, 'order_id');
213586
- const clientOrderId = this.safeString(order, 'clientOid');
213587
- const price = this.safeString(order, 'price');
213588
- const filled = this.safeString(order, 'filled_size');
213589
- const amount = this.safeString(order, 'size');
213590
- const type = this.safeString(order, 'type');
213591
- const rawState = this.safeString(order, 'state');
213592
- const status = this.parseOrderStatusByType(market['type'], rawState);
213593
- 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');
213594
214097
  const symbol = market['symbol'];
213595
- const side = this.safeStringLower(order, 'side');
213596
- return this.safeOrder({
213597
- '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,
213598
214105
  'symbol': symbol,
213599
- 'id': id,
213600
- 'clientOrderId': clientOrderId,
213601
- 'timestamp': undefined,
213602
- 'datetime': undefined,
213603
- 'lastTradeTimestamp': timestamp,
213604
- 'type': type,
213605
- 'timeInForce': undefined,
213606
- 'postOnly': undefined,
213607
- 'side': side,
213608
- 'price': price,
213609
- 'stopPrice': undefined,
213610
- 'triggerPrice': undefined,
213611
- 'amount': amount,
213612
- 'cost': undefined,
213613
- 'average': undefined,
213614
- 'filled': filled,
213615
- 'remaining': undefined,
213616
- 'status': status,
213617
- 'fee': undefined,
213618
- 'trades': undefined,
213619
- }, 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
+ });
213620
214132
  }
213621
214133
  handleTrade(client, message) {
213622
214134
  //
213623
- // {
213624
- // "table": "spot/trade",
213625
- // "data": [
213626
- // {
213627
- // "price": "52700.50",
213628
- // "s_t": 1630982050,
213629
- // "side": "buy",
213630
- // "size": "0.00112",
213631
- // "symbol": "BTC_USDT"
213632
- // },
213633
- // ]
213634
- // }
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
+ // }
213635
214148
  //
213636
- const table = this.safeString(message, 'table');
213637
- const data = this.safeValue(message, 'data', []);
213638
- 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;
213639
214175
  for (let i = 0; i < data.length; i++) {
213640
- const trade = this.parseTrade(data[i]);
214176
+ const trade = this.parseWsTrade(data[i]);
213641
214177
  const symbol = trade['symbol'];
213642
- const marketId = this.safeString(trade['info'], 'symbol');
213643
- const messageHash = table + ':' + marketId;
213644
- let stored = this.safeValue(this.trades, symbol);
214178
+ const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
214179
+ stored = this.safeValue(this.trades, symbol);
213645
214180
  if (stored === undefined) {
213646
214181
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCache */ .ZL(tradesLimit);
213647
214182
  this.trades[symbol] = stored;
213648
214183
  }
213649
214184
  stored.append(trade);
213650
- client.resolve(stored, messageHash);
213651
214185
  }
214186
+ let messageHash = channel;
214187
+ if (isSpot) {
214188
+ messageHash += ':' + this.safeString(data[0], 'symbol');
214189
+ }
214190
+ client.resolve(stored, messageHash);
213652
214191
  return message;
213653
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
+ }
213654
214237
  handleTicker(client, message) {
213655
214238
  //
213656
- // {
213657
- // "data": [
213658
- // {
213659
- // "base_volume_24h": "78615593.81",
213660
- // "high_24h": "52756.97",
213661
- // "last_price": "52638.31",
213662
- // "low_24h": "50991.35",
213663
- // "open_24h": "51692.03",
213664
- // "s_t": 1630981727,
213665
- // "symbol": "BTC_USDT"
213666
- // }
213667
- // ],
213668
- // "table": "spot/ticker"
213669
- // }
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
+ // }
213670
214267
  //
213671
214268
  const table = this.safeString(message, 'table');
213672
- const data = this.safeValue(message, 'data', []);
213673
- for (let i = 0; i < data.length; i++) {
213674
- const ticker = this.parseTicker(data[i]);
213675
- const symbol = ticker['symbol'];
213676
- const marketId = this.safeString(ticker['info'], 'symbol');
213677
- 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');
213678
214287
  this.tickers[symbol] = ticker;
213679
- client.resolve(ticker, messageHash);
214288
+ client.resolve(ticker, 'tickers');
214289
+ this.resolvePromiseIfMessagehashMatches(client, 'tickers::', symbol, ticker);
213680
214290
  }
213681
214291
  return message;
213682
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
+ }
213683
214330
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
213684
214331
  /**
213685
214332
  * @method
213686
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
213687
214336
  * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
213688
214337
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
213689
214338
  * @param {string} timeframe the length of time each candle represents
@@ -213694,10 +214343,19 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213694
214343
  */
213695
214344
  await this.loadMarkets();
213696
214345
  symbol = this.symbol(symbol);
214346
+ const market = this.market(symbol);
214347
+ let type = 'spot';
214348
+ [type, params] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
213697
214349
  const timeframes = this.safeValue(this.options, 'timeframes', {});
213698
214350
  const interval = this.safeString(timeframes, timeframe);
213699
- const name = 'kline' + interval;
213700
- 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);
213701
214359
  if (this.newUpdates) {
213702
214360
  limit = ohlcv.getLimit(symbol, limit);
213703
214361
  }
@@ -213705,40 +214363,82 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213705
214363
  }
213706
214364
  handleOHLCV(client, message) {
213707
214365
  //
213708
- // {
213709
- // "data": [
213710
- // {
213711
- // "candle": [
213712
- // 1631056350,
213713
- // "46532.83",
213714
- // "46555.71",
213715
- // "46511.41",
213716
- // "46555.71",
213717
- // "0.25"
213718
- // ],
213719
- // "symbol": "BTC_USDT"
213720
- // }
213721
- // ],
213722
- // "table": "spot/kline1m"
213723
- // }
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
+ // }
213724
214399
  //
213725
- const table = this.safeString(message, 'table');
213726
- const data = this.safeValue(message, 'data', []);
213727
- const parts = table.split('/');
213728
- const part1 = this.safeString(parts, 1);
213729
- 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);
213730
214412
  // use a reverse lookup in a static map instead
213731
214413
  const timeframes = this.safeValue(this.options, 'timeframes', {});
213732
214414
  const timeframe = this.findTimeframe(interval, timeframes);
213733
214415
  const duration = this.parseTimeframe(timeframe);
213734
214416
  const durationInMs = duration * 1000;
213735
- for (let i = 0; i < data.length; i++) {
213736
- const marketId = this.safeString(data[i], 'symbol');
213737
- const candle = this.safeValue(data[i], 'candle');
213738
- 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');
213739
214440
  const symbol = market['symbol'];
213740
- const parsed = this.parseOHLCV(candle, market);
213741
- parsed[0] = this.parseToInt(parsed[0] / durationInMs) * durationInMs;
214441
+ const items = this.safeValue(data, 'items', []);
213742
214442
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
213743
214443
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
213744
214444
  if (stored === undefined) {
@@ -213746,24 +214446,34 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213746
214446
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
213747
214447
  this.ohlcvs[symbol][timeframe] = stored;
213748
214448
  }
213749
- stored.append(parsed);
213750
- const messageHash = table + ':' + marketId;
213751
- 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);
213752
214455
  }
213753
214456
  }
213754
214457
  async watchOrderBook(symbol, limit = undefined, params = {}) {
213755
214458
  /**
213756
214459
  * @method
213757
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
213758
214463
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
213759
214464
  * @param {string} symbol unified symbol of the market to fetch the order book for
213760
214465
  * @param {int} [limit] the maximum amount of order book entries to return
213761
214466
  * @param {object} [params] extra parameters specific to the exchange API endpoint
213762
214467
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
213763
214468
  */
214469
+ await this.loadMarkets();
213764
214470
  const options = this.safeValue(this.options, 'watchOrderBook', {});
213765
214471
  const depth = this.safeString(options, 'depth', 'depth50');
213766
- 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);
213767
214477
  return orderbook.limit();
213768
214478
  }
213769
214479
  handleDelta(bookside, delta) {
@@ -213811,22 +214521,19 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213811
214521
  }
213812
214522
  handleOrderBook(client, message) {
213813
214523
  //
214524
+ // spot
213814
214525
  // {
213815
214526
  // "data": [
213816
214527
  // {
213817
214528
  // "asks": [
213818
214529
  // [ '46828.38', "0.21847" ],
213819
214530
  // [ '46830.68', "0.08232" ],
213820
- // [ '46832.08', "0.09285" ],
213821
- // [ '46837.82', "0.02028" ],
213822
- // [ '46839.43', "0.15068" ]
214531
+ // ...
213823
214532
  // ],
213824
214533
  // "bids": [
213825
214534
  // [ '46820.78', "0.00444" ],
213826
214535
  // [ '46814.33', "0.00234" ],
213827
- // [ '46813.50', "0.05021" ],
213828
- // [ '46808.14', "0.00217" ],
213829
- // [ '46808.04', "0.00013" ]
214536
+ // ...
213830
214537
  // ],
213831
214538
  // "ms_t": 1631044962431,
213832
214539
  // "symbol": "BTC_USDT"
@@ -213834,32 +214541,99 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213834
214541
  // ],
213835
214542
  // "table": "spot/depth5"
213836
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
+ // }
213837
214564
  //
213838
- const data = this.safeValue(message, 'data', []);
213839
- 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');
213840
214572
  const parts = table.split('/');
213841
214573
  const lastPart = this.safeString(parts, 1);
213842
- const limitString = lastPart.replace('depth', '');
213843
- const limit = parseInt(limitString);
213844
- for (let i = 0; i < data.length; i++) {
213845
- const update = data[i];
213846
- 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');
213847
214600
  const symbol = this.safeSymbol(marketId);
213848
214601
  let orderbook = this.safeValue(this.orderbooks, symbol);
213849
214602
  if (orderbook === undefined) {
213850
214603
  orderbook = this.orderBook({}, limit);
214604
+ orderbook['symbol'] = symbol;
213851
214605
  this.orderbooks[symbol] = orderbook;
213852
214606
  }
213853
- orderbook.reset({});
213854
- this.handleOrderBookMessage(client, update, orderbook);
213855
- 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;
213856
214631
  client.resolve(orderbook, messageHash);
213857
214632
  }
213858
- return message;
213859
214633
  }
213860
- async authenticate(params = {}) {
214634
+ async authenticate(type, params = {}) {
213861
214635
  this.checkRequiredCredentials();
213862
- const url = this.implodeHostname(this.urls['api']['ws']['private']);
214636
+ const url = this.implodeHostname(this.urls['api']['ws'][type]['private']);
213863
214637
  const messageHash = 'authenticated';
213864
214638
  const client = this.client(url);
213865
214639
  const future = client.future(messageHash);
@@ -213869,16 +214643,29 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213869
214643
  const memo = this.uid;
213870
214644
  const path = 'bitmart.WebSocket';
213871
214645
  const auth = timestamp + '#' + memo + '#' + path;
213872
- const signature = this.hmac(this.encode(auth), this.encode(this.secret), _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_3__/* .sha256 */ .J);
213873
- const operation = 'login';
213874
- const request = {
213875
- 'op': operation,
213876
- 'args': [
213877
- this.apiKey,
213878
- timestamp,
213879
- signature,
213880
- ],
213881
- };
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
+ }
213882
214669
  const message = this.extend(request, params);
213883
214670
  this.watch(url, messageHash, message, messageHash);
213884
214671
  }
@@ -213886,13 +214673,16 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213886
214673
  }
213887
214674
  handleSubscriptionStatus(client, message) {
213888
214675
  //
213889
- // {"event":"subscribe","channel":"spot/depth:BTC-USDT"}
214676
+ // {"event":"subscribe","channel":"spot/depth:BTC-USDT"}
213890
214677
  //
213891
214678
  return message;
213892
214679
  }
213893
214680
  handleAuthenticate(client, message) {
213894
214681
  //
213895
- // { event: "login" }
214682
+ // spot
214683
+ // { event: "login" }
214684
+ // swap
214685
+ // { action: 'access', success: true }
213896
214686
  //
213897
214687
  const messageHash = 'authenticated';
213898
214688
  const future = this.safeValue(client.futures, messageHash);
@@ -213900,29 +214690,41 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213900
214690
  }
213901
214691
  handleErrorMessage(client, message) {
213902
214692
  //
213903
- // { event: "error", message: "Invalid sign", errorCode: 30013 }
213904
- // {"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
+ // }
213905
214702
  //
213906
214703
  const errorCode = this.safeString(message, 'errorCode');
214704
+ const error = this.safeString(message, 'error');
213907
214705
  try {
213908
- if (errorCode !== undefined) {
214706
+ if (errorCode !== undefined || error !== undefined) {
213909
214707
  const feedback = this.id + ' ' + this.json(message);
213910
214708
  this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
213911
- const messageString = this.safeValue(message, 'message');
213912
- if (messageString !== undefined) {
213913
- 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);
213914
214714
  }
214715
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(feedback);
213915
214716
  }
213916
214717
  return false;
213917
214718
  }
213918
214719
  catch (e) {
213919
- if (e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError) {
214720
+ if ((e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError)) {
213920
214721
  const messageHash = 'authenticated';
213921
214722
  client.reject(e, messageHash);
213922
214723
  if (messageHash in client.subscriptions) {
213923
214724
  delete client.subscriptions[messageHash];
213924
214725
  }
213925
214726
  }
214727
+ client.reject(e);
213926
214728
  return true;
213927
214729
  }
213928
214730
  }
@@ -213955,14 +214757,14 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213955
214757
  //
213956
214758
  // { data: '', table: "spot/user/order" }
213957
214759
  //
213958
- const table = this.safeString(message, 'table');
213959
- if (table === undefined) {
213960
- 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');
213961
214763
  if (event !== undefined) {
213962
214764
  const methods = {
213963
214765
  // 'info': this.handleSystemStatus,
213964
- // 'book': 'handleOrderBook',
213965
214766
  'login': this.handleAuthenticate,
214767
+ 'access': this.handleAuthenticate,
213966
214768
  'subscribe': this.handleSubscriptionStatus,
213967
214769
  };
213968
214770
  const method = this.safeValue(methods, event);
@@ -213975,30 +214777,25 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213975
214777
  }
213976
214778
  }
213977
214779
  else {
213978
- const parts = table.split('/');
213979
- const name = this.safeString(parts, 1);
213980
214780
  const methods = {
213981
- 'depth': this.handleOrderBook,
213982
214781
  'depth5': this.handleOrderBook,
213983
214782
  'depth20': this.handleOrderBook,
213984
214783
  'depth50': this.handleOrderBook,
213985
214784
  'ticker': this.handleTicker,
213986
214785
  'trade': this.handleTrade,
213987
- // ...
214786
+ 'kline': this.handleOHLCV,
214787
+ 'order': this.handleOrders,
214788
+ 'position': this.handlePositions,
214789
+ 'balance': this.handleBalance,
214790
+ 'asset': this.handleBalance,
213988
214791
  };
213989
- let method = this.safeValue(methods, name);
213990
- if (name.indexOf('kline') >= 0) {
213991
- method = this.handleOHLCV;
213992
- }
213993
- const privateName = this.safeString(parts, 2);
213994
- if (privateName === 'order') {
213995
- method = this.handleOrders;
213996
- }
213997
- if (method === undefined) {
213998
- return message;
213999
- }
214000
- else {
214001
- 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
+ }
214002
214799
  }
214003
214800
  }
214004
214801
  }
@@ -289039,7 +289836,7 @@ SOFTWARE.
289039
289836
 
289040
289837
  //-----------------------------------------------------------------------------
289041
289838
  // this is updated by vss.js when building
289042
- const version = '4.1.84';
289839
+ const version = '4.1.85';
289043
289840
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
289044
289841
  //-----------------------------------------------------------------------------
289045
289842