ccxt 4.2.36 → 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.
@@ -3738,10 +3738,22 @@ class bybit extends bybit$1 {
3738
3738
  if (isStopLoss) {
3739
3739
  const slTriggerPrice = this.safeValue2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
3740
3740
  request['stopLoss'] = this.priceToPrecision(symbol, slTriggerPrice);
3741
+ const slLimitPrice = this.safeValue(stopLoss, 'price');
3742
+ if (slLimitPrice !== undefined) {
3743
+ request['tpslMode'] = 'Partial';
3744
+ request['slOrderType'] = 'Limit';
3745
+ request['slLimitPrice'] = this.priceToPrecision(symbol, slLimitPrice);
3746
+ }
3741
3747
  }
3742
3748
  if (isTakeProfit) {
3743
3749
  const tpTriggerPrice = this.safeValue2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit);
3744
3750
  request['takeProfit'] = this.priceToPrecision(symbol, tpTriggerPrice);
3751
+ const tpLimitPrice = this.safeValue(takeProfit, 'price');
3752
+ if (tpLimitPrice !== undefined) {
3753
+ request['tpslMode'] = 'Partial';
3754
+ request['tpOrderType'] = 'Limit';
3755
+ request['tpLimitPrice'] = this.priceToPrecision(symbol, tpLimitPrice);
3756
+ }
3745
3757
  }
3746
3758
  }
