ccxt 4.2.90 → 4.2.92

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.
@@ -9315,7 +9315,7 @@ class Exchange {
9315
9315
  parseToInt(number) {
9316
9316
  // Solve Common parseInt misuse ex: parseInt ((since / 1000).toString ())
9317
9317
  // using a number as parameter which is not valid in ts
9318
- const stringifiedNumber = number.toString();
9318
+ const stringifiedNumber = this.numberToString(number);
9319
9319
  const convertedNumber = parseFloat(stringifiedNumber);
9320
9320
  return parseInt(convertedNumber);
9321
9321
  }
@@ -11808,13 +11808,6 @@ class Exchange {
11808
11808
  if (!this.substituteCommonCurrencyCodes) {
11809
11809
  return code;
11810
11810
  }
11811
- // if the provided code already exists as a value in commonCurrencies dict, then we should not again transform it
11812
- // more details at: https://github.com/ccxt/ccxt/issues/21112#issuecomment-2031293691
11813
- const commonCurrencies = Object.values(this.commonCurrencies);
11814
- const exists = this.inArray(code, commonCurrencies);
11815
- if (exists) {
11816
- return code;
11817
- }
11818
11811
  return this.safeString(this.commonCurrencies, code, code);
11819
11812
  }
11820
11813
  currency(code) {
@@ -12465,7 +12458,6 @@ class Exchange {
12465
12458
  * @returns {object} objects with withdraw and deposit fees, indexed by currency codes
12466
12459
  */
12467
12460
  const depositWithdrawFees = {};
12468
- codes = this.marketCodes(codes);
12469
12461
  const isArray = Array.isArray(response);
12470
12462
  let responseKeys = response;
12471
12463
  if (!isArray) {
@@ -13035,7 +13027,7 @@ class Exchange {
13035
13027
  return reconstructedDate;
13036
13028
  }
13037
13029
  convertMarketIdExpireDate(date) {
13038
- // parse 19JAN24 to 240119
13030
+ // parse 03JAN24 to 240103
13039
13031
  const monthMappping = {
13040
13032
  'JAN': '01',
13041
13033
  'FEB': '02',
@@ -13050,6 +13042,10 @@ class Exchange {
13050
13042
  'NOV': '11',
13051
13043
  'DEC': '12',
13052
13044
  };
13045
+ // if exchange omits first zero and provides i.e. '3JAN24' instead of '03JAN24'
13046
+ if (date.length === 6) {
13047
+ date = '0' + date;
13048
+ }
13053
13049
  const year = date.slice(0, 2);
13054
13050
  const monthName = date.slice(2, 5);
13055
13051
  const month = this.safeString(monthMappping, monthName);
@@ -84546,6 +84542,7 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
84546
84542
  'v5/broker/earning-record': 5,
84547
84543
  'v5/broker/earnings-info': 5,
84548
84544
  'v5/broker/account-info': 5,
84545
+ 'v5/broker/asset/query-sub-member-deposit-record': 10,
84549
84546
  },
84550
84547
  'post': {
84551
84548
  // Legacy option USDC
@@ -94765,6 +94762,7 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
94765
94762
  'CGLD': 'CELO',
94766
94763
  },
94767
94764
  'options': {
94765
+ 'brokerId': 'ccxt',
94768
94766
  'stablePairs': ['BUSD-USD', 'CBETH-ETH', 'DAI-USD', 'GUSD-USD', 'GYEN-USD', 'PAX-USD', 'PAX-USDT', 'USDC-EUR', 'USDC-GBP', 'USDT-EUR', 'USDT-GBP', 'USDT-USD', 'USDT-USDC', 'WBTC-BTC'],
94769
94767
  'fetchCurrencies': {
94770
94768
  'expires': 5000,
@@ -96775,8 +96773,9 @@ class coinbase extends _abstract_coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
96775
96773
  */
96776
96774
  await this.loadMarkets();
96777
96775
  const market = this.market(symbol);
96776
+ const id = this.safeString(this.options, 'brokerId', 'ccxt');
96778
96777
  let request = {
96779
- 'client_order_id': this.uuid(),
96778
+ 'client_order_id': id + '-' + this.uuid(),
96780
96779
  'product_id': market['id'],
96781
96780
  'side': side.toUpperCase(),
96782
96781
  };
@@ -127450,117 +127449,130 @@ class deribit extends _abstract_deribit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
127450
127449
  * @name deribit#fetchMarkets
127451
127450
  * @description retrieves data on all markets for deribit
127452
127451
  * @see https://docs.deribit.com/#public-get_currencies
127452
+ * @see https://docs.deribit.com/#public-get_instruments
127453
127453
  * @param {object} [params] extra parameters specific to the exchange API endpoint
127454
127454
  * @returns {object[]} an array of objects representing market data
127455
127455
  */
127456
- const currenciesResponse = await this.publicGetGetCurrencies(params);
127457
- //
127458
- // {
127459
- // "jsonrpc": "2.0",
127460
- // "result": [
127461
- // {
127462
- // "withdrawal_priorities": [
127463
- // { value: 0.15, name: "very_low" },
127464
- // { value: 1.5, name: "very_high" },
127465
- // ],
127466
- // "withdrawal_fee": 0.0005,
127467
- // "min_withdrawal_fee": 0.0005,
127468
- // "min_confirmations": 1,
127469
- // "fee_precision": 4,
127470
- // "currency_long": "Bitcoin",
127471
- // "currency": "BTC",
127472
- // "coin_type": "BITCOIN"
127473
- // }
127474
- // ],
127475
- // "usIn": 1583761588590479,
127476
- // "usOut": 1583761588590544,
127477
- // "usDiff": 65,
127478
- // "testnet": false
127479
- // }
127480
- //
127481
- const parsedMarkets = {};
127482
- const currenciesResult = this.safeValue(currenciesResponse, 'result', []);
127456
+ const instrumentsResponses = [];
127483
127457
  const result = [];
127484
- for (let i = 0; i < currenciesResult.length; i++) {
127485
- const currencyId = this.safeString(currenciesResult[i], 'currency');
127486
- const request = {
127487
- 'currency': currencyId,
127488
- };
127489
- const instrumentsResponse = await this.publicGetGetInstruments(this.extend(request, params));
127458
+ const parsedMarkets = {};
127459
+ let fetchAllMarkets = undefined;
127460
+ [fetchAllMarkets, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'fetchAllMarkets', true);
127461
+ if (fetchAllMarkets) {
127462
+ const instrumentsResponse = await this.publicGetGetInstruments(params);
127463
+ instrumentsResponses.push(instrumentsResponse);
127464
+ }
127465
+ else {
127466
+ const currenciesResponse = await this.publicGetGetCurrencies(params);
127490
127467
  //
127491
127468
  // {
127492
- // "jsonrpc":"2.0",
127493
- // "result":[
127494
- // {
127495
- // "tick_size":0.0005,
127496
- // "taker_commission":0.0003,
127497
- // "strike":52000.0,
127498
- // "settlement_period":"month",
127499
- // "settlement_currency":"BTC",
127500
- // "quote_currency":"BTC",
127501
- // "option_type":"put", // put, call
127502
- // "min_trade_amount":0.1,
127503
- // "maker_commission":0.0003,
127504
- // "kind":"option",
127505
- // "is_active":true,
127506
- // "instrument_name":"BTC-24JUN22-52000-P",
127507
- // "expiration_timestamp":1656057600000,
127508
- // "creation_timestamp":1648199543000,
127509
- // "counter_currency":"USD",
127510
- // "contract_size":1.0,
127511
- // "block_trade_commission":0.0003,
127512
- // "base_currency":"BTC"
127513
- // },
127514
- // {
127515
- // "tick_size":0.5,
127516
- // "taker_commission":0.0005,
127517
- // "settlement_period":"month", // month, week
127518
- // "settlement_currency":"BTC",
127519
- // "quote_currency":"USD",
127520
- // "min_trade_amount":10.0,
127521
- // "max_liquidation_commission":0.0075,
127522
- // "max_leverage":50,
127523
- // "maker_commission":0.0,
127524
- // "kind":"future",
127525
- // "is_active":true,
127526
- // "instrument_name":"BTC-27MAY22",
127527
- // "future_type":"reversed",
127528
- // "expiration_timestamp":1653638400000,
127529
- // "creation_timestamp":1648195209000,
127530
- // "counter_currency":"USD",
127531
- // "contract_size":10.0,
127532
- // "block_trade_commission":0.0001,
127533
- // "base_currency":"BTC"
127534
- // },
127469
+ // "jsonrpc": "2.0",
127470
+ // "result": [
127535
127471
  // {
127536
- // "tick_size":0.5,
127537
- // "taker_commission":0.0005,
127538
- // "settlement_period":"perpetual",
127539
- // "settlement_currency":"BTC",
127540
- // "quote_currency":"USD",
127541
- // "min_trade_amount":10.0,
127542
- // "max_liquidation_commission":0.0075,
127543
- // "max_leverage":50,
127544
- // "maker_commission":0.0,
127545
- // "kind":"future",
127546
- // "is_active":true,
127547
- // "instrument_name":"BTC-PERPETUAL",
127548
- // "future_type":"reversed",
127549
- // "expiration_timestamp":32503708800000,
127550
- // "creation_timestamp":1534242287000,
127551
- // "counter_currency":"USD",
127552
- // "contract_size":10.0,
127553
- // "block_trade_commission":0.0001,
127554
- // "base_currency":"BTC"
127555
- // },
127472
+ // "withdrawal_priorities": [
127473
+ // { value: 0.15, name: "very_low" },
127474
+ // { value: 1.5, name: "very_high" },
127475
+ // ],
127476
+ // "withdrawal_fee": 0.0005,
127477
+ // "min_withdrawal_fee": 0.0005,
127478
+ // "min_confirmations": 1,
127479
+ // "fee_precision": 4,
127480
+ // "currency_long": "Bitcoin",
127481
+ // "currency": "BTC",
127482
+ // "coin_type": "BITCOIN"
127483
+ // }
127556
127484
  // ],
127557
- // "usIn":1648691472831791,
127558
- // "usOut":1648691472831896,
127559
- // "usDiff":105,
127560
- // "testnet":false
127485
+ // "usIn": 1583761588590479,
127486
+ // "usOut": 1583761588590544,
127487
+ // "usDiff": 65,
127488
+ // "testnet": false
127561
127489
  // }
127562
127490
  //
127563
- const instrumentsResult = this.safeValue(instrumentsResponse, 'result', []);
127491
+ const currenciesResult = this.safeValue(currenciesResponse, 'result', []);
127492
+ for (let i = 0; i < currenciesResult.length; i++) {
127493
+ const currencyId = this.safeString(currenciesResult[i], 'currency');
127494
+ const request = {
127495
+ 'currency': currencyId,
127496
+ };
127497
+ const instrumentsResponse = await this.publicGetGetInstruments(this.extend(request, params));
127498
+ //
127499
+ // {
127500
+ // "jsonrpc":"2.0",
127501
+ // "result":[
127502
+ // {
127503
+ // "tick_size":0.0005,
127504
+ // "taker_commission":0.0003,
127505
+ // "strike":52000.0,
127506
+ // "settlement_period":"month",
127507
+ // "settlement_currency":"BTC",
127508
+ // "quote_currency":"BTC",
127509
+ // "option_type":"put", // put, call
127510
+ // "min_trade_amount":0.1,
127511
+ // "maker_commission":0.0003,
127512
+ // "kind":"option",
127513
+ // "is_active":true,
127514
+ // "instrument_name":"BTC-24JUN22-52000-P",
127515
+ // "expiration_timestamp":1656057600000,
127516
+ // "creation_timestamp":1648199543000,
127517
+ // "counter_currency":"USD",
127518
+ // "contract_size":1.0,
127519
+ // "block_trade_commission":0.0003,
127520
+ // "base_currency":"BTC"
127521
+ // },
127522
+ // {
127523
+ // "tick_size":0.5,
127524
+ // "taker_commission":0.0005,
127525
+ // "settlement_period":"month", // month, week
127526
+ // "settlement_currency":"BTC",
127527
+ // "quote_currency":"USD",
127528
+ // "min_trade_amount":10.0,
127529
+ // "max_liquidation_commission":0.0075,
127530
+ // "max_leverage":50,
127531
+ // "maker_commission":0.0,
127532
+ // "kind":"future",
127533
+ // "is_active":true,
127534
+ // "instrument_name":"BTC-27MAY22",
127535
+ // "future_type":"reversed",
127536
+ // "expiration_timestamp":1653638400000,
127537
+ // "creation_timestamp":1648195209000,
127538
+ // "counter_currency":"USD",
127539
+ // "contract_size":10.0,
127540
+ // "block_trade_commission":0.0001,
127541
+ // "base_currency":"BTC"
127542
+ // },
127543
+ // {
127544
+ // "tick_size":0.5,
127545
+ // "taker_commission":0.0005,
127546
+ // "settlement_period":"perpetual",
127547
+ // "settlement_currency":"BTC",
127548
+ // "quote_currency":"USD",
127549
+ // "min_trade_amount":10.0,
127550
+ // "max_liquidation_commission":0.0075,
127551
+ // "max_leverage":50,
127552
+ // "maker_commission":0.0,
127553
+ // "kind":"future",
127554
+ // "is_active":true,
127555
+ // "instrument_name":"BTC-PERPETUAL",
127556
+ // "future_type":"reversed",
127557
+ // "expiration_timestamp":32503708800000,
127558
+ // "creation_timestamp":1534242287000,
127559
+ // "counter_currency":"USD",
127560
+ // "contract_size":10.0,
127561
+ // "block_trade_commission":0.0001,
127562
+ // "base_currency":"BTC"
127563
+ // },
127564
+ // ],
127565
+ // "usIn":1648691472831791,
127566
+ // "usOut":1648691472831896,
127567
+ // "usDiff":105,
127568
+ // "testnet":false
127569
+ // }
127570
+ //
127571
+ instrumentsResponses.push(instrumentsResponse);
127572
+ }
127573
+ }
127574
+ for (let i = 0; i < instrumentsResponses.length; i++) {
127575
+ const instrumentsResult = this.safeValue(instrumentsResponses[i], 'result', []);
127564
127576
  for (let k = 0; k < instrumentsResult.length; k++) {
127565
127577
  const market = instrumentsResult[k];
127566
127578
  const kind = this.safeString(market, 'kind');
@@ -145334,7 +145346,8 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
145334
145346
  // '<td>0.01 USD', // quote currency price increment
145335
145347
  // '</tr>'
145336
145348
  // ]
145337
- const marketId = cells[0].replace('<td>', '');
145349
+ let marketId = cells[0].replace('<td>', '');
145350
+ marketId = marketId.replace('*', '');
145338
145351
  // const base = this.safeCurrencyCode (baseId);
145339
145352
  const minAmountString = cells[1].replace('<td>', '');
145340
145353
  const minAmountParts = minAmountString.split(' ');
@@ -170547,10 +170560,7 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
170547
170560
  if (currencyId !== undefined) {
170548
170561
  if (currencyId.length > 3) {
170549
170562
  if ((currencyId.indexOf('X') === 0) || (currencyId.indexOf('Z') === 0)) {
170550
- if (currencyId.indexOf('.') > 0) {
170551
- return super.safeCurrency(currencyId, currency);
170552
- }
170553
- else {
170563
+ if (!(currencyId.indexOf('.') > 0)) {
170554
170564
  currencyId = currencyId.slice(1);
170555
170565
  }
170556
170566
  }
@@ -170599,8 +170609,13 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
170599
170609
  // {
170600
170610
  // "error": [],
170601
170611
  // "result": {
170602
- // "ADA": { "aclass": "currency", "altname": "ADA", "decimals": 8, "display_decimals": 6 },
170603
- // "BCH": { "aclass": "currency", "altname": "BCH", "decimals": 10, "display_decimals": 5 },
170612
+ // "BCH": {
170613
+ // "aclass": "currency",
170614
+ // "altname": "BCH",
170615
+ // "decimals": 10,
170616
+ // "display_decimals": 5
170617
+ // "status": "enabled",
170618
+ // },
170604
170619
  // ...
170605
170620
  // },
170606
170621
  // }
@@ -170615,15 +170630,15 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
170615
170630
  // see: https://support.kraken.com/hc/en-us/articles/201893608-What-are-the-withdrawal-fees-
170616
170631
  // to add support for multiple withdrawal/deposit methods and
170617
170632
  // differentiated fees for each particular method
170618
- const code = this.safeCurrencyCode(this.safeString(currency, 'altname'));
170633
+ const code = this.safeCurrencyCode(id);
170619
170634
  const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'decimals')));
170620
170635
  // assumes all currencies are active except those listed above
170621
- const active = !this.inArray(code, this.options['inactiveCurrencies']);
170636
+ const active = this.safeString(currency, 'status') === 'enabled';
170622
170637
  result[code] = {
170623
170638
  'id': id,
170624
170639
  'code': code,
170625
170640
  'info': currency,
170626
- 'name': code,
170641
+ 'name': this.safeString(currency, 'altname'),
170627
170642
  'active': active,
170628
170643
  'deposit': undefined,
170629
170644
  'withdraw': undefined,
@@ -172652,15 +172667,15 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
172652
172667
  * @name kraken#fetchPositions
172653
172668
  * @description fetch all open positions
172654
172669
  * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
172655
- * @param {string[]|undefined} symbols not used by kraken fetchPositions ()
172670
+ * @param {string[]} [symbols] not used by kraken fetchPositions ()
172656
172671
  * @param {object} [params] extra parameters specific to the exchange API endpoint
172657
172672
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
172658
172673
  */
172659
172674
  await this.loadMarkets();
172660
172675
  const request = {
172661
- // 'txid': 'comma delimited list of transaction ids to restrict output to',
172662
- // 'docalcs': false, // whether or not to include profit/loss calculations
172663
- // 'consolidation': 'market', // what to consolidate the positions data around, market will consolidate positions based on market pair
172676
+ // 'txid': 'comma delimited list of transaction ids to restrict output to',
172677
+ 'docalcs': 'true',
172678
+ 'consolidation': 'market', // what to consolidate the positions data around, market will consolidate positions based on market pair
172664
172679
  };
172665
172680
  const response = await this.privatePostOpenPositions(this.extend(request, params));
172666
172681
  //
@@ -172708,9 +172723,58 @@ class kraken extends _abstract_kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
172708
172723
  // ]
172709
172724
  // }
172710
172725
  //
172711
- const result = this.safeValue(response, 'result');
172712
- // todo unify parsePosition/parsePositions
172713
- return result;
172726
+ symbols = this.marketSymbols(symbols);
172727
+ const result = this.safeList(response, 'result');
172728
+ const results = this.parsePositions(result, symbols);
172729
+ return this.filterByArrayPositions(results, 'symbol', symbols, false);
172730
+ }
172731
+ parsePosition(position, market = undefined) {
172732
+ //
172733
+ // {
172734
+ // "pair": "ETHUSDT",
172735
+ // "positions": "1",
172736
+ // "type": "buy",
172737
+ // "leverage": "2.00000",
172738
+ // "cost": "28.49800",
172739
+ // "fee": "0.07979",
172740
+ // "vol": "0.02000000",
172741
+ // "vol_closed": "0.00000000",
172742
+ // "margin": "14.24900"
172743
+ // }
172744
+ //
172745
+ const marketId = this.safeString(position, 'pair');
172746
+ const rawSide = this.safeString(position, 'type');
172747
+ const side = (rawSide === 'buy') ? 'long' : 'short';
172748
+ return this.safePosition({
172749
+ 'info': position,
172750
+ 'id': undefined,
172751
+ 'symbol': this.safeSymbol(marketId, market),
172752
+ 'notional': undefined,
172753
+ 'marginMode': undefined,
172754
+ 'liquidationPrice': undefined,
172755
+ 'entryPrice': undefined,
172756
+ 'unrealizedPnl': this.safeNumber(position, 'net'),
172757
+ 'realizedPnl': undefined,
172758
+ 'percentage': undefined,
172759
+ 'contracts': this.safeNumber(position, 'vol'),
172760
+ 'contractSize': undefined,
172761
+ 'markPrice': undefined,
172762
+ 'lastPrice': undefined,
172763
+ 'side': side,
172764
+ 'hedged': undefined,
172765
+ 'timestamp': undefined,
172766
+ 'datetime': undefined,
172767
+ 'lastUpdateTimestamp': undefined,
172768
+ 'maintenanceMargin': undefined,
172769
+ 'maintenanceMarginPercentage': undefined,
172770
+ 'collateral': undefined,
172771
+ 'initialMargin': this.safeNumber(position, 'margin'),
172772
+ 'initialMarginPercentage': undefined,
172773
+ 'leverage': this.safeNumber(position, 'leverage'),
172774
+ 'marginRatio': undefined,
172775
+ 'stopLossPrice': undefined,
172776
+ 'takeProfitPrice': undefined,
172777
+ });
172714
172778
  }
172715
172779
  parseAccountType(account) {
172716
172780
  const accountByType = {
@@ -208126,7 +208190,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208126
208190
  // ]
208127
208191
  // }
208128
208192
  //
208129
- const data = this.safeValue(response, 'data', []);
208193
+ const data = this.safeList(response, 'data', []);
208130
208194
  const dataLength = data.length;
208131
208195
  const update = {
208132
208196
  'updated': undefined,
@@ -208174,8 +208238,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208174
208238
  // "msg": ""
208175
208239
  // }
208176
208240
  //
208177
- const data = this.safeValue(response, 'data', []);
208178
- const first = this.safeValue(data, 0, {});
208241
+ const data = this.safeList(response, 'data', []);
208242
+ const first = this.safeDict(data, 0, {});
208179
208243
  return this.safeInteger(first, 'ts');
208180
208244
  }
208181
208245
  async fetchAccounts(params = {}) {
@@ -208207,7 +208271,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208207
208271
  // "msg": ""
208208
208272
  // }
208209
208273
  //
208210
- const data = this.safeValue(response, 'data', []);
208274
+ const data = this.safeList(response, 'data', []);
208211
208275
  const result = [];
208212
208276
  for (let i = 0; i < data.length; i++) {
208213
208277
  const account = data[i];
@@ -208232,7 +208296,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208232
208296
  * @param {object} [params] extra parameters specific to the exchange API endpoint
208233
208297
  * @returns {object[]} an array of objects representing market data
208234
208298
  */
208235
- const types = this.safeValue(this.options, 'fetchMarkets');
208299
+ const types = this.safeList(this.options, 'fetchMarkets', []);
208236
208300
  let promises = [];
208237
208301
  let result = [];
208238
208302
  for (let i = 0; i < types.length; i++) {
@@ -208336,7 +208400,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208336
208400
  }
208337
208401
  }
208338
208402
  const tickSize = this.safeString(market, 'tickSz');
208339
- const fees = this.safeValue2(this.fees, type, 'trading', {});
208403
+ const fees = this.safeDict2(this.fees, type, 'trading', {});
208340
208404
  let maxLeverage = this.safeString(market, 'lever', '1');
208341
208405
  maxLeverage = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O.stringMax(maxLeverage, '1');
208342
208406
  const maxSpotCost = this.safeNumber(market, 'maxMktSz');
@@ -208395,7 +208459,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208395
208459
  'instType': this.convertToInstrumentType(type),
208396
208460
  };
208397
208461
  if (type === 'option') {
208398
- const optionsUnderlying = this.safeValue(this.options, 'defaultUnderlying', ['BTC-USD', 'ETH-USD']);
208462
+ const optionsUnderlying = this.safeList(this.options, 'defaultUnderlying', ['BTC-USD', 'ETH-USD']);
208399
208463
  const promises = [];
208400
208464
  for (let i = 0; i < optionsUnderlying.length; i++) {
208401
208465
  const underlying = optionsUnderlying[i];
@@ -208405,8 +208469,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208405
208469
  const promisesResult = await Promise.all(promises);
208406
208470
  let markets = [];
208407
208471
  for (let i = 0; i < promisesResult.length; i++) {
208408
- const res = this.safeValue(promisesResult, i, {});
208409
- const options = this.safeValue(res, 'data', []);
208472
+ const res = this.safeDict(promisesResult, i, {});
208473
+ const options = this.safeList(res, 'data', []);
208410
208474
  markets = this.arrayConcat(markets, options);
208411
208475
  }
208412
208476
  return this.parseMarkets(markets);
@@ -208445,7 +208509,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208445
208509
  // "msg": ""
208446
208510
  // }
208447
208511
  //
208448
- const dataResponse = this.safeValue(response, 'data', []);
208512
+ const dataResponse = this.safeList(response, 'data', []);
208449
208513
  return this.parseMarkets(dataResponse);
208450
208514
  }
208451
208515
  safeNetwork(networkId) {
@@ -208522,7 +208586,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208522
208586
  // "msg": ""
208523
208587
  // }
208524
208588
  //
208525
- const data = this.safeValue(response, 'data', []);
208589
+ const data = this.safeList(response, 'data', []);
208526
208590
  const result = {};
208527
208591
  const dataByCurrencyId = this.groupBy(data, 'ccy');
208528
208592
  const currencyIds = Object.keys(dataByCurrencyId);
@@ -208538,11 +208602,11 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208538
208602
  let maxPrecision = undefined;
208539
208603
  for (let j = 0; j < chains.length; j++) {
208540
208604
  const chain = chains[j];
208541
- const canDeposit = this.safeValue(chain, 'canDep');
208605
+ const canDeposit = this.safeBool(chain, 'canDep');
208542
208606
  depositEnabled = (canDeposit) ? canDeposit : depositEnabled;
208543
- const canWithdraw = this.safeValue(chain, 'canWd');
208607
+ const canWithdraw = this.safeBool(chain, 'canWd');
208544
208608
  withdrawEnabled = (canWithdraw) ? canWithdraw : withdrawEnabled;
208545
- const canInternal = this.safeValue(chain, 'canInternal');
208609
+ const canInternal = this.safeBool(chain, 'canInternal');
208546
208610
  const active = (canDeposit && canWithdraw && canInternal) ? true : false;
208547
208611
  currencyActive = (active) ? active : currencyActive;
208548
208612
  const networkId = this.safeString(chain, 'chain');
@@ -208575,7 +208639,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208575
208639
  };
208576
208640
  }
208577
208641
  }
208578
- const firstChain = this.safeValue(chains, 0);
208642
+ const firstChain = this.safeDict(chains, 0, {});
208579
208643
  result[code] = {
208580
208644
  'info': undefined,
208581
208645
  'code': code,
@@ -208651,8 +208715,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208651
208715
  // ]
208652
208716
  // }
208653
208717
  //
208654
- const data = this.safeValue(response, 'data', []);
208655
- const first = this.safeValue(data, 0, {});
208718
+ const data = this.safeList(response, 'data', []);
208719
+ const first = this.safeDict(data, 0, {});
208656
208720
  const timestamp = this.safeInteger(first, 'ts');
208657
208721
  return this.parseOrderBook(first, symbol, timestamp);
208658
208722
  }
@@ -208753,7 +208817,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208753
208817
  // ]
208754
208818
  // }
208755
208819
  //
208756
- const data = this.safeValue(response, 'data', []);
208820
+ const data = this.safeList(response, 'data', []);
208757
208821
  const first = this.safeDict(data, 0, {});
208758
208822
  return this.parseTicker(first, market);
208759
208823
  }
@@ -208776,7 +208840,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208776
208840
  'instType': this.convertToInstrumentType(marketType),
208777
208841
  };
208778
208842
  if (marketType === 'option') {
208779
- const defaultUnderlying = this.safeValue(this.options, 'defaultUnderlying', 'BTC-USD');
208843
+ const defaultUnderlying = this.safeString(this.options, 'defaultUnderlying', 'BTC-USD');
208780
208844
  const currencyId = this.safeString2(params, 'uly', 'marketId', defaultUnderlying);
208781
208845
  if (currencyId === undefined) {
208782
208846
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets');
@@ -209042,7 +209106,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209042
209106
  }
209043
209107
  const price = this.safeString(params, 'price');
209044
209108
  params = this.omit(params, 'price');
209045
- const options = this.safeValue(this.options, 'fetchOHLCV', {});
209109
+ const options = this.safeDict(this.options, 'fetchOHLCV', {});
209046
209110
  const timezone = this.safeString(options, 'timezone', 'UTC');
209047
209111
  if (limit === undefined) {
209048
209112
  limit = 100; // default 100, max 100
@@ -209175,7 +209239,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209175
209239
  // }
209176
209240
  //
209177
209241
  const rates = [];
209178
- const data = this.safeValue(response, 'data', []);
209242
+ const data = this.safeList(response, 'data', []);
209179
209243
  for (let i = 0; i < data.length; i++) {
209180
209244
  const rate = data[i];
209181
209245
  const timestamp = this.safeInteger(rate, 'fundingTime');
@@ -209200,10 +209264,10 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209200
209264
  }
209201
209265
  parseTradingBalance(response) {
209202
209266
  const result = { 'info': response };
209203
- const data = this.safeValue(response, 'data', []);
209204
- const first = this.safeValue(data, 0, {});
209267
+ const data = this.safeList(response, 'data', []);
209268
+ const first = this.safeDict(data, 0, {});
209205
209269
  const timestamp = this.safeInteger(first, 'uTime');
209206
- const details = this.safeValue(first, 'details', []);
209270
+ const details = this.safeList(first, 'details', []);
209207
209271
  for (let i = 0; i < details.length; i++) {
209208
209272
  const balance = details[i];
209209
209273
  const currencyId = this.safeString(balance, 'ccy');
@@ -209228,7 +209292,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209228
209292
  }
209229
209293
  parseFundingBalance(response) {
209230
209294
  const result = { 'info': response };
209231
- const data = this.safeValue(response, 'data', []);
209295
+ const data = this.safeList(response, 'data', []);
209232
209296
  for (let i = 0; i < data.length; i++) {
209233
209297
  const balance = data[i];
209234
209298
  const currencyId = this.safeString(balance, 'ccy');
@@ -209312,8 +209376,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209312
209376
  // "msg": ""
209313
209377
  // }
209314
209378
  //
209315
- const data = this.safeValue(response, 'data', []);
209316
- const first = this.safeValue(data, 0, {});
209379
+ const data = this.safeList(response, 'data', []);
209380
+ const first = this.safeDict(data, 0, {});
209317
209381
  return this.parseTradingFee(first, market);
209318
209382
  }
209319
209383
  async fetchBalance(params = {}) {
@@ -209801,8 +209865,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
209801
209865
  else {
209802
209866
  response = await this.privatePostTradeBatchOrders(request);
209803
209867
  }
209804
- const data = this.safeValue(response, 'data', []);
209805
- const first = this.safeValue(data, 0);
209868
+ const data = this.safeList(response, 'data', []);
209869
+ const first = this.safeDict(data, 0, {});
209806
209870
  const order = this.parseOrder(first, market);
209807
209871
  order['type'] = type;
209808
209872
  order['side'] = side;
@@ -211313,7 +211377,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211313
211377
  // ]
211314
211378
  // }
211315
211379
  //
211316
- const data = this.safeValue(response, 'data', []);
211380
+ const data = this.safeList(response, 'data', []);
211317
211381
  return this.parseLedger(data, currency, since, limit);
211318
211382
  }
211319
211383
  parseLedgerEntryType(type) {
@@ -239776,8 +239840,8 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
239776
239840
  for (let i = 0; i < marketIds.length; i++) {
239777
239841
  const marketId = marketIds[i];
239778
239842
  const market = this.safeMarket(marketId);
239779
- const messageHash = table + ':' + marketId;
239780
239843
  const symbol = market['symbol'];
239844
+ const messageHash = table + ':' + symbol;
239781
239845
  const trades = this.parseTrades(dataByMarketIds[marketId], market);
239782
239846
  let stored = this.safeValue(this.trades, symbol);
239783
239847
  if (stored === undefined) {
@@ -239802,23 +239866,7 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
239802
239866
  * @param {object} [params] extra parameters specific to the exchange API endpoint
239803
239867
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
239804
239868
  */
239805
- await this.loadMarkets();
239806
- const market = this.market(symbol);
239807
- symbol = market['symbol'];
239808
- const table = 'trade';
239809
- const messageHash = table + ':' + market['id'];
239810
- const url = this.urls['api']['ws'];
239811
- const request = {
239812
- 'op': 'subscribe',
239813
- 'args': [
239814
- messageHash,
239815
- ],
239816
- };
239817
- const trades = await this.watch(url, messageHash, this.extend(request, params), messageHash);
239818
- if (this.newUpdates) {
239819
- limit = trades.getLimit(symbol, limit);
239820
- }
239821
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
239869
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
239822
239870
  }
239823
239871
  async authenticate(params = {}) {
239824
239872
  const url = this.urls['api']['ws'];
@@ -240451,6 +240499,43 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
240451
240499
  const orderbook = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), topics);
240452
240500
  return orderbook.limit();
240453
240501
  }
240502
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
240503
+ /**
240504
+ * @method
240505
+ * @name bitmex#watchTradesForSymbols
240506
+ * @description get the list of most recent trades for a list of symbols
240507
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
240508
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
240509
+ * @param {int} [limit] the maximum amount of trades to fetch
240510
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
240511
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
240512
+ */
240513
+ await this.loadMarkets();
240514
+ symbols = this.marketSymbols(symbols, undefined, false);
240515
+ const table = 'trade';
240516
+ const topics = [];
240517
+ const messageHashes = [];
240518
+ for (let i = 0; i < symbols.length; i++) {
240519
+ const symbol = symbols[i];
240520
+ const market = this.market(symbol);
240521
+ const topic = table + ':' + market['id'];
240522
+ topics.push(topic);
240523
+ const messageHash = table + ':' + symbol;
240524
+ messageHashes.push(messageHash);
240525
+ }
240526
+ const url = this.urls['api']['ws'];
240527
+ const request = {
240528
+ 'op': 'subscribe',
240529
+ 'args': topics,
240530
+ };
240531
+ const trades = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), topics);
240532
+ if (this.newUpdates) {
240533
+ const first = this.safeValue(trades, 0);
240534
+ const tradeSymbol = this.safeString(first, 'symbol');
240535
+ limit = trades.getLimit(tradeSymbol, limit);
240536
+ }
240537
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
240538
+ }
240454
240539
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
240455
240540
  /**
240456
240541
  * @method
@@ -266864,8 +266949,8 @@ class krakenfutures extends _krakenfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
266864
266949
  /* harmony export */ Z: () => (/* binding */ kucoin)
266865
266950
  /* harmony export */ });
266866
266951
  /* harmony import */ var _kucoin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3583);
266867
- /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6689);
266868
- /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3020);
266952
+ /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6689);
266953
+ /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3020);
266869
266954
  // ---------------------------------------------------------------------------
266870
266955
 
266871
266956
 
@@ -266883,6 +266968,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
266883
266968
  'cancelOrderWs': false,
266884
266969
  'cancelOrdersWs': false,
266885
266970
  'cancelAllOrdersWs': false,
266971
+ 'watchBidsAsks': true,
266886
266972
  'watchOrderBook': true,
266887
266973
  'watchOrders': true,
266888
266974
  'watchMyTrades': true,
@@ -267150,6 +267236,92 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267150
267236
  }
267151
267237
  }
267152
267238
  }
267239
+ async watchBidsAsks(symbols = undefined, params = {}) {
267240
+ /**
267241
+ * @method
267242
+ * @name kucoin#watchBidsAsks
267243
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
267244
+ * @description watches best bid & ask for symbols
267245
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
267246
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
267247
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
267248
+ */
267249
+ const ticker = await this.watchMultiHelper('watchBidsAsks', '/spotMarket/level1:', symbols, params);
267250
+ if (this.newUpdates) {
267251
+ const tickers = {};
267252
+ tickers[ticker['symbol']] = ticker;
267253
+ return tickers;
267254
+ }
267255
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
267256
+ }
267257
+ async watchMultiHelper(methodName, channelName, symbols = undefined, params = {}) {
267258
+ await this.loadMarkets();
267259
+ symbols = this.marketSymbols(symbols, undefined, false, true, false);
267260
+ const length = symbols.length;
267261
+ if (length > 100) {
267262
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' ' + methodName + '() accepts a maximum of 100 symbols');
267263
+ }
267264
+ const messageHashes = [];
267265
+ for (let i = 0; i < symbols.length; i++) {
267266
+ const symbol = symbols[i];
267267
+ const market = this.market(symbol);
267268
+ messageHashes.push('bidask@' + market['symbol']);
267269
+ }
267270
+ const url = await this.negotiate(false);
267271
+ const marketIds = this.marketIds(symbols);
267272
+ const joined = marketIds.join(',');
267273
+ const requestId = this.requestId().toString();
267274
+ const request = {
267275
+ 'id': requestId,
267276
+ 'type': 'subscribe',
267277
+ 'topic': channelName + joined,
267278
+ 'response': true,
267279
+ };
267280
+ const message = this.extend(request, params);
267281
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
267282
+ }
267283
+ handleBidAsk(client, message) {
267284
+ //
267285
+ // arrives one symbol dict
267286
+ //
267287
+ // {
267288
+ // topic: '/spotMarket/level1:ETH-USDT',
267289
+ // type: 'message',
267290
+ // data: {
267291
+ // asks: [ '3347.42', '2.0778387' ],
267292
+ // bids: [ '3347.41', '6.0411697' ],
267293
+ // timestamp: 1712231142085
267294
+ // },
267295
+ // subject: 'level1'
267296
+ // }
267297
+ //
267298
+ const parsedTicker = this.parseWsBidAsk(message);
267299
+ const symbol = parsedTicker['symbol'];
267300
+ this.bidsasks[symbol] = parsedTicker;
267301
+ const messageHash = 'bidask@' + symbol;
267302
+ client.resolve(parsedTicker, messageHash);
267303
+ }
267304
+ parseWsBidAsk(ticker, market = undefined) {
267305
+ const topic = this.safeString(ticker, 'topic');
267306
+ const parts = topic.split(':');
267307
+ const marketId = parts[1];
267308
+ market = this.safeMarket(marketId, market);
267309
+ const symbol = this.safeString(market, 'symbol');
267310
+ const data = this.safeDict(ticker, 'data', {});
267311
+ const ask = this.safeList(data, 'asks', []);
267312
+ const bid = this.safeList(data, 'bids', []);
267313
+ const timestamp = this.safeInteger(data, 'timestamp');
267314
+ return this.safeTicker({
267315
+ 'symbol': symbol,
267316
+ 'timestamp': timestamp,
267317
+ 'datetime': this.iso8601(timestamp),
267318
+ 'ask': this.safeNumber(ask, 0),
267319
+ 'askVolume': this.safeNumber(ask, 1),
267320
+ 'bid': this.safeNumber(bid, 0),
267321
+ 'bidVolume': this.safeNumber(bid, 1),
267322
+ 'info': ticker,
267323
+ }, market);
267324
+ }
267153
267325
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
267154
267326
  /**
267155
267327
  * @method
@@ -267211,7 +267383,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267211
267383
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
267212
267384
  if (stored === undefined) {
267213
267385
  const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
267214
- stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheByTimestamp */ .Py(limit);
267386
+ stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
267215
267387
  this.ohlcvs[symbol][timeframe] = stored;
