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.
@@ -1219,7 +1219,7 @@ class okx extends okx$1 {
1219
1219
  // ]
1220
1220
  // }
1221
1221
  //
1222
- const data = this.safeValue(response, 'data', []);
1222
+ const data = this.safeList(response, 'data', []);
1223
1223
  const dataLength = data.length;
1224
1224
  const update = {
1225
1225
  'updated': undefined,
@@ -1267,8 +1267,8 @@ class okx extends okx$1 {
1267
1267
  // "msg": ""
1268
1268
  // }
1269
1269
  //
1270
- const data = this.safeValue(response, 'data', []);
1271
- const first = this.safeValue(data, 0, {});
1270
+ const data = this.safeList(response, 'data', []);
1271
+ const first = this.safeDict(data, 0, {});
1272
1272
  return this.safeInteger(first, 'ts');
1273
1273
  }
1274
1274
  async fetchAccounts(params = {}) {
@@ -1300,7 +1300,7 @@ class okx extends okx$1 {
1300
1300
  // "msg": ""
1301
1301
  // }
1302
1302
  //
1303
- const data = this.safeValue(response, 'data', []);
1303
+ const data = this.safeList(response, 'data', []);
1304
1304
  const result = [];
1305
1305
  for (let i = 0; i < data.length; i++) {
1306
1306
  const account = data[i];
@@ -1325,7 +1325,7 @@ class okx extends okx$1 {
1325
1325
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1326
1326
  * @returns {object[]} an array of objects representing market data
1327
1327
  */
1328
- const types = this.safeValue(this.options, 'fetchMarkets');
1328
+ const types = this.safeList(this.options, 'fetchMarkets', []);
1329
1329
  let promises = [];
1330
1330
  let result = [];
1331
1331
  for (let i = 0; i < types.length; i++) {
@@ -1429,7 +1429,7 @@ class okx extends okx$1 {
1429
1429
  }
1430
1430
  }
1431
1431
  const tickSize = this.safeString(market, 'tickSz');
1432
- const fees = this.safeValue2(this.fees, type, 'trading', {});
1432
+ const fees = this.safeDict2(this.fees, type, 'trading', {});
1433
1433
  let maxLeverage = this.safeString(market, 'lever', '1');
1434
1434
  maxLeverage = Precise["default"].stringMax(maxLeverage, '1');
1435
1435
  const maxSpotCost = this.safeNumber(market, 'maxMktSz');
@@ -1488,7 +1488,7 @@ class okx extends okx$1 {
1488
1488
  'instType': this.convertToInstrumentType(type),
1489
1489
  };
1490
1490
  if (type === 'option') {
1491
- const optionsUnderlying = this.safeValue(this.options, 'defaultUnderlying', ['BTC-USD', 'ETH-USD']);
1491
+ const optionsUnderlying = this.safeList(this.options, 'defaultUnderlying', ['BTC-USD', 'ETH-USD']);
1492
1492
  const promises = [];
1493
1493
  for (let i = 0; i < optionsUnderlying.length; i++) {
1494
1494
  const underlying = optionsUnderlying[i];
@@ -1498,8 +1498,8 @@ class okx extends okx$1 {
1498
1498
  const promisesResult = await Promise.all(promises);
1499
1499
  let markets = [];
1500
1500
  for (let i = 0; i < promisesResult.length; i++) {
1501
- const res = this.safeValue(promisesResult, i, {});
1502
- const options = this.safeValue(res, 'data', []);
1501
+ const res = this.safeDict(promisesResult, i, {});
1502
+ const options = this.safeList(res, 'data', []);
1503
1503
  markets = this.arrayConcat(markets, options);
1504
1504
  }
1505
1505
  return this.parseMarkets(markets);
@@ -1538,7 +1538,7 @@ class okx extends okx$1 {
1538
1538
  // "msg": ""
1539
1539
  // }
1540
1540
  //
1541
- const dataResponse = this.safeValue(response, 'data', []);
1541
+ const dataResponse = this.safeList(response, 'data', []);
1542
1542
  return this.parseMarkets(dataResponse);
1543
1543
  }
1544
1544
  safeNetwork(networkId) {
@@ -1615,7 +1615,7 @@ class okx extends okx$1 {
1615
1615
  // "msg": ""
1616
1616
  // }
1617
1617
  //
1618
- const data = this.safeValue(response, 'data', []);
1618
+ const data = this.safeList(response, 'data', []);
1619
1619
  const result = {};
1620
1620
  const dataByCurrencyId = this.groupBy(data, 'ccy');
1621
1621
  const currencyIds = Object.keys(dataByCurrencyId);
@@ -1631,11 +1631,11 @@ class okx extends okx$1 {
1631
1631
  let maxPrecision = undefined;
1632
1632
  for (let j = 0; j < chains.length; j++) {
1633
1633
  const chain = chains[j];
1634
- const canDeposit = this.safeValue(chain, 'canDep');
1634
+ const canDeposit = this.safeBool(chain, 'canDep');
1635
1635
  depositEnabled = (canDeposit) ? canDeposit : depositEnabled;
1636
- const canWithdraw = this.safeValue(chain, 'canWd');
1636
+ const canWithdraw = this.safeBool(chain, 'canWd');
1637
1637
  withdrawEnabled = (canWithdraw) ? canWithdraw : withdrawEnabled;
1638
- const canInternal = this.safeValue(chain, 'canInternal');
1638
+ const canInternal = this.safeBool(chain, 'canInternal');
1639
1639
  const active = (canDeposit && canWithdraw && canInternal) ? true : false;
1640
1640
  currencyActive = (active) ? active : currencyActive;
1641
1641
  const networkId = this.safeString(chain, 'chain');
@@ -1668,7 +1668,7 @@ class okx extends okx$1 {
1668
1668
  };
1669
1669
  }
1670
1670
  }
1671
- const firstChain = this.safeValue(chains, 0);
1671
+ const firstChain = this.safeDict(chains, 0, {});
1672
1672
  result[code] = {
1673
1673
  'info': undefined,
1674
1674
  'code': code,
@@ -1744,8 +1744,8 @@ class okx extends okx$1 {
1744
1744
  // ]
1745
1745
  // }
1746
1746
  //
1747
- const data = this.safeValue(response, 'data', []);
1748
- const first = this.safeValue(data, 0, {});
1747
+ const data = this.safeList(response, 'data', []);
1748
+ const first = this.safeDict(data, 0, {});
1749
1749
  const timestamp = this.safeInteger(first, 'ts');
1750
1750
  return this.parseOrderBook(first, symbol, timestamp);
1751
1751
  }
@@ -1846,7 +1846,7 @@ class okx extends okx$1 {
1846
1846
  // ]
1847
1847
  // }
1848
1848
  //
1849
- const data = this.safeValue(response, 'data', []);
1849
+ const data = this.safeList(response, 'data', []);
1850
1850
  const first = this.safeDict(data, 0, {});
1851
1851
  return this.parseTicker(first, market);
1852
1852
  }
@@ -1869,7 +1869,7 @@ class okx extends okx$1 {
1869
1869
  'instType': this.convertToInstrumentType(marketType),
1870
1870
  };
1871
1871
  if (marketType === 'option') {
1872
- const defaultUnderlying = this.safeValue(this.options, 'defaultUnderlying', 'BTC-USD');
1872
+ const defaultUnderlying = this.safeString(this.options, 'defaultUnderlying', 'BTC-USD');
1873
1873
  const currencyId = this.safeString2(params, 'uly', 'marketId', defaultUnderlying);
1874
1874
  if (currencyId === undefined) {
1875
1875
  throw new errors.ArgumentsRequired(this.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets');
@@ -2135,7 +2135,7 @@ class okx extends okx$1 {
2135
2135
  }
2136
2136
  const price = this.safeString(params, 'price');
2137
2137
  params = this.omit(params, 'price');
2138
- const options = this.safeValue(this.options, 'fetchOHLCV', {});
2138
+ const options = this.safeDict(this.options, 'fetchOHLCV', {});
2139
2139
  const timezone = this.safeString(options, 'timezone', 'UTC');
2140
2140
  if (limit === undefined) {
2141
2141
  limit = 100; // default 100, max 100
@@ -2268,7 +2268,7 @@ class okx extends okx$1 {
2268
2268
  // }
2269
2269
  //
2270
2270
  const rates = [];
2271
- const data = this.safeValue(response, 'data', []);
2271
+ const data = this.safeList(response, 'data', []);
2272
2272
  for (let i = 0; i < data.length; i++) {
2273
2273
  const rate = data[i];
2274
2274
  const timestamp = this.safeInteger(rate, 'fundingTime');
@@ -2293,10 +2293,10 @@ class okx extends okx$1 {
2293
2293
  }
2294
2294
  parseTradingBalance(response) {
2295
2295
  const result = { 'info': response };
2296
- const data = this.safeValue(response, 'data', []);
2297
- const first = this.safeValue(data, 0, {});
2296
+ const data = this.safeList(response, 'data', []);
2297
+ const first = this.safeDict(data, 0, {});
2298
2298
  const timestamp = this.safeInteger(first, 'uTime');
2299
- const details = this.safeValue(first, 'details', []);
2299
+ const details = this.safeList(first, 'details', []);
2300
2300
  for (let i = 0; i < details.length; i++) {
2301
2301
  const balance = details[i];
2302
2302
  const currencyId = this.safeString(balance, 'ccy');
@@ -2321,7 +2321,7 @@ class okx extends okx$1 {
2321
2321
  }
2322
2322
  parseFundingBalance(response) {
2323
2323
  const result = { 'info': response };
2324
- const data = this.safeValue(response, 'data', []);
2324
+ const data = this.safeList(response, 'data', []);
2325
2325
  for (let i = 0; i < data.length; i++) {
2326
2326
  const balance = data[i];
2327
2327
  const currencyId = this.safeString(balance, 'ccy');
@@ -2405,8 +2405,8 @@ class okx extends okx$1 {
2405
2405
  // "msg": ""
2406
2406
  // }
2407
2407
  //
2408
- const data = this.safeValue(response, 'data', []);
2409
- const first = this.safeValue(data, 0, {});
2408
+ const data = this.safeList(response, 'data', []);
2409
+ const first = this.safeDict(data, 0, {});
2410
2410
  return this.parseTradingFee(first, market);
2411
2411
  }
2412
2412
  async fetchBalance(params = {}) {
@@ -2894,8 +2894,8 @@ class okx extends okx$1 {
2894
2894
  else {
2895
2895
  response = await this.privatePostTradeBatchOrders(request);
2896
2896
  }
2897
- const data = this.safeValue(response, 'data', []);
2898
- const first = this.safeValue(data, 0);
2897
+ const data = this.safeList(response, 'data', []);
2898
+ const first = this.safeDict(data, 0, {});
2899
2899
  const order = this.parseOrder(first, market);
2900
2900
  order['type'] = type;
2901
2901
  order['side'] = side;
@@ -4406,7 +4406,7 @@ class okx extends okx$1 {
4406
4406
  // ]
4407
4407
  // }
4408
4408
  //
4409
- const data = this.safeValue(response, 'data', []);
4409
+ const data = this.safeList(response, 'data', []);
4410
4410
  return this.parseLedger(data, currency, since, limit);
4411
4411
  }
4412
4412
  parseLedgerEntryType(type) {
@@ -541,8 +541,8 @@ class bitmex extends bitmex$1 {
541
541
  for (let i = 0; i < marketIds.length; i++) {
542
542
  const marketId = marketIds[i];
543
543
  const market = this.safeMarket(marketId);
544
- const messageHash = table + ':' + marketId;
545
544
  const symbol = market['symbol'];
545
+ const messageHash = table + ':' + symbol;
546
546
  const trades = this.parseTrades(dataByMarketIds[marketId], market);
547
547
  let stored = this.safeValue(this.trades, symbol);
548
548
  if (stored === undefined) {
@@ -567,23 +567,7 @@ class bitmex extends bitmex$1 {
567
567
  * @param {object} [params] extra parameters specific to the exchange API endpoint
568
568
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
569
569
  */
570
- await this.loadMarkets();
571
- const market = this.market(symbol);
572
- symbol = market['symbol'];
573
- const table = 'trade';
574
- const messageHash = table + ':' + market['id'];
575
- const url = this.urls['api']['ws'];
576
- const request = {
577
- 'op': 'subscribe',
578
- 'args': [
579
- messageHash,
580
- ],
581
- };
582
- const trades = await this.watch(url, messageHash, this.extend(request, params), messageHash);
583
- if (this.newUpdates) {
584
- limit = trades.getLimit(symbol, limit);
585
- }
586
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
570
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
587
571
  }
588
572
  async authenticate(params = {}) {
589
573
  const url = this.urls['api']['ws'];
@@ -1216,6 +1200,43 @@ class bitmex extends bitmex$1 {
1216
1200
  const orderbook = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), topics);
1217
1201
  return orderbook.limit();
1218
1202
  }
1203
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
1204
+ /**
1205
+ * @method
1206
+ * @name bitmex#watchTradesForSymbols
1207
+ * @description get the list of most recent trades for a list of symbols
1208
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
1209
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1210
+ * @param {int} [limit] the maximum amount of trades to fetch
1211
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1212
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1213
+ */
1214
+ await this.loadMarkets();
1215
+ symbols = this.marketSymbols(symbols, undefined, false);
1216
+ const table = 'trade';
1217
+ const topics = [];
1218
+ const messageHashes = [];
1219
+ for (let i = 0; i < symbols.length; i++) {
1220
+ const symbol = symbols[i];
1221
+ const market = this.market(symbol);
1222
+ const topic = table + ':' + market['id'];
1223
+ topics.push(topic);
1224
+ const messageHash = table + ':' + symbol;
1225
+ messageHashes.push(messageHash);
1226
+ }
1227
+ const url = this.urls['api']['ws'];
1228
+ const request = {
1229
+ 'op': 'subscribe',
1230
+ 'args': topics,
1231
+ };
1232
+ const trades = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), topics);
1233
+ if (this.newUpdates) {
1234
+ const first = this.safeValue(trades, 0);
1235
+ const tradeSymbol = this.safeString(first, 'symbol');
1236
+ limit = trades.getLimit(tradeSymbol, limit);
1237
+ }
1238
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
1239
+ }
1219
1240
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1220
1241
  /**
1221
1242
  * @method
@@ -18,6 +18,7 @@ class kucoin extends kucoin$1 {
18
18
  'cancelOrderWs': false,
19
19
  'cancelOrdersWs': false,
20
20
  'cancelAllOrdersWs': false,
21
+ 'watchBidsAsks': true,
21
22
  'watchOrderBook': true,
22
23
  'watchOrders': true,
23
24
  'watchMyTrades': true,
@@ -285,6 +286,92 @@ class kucoin extends kucoin$1 {
285
286
  }
286
287
  }
287
288
  }
289
+ async watchBidsAsks(symbols = undefined, params = {}) {
290
+ /**
291
+ * @method
292
+ * @name kucoin#watchBidsAsks
293
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
294
+ * @description watches best bid & ask for symbols
295
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
296
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
297
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
298
+ */
299
+ const ticker = await this.watchMultiHelper('watchBidsAsks', '/spotMarket/level1:', symbols, params);
300
+ if (this.newUpdates) {
301
+ const tickers = {};
302
+ tickers[ticker['symbol']] = ticker;
303
+ return tickers;
304
+ }
305
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
306
+ }
307
+ async watchMultiHelper(methodName, channelName, symbols = undefined, params = {}) {
308
+ await this.loadMarkets();
309
+ symbols = this.marketSymbols(symbols, undefined, false, true, false);
310
+ const length = symbols.length;
311
+ if (length > 100) {
312
+ throw new errors.ArgumentsRequired(this.id + ' ' + methodName + '() accepts a maximum of 100 symbols');
313
+ }
314
+ const messageHashes = [];
315
+ for (let i = 0; i < symbols.length; i++) {
316
+ const symbol = symbols[i];
317
+ const market = this.market(symbol);
318
+ messageHashes.push('bidask@' + market['symbol']);
319
+ }
320
+ const url = await this.negotiate(false);
321
+ const marketIds = this.marketIds(symbols);
322
+ const joined = marketIds.join(',');
323
+ const requestId = this.requestId().toString();
324
+ const request = {
325
+ 'id': requestId,
326
+ 'type': 'subscribe',
327
+ 'topic': channelName + joined,
328
+ 'response': true,
329
+ };
330
+ const message = this.extend(request, params);
331
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
332
+ }
333
+ handleBidAsk(client, message) {
334
+ //
335
+ // arrives one symbol dict
336
+ //
337
+ // {
338
+ // topic: '/spotMarket/level1:ETH-USDT',
339
+ // type: 'message',
340
+ // data: {
341
+ // asks: [ '3347.42', '2.0778387' ],
342
+ // bids: [ '3347.41', '6.0411697' ],
343
+ // timestamp: 1712231142085
344
+ // },
345
+ // subject: 'level1'
346
+ // }
347
+ //
348
+ const parsedTicker = this.parseWsBidAsk(message);
349
+ const symbol = parsedTicker['symbol'];
350
+ this.bidsasks[symbol] = parsedTicker;
351
+ const messageHash = 'bidask@' + symbol;
352
+ client.resolve(parsedTicker, messageHash);
353
+ }
354
+ parseWsBidAsk(ticker, market = undefined) {
355
+ const topic = this.safeString(ticker, 'topic');
356
+ const parts = topic.split(':');
357
+ const marketId = parts[1];
358
+ market = this.safeMarket(marketId, market);
359
+ const symbol = this.safeString(market, 'symbol');
360
+ const data = this.safeDict(ticker, 'data', {});
361
+ const ask = this.safeList(data, 'asks', []);
362
+ const bid = this.safeList(data, 'bids', []);
363
+ const timestamp = this.safeInteger(data, 'timestamp');
364
+ return this.safeTicker({
365
+ 'symbol': symbol,
366
+ 'timestamp': timestamp,
367
+ 'datetime': this.iso8601(timestamp),
368
+ 'ask': this.safeNumber(ask, 0),
369
+ 'askVolume': this.safeNumber(ask, 1),
370
+ 'bid': this.safeNumber(bid, 0),
371
+ 'bidVolume': this.safeNumber(bid, 1),
372
+ 'info': ticker,
373
+ }, market);
374
+ }
288
375
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
289
376
  /**
290
377
  * @method
@@ -676,6 +763,9 @@ class kucoin extends kucoin$1 {
676
763
  // }
677
764
  //
678
765
  const id = this.safeString(message, 'id');
766
+ if (!(id in client.subscriptions)) {
767
+ return;
768
+ }
679
769
  const subscriptionHash = this.safeString(client.subscriptions, id);
680
770
  const subscription = this.safeValue(client.subscriptions, subscriptionHash);
681
771
  delete client.subscriptions[id];
@@ -1049,6 +1139,7 @@ class kucoin extends kucoin$1 {
1049
1139
  }
1050
1140
  const subject = this.safeString(message, 'subject');
1051
1141
  const methods = {
1142
+ 'level1': this.handleBidAsk,
1052
1143
  'level2': this.handleOrderBook,
1053
1144
  'trade.l2update': this.handleOrderBook,
1054
1145
  'trade.ticker': this.handleTicker,