3747
3759
  if (market['spot']) {
@@ -6023,9 +6035,6 @@ class bybit extends bybit$1 {
6023
6035
  if (timestamp === undefined) {
6024
6036
  timestamp = this.safeIntegerN(position, ['updatedTime', 'updatedAt']);
6025
6037
  }
6026
- // default to cross of USDC margined positions
6027
- const tradeMode = this.safeInteger(position, 'tradeMode', 0);
6028
- const marginMode = tradeMode ? 'isolated' : 'cross';
6029
6038
  let collateralString = this.safeString(position, 'positionBalance');
6030
6039
  const entryPrice = this.omitZero(this.safeString2(position, 'entryPrice', 'avgPrice'));
6031
6040
  const liquidationPrice = this.omitZero(this.safeString(position, 'liqPrice'));
@@ -6089,7 +6098,7 @@ class bybit extends bybit$1 {
6089
6098
  'markPrice': this.safeNumber(position, 'markPrice'),
6090
6099
  'lastPrice': undefined,
6091
6100
  'collateral': this.parseNumber(collateralString),
6092
- 'marginMode': marginMode,
6101
+ 'marginMode': undefined,
6093
6102
  'side': side,
6094
6103
  'percentage': undefined,
6095
6104
  'stopLossPrice': this.safeNumber2(position, 'stop_loss', 'stopLoss'),
@@ -16,9 +16,11 @@ class gemini extends gemini$1 {
16
16
  'watchTicker': false,
17
17
  'watchTickers': false,
18
18
  'watchTrades': true,
19
+ 'watchTradesForSymbols': true,
19
20
  'watchMyTrades': false,
20
21
  'watchOrders': true,
21
22
  'watchOrderBook': true,
23
+ 'watchOrderBookForSymbols': true,
22
24
  'watchOHLCV': true,
23
25
  },
24
26
  'hostname': 'api.gemini.com',
@@ -67,7 +69,29 @@ class gemini extends gemini$1 {
67
69
  }
68
70
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
69
71
  }
72
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
73
+ /**
74
+ * @method
75
+ * @name gemini#watchTradesForSymbols
76
+ * @see https://docs.gemini.com/websocket-api/#multi-market-data
77
+ * @description get the list of most recent trades for a list of symbols
78
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
79
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
80
+ * @param {int} [limit] the maximum amount of trades to fetch
81
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
82
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
83
+ */
84
+ const trades = await this.helperForWatchMultipleConstruct('trades', symbols, params);
85
+ if (this.newUpdates) {
86
+ const first = this.safeList(trades, 0);
87
+ const tradeSymbol = this.safeString(first, 'symbol');
88
+ limit = trades.getLimit(tradeSymbol, limit);
89
+ }
90
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
91
+ }
70
92
  parseWsTrade(trade, market = undefined) {
93
+ //
94
+ // regular v2 trade
71
95
  //
72
96
  // {
73
97
  // "type": "trade",
@@ -79,11 +103,31 @@ class gemini extends gemini$1 {
79
103
  // "side": "buy"
80
104
  // }
81
105
  //
106
+ // multi data trade
107
+ //
108
+ // {
109
+ // "type": "trade",
110
+ // "symbol": "ETHUSD",
111
+ // "tid": "1683002242170204", // this is not TS, but somewhat ID
112
+ // "price": "2299.24",
113
+ // "amount": "0.002662",
114
+ // "makerSide": "bid"
115
+ // }
116
+ //
82
117
  const timestamp = this.safeInteger(trade, 'timestamp');
83
- const id = this.safeString(trade, 'event_id');
118
+ const id = this.safeString2(trade, 'event_id', 'tid');
84
119
  const priceString = this.safeString(trade, 'price');
85
- const amountString = this.safeString(trade, 'quantity');
86
- const side = this.safeStringLower(trade, 'side');
120
+ const amountString = this.safeString2(trade, 'quantity', 'amount');
121
+ let side = this.safeStringLower(trade, 'side');
122
+ if (side === undefined) {
123
+ const marketSide = this.safeStringLower(trade, 'makerSide');
124
+ if (marketSide === 'bid') {
125
+ side = 'sell';
126
+ }
127
+ else if (marketSide === 'ask') {
128
+ side = 'buy';
129
+ }
130
+ }
87
131
  const marketId = this.safeStringLower(trade, 'symbol');
88
132
  const symbol = this.safeSymbol(marketId, market);
89
133
  return this.safeTrade({
@@ -183,6 +227,34 @@ class gemini extends gemini$1 {
183
227
  client.resolve(stored, messageHash);
184
228
  }
185
229
  }
230
+ handleTradesForMultidata(client, trades, timestamp) {
231
+ if (trades !== undefined) {
232
+ const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
233
+ const storesForSymbols = {};
234
+ for (let i = 0; i < trades.length; i++) {
235
+ const marketId = trades[i]['symbol'];
236
+ const market = this.safeMarket(marketId.toLowerCase());
237
+ const symbol = market['symbol'];
238
+ const trade = this.parseWsTrade(trades[i], market);
239
+ trade['timestamp'] = timestamp;
240
+ trade['datetime'] = this.iso8601(timestamp);
241
+ let stored = this.safeValue(this.trades, symbol);
242
+ if (stored === undefined) {
243
+ stored = new Cache.ArrayCache(tradesLimit);
244
+ this.trades[symbol] = stored;
245
+ }
246
+ stored.append(trade);
247
+ storesForSymbols[symbol] = stored;
248
+ }
249
+ const symbols = Object.keys(storesForSymbols);
250
+ for (let i = 0; i < symbols.length; i++) {
251
+ const symbol = symbols[i];
252
+ const stored = storesForSymbols[symbol];
253
+ const messageHash = 'trades:' + symbol;
254
+ client.resolve(stored, messageHash);
255
+ }
256
+ }
257
+ }
186
258
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
187
259
  /**
188
260
  * @method
@@ -328,6 +400,93 @@ class gemini extends gemini$1 {
328
400
  this.orderbooks[symbol] = orderbook;
329
401
  client.resolve(orderbook, messageHash);
330
402
  }
403
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
404
+ /**
405
+ * @method
406
+ * @name gemini#watchOrderBookForSymbols
407
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
408
+ * @see https://docs.gemini.com/websocket-api/#multi-market-data
409
+ * @param {string[]} symbols unified array of symbols
410
+ * @param {int} [limit] the maximum amount of order book entries to return
411
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
412
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
413
+ */
414
+ const orderbook = await this.helperForWatchMultipleConstruct('orderbook', symbols, params);
415
+ return orderbook.limit();
416
+ }
417
+ async helperForWatchMultipleConstruct(itemHashName, symbols, params = {}) {
418
+ await this.loadMarkets();
419
+ symbols = this.marketSymbols(symbols, undefined, false, true, true);
420
+ const firstMarket = this.market(symbols[0]);
421
+ if (!firstMarket['spot'] && !firstMarket['linear']) {
422
+ throw new errors.NotSupported(this.id + ' watchMultiple supports only spot or linear-swap symbols');
423
+ }
424
+ const messageHashes = [];
425
+ const marketIds = [];
426
+ for (let i = 0; i < symbols.length; i++) {
427
+ const symbol = symbols[i];
428
+ const messageHash = itemHashName + ':' + symbol;
429
+ messageHashes.push(messageHash);
430
+ const market = this.market(symbol);
431
+ marketIds.push(market['id']);
432
+ }
433
+ const queryStr = marketIds.join(',');
434
+ let url = this.urls['api']['ws'] + '/v1/multimarketdata?symbols=' + queryStr + '&heartbeat=true&';
435
+ if (itemHashName === 'orderbook') {
436
+ url += 'trades=false&bids=true&offers=true';
437
+ }
438
+ else if (itemHashName === 'trades') {
439
+ url += 'trades=true&bids=false&offers=false';
440
+ }
441
+ return await this.watchMultiple(url, messageHashes, undefined);
442
+ }
443
+ handleOrderBookForMultidata(client, rawOrderBookChanges, timestamp, nonce) {
444
+ //
445
+ // rawOrderBookChanges
446
+ //
447
+ // [
448
+ // {
449
+ // delta: "4105123935484.817624",
450
+ // price: "0.000000001",
451
+ // reason: "initial", // initial|cancel|place
452
+ // remaining: "4105123935484.817624",
453
+ // side: "bid", // bid|ask
454
+ // symbol: "SHIBUSD",
455
+ // type: "change", // seems always change
456
+ // },
457
+ // ...
458
+ //
459
+ const marketId = rawOrderBookChanges[0]['symbol'];
460
+ const market = this.safeMarket(marketId.toLowerCase());
461
+ const symbol = market['symbol'];
462
+ const messageHash = 'orderbook:' + symbol;
463
+ let orderbook = this.safeDict(this.orderbooks, symbol);
464
+ if (orderbook === undefined) {
465
+ orderbook = this.orderBook();
466
+ }
467
+ const bids = orderbook['bids'];
468
+ const asks = orderbook['asks'];
469
+ for (let i = 0; i < rawOrderBookChanges.length; i++) {
470
+ const entry = rawOrderBookChanges[i];
471
+ const price = this.safeNumber(entry, 'price');
472
+ const size = this.safeNumber(entry, 'remaining');
473
+ const rawSide = this.safeString(entry, 'side');
474
+ if (rawSide === 'bid') {
475
+ bids.store(price, size);
476
+ }
477
+ else {
478
+ asks.store(price, size);
479
+ }
480
+ }
481
+ orderbook['bids'] = bids;
482
+ orderbook['asks'] = asks;
483
+ orderbook['symbol'] = symbol;
484
+ orderbook['nonce'] = nonce;
485
+ orderbook['timestamp'] = timestamp;
486
+ orderbook['datetime'] = this.iso8601(timestamp);
487
+ this.orderbooks[symbol] = orderbook;
488
+ client.resolve(orderbook, messageHash);
489
+ }
331
490
  handleL2Updates(client, message) {
332
491
  //
333
492
  // {
@@ -408,6 +567,7 @@ class gemini extends gemini$1 {
408
567
  // "socket_sequence": 7
409
568
  // }
410
569
  //
570
+ client.lastPong = this.milliseconds();
411
571
  return message;
412
572
  }
413
573
  handleSubscription(client, message) {
@@ -610,6 +770,33 @@ class gemini extends gemini$1 {
610
770
  if (method !== undefined) {
611
771
  method.call(this, client, message);
612
772
  }
773
+ // handle multimarketdata
774
+ if (type === 'update') {
775
+ const ts = this.safeInteger(message, 'timestampms', this.milliseconds());
776
+ const eventId = this.safeInteger(message, 'eventId');
777
+ const events = this.safeList(message, 'events');
778
+ const orderBookItems = [];
779
+ const collectedEventsOfTrades = [];
780
+ for (let i = 0; i < events.length; i++) {
781
+ const event = events[i];
782
+ const eventType = this.safeString(event, 'type');
783
+ const isOrderBook = (eventType === 'change') && ('side' in event) && this.inArray(event['side'], ['ask', 'bid']);
784
+ if (isOrderBook) {
785
+ orderBookItems.push(event);
786
+ }
787
+ else if (eventType === 'trade') {
788
+ collectedEventsOfTrades.push(events[i]);
789
+ }
790
+ }
791
+ const lengthOb = orderBookItems.length;
792
+ if (lengthOb > 0) {
793
+ this.handleOrderBookForMultidata(client, orderBookItems, ts, eventId);
794
+ }
795
+ const lengthTrades = collectedEventsOfTrades.length;
796
+ if (lengthTrades > 0) {
797
+ this.handleTradesForMultidata(client, collectedEventsOfTrades, ts);
798
+ }
799
+ }
613
800
  }
614
801
  async authenticate(params = {}) {
615
802
  const url = this.safeString(params, 'url');
@@ -37,6 +37,7 @@ class kucoin extends kucoin$1 {
37
37
  'watchOrderBook': {
38
38
  'snapshotDelay': 5,
39
39
  'snapshotMaxRetries': 3,
40
+ 'method': '/market/level2', // '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50'
40
41
  },
41
42
  },
42
43
  'streaming': {
@@ -438,10 +439,15 @@ class kucoin extends kucoin$1 {
438
439
  /**
439
440
  * @method
440
441
  * @name kucoin#watchOrderBook
442
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
443
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
444
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
445
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
441
446
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
442
447
  * @param {string} symbol unified symbol of the market to fetch the order book for
443
448
  * @param {int} [limit] the maximum amount of order book entries to return
444
449
  * @param {object} [params] extra parameters specific to the exchange API endpoint
450
+ * @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
445
451
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
446
452
  */
447
453
  //
@@ -465,10 +471,15 @@ class kucoin extends kucoin$1 {
465
471
  /**
466
472
  * @method
467
473
  * @name kucoin#watchOrderBookForSymbols
474
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level1-bbo-market-data
475
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-market-data
476
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-5-best-ask-bid-orders
477
+ * @see https://www.kucoin.com/docs/websocket/spot-trading/public-channels/level2-50-best-ask-bid-orders
468
478
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
469
479
  * @param {string[]} symbols unified array of symbols
470
480
  * @param {int} [limit] the maximum amount of order book entries to return
471
481
  * @param {object} [params] extra parameters specific to the exchange API endpoint
482
+ * @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
472
483
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
473
484
  */
474
485
  const symbolsLength = symbols.length;
@@ -476,28 +487,36 @@ class kucoin extends kucoin$1 {
476
487
  throw new errors.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
477
488
  }
478
489
  if (limit !== undefined) {
479
- if ((limit !== 20) && (limit !== 100)) {
480
- throw new errors.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
490
+ if ((limit !== 20) && (limit !== 100) && (limit !== 50) && (limit !== 5)) {
491
+ throw new errors.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 5, 20, 50 or 100");
481
492
  }
482
493
  }
483
494
  await this.loadMarkets();
484
495
  symbols = this.marketSymbols(symbols);
485
496
  const marketIds = this.marketIds(symbols);
486
497
  const url = await this.negotiate(false);
487
- const topic = '/market/level2:' + marketIds.join(',');
498
+ let method = undefined;
499
+ [method, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'method', '/market/level2');
500
+ if ((limit === 5) || (limit === 50)) {
501
+ method = '/spotMarket/level2Depth' + limit.toString();
502
+ }
503
+ const topic = method + ':' + marketIds.join(',');
488
504
  const messageHashes = [];
489
505
  const subscriptionHashes = [];
490
506
  for (let i = 0; i < symbols.length; i++) {
491
507
  const symbol = symbols[i];
492
508
  messageHashes.push('orderbook:' + symbol);
493
509
  const marketId = marketIds[i];
494
- subscriptionHashes.push('/market/level2:' + marketId);
510
+ subscriptionHashes.push(method + ':' + marketId);
511
+ }
512
+ let subscription = {};
513
+ if (method === '/market/level2') { // other streams return the entire orderbook, so we don't need to fetch the snapshot through REST
514
+ subscription = {
515
+ 'method': this.handleOrderBookSubscription,
516
+ 'symbols': symbols,
517
+ 'limit': limit,
518
+ };
495
519
  }
496
- const subscription = {
497
- 'method': this.handleOrderBookSubscription,
498
- 'symbols': symbols,
499
- 'limit': limit,
500
- };
501
520
  const orderbook = await this.subscribeMultiple(url, messageHashes, topic, subscriptionHashes, params, subscription);
502
521
  return orderbook.limit();
503
522
  }
@@ -521,41 +540,74 @@ class kucoin extends kucoin$1 {
521
540
  // }
522
541
  // }
523
542
  //
543
+ // {
544
+ // "topic": "/spotMarket/level2Depth5:BTC-USDT",
545
+ // "type": "message",
546
+ // "data": {
547
+ // "asks": [
548
+ // [
549
+ // "42815.6",
550
+ // "1.24016245"
551
+ // ]
552
+ // ],
553
+ // "bids": [
554
+ // [
555
+ // "42815.5",
556
+ // "0.08652716"
557
+ // ]
558
+ // ],
559
+ // "timestamp": 1707204474018
560
+ // },
561
+ // "subject": "level2"
562
+ // }
563
+ //
524
564
  const data = this.safeValue(message, 'data');
525
- const marketId = this.safeString(data, 'symbol');
565
+ const subject = this.safeString(message, 'subject');
566
+ const topic = this.safeString(message, 'topic');
567
+ const topicParts = topic.split(':');
568
+ const topicSymbol = this.safeString(topicParts, 1);
569
+ const topicChannel = this.safeString(topicParts, 0);
570
+ const marketId = this.safeString(data, 'symbol', topicSymbol);
526
571
  const symbol = this.safeSymbol(marketId, undefined, '-');
527
572
  const messageHash = 'orderbook:' + symbol;
528
- const storedOrderBook = this.orderbooks[symbol];
529
- const nonce = this.safeInteger(storedOrderBook, 'nonce');
530
- const deltaEnd = this.safeInteger(data, 'sequenceEnd');
531
- if (nonce === undefined) {
532
- const cacheLength = storedOrderBook.cache.length;
533
- const topic = this.safeString(message, 'topic');
534
- const topicParts = topic.split(':');
535
- const topicSymbol = this.safeString(topicParts, 1);
536
- const topicChannel = this.safeString(topicParts, 0);
537
- const subscriptions = Object.keys(client.subscriptions);
538
- let subscription = undefined;
539
- for (let i = 0; i < subscriptions.length; i++) {
540
- const key = subscriptions[i];
541
- if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
542
- subscription = client.subscriptions[key];
543
- break;
544
- }
573
+ let orderbook = this.safeDict(this.orderbooks, symbol);
574
+ if (subject === 'level2') {
575
+ if (orderbook === undefined) {
576
+ orderbook = this.orderBook();
545
577
  }
546
- const limit = this.safeInteger(subscription, 'limit');
547
- const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
548
- if (cacheLength === snapshotDelay) {
549
- this.spawn(this.loadOrderBook, client, messageHash, symbol, limit, {});
578
+ else {
579
+ orderbook.reset();
550
580
  }
551
- storedOrderBook.cache.push(data);
552
- return;
581
+ orderbook['symbol'] = symbol;
553
582
  }
554
- else if (nonce >= deltaEnd) {
555
- return;
583
+ else {
584
+ const nonce = this.safeInteger(orderbook, 'nonce');
585
+ const deltaEnd = this.safeInteger2(data, 'sequenceEnd', 'timestamp');
586
+ if (nonce === undefined) {
587
+ const cacheLength = orderbook.cache.length;
588
+ const subscriptions = Object.keys(client.subscriptions);
589
+ let subscription = undefined;
590
+ for (let i = 0; i < subscriptions.length; i++) {
591
+ const key = subscriptions[i];
592
+ if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
593
+ subscription = client.subscriptions[key];
594
+ break;
595
+ }
596
+ }
597
+ const limit = this.safeInteger(subscription, 'limit');
598
+ const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
599
+ if (cacheLength === snapshotDelay) {
600
+ this.spawn(this.loadOrderBook, client, messageHash, symbol, limit, {});
601
+ }
602
+ orderbook.cache.push(data);
603
+ return;
604
+ }
605
+ else if (nonce >= deltaEnd) {
606
+ return;
607
+ }
556
608
  }
557
- this.handleDelta(storedOrderBook, data);
558
- client.resolve(storedOrderBook, messageHash);
609
+ this.handleDelta(orderbook, data);
610
+ client.resolve(orderbook, messageHash);
559
611
  }
560
612
  getCacheIndex(orderbook, cache) {
561
613
  const firstDelta = this.safeValue(cache, 0);
@@ -575,11 +627,11 @@ class kucoin extends kucoin$1 {
575
627
  return cache.length;
576
628
  }
577
629
  handleDelta(orderbook, delta) {
578
- orderbook['nonce'] = this.safeInteger(delta, 'sequenceEnd');
579
- const timestamp = this.safeInteger(delta, 'time');
630
+ const timestamp = this.safeInteger2(delta, 'time', 'timestamp');
631
+ orderbook['nonce'] = this.safeInteger(delta, 'sequenceEnd', timestamp);
580
632
  orderbook['timestamp'] = timestamp;
581
633
  orderbook['datetime'] = this.iso8601(timestamp);
582
- const changes = this.safeValue(delta, 'changes');
634
+ const changes = this.safeValue(delta, 'changes', delta);
583
635
  const bids = this.safeValue(changes, 'bids', []);
584
636
  const asks = this.safeValue(changes, 'asks', []);
585
637
  const storedBids = orderbook['bids'];
@@ -993,6 +1045,7 @@ class kucoin extends kucoin$1 {
993
1045
  }
994
1046
  const subject = this.safeString(message, 'subject');
995
1047
  const methods = {
1048
+ 'level2': this.handleOrderBook,
996
1049
  'trade.l2update': this.handleOrderBook,
997
1050
  'trade.ticker': this.handleTicker,
998
1051
  'trade.snapshot': this.handleTicker,
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.2.35";
7
+ declare const version = "4.2.37";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
@@ -37,6 +37,7 @@ import bitteam from './src/bitteam.js';
37
37
  import bitvavo from './src/bitvavo.js';
38
38
  import bl3p from './src/bl3p.js';
39
39
  import blockchaincom from './src/blockchaincom.js';
40
+ import blofin from './src/blofin.js';
40
41
  import btcalpha from './src/btcalpha.js';
41
42
  import btcbox from './src/btcbox.js';
42
43
  import btcmarkets from './src/btcmarkets.js';
@@ -199,6 +200,7 @@ declare const exchanges: {
199
200
  bitvavo: typeof bitvavo;
200
201
  bl3p: typeof bl3p;
201
202
  blockchaincom: typeof blockchaincom;
203
+ blofin: typeof blofin;
202
204
  btcalpha: typeof btcalpha;
203
205
  btcbox: typeof btcbox;
204
206
  btcmarkets: typeof btcmarkets;
@@ -432,6 +434,7 @@ declare const ccxt: {
432
434
  bitvavo: typeof bitvavo;
433
435
  bl3p: typeof bl3p;
434
436
  blockchaincom: typeof blockchaincom;
437
+ blofin: typeof blofin;
435
438
  btcalpha: typeof btcalpha;
436
439
  btcbox: typeof btcbox;
437
440
  btcmarkets: typeof btcmarkets;
@@ -501,5 +504,5 @@ declare const ccxt: {
501
504
  zaif: typeof zaif;
502
505
  zonda: typeof zonda;
503
506
  } & typeof functions & typeof errors;
504
- export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange, Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbay, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitforex, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbasepro, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hitbtc, hitbtc3, hollaex, htx, huobi, huobijp, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, p2b, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, upbit, wavesexchange, wazirx, whitebit, woo, yobit, zaif, zonda, };
507
+ export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange, Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbay, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitforex, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, blofin, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbasepro, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hitbtc, hitbtc3, hollaex, htx, huobi, huobijp, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, p2b, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, upbit, wavesexchange, wazirx, whitebit, woo, yobit, zaif, zonda, };
505
508
  export default ccxt;
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.2.36';
41
+ const version = '4.2.38';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -73,6 +73,7 @@ import bitteam from './src/bitteam.js';
73
73
  import bitvavo from './src/bitvavo.js';
74
74
  import bl3p from './src/bl3p.js';
75
75
  import blockchaincom from './src/blockchaincom.js';
76
+ import blofin from './src/blofin.js';
76
77
  import btcalpha from './src/btcalpha.js';
77
78
  import btcbox from './src/btcbox.js';
78
79
  import btcmarkets from './src/btcmarkets.js';
@@ -236,6 +237,7 @@ const exchanges = {
236
237
  'bitvavo': bitvavo,
237
238
  'bl3p': bl3p,
238
239
  'blockchaincom': blockchaincom,
240
+ 'blofin': blofin,
239
241
  'btcalpha': btcalpha,
240
242
  'btcbox': btcbox,
241
243
  'btcmarkets': btcmarkets,
@@ -380,6 +382,6 @@ pro.exchanges = Object.keys(pro);
380
382
  pro['Exchange'] = Exchange; // now the same for rest and ts
381
383
  //-----------------------------------------------------------------------------
382
384
  const ccxt = Object.assign({ version, Exchange, Precise, 'exchanges': Object.keys(exchanges), 'pro': pro }, exchanges, functions, errors);
383
- export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbay, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitforex, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbasepro, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hitbtc, hitbtc3, hollaex, htx, huobi, huobijp, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, p2b, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, upbit, wavesexchange, wazirx, whitebit, woo, yobit, zaif, zonda, };
385
+ export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbay, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitforex, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, blofin, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbasepro, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hitbtc, hitbtc3, hollaex, htx, huobi, huobijp, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, p2b, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, upbit, wavesexchange, wazirx, whitebit, woo, yobit, zaif, zonda, };
384
386
  export default ccxt;
385
387
  //-----------------------------------------------------------------------------
@@ -0,0 +1,36 @@
1
+ import { implicitReturnType } from '../base/types.js';
2
+ import { Exchange as _Exchange } from '../base/Exchange.js';
3
+ interface Exchange {
4
+ publicGetMarketInstruments(params?: {}): Promise<implicitReturnType>;
5
+ publicGetMarketTickers(params?: {}): Promise<implicitReturnType>;
6
+ publicGetMarketBooks(params?: {}): Promise<implicitReturnType>;
7
+ publicGetMarketTrades(params?: {}): Promise<implicitReturnType>;
8
+ publicGetMarketCandles(params?: {}): Promise<implicitReturnType>;
9
+ publicGetMarketMarkPrice(params?: {}): Promise<implicitReturnType>;
10
+ publicGetMarketFundingRate(params?: {}): Promise<implicitReturnType>;
11
+ publicGetMarketFundingRateHistory(params?: {}): Promise<implicitReturnType>;
12
+ privateGetAssetBalances(params?: {}): Promise<implicitReturnType>;
13
+ privateGetTradeOrdersPending(params?: {}): Promise<implicitReturnType>;
14
+ privateGetTradeFillsHistory(params?: {}): Promise<implicitReturnType>;
15
+ privateGetAssetDepositHistory(params?: {}): Promise<implicitReturnType>;
16
+ privateGetAssetWithdrawalHistory(params?: {}): Promise<implicitReturnType>;
17
+ privateGetAssetBills(params?: {}): Promise<implicitReturnType>;
18
+ privateGetAccountBalance(params?: {}): Promise<implicitReturnType>;
19
+ privateGetAccountPositions(params?: {}): Promise<implicitReturnType>;
20
+ privateGetAccountLeverageInfo(params?: {}): Promise<implicitReturnType>;
21
+ privateGetTradeOrdersTpslPending(params?: {}): Promise<implicitReturnType>;
22
+ privateGetTradeOrdersHistory(params?: {}): Promise<implicitReturnType>;
23
+ privateGetTradeOrdersTpslHistory(params?: {}): Promise<implicitReturnType>;
24
+ privatePostTradeOrder(params?: {}): Promise<implicitReturnType>;
25
+ privatePostTradeCancelOrder(params?: {}): Promise<implicitReturnType>;
26
+ privatePostAccountSetLeverage(params?: {}): Promise<implicitReturnType>;
27
+ privatePostTradeBatchOrders(params?: {}): Promise<implicitReturnType>;
28
+ privatePostTradeOrderTpsl(params?: {}): Promise<implicitReturnType>;
29
+ privatePostTradeCancelBatchOrders(params?: {}): Promise<implicitReturnType>;
30
+ privatePostTradeCancelTpsl(params?: {}): Promise<implicitReturnType>;
31
+ privatePostTradeClosePosition(params?: {}): Promise<implicitReturnType>;
32
+ privatePostAssetTransfer(params?: {}): Promise<implicitReturnType>;
33
+ }
34
+ declare abstract class Exchange extends _Exchange {
35
+ }
36
+ export default Exchange;
@@ -0,0 +1,11 @@
1
+ // ----------------------------------------------------------------------------
2
+
3
+ // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+ // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
+
7
+ // -------------------------------------------------------------------------------
8
+ import { Exchange as _Exchange } from '../base/Exchange.js';
9
+ class Exchange extends _Exchange {
10
+ }
11
+ export default Exchange;
@@ -103,6 +103,7 @@ export interface Order {
103
103
  filled: number;
104
104
  remaining: number;
105
105
  stopPrice?: number;
106
+ triggerPrice?: number;
106
107
  takeProfitPrice?: number;
107
108
  stopLossPrice?: number;
108
109
  cost: number;
@@ -234,6 +235,7 @@ export interface Position {
234
235
  notional?: number;
235
236
  leverage?: number;
236
237
  unrealizedPnl?: number;
238
+ realizedPnl?: number;
237
239
  collateral?: number;
238
240
  entryPrice?: number;
239
241
  markPrice?: number;