267216
267388
  }
267217
267389
  const ohlcv = this.parseOHLCV(candles, market);
@@ -267244,7 +267416,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267244
267416
  */
267245
267417
  const symbolsLength = symbols.length;
267246
267418
  if (symbolsLength === 0) {
267247
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
267419
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
267248
267420
  }
267249
267421
  await this.loadMarkets();
267250
267422
  symbols = this.marketSymbols(symbols);
@@ -267294,7 +267466,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267294
267466
  let trades = this.safeValue(this.trades, symbol);
267295
267467
  if (trades === undefined) {
267296
267468
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
267297
- trades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCache */ .ZL(limit);
267469
+ trades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCache */ .ZL(limit);
267298
267470
  this.trades[symbol] = trades;
267299
267471
  }
267300
267472
  trades.append(trade);
@@ -267349,11 +267521,11 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267349
267521
  */
267350
267522
  const symbolsLength = symbols.length;
267351
267523
  if (symbolsLength === 0) {
267352
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
267524
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
267353
267525
  }
267354
267526
  if (limit !== undefined) {
267355
267527
  if ((limit !== 20) && (limit !== 100) && (limit !== 50) && (limit !== 5)) {
267356
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 5, 20, 50 or 100");
267528
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 5, 20, 50 or 100");
267357
267529
  }
267358
267530
  }
