ccxt 4.2.37 → 4.2.38

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.
@@ -40,6 +40,7 @@ export default class kucoin extends kucoinRest {
40
40
  'watchOrderBook': {
41
41
  'snapshotDelay': 5,
42
42
  'snapshotMaxRetries': 3,
43
+ 'method': '/market/level2', // '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50'
43
44
  },
44
45
  },
45
46
  'streaming': {
@@ -441,10 +442,15 @@ export default class kucoin extends kucoinRest {
441
442
  /**
442
443
  * @method
443
444
  * @name kucoin#watchOrderBook
445
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
446
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
447
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
448
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
444
449
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
445
450
  * @param {string} symbol unified symbol of the market to fetch the order book for
446
451
  * @param {int} [limit] the maximum amount of order book entries to return
447
452
  * @param {object} [params] extra parameters specific to the exchange API endpoint
453
+ * @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
448
454
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
449
455
  */
450
456
  //
@@ -468,10 +474,15 @@ export default class kucoin extends kucoinRest {
468
474
  /**
469
475
  * @method
470
476
  * @name kucoin#watchOrderBookForSymbols
477
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
478
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
479
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
480
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
471
481
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
472
482
  * @param {string[]} symbols unified array of symbols
473
483
  * @param {int} [limit] the maximum amount of order book entries to return
474
484
  * @param {object} [params] extra parameters specific to the exchange API endpoint
485
+ * @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
475
486
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
476
487
  */
477
488
  const symbolsLength = symbols.length;
@@ -479,28 +490,36 @@ export default class kucoin extends kucoinRest {
479
490
  throw new ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
480
491
  }
481
492
  if (limit !== undefined) {
482
- if ((limit !== 20) && (limit !== 100)) {
483
- throw new ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
493
+ if ((limit !== 20) && (limit !== 100) && (limit !== 50) && (limit !== 5)) {
494
+ throw new ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 5, 20, 50 or 100");
484
495
  }
485
496
  }
486
497
  await this.loadMarkets();
487
498
  symbols = this.marketSymbols(symbols);
488
499
  const marketIds = this.marketIds(symbols);
489
500
  const url = await this.negotiate(false);
490
- const topic = '/market/level2:' + marketIds.join(',');
501
+ let method = undefined;
502
+ [method, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'method', '/market/level2');
503
+ if ((limit === 5) || (limit === 50)) {
504
+ method = '/spotMarket/level2Depth' + limit.toString();
505
+ }
506
+ const topic = method + ':' + marketIds.join(',');
491
507
  const messageHashes = [];
492
508
  const subscriptionHashes = [];
493
509
  for (let i = 0; i < symbols.length; i++) {
494
510
  const symbol = symbols[i];
495
511
  messageHashes.push('orderbook:' + symbol);
496
512
  const marketId = marketIds[i];
497
- subscriptionHashes.push('/market/level2:' + marketId);
513
+ subscriptionHashes.push(method + ':' + marketId);
514
+ }
515
+ let subscription = {};
516
+ if (method === '/market/level2') { // other streams return the entire orderbook, so we don't need to fetch the snapshot through REST
517
+ subscription = {
518
+ 'method': this.handleOrderBookSubscription,
519
+ 'symbols': symbols,
520
+ 'limit': limit,
521
+ };
498
522
  }
499
- const subscription = {
500
- 'method': this.handleOrderBookSubscription,
501
- 'symbols': symbols,
502
- 'limit': limit,
503
- };
504
523
  const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, params, subscription);
505
524
  return orderbook.limit();
506
525
  }
@@ -524,41 +543,74 @@ export default class kucoin extends kucoinRest {
524
543
  // }
525
544
  // }
526
545
  //
546
+ // {
547
+ // "topic": "/spotMarket/level2Depth5:BTC-USDT",
548
+ // "type": "message",
549
+ // "data": {
550
+ // "asks": [
551
+ // [
552
+ // "42815.6",
553
+ // "1.24016245"
554
+ // ]
555
+ // ],
556
+ // "bids": [
557
+ // [
558
+ // "42815.5",
559
+ // "0.08652716"
560
+ // ]
561
+ // ],
562
+ // "timestamp": 1707204474018
563
+ // },
564
+ // "subject": "level2"
565
+ // }
566
+ //
527
567
  const data = this.safeValue(message, 'data');
528
- const marketId = this.safeString(data, 'symbol');
568
+ const subject = this.safeString(message, 'subject');
569
+ const topic = this.safeString(message, 'topic');
570
+ const topicParts = topic.split(':');
571
+ const topicSymbol = this.safeString(topicParts, 1);
572
+ const topicChannel = this.safeString(topicParts, 0);
573
+ const marketId = this.safeString(data, 'symbol', topicSymbol);
529
574
  const symbol = this.safeSymbol(marketId, undefined, '-');
530
575
  const messageHash = 'orderbook:' + symbol;
531
- const storedOrderBook = this.orderbooks[symbol];
532
- const nonce = this.safeInteger(storedOrderBook, 'nonce');
533
- const deltaEnd = this.safeInteger(data, 'sequenceEnd');
534
- if (nonce === undefined) {
535
- const cacheLength = storedOrderBook.cache.length;
536
- const topic = this.safeString(message, 'topic');
537
- const topicParts = topic.split(':');
538
- const topicSymbol = this.safeString(topicParts, 1);
539
- const topicChannel = this.safeString(topicParts, 0);
540
- const subscriptions = Object.keys(client.subscriptions);
541
- let subscription = undefined;
542
- for (let i = 0; i < subscriptions.length; i++) {
543
- const key = subscriptions[i];
544
- if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
545
- subscription = client.subscriptions[key];
546
- break;
547
- }
576
+ let orderbook = this.safeDict(this.orderbooks, symbol);
577
+ if (subject === 'level2') {
578
+ if (orderbook === undefined) {
579
+ orderbook = this.orderBook();
548
580
  }
549
- const limit = this.safeInteger(subscription, 'limit');
550
- const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
551
- if (cacheLength === snapshotDelay) {
552
- this.spawn(this.loadOrderBook, client, messageHash, symbol, limit, {});
581
+ else {
582
+ orderbook.reset();
553
583
  }
554
- storedOrderBook.cache.push(data);
555
- return;
584
+ orderbook['symbol'] = symbol;
556
585
  }
557
- else if (nonce >= deltaEnd) {
558
- return;
586
+ else {
587
+ const nonce = this.safeInteger(orderbook, 'nonce');
588
+ const deltaEnd = this.safeInteger2(data, 'sequenceEnd', 'timestamp');
589
+ if (nonce === undefined) {
590
+ const cacheLength = orderbook.cache.length;
591
+ const subscriptions = Object.keys(client.subscriptions);
592
+ let subscription = undefined;
593
+ for (let i = 0; i < subscriptions.length; i++) {
594
+ const key = subscriptions[i];
595
+ if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
596
+ subscription = client.subscriptions[key];
597
+ break;
598
+ }
599
+ }
600
+ const limit = this.safeInteger(subscription, 'limit');
601
+ const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
602
+ if (cacheLength === snapshotDelay) {
603
+ this.spawn(this.loadOrderBook, client, messageHash, symbol, limit, {});
604
+ }
605
+ orderbook.cache.push(data);
606
+ return;
607
+ }
608
+ else if (nonce >= deltaEnd) {
609
+ return;
610
+ }
559
611
  }
560
- this.handleDelta(storedOrderBook, data);
561
- client.resolve(storedOrderBook, messageHash);
612
+ this.handleDelta(orderbook, data);
613
+ client.resolve(orderbook, messageHash);
562
614
  }
563
615
  getCacheIndex(orderbook, cache) {
564
616
  const firstDelta = this.safeValue(cache, 0);
@@ -578,11 +630,11 @@ export default class kucoin extends kucoinRest {
578
630
  return cache.length;
579
631
  }
580
632
  handleDelta(orderbook, delta) {
581
- orderbook['nonce'] = this.safeInteger(delta, 'sequenceEnd');
582
- const timestamp = this.safeInteger(delta, 'time');
633
+ const timestamp = this.safeInteger2(delta, 'time', 'timestamp');
634
+ orderbook['nonce'] = this.safeInteger(delta, 'sequenceEnd', timestamp);
583
635
  orderbook['timestamp'] = timestamp;
584
636
  orderbook['datetime'] = this.iso8601(timestamp);
585
- const changes = this.safeValue(delta, 'changes');
637
+ const changes = this.safeValue(delta, 'changes', delta);
586
638
  const bids = this.safeValue(changes, 'bids', []);
587
639
  const asks = this.safeValue(changes, 'asks', []);
588
640
  const storedBids = orderbook['bids'];
@@ -996,6 +1048,7 @@ export default class kucoin extends kucoinRest {
996
1048
  }
997
1049
  const subject = this.safeString(message, 'subject');
998
1050
  const methods = {
1051
+ 'level2': this.handleOrderBook,
999
1052
  'trade.l2update': this.handleOrderBook,
1000
1053
  'trade.ticker': this.handleTicker,
1001
1054
  'trade.snapshot': this.handleTicker,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.2.37",
3
+ "version": "4.2.38",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",