267359
267531
  await this.loadMarkets();
@@ -267541,6 +267713,9 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267541
267713
  // }
267542
267714
  //
267543
267715
  const id = this.safeString(message, 'id');
267716
+ if (!(id in client.subscriptions)) {
267717
+ return;
267718
+ }
267544
267719
  const subscriptionHash = this.safeString(client.subscriptions, id);
267545
267720
  const subscription = this.safeValue(client.subscriptions, subscriptionHash);
267546
267721
  delete client.subscriptions[id];
@@ -267710,8 +267885,8 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267710
267885
  const isTriggerOrder = (triggerPrice !== undefined);
267711
267886
  if (this.orders === undefined) {
267712
267887
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
267713
- this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
267714
- this.triggerOrders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
267888
+ this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
267889
+ this.triggerOrders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
267715
267890
  }
267716
267891
  const cachedOrders = isTriggerOrder ? this.triggerOrders : this.orders;
267717
267892
  const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
@@ -267759,7 +267934,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267759
267934
  handleMyTrade(client, message) {
267760
267935
  if (this.myTrades === undefined) {
267761
267936
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
267762
- this.myTrades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
267937
+ this.myTrades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
267763
267938
  }
267764
267939
  const data = this.safeDict(message, 'data');
267765
267940
  const parsed = this.parseWsTrade(data);
@@ -267914,6 +268089,7 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
267914
268089
  }
267915
268090
  const subject = this.safeString(message, 'subject');
267916
268091
  const methods = {
268092
+ 'level1': this.handleBidAsk,
267917
268093
  'level2': this.handleOrderBook,
267918
268094
  'trade.l2update': this.handleOrderBook,
267919
268095
  'trade.ticker': this.handleTicker,
@@ -268003,6 +268179,8 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268003
268179
  'has': {
268004
268180
  'ws': true,
268005
268181
  'watchTicker': true,
268182
+ 'watchTickers': true,
268183
+ 'watchBidsAsks': true,
268006
268184
  'watchTrades': true,
268007
268185
  'watchOrderBook': true,
268008
268186
  'watchOrders': true,
@@ -268032,9 +268210,6 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268032
268210
  'snapshotDelay': 20,
268033
268211
  'snapshotMaxRetries': 3,
268034
268212
  },
268035
- 'watchTicker': {
268036
- 'name': 'contractMarket/tickerV2', // market/ticker
268037
- },
268038
268213
  'watchPosition': {
268039
268214
  'fetchPositionSnapshot': true,
268040
268215
  'awaitPositionSnapshot': true, // whether to wait for the position snapshot before providing updates
@@ -268137,7 +268312,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268137
268312
  }
268138
268313
  return await this.watch(url, messageHash, message, subscriptionHash, subscription);
268139
268314
  }
268140
- async subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscription, params = {}) {
268315
+ async subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params = {}) {
268141
268316
  const requestId = this.requestId().toString();
268142
268317
  const request = {
268143
268318
  'id': requestId,
@@ -268145,24 +268320,14 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268145
268320
  'topic': topic,
268146
268321
  'response': true,
268147
268322
  };
268148
- const message = this.extend(request, params);
268149
- const subscriptionRequest = {
268150
- 'id': requestId,
268151
- };
268152
- if (subscription === undefined) {
268153
- subscription = subscriptionRequest;
268154
- }
268155
- else {
268156
- subscription = this.extend(subscriptionRequest, subscription);
268157
- }
268158
- return await this.watchMultiple(url, messageHashes, message, subscriptionHashes, subscription);
268323
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), subscriptionHashes, subscriptionArgs);
268159
268324
  }
268160
268325
  async watchTicker(symbol, params = {}) {
268161
268326
  /**
268162
268327
  * @method
268163
268328
  * @name kucoinfutures#watchTicker
268164
268329
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
268165
- * @see https://docs.kucoin.com/futures/#get-real-time-symbol-ticker-v2
268330
+ * @see https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker
268166
268331
  * @param {string} symbol unified symbol of the market to fetch the ticker for
268167
268332
  * @param {object} [params] extra parameters specific to the exchange API endpoint
268168
268333
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
@@ -268170,30 +268335,48 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268170
268335
  await this.loadMarkets();
268171
268336
  const market = this.market(symbol);
268172
268337
  symbol = market['symbol'];
268173
- const url = await this.negotiate(false);
268174
- const options = this.safeValue(this.options, 'watchTicker', {});
268175
- const channel = this.safeString(options, 'name', 'contractMarket/tickerV2');
268176
- const topic = '/' + channel + ':' + market['id'];
268177
- const messageHash = 'ticker:' + symbol;
268178
- return await this.subscribe(url, messageHash, topic, undefined, params);
268338
+ params['callerMethodName'] = 'watchTicker';
268339
+ const tickers = await this.watchTickers([symbol], params);
268340
+ return tickers[symbol];
268341
+ }
268342
+ async watchTickers(symbols = undefined, params = {}) {
268343
+ /**
268344
+ * @method
268345
+ * @name kucoinfutures#watchTickers
268346
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
268347
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
268348
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
268349
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
268350
+ */
268351
+ await this.loadMarkets();
268352
+ const ticker = await this.watchMultiRequest('watchTickers', '/contractMarket/ticker:', symbols, params);
268353
+ if (this.newUpdates) {
268354
+ const tickers = {};
268355
+ tickers[ticker['symbol']] = ticker;
268356
+ return tickers;
268357
+ }
268358
+ return this.filterByArray(this.tickers, 'symbol', symbols);
268179
268359
  }
268180
268360
  handleTicker(client, message) {
268181
268361
  //
268182
- // market/tickerV2
268362
+ // ticker (v1)
268183
268363
  //
268184
268364
  // {
268185
- // "type": "message",
268186
- // "topic": "/contractMarket/tickerV2:ADAUSDTM",
268187
- // "subject": "tickerV2",
268188
- // "data": {
268189
- // "symbol": "ADAUSDTM",
268190
- // "sequence": 1668007800439,
268191
- // "bestBidSize": 178,
268192
- // "bestBidPrice": "0.35959",
268193
- // "bestAskPrice": "0.35981",
268194
- // "ts": "1668141430037124460",
268195
- // "bestAskSize": 134
268196
- // }
268365
+ // "subject": "ticker",
268366
+ // "topic": "/contractMarket/ticker:XBTUSDM",
268367
+ // "data": {
268368
+ // "symbol": "XBTUSDM", //Market of the symbol
268369
+ // "sequence": 45, //Sequence number which is used to judge the continuity of the pushed messages
268370
+ // "side": "sell", //Transaction side of the last traded taker order
268371
+ // "price": "3600.0", //Filled price
268372
+ // "size": 16, //Filled quantity
268373
+ // "tradeId": "5c9dcf4170744d6f5a3d32fb", //Order ID
268374
+ // "bestBidSize": 795, //Best bid size
268375
+ // "bestBidPrice": "3200.0", //Best bid
268376
+ // "bestAskPrice": "3600.0", //Best ask size
268377
+ // "bestAskSize": 284, //Best ask
268378
+ // "ts": 1553846081210004941 //Filled time - nanosecond
268379
+ // }
268197
268380
  // }
268198
268381
  //
268199
268382
  const data = this.safeValue(message, 'data', {});
@@ -268201,9 +268384,95 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268201
268384
  const market = this.safeMarket(marketId, undefined, '-');
268202
268385
  const ticker = this.parseTicker(data, market);
268203
268386
  this.tickers[market['symbol']] = ticker;
268204
- const messageHash = 'ticker:' + market['symbol'];
268205
- client.resolve(ticker, messageHash);
268206
- return message;
268387
+ client.resolve(ticker, this.getMessageHash('ticker', market['symbol']));
268388
+ }
268389
+ async watchBidsAsks(symbols = undefined, params = {}) {
268390
+ /**
268391
+ * @method
268392
+ * @name kucoinfutures#watchBidsAsks
268393
+ * @see https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker-v2
268394
+ * @description watches best bid & ask for symbols
268395
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
268396
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
268397
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
268398
+ */
268399
+ const ticker = await this.watchMultiRequest('watchBidsAsks', '/contractMarket/tickerV2:', symbols, params);
268400
+ if (this.newUpdates) {
268401
+ const tickers = {};
268402
+ tickers[ticker['symbol']] = ticker;
268403
+ return tickers;
268404
+ }
268405
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
268406
+ }
268407
+ async watchMultiRequest(methodName, channelName, symbols = undefined, params = {}) {
268408
+ await this.loadMarkets();
268409
+ [methodName, params] = this.handleParamString(params, 'callerMethodName', methodName);
268410
+ const isBidsAsks = (methodName === 'watchBidsAsks');
268411
+ symbols = this.marketSymbols(symbols, undefined, false, true, false);
268412
+ const length = symbols.length;
268413
+ if (length > 100) {
268414
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' ' + methodName + '() accepts a maximum of 100 symbols');
268415
+ }
268416
+ const messageHashes = [];
268417
+ for (let i = 0; i < symbols.length; i++) {
268418
+ const symbol = symbols[i];
268419
+ const market = this.market(symbol);
268420
+ const prefix = isBidsAsks ? 'bidask' : 'ticker';
268421
+ messageHashes.push(this.getMessageHash(prefix, market['symbol']));
268422
+ }
268423
+ const url = await this.negotiate(false);
268424
+ const marketIds = this.marketIds(symbols);
268425
+ const joined = marketIds.join(',');
268426
+ const requestId = this.requestId().toString();
268427
+ const request = {
268428
+ 'id': requestId,
268429
+ 'type': 'subscribe',
268430
+ 'topic': channelName + joined,
268431
+ 'response': true,
268432
+ };
268433
+ const subscription = {
268434
+ 'id': requestId,
268435
+ };
268436
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscription);
268437
+ }
268438
+ handleBidAsk(client, message) {
268439
+ //
268440
+ // arrives one symbol dict
268441
+ //
268442
+ // {
268443
+ // "subject": "tickerV2",
268444
+ // "topic": "/contractMarket/tickerV2:XBTUSDM",
268445
+ // "data": {
268446
+ // "symbol": "XBTUSDM", //Market of the symbol
268447
+ // "bestBidSize": 795, // Best bid size
268448
+ // "bestBidPrice": 3200.0, // Best bid
268449
+ // "bestAskPrice": 3600.0, // Best ask
268450
+ // "bestAskSize": 284, // Best ask size
268451
+ // "ts": 1553846081210004941 // Filled time - nanosecond
268452
+ // }
268453
+ // }
268454
+ //
268455
+ const parsedTicker = this.parseWsBidAsk(message);
268456
+ const symbol = parsedTicker['symbol'];
268457
+ this.bidsasks[symbol] = parsedTicker;
268458
+ client.resolve(parsedTicker, this.getMessageHash('bidask', symbol));
268459
+ }
268460
+ parseWsBidAsk(ticker, market = undefined) {
268461
+ const data = this.safeDict(ticker, 'data', {});
268462
+ const marketId = this.safeString(data, 'symbol');
268463
+ market = this.safeMarket(marketId, market);
268464
+ const symbol = this.safeString(market, 'symbol');
268465
+ const timestamp = this.safeIntegerProduct(data, 'ts', 0.000001);
268466
+ return this.safeTicker({
268467
+ 'symbol': symbol,
268468
+ 'timestamp': timestamp,
268469
+ 'datetime': this.iso8601(timestamp),
268470
+ 'ask': this.safeNumber(data, 'bestAskPrice'),
268471
+ 'askVolume': this.safeNumber(data, 'bestAskSize'),
268472
+ 'bid': this.safeNumber(data, 'bestBidPrice'),
268473
+ 'bidVolume': this.safeNumber(data, 'bestBidSize'),
268474
+ 'info': ticker,
268475
+ }, market);
268207
268476
  }
268208
268477
  async watchPosition(symbol = undefined, params = {}) {
268209
268478
  /**
@@ -268422,7 +268691,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268422
268691
  messageHashes.push('trades:' + symbol);
268423
268692
  subscriptionHashes.push('/contractMarket/execution:' + marketId);
268424
268693
  }
268425
- const trades = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, params);
268694
+ const trades = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, undefined, params);
268426
268695
  if (this.newUpdates) {
268427
268696
  const first = this.safeValue(trades, 0);
268428
268697
  const tradeSymbol = this.safeString(first, 'symbol');
@@ -268508,9 +268777,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268508
268777
  const marketIds = this.marketIds(symbols);
268509
268778
  const url = await this.negotiate(false);
268510
268779
  const topic = '/contractMarket/level2:' + marketIds.join(',');
268511
- const subscription = {
268512
- 'method': this.handleOrderBookSubscription,
268513
- 'symbols': symbols,
268780
+ const subscriptionArgs = {
268514
268781
  'limit': limit,
268515
268782
  };
268516
268783
  const subscriptionHashes = [];
@@ -268521,7 +268788,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268521
268788
  messageHashes.push('orderbook:' + symbol);
268522
268789
  subscriptionHashes.push('/contractMarket/level2:' + marketId);
268523
268790
  }
268524
- const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscription, params);
268791
+ const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params);
268525
268792
  return orderbook.limit();
268526
268793
  }
268527
268794
  handleDelta(orderbook, delta) {
@@ -268572,11 +268839,13 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268572
268839
  const marketId = this.safeString(topicParts, 1);
268573
268840
  const symbol = this.safeSymbol(marketId, undefined, '-');
268574
268841
  const messageHash = 'orderbook:' + symbol;
268575
- const storedOrderBook = this.safeValue(this.orderbooks, symbol);
268576
- const nonce = this.safeInteger(storedOrderBook, 'nonce');
268577
- if (storedOrderBook === undefined) {
268578
- return; // this shouldn't be needed, but for some reason sometimes this runs before handleOrderBookSubscription in c#
268842
+ if (!(symbol in this.orderbooks)) {
268843
+ const subscriptionArgs = this.safeDict(client.subscriptions, topic, {});
268844
+ const limit = this.safeInteger(subscriptionArgs, 'limit');
268845
+ this.orderbooks[symbol] = this.orderBook({}, limit);
268579
268846
  }
268847
+ const storedOrderBook = this.orderbooks[symbol];
268848
+ const nonce = this.safeInteger(storedOrderBook, 'nonce');
268580
268849
  const deltaEnd = this.safeInteger(data, 'sequence');
268581
268850
  if (nonce === undefined) {
268582
268851
  const cacheLength = storedOrderBook.cache.length;
@@ -268622,39 +268891,6 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268622
268891
  }
268623
268892
  return cache.length;
268624
268893
  }
268625
- handleOrderBookSubscription(client, message, subscription) {
268626
- const limit = this.safeInteger(subscription, 'limit');
268627
- const symbols = this.safeValue(subscription, 'symbols');
268628
- if (symbols === undefined) {
268629
- const symbol = this.safeString(subscription, 'symbol');
268630
- this.orderbooks[symbol] = this.orderBook({}, limit);
268631
- }
268632
- else {
268633
- for (let i = 0; i < symbols.length; i++) {
268634
- const symbol = symbols[i];
268635
- this.orderbooks[symbol] = this.orderBook({}, limit);
268636
- }
268637
- }
268638
- // moved snapshot initialization to handleOrderBook to fix
268639
- // https://github.com/ccxt/ccxt/issues/6820
268640
- // the general idea is to fetch the snapshot after the first delta
268641
- // but not before, because otherwise we cannot synchronize the feed
268642
- }
268643
- handleSubscriptionStatus(client, message) {
268644
- //
268645
- // {
268646
- // "id": "1578090438322",
268647
- // "type": "ack"
268648
- // }
268649
- //
268650
- const id = this.safeString(message, 'id');
268651
- const subscriptionsById = this.indexBy(client.subscriptions, 'id');
268652
- const subscription = this.safeValue(subscriptionsById, id, {});
268653
- const method = this.safeValue(subscription, 'method');
268654
- if (method !== undefined) {
268655
- method.call(this, client, message, subscription);
268656
- }
268657
- }
268658
268894
  handleSystemStatus(client, message) {
268659
268895
  //
268660
268896
  // todo: answer the question whether handleSystemStatus should be renamed
@@ -268913,7 +269149,8 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268913
269149
  const subject = this.safeString(message, 'subject');
268914
269150
  const methods = {
268915
269151
  'level2': this.handleOrderBook,
268916
- 'tickerV2': this.handleTicker,
269152
+ 'ticker': this.handleTicker,
269153
+ 'tickerV2': this.handleBidAsk,
268917
269154
  'availableBalance.change': this.handleBalance,
268918
269155
  'match': this.handleTrade,
268919
269156
  'orderChange': this.handleOrder,
@@ -268927,6 +269164,15 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268927
269164
  method.call(this, client, message);
268928
269165
  }
268929
269166
  }
269167
+ getMessageHash(elementName, symbol = undefined) {
269168
+ // elementName can be 'ticker', 'bidask', ...
269169
+ if (symbol !== undefined) {
269170
+ return elementName + '@' + symbol;
269171
+ }
269172
+ else {
269173
+ return elementName + 's@all';
269174
+ }
269175
+ }
268930
269176
  ping(client) {
268931
269177
  // kucoin does not support built-in ws protocol-level ping-pong
268932
269178
  // instead it requires a custom json-based text ping-pong
@@ -268966,7 +269212,6 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
268966
269212
  const methods = {
268967
269213
  // 'heartbeat': this.handleHeartbeat,
268968
269214
  'welcome': this.handleSystemStatus,
268969
- 'ack': this.handleSubscriptionStatus,
268970
269215
  'message': this.handleSubject,
268971
269216
  'pong': this.handlePong,
268972
269217
  'error': this.handleErrorMessage,
@@ -325367,7 +325612,7 @@ SOFTWARE.
325367
325612
 
325368
325613
  //-----------------------------------------------------------------------------
325369
325614
  // this is updated by vss.js when building
325370
- const version = '4.2.90';
325615
+ const version = '4.2.92';
325371
325616
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
325372
325617
  //-----------------------------------------------------------------------------
325373
325618