ccxt 4.4.77 → 4.4.80

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.
Files changed (154) hide show
  1. package/README.md +8 -10
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +8 -4
  4. package/dist/cjs/src/abstract/ace.js +1 -1
  5. package/dist/cjs/src/abstract/apex.js +9 -0
  6. package/dist/cjs/src/ace.js +1 -1
  7. package/dist/cjs/src/apex.js +1949 -0
  8. package/dist/cjs/src/ascendex.js +25 -4
  9. package/dist/cjs/src/base/Exchange.js +42 -2
  10. package/dist/cjs/src/binance.js +9 -1
  11. package/dist/cjs/src/bingx.js +3 -3
  12. package/dist/cjs/src/bitfinex.js +64 -36
  13. package/dist/cjs/src/bitget.js +191 -138
  14. package/dist/cjs/src/bitmart.js +7 -2
  15. package/dist/cjs/src/bitmex.js +16 -8
  16. package/dist/cjs/src/bitopro.js +5 -1
  17. package/dist/cjs/src/bitrue.js +2 -1
  18. package/dist/cjs/src/bitso.js +1 -1
  19. package/dist/cjs/src/bitteam.js +2 -0
  20. package/dist/cjs/src/bitvavo.js +28 -10
  21. package/dist/cjs/src/btcalpha.js +1 -1
  22. package/dist/cjs/src/btcmarkets.js +1 -1
  23. package/dist/cjs/src/btcturk.js +1 -1
  24. package/dist/cjs/src/bybit.js +32 -16
  25. package/dist/cjs/src/cex.js +1 -1
  26. package/dist/cjs/src/coinbase.js +18 -2
  27. package/dist/cjs/src/coincatch.js +68 -0
  28. package/dist/cjs/src/coinex.js +1 -0
  29. package/dist/cjs/src/coinlist.js +1 -0
  30. package/dist/cjs/src/coinone.js +1 -0
  31. package/dist/cjs/src/delta.js +4 -0
  32. package/dist/cjs/src/deribit.js +1 -0
  33. package/dist/cjs/src/hitbtc.js +3 -0
  34. package/dist/cjs/src/hollaex.js +1 -0
  35. package/dist/cjs/src/htx.js +7 -3
  36. package/dist/cjs/src/huobijp.js +1 -0
  37. package/dist/cjs/src/hyperliquid.js +14 -4
  38. package/dist/cjs/src/kraken.js +2 -0
  39. package/dist/cjs/src/mexc.js +50 -57
  40. package/dist/cjs/src/okx.js +1 -1
  41. package/dist/cjs/src/phemex.js +2 -1
  42. package/dist/cjs/src/poloniex.js +2 -1
  43. package/dist/cjs/src/pro/apex.js +1043 -0
  44. package/dist/cjs/src/pro/binance.js +3 -3
  45. package/dist/cjs/src/pro/coinbase.js +45 -68
  46. package/dist/cjs/src/pro/gate.js +27 -2
  47. package/dist/cjs/src/pro/hollaex.js +2 -2
  48. package/dist/cjs/src/pro/p2b.js +2 -2
  49. package/dist/cjs/src/pro/tradeogre.js +283 -0
  50. package/dist/cjs/src/pro/upbit.js +43 -0
  51. package/dist/cjs/src/probit.js +1 -0
  52. package/dist/cjs/src/static_dependencies/zklink/zklink-sdk-web.js +2639 -0
  53. package/dist/cjs/src/timex.js +2 -2
  54. package/dist/cjs/src/tradeogre.js +2 -1
  55. package/dist/cjs/src/upbit.js +277 -67
  56. package/dist/cjs/src/whitebit.js +66 -12
  57. package/dist/cjs/src/woo.js +3 -1
  58. package/dist/cjs/src/xt.js +9 -0
  59. package/js/ccxt.d.ts +11 -5
  60. package/js/ccxt.js +8 -4
  61. package/js/src/abstract/apex.d.ts +34 -0
  62. package/js/src/abstract/bitmart.d.ts +1 -0
  63. package/js/src/apex.d.ts +333 -0
  64. package/js/src/apex.js +1945 -0
  65. package/js/src/ascendex.d.ts +3 -3
  66. package/js/src/ascendex.js +25 -4
  67. package/js/src/base/Exchange.d.ts +2 -0
  68. package/js/src/base/Exchange.js +42 -1
  69. package/js/src/binance.d.ts +7 -7
  70. package/js/src/binance.js +9 -1
  71. package/js/src/bingx.js +3 -3
  72. package/js/src/bitfinex.d.ts +3 -3
  73. package/js/src/bitfinex.js +64 -36
  74. package/js/src/bitflyer.d.ts +2 -2
  75. package/js/src/bitget.d.ts +2 -0
  76. package/js/src/bitget.js +191 -138
  77. package/js/src/bitmart.d.ts +5 -4
  78. package/js/src/bitmart.js +7 -2
  79. package/js/src/bitmex.d.ts +3 -3
  80. package/js/src/bitmex.js +16 -8
  81. package/js/src/bitopro.js +5 -1
  82. package/js/src/bitrue.js +2 -1
  83. package/js/src/bitso.js +1 -1
  84. package/js/src/bitteam.js +2 -0
  85. package/js/src/bitvavo.js +28 -10
  86. package/js/src/btcalpha.js +1 -1
  87. package/js/src/btcmarkets.js +1 -1
  88. package/js/src/btcturk.js +1 -1
  89. package/js/src/bybit.js +32 -16
  90. package/js/src/cex.js +1 -1
  91. package/js/src/coinbase.d.ts +4 -4
  92. package/js/src/coinbase.js +18 -2
  93. package/js/src/coinbaseexchange.d.ts +1 -1
  94. package/js/src/coincatch.d.ts +11 -0
  95. package/js/src/coincatch.js +68 -0
  96. package/js/src/coinex.js +1 -0
  97. package/js/src/coinlist.js +1 -0
  98. package/js/src/coinone.js +1 -0
  99. package/js/src/cryptocom.d.ts +4 -4
  100. package/js/src/delta.js +4 -0
  101. package/js/src/deribit.d.ts +4 -4
  102. package/js/src/deribit.js +1 -0
  103. package/js/src/derive.d.ts +3 -3
  104. package/js/src/digifinex.d.ts +4 -4
  105. package/js/src/hitbtc.js +3 -0
  106. package/js/src/hollaex.js +1 -0
  107. package/js/src/htx.d.ts +4 -4
  108. package/js/src/htx.js +7 -3
  109. package/js/src/huobijp.js +1 -0
  110. package/js/src/hyperliquid.d.ts +1 -0
  111. package/js/src/hyperliquid.js +14 -4
  112. package/js/src/kraken.d.ts +3 -3
  113. package/js/src/kraken.js +2 -0
  114. package/js/src/krakenfutures.d.ts +2 -2
  115. package/js/src/kucoinfutures.d.ts +5 -5
  116. package/js/src/mexc.d.ts +1 -0
  117. package/js/src/mexc.js +50 -57
  118. package/js/src/okx.js +1 -1
  119. package/js/src/oxfun.d.ts +3 -3
  120. package/js/src/phemex.d.ts +3 -3
  121. package/js/src/phemex.js +2 -1
  122. package/js/src/poloniex.d.ts +3 -3
  123. package/js/src/poloniex.js +2 -1
  124. package/js/src/pro/apex.d.ts +160 -0
  125. package/js/src/pro/apex.js +1038 -0
  126. package/js/src/pro/binance.js +3 -3
  127. package/js/src/pro/coinbase.d.ts +4 -3
  128. package/js/src/pro/coinbase.js +45 -66
  129. package/js/src/pro/gate.js +27 -2
  130. package/js/src/pro/hollaex.js +2 -2
  131. package/js/src/pro/p2b.js +2 -2
  132. package/js/src/pro/tradeogre.d.ts +49 -0
  133. package/js/src/pro/tradeogre.js +278 -0
  134. package/js/src/pro/upbit.d.ts +16 -1
  135. package/js/src/pro/upbit.js +43 -0
  136. package/js/src/probit.js +1 -0
  137. package/js/src/static_dependencies/zklink/zklink-sdk-web.d.ts +1279 -0
  138. package/js/src/static_dependencies/zklink/zklink-sdk-web.js +4276 -0
  139. package/js/src/timex.js +2 -2
  140. package/js/src/tradeogre.js +2 -1
  141. package/js/src/upbit.d.ts +75 -23
  142. package/js/src/upbit.js +277 -67
  143. package/js/src/vertex.d.ts +3 -3
  144. package/js/src/whitebit.js +66 -12
  145. package/js/src/woo.d.ts +4 -4
  146. package/js/src/woo.js +3 -1
  147. package/js/src/woofipro.d.ts +4 -4
  148. package/js/src/xt.d.ts +4 -4
  149. package/js/src/xt.js +9 -0
  150. package/package.json +2 -2
  151. package/js/src/abstract/ace.d.ts +0 -18
  152. package/js/src/ace.d.ts +0 -158
  153. package/js/src/ace.js +0 -1175
  154. /package/js/src/abstract/{ace.js → apex.js} +0 -0
@@ -62,12 +62,12 @@ export default class binance extends binanceRest {
62
62
  'urls': {
63
63
  'test': {
64
64
  'ws': {
65
- 'spot': 'wss://testnet.binance.vision/ws',
66
- 'margin': 'wss://testnet.binance.vision/ws',
65
+ 'spot': 'wss://stream.testnet.binance.vision/ws',
66
+ 'margin': 'wss://stream.testnet.binance.vision/ws',
67
67
  'future': 'wss://fstream.binancefuture.com/ws',
68
68
  'delivery': 'wss://dstream.binancefuture.com/ws',
69
69
  'ws-api': {
70
- 'spot': 'wss://testnet.binance.vision/ws-api/v3',
70
+ 'spot': 'wss://ws-api.testnet.binance.vision/ws-api/v3',
71
71
  'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
72
72
  'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
73
73
  },
@@ -47,7 +47,7 @@ export default class coinbase extends coinbaseRest {
47
47
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
48
48
  */
49
49
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
50
- handleTickers(client: any, message: any): any;
50
+ handleTickers(client: any, message: any): void;
51
51
  parseWsTicker(ticker: any, market?: any): Ticker;
52
52
  /**
53
53
  * @method
@@ -107,11 +107,12 @@ export default class coinbase extends coinbaseRest {
107
107
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
108
108
  */
109
109
  watchOrderBookForSymbols(symbols: string[], limit?: Int, params?: {}): Promise<OrderBook>;
110
- handleTrade(client: any, message: any): any;
111
- handleOrder(client: any, message: any): any;
110
+ handleTrade(client: any, message: any): void;
111
+ handleOrder(client: any, message: any): void;
112
112
  parseWsOrder(order: any, market?: any): Order;
113
113
  handleOrderBookHelper(orderbook: any, updates: any): void;
114
114
  handleOrderBook(client: any, message: any): void;
115
+ tryResolveUsdc(client: any, messageHash: any, result: any): void;
115
116
  handleSubscriptionStatus(client: any, message: any): any;
116
117
  handleHeartbeats(client: any, message: any): any;
117
118
  handleMessage(client: any, message: any): void;
@@ -69,7 +69,7 @@ export default class coinbase extends coinbaseRest {
69
69
  }
70
70
  else if (symbol !== undefined) {
71
71
  market = this.market(symbol);
72
- messageHash = name + '::' + market['id'];
72
+ messageHash = name + '::' + symbol;
73
73
  productIds = [market['id']];
74
74
  }
75
75
  const url = this.urls['api']['ws'];
@@ -107,7 +107,7 @@ export default class coinbase extends coinbaseRest {
107
107
  const market = this.market(symbol);
108
108
  const marketId = market['id'];
109
109
  productIds.push(marketId);
110
- messageHashes.push(name + '::' + marketId);
110
+ messageHashes.push(name + '::' + symbol);
111
111
  }
112
112
  const url = this.urls['api']['ws'];
113
113
  let subscribe = {
@@ -175,8 +175,11 @@ export default class coinbase extends coinbaseRest {
175
175
  symbols = this.symbols;
176
176
  }
177
177
  const name = 'ticker_batch';
178
- const tickers = await this.subscribe(name, false, symbols, params);
178
+ const ticker = await this.subscribeMultiple(name, false, symbols, params);
179
179
  if (this.newUpdates) {
180
+ const tickers = {};
181
+ const symbol = ticker['symbol'];
182
+ tickers[symbol] = ticker;
180
183
  return tickers;
181
184
  }
182
185
  return this.tickers;
@@ -272,7 +275,7 @@ export default class coinbase extends coinbaseRest {
272
275
  //
273
276
  //
274
277
  const channel = this.safeString(message, 'channel');
275
- const events = this.safeValue(message, 'events', []);
278
+ const events = this.safeList(message, 'events', []);
276
279
  const datetime = this.safeString(message, 'timestamp');
277
280
  const timestamp = this.parse8601(datetime);
278
281
  const newTickers = [];
@@ -281,38 +284,21 @@ export default class coinbase extends coinbaseRest {
281
284
  const tickers = this.safeList(tickersObj, 'tickers', []);
282
285
  for (let j = 0; j < tickers.length; j++) {
283
286
  const ticker = tickers[j];
287
+ const wsMarketId = this.safeString(ticker, 'product_id');
288
+ if (wsMarketId === undefined) {
289
+ continue;
290
+ }
284
291
  const result = this.parseWsTicker(ticker);
285
292
  result['timestamp'] = timestamp;
286
293
  result['datetime'] = datetime;
287
294
  const symbol = result['symbol'];
288
295
  this.tickers[symbol] = result;
289
- const wsMarketId = this.safeString(ticker, 'product_id');
290
- if (wsMarketId === undefined) {
291
- continue;
292
- }
293
- const messageHash = channel + '::' + wsMarketId;
294
296
  newTickers.push(result);
297
+ const messageHash = channel + '::' + symbol;
295
298
  client.resolve(result, messageHash);
296
- if (messageHash.endsWith('USD')) {
297
- client.resolve(result, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
298
- }
299
- }
300
- }
301
- const messageHashes = this.findMessageHashes(client, 'ticker_batch::');
302
- for (let i = 0; i < messageHashes.length; i++) {
303
- const messageHash = messageHashes[i];
304
- const parts = messageHash.split('::');
305
- const symbolsString = parts[1];
306
- const symbols = symbolsString.split(',');
307
- const tickers = this.filterByArray(newTickers, 'symbol', symbols);
308
- if (!this.isEmpty(tickers)) {
309
- client.resolve(tickers, messageHash);
310
- if (messageHash.endsWith('USD')) {
311
- client.resolve(tickers, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
312
- }
299
+ this.tryResolveUsdc(client, messageHash, result);
313
300
  }
314
301
  }
315
- return message;
316
302
  }
317
303
  parseWsTicker(ticker, market = undefined) {
318
304
  //
@@ -480,13 +466,13 @@ export default class coinbase extends coinbaseRest {
480
466
  // ]
481
467
  // }
482
468
  //
483
- const events = this.safeValue(message, 'events');
469
+ const events = this.safeList(message, 'events');
484
470
  const event = this.safeValue(events, 0);
485
- const trades = this.safeValue(event, 'trades');
486
- const trade = this.safeValue(trades, 0);
471
+ const trades = this.safeList(event, 'trades');
472
+ const trade = this.safeDict(trades, 0);
487
473
  const marketId = this.safeString(trade, 'product_id');
488
- const messageHash = 'market_trades::' + marketId;
489
474
  const symbol = this.safeSymbol(marketId);
475
+ const messageHash = 'market_trades::' + symbol;
490
476
  let tradesArray = this.safeValue(this.trades, symbol);
491
477
  if (tradesArray === undefined) {
492
478
  const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
@@ -495,17 +481,14 @@ export default class coinbase extends coinbaseRest {
495
481
  }
496
482
  for (let i = 0; i < events.length; i++) {
497
483
  const currentEvent = events[i];
498
- const currentTrades = this.safeValue(currentEvent, 'trades');
484
+ const currentTrades = this.safeList(currentEvent, 'trades');
499
485
  for (let j = 0; j < currentTrades.length; j++) {
500
486
  const item = currentTrades[i];
501
487
  tradesArray.append(this.parseTrade(item));
502
488
  }
503
489
  }
504
490
  client.resolve(tradesArray, messageHash);
505
- if (marketId.endsWith('USD')) {
506
- client.resolve(tradesArray, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
507
- }
508
- return message;
491
+ this.tryResolveUsdc(client, messageHash, tradesArray);
509
492
  }
510
493
  handleOrder(client, message) {
511
494
  //
@@ -536,7 +519,7 @@ export default class coinbase extends coinbaseRest {
536
519
  // ]
537
520
  // }
538
521
  //
539
- const events = this.safeValue(message, 'events');
522
+ const events = this.safeList(message, 'events');
540
523
  const marketIds = [];
541
524
  if (this.orders === undefined) {
542
525
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
@@ -544,7 +527,7 @@ export default class coinbase extends coinbaseRest {
544
527
  }
545
528
  for (let i = 0; i < events.length; i++) {
546
529
  const event = events[i];
547
- const responseOrders = this.safeValue(event, 'orders');
530
+ const responseOrders = this.safeList(event, 'orders');
548
531
  for (let j = 0; j < responseOrders.length; j++) {
549
532
  const responseOrder = responseOrders[j];
550
533
  const parsed = this.parseWsOrder(responseOrder);
@@ -558,14 +541,12 @@ export default class coinbase extends coinbaseRest {
558
541
  }
559
542
  for (let i = 0; i < marketIds.length; i++) {
560
543
  const marketId = marketIds[i];
561
- const messageHash = 'user::' + marketId;
544
+ const symbol = this.safeSymbol(marketId);
545
+ const messageHash = 'user::' + symbol;
562
546
  client.resolve(this.orders, messageHash);
563
- if (messageHash.endsWith('USD')) {
564
- client.resolve(this.orders, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
565
- }
547
+ this.tryResolveUsdc(client, messageHash, this.orders);
566
548
  }
567
549
  client.resolve(this.orders, 'user');
568
- return message;
569
550
  }
570
551
  parseWsOrder(order, market = undefined) {
571
552
  //
@@ -656,40 +637,38 @@ export default class coinbase extends coinbaseRest {
656
637
  // ]
657
638
  // }
658
639
  //
659
- const events = this.safeValue(message, 'events');
640
+ const events = this.safeList(message, 'events');
660
641
  const datetime = this.safeString(message, 'timestamp');
661
642
  for (let i = 0; i < events.length; i++) {
662
643
  const event = events[i];
663
- const updates = this.safeValue(event, 'updates', []);
644
+ const updates = this.safeList(event, 'updates', []);
664
645
  const marketId = this.safeString(event, 'product_id');
665
- const messageHash = 'level2::' + marketId;
646
+ // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD, as they are aliases
647
+ const market = this.safeMarket(marketId);
648
+ const symbol = market['symbol'];
649
+ const messageHash = 'level2::' + symbol;
666
650
  const subscription = this.safeValue(client.subscriptions, messageHash, {});
667
651
  const limit = this.safeInteger(subscription, 'limit');
668
- const symbol = this.safeSymbol(marketId);
669
652
  const type = this.safeString(event, 'type');
670
653
  if (type === 'snapshot') {
671
654
  this.orderbooks[symbol] = this.orderBook({}, limit);
672
- const orderbook = this.orderbooks[symbol];
673
- this.handleOrderBookHelper(orderbook, updates);
674
- orderbook['timestamp'] = this.parse8601(datetime);
675
- orderbook['datetime'] = datetime;
676
- orderbook['symbol'] = symbol;
677
- client.resolve(orderbook, messageHash);
678
- if (messageHash.endsWith('USD')) {
679
- client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
680
- }
681
655
  }
682
- else if (type === 'update') {
683
- const orderbook = this.orderbooks[symbol];
684
- this.handleOrderBookHelper(orderbook, updates);
685
- orderbook['datetime'] = datetime;
686
- orderbook['timestamp'] = this.parse8601(datetime);
687
- orderbook['symbol'] = symbol;
688
- client.resolve(orderbook, messageHash);
689
- if (messageHash.endsWith('USD')) {
690
- client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
691
- }
656
+ // unknown bug, can't reproduce, but sometimes orderbook is undefined
657
+ if (!(symbol in this.orderbooks) && this.orderbooks[symbol] === undefined) {
658
+ continue;
692
659
  }
660
+ const orderbook = this.orderbooks[symbol];
661
+ this.handleOrderBookHelper(orderbook, updates);
662
+ orderbook['timestamp'] = this.parse8601(datetime);
663
+ orderbook['datetime'] = datetime;
664
+ orderbook['symbol'] = symbol;
665
+ client.resolve(orderbook, messageHash);
666
+ this.tryResolveUsdc(client, messageHash, orderbook);
667
+ }
668
+ }
669
+ tryResolveUsdc(client, messageHash, result) {
670
+ if (messageHash.endsWith('/USD') || messageHash.endsWith('-USD')) {
671
+ client.resolve(result, messageHash + 'C'); // when subscribing to BTC/USDC and coinbase returns BTC/USD, so resolve USDC too
693
672
  }
694
673
  }
695
674
  handleSubscriptionStatus(client, message) {
@@ -1236,8 +1236,33 @@ export default class gate extends gateRest {
1236
1236
  for (let i = 0; i < data.length; i++) {
1237
1237
  const rawPosition = data[i];
1238
1238
  const position = this.parsePosition(rawPosition);
1239
- newPositions.push(position);
1240
- cache.append(position);
1239
+ const symbol = this.safeString(position, 'symbol');
1240
+ const side = this.safeString(position, 'side');
1241
+ // Control when position is closed no side is returned
1242
+ if (side === undefined) {
1243
+ const prevLongPosition = this.safeDict(cache, symbol + 'long');
1244
+ if (prevLongPosition !== undefined) {
1245
+ position['side'] = prevLongPosition['side'];
1246
+ newPositions.push(position);
1247
+ cache.append(position);
1248
+ }
1249
+ const prevShortPosition = this.safeDict(cache, symbol + 'short');
1250
+ if (prevShortPosition !== undefined) {
1251
+ position['side'] = prevShortPosition['side'];
1252
+ newPositions.push(position);
1253
+ cache.append(position);
1254
+ }
1255
+ // if no prev position is found, default to long
1256
+ if (prevLongPosition === undefined && prevShortPosition === undefined) {
1257
+ position['side'] = 'long';
1258
+ newPositions.push(position);
1259
+ cache.append(position);
1260
+ }
1261
+ }
1262
+ else {
1263
+ newPositions.push(position);
1264
+ cache.append(position);
1265
+ }
1241
1266
  }
1242
1267
  const messageHashes = this.findMessageHashes(client, type + ':positions::');
1243
1268
  for (let i = 0; i < messageHashes.length; i++) {
@@ -589,10 +589,10 @@ export default class hollaex extends hollaexRest {
589
589
  }
590
590
  onError(client, error) {
591
591
  this.options['ws-expires'] = undefined;
592
- this.onError(client, error);
592
+ super.onError(client, error);
593
593
  }
594
594
  onClose(client, error) {
595
595
  this.options['ws-expires'] = undefined;
596
- this.onClose(client, error);
596
+ super.onClose(client, error);
597
597
  }
598
598
  }
package/js/src/pro/p2b.js CHANGED
@@ -491,10 +491,10 @@ export default class p2b extends p2bRest {
491
491
  }
492
492
  onError(client, error) {
493
493
  this.options['tickerSubs'] = this.createSafeDictionary();
494
- this.onError(client, error);
494
+ super.onError(client, error);
495
495
  }
496
496
  onClose(client, error) {
497
497
  this.options['tickerSubs'] = this.createSafeDictionary();
498
- this.onClose(client, error);
498
+ super.onClose(client, error);
499
499
  }
500
500
  }
@@ -0,0 +1,49 @@
1
+ import tradeogreRest from '../tradeogre.js';
2
+ import type { Int, OrderBook, Trade } from '../base/types.js';
3
+ import Client from '../base/ws/Client.js';
4
+ export default class tradeogre extends tradeogreRest {
5
+ describe(): any;
6
+ /**
7
+ * @method
8
+ * @name tradeogre#watchOrderBook
9
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
10
+ * @see https://tradeogre.com/help/api
11
+ * @param {string} symbol unified symbol of the market to fetch the order book for
12
+ * @param {int} [limit] the maximum amount of order book entries to return (not used by the exchange)
13
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
14
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
15
+ */
16
+ watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
17
+ handleOrderBook(client: Client, message: any): void;
18
+ handleDelta(orderbook: any, delta: any): void;
19
+ handleBidAsks(bookSide: any, bidAsks: any): void;
20
+ getCacheIndex(orderbook: any, deltas: any): any;
21
+ /**
22
+ * @method
23
+ * @name tradeogre#watchTrades
24
+ * @description watches information on multiple trades made in a market
25
+ * @see https://tradeogre.com/help/api
26
+ * @param {string} symbol unified market symbol of the market trades were made in
27
+ * @param {int} [since] the earliest time in ms to fetch trades for
28
+ * @param {int} [limit] the maximum number of trade structures to retrieve
29
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
30
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
31
+ */
32
+ watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
33
+ /**
34
+ * @method
35
+ * @name tradeogre#watchTradesForSymbols
36
+ * @see https://tradeogre.com/help/api
37
+ * @description get the list of most recent trades for a list of symbols
38
+ * @param {string[]} symbols unified symbol of the market to fetch trades for (empty array means all markets)
39
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
40
+ * @param {int} [limit] the maximum amount of trades to fetch
41
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
42
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
43
+ */
44
+ watchTradesForSymbols(symbols: string[], since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
45
+ handleTrade(client: Client, message: any): void;
46
+ parseWsTrade(trade: any, market?: any): Trade;
47
+ parseWsTradeSide(side: any): string;
48
+ handleMessage(client: Client, message: any): void;
49
+ }
@@ -0,0 +1,278 @@
1
+ // ---------------------------------------------------------------------------
2
+ import tradeogreRest from '../tradeogre.js';
3
+ import { ArrayCache } from '../base/ws/Cache.js';
4
+ // ---------------------------------------------------------------------------
5
+ export default class tradeogre extends tradeogreRest {
6
+ describe() {
7
+ return this.deepExtend(super.describe(), {
8
+ 'has': {
9
+ 'ws': true,
10
+ 'watchTrades': true,
11
+ 'watchTradesForSymbols': true,
12
+ 'watchOrderBook': true,
13
+ 'watchOrderBookForSymbols': false,
14
+ 'watchOHLCV': false,
15
+ 'watchOHLCVForSymbols': false,
16
+ 'watchOrders': false,
17
+ 'watchMyTrades': false,
18
+ 'watchTicker': false,
19
+ 'watchTickers': false,
20
+ 'watchBidsAsks': false,
21
+ 'watchBalance': false,
22
+ 'createOrderWs': false,
23
+ 'editOrderWs': false,
24
+ 'cancelOrderWs': false,
25
+ 'cancelOrdersWs': false,
26
+ },
27
+ 'urls': {
28
+ 'api': {
29
+ 'ws': 'wss://tradeogre.com:8443',
30
+ },
31
+ },
32
+ 'options': {},
33
+ 'streaming': {},
34
+ });
35
+ }
36
+ /**
37
+ * @method
38
+ * @name tradeogre#watchOrderBook
39
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
40
+ * @see https://tradeogre.com/help/api
41
+ * @param {string} symbol unified symbol of the market to fetch the order book for
42
+ * @param {int} [limit] the maximum amount of order book entries to return (not used by the exchange)
43
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
44
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
45
+ */
46
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
47
+ await this.loadMarkets();
48
+ const market = this.market(symbol);
49
+ const url = this.urls['api']['ws'];
50
+ const messageHash = 'orderbook' + ':' + market['symbol'];
51
+ const request = {
52
+ 'a': 'subscribe',
53
+ 'e': 'book',
54
+ 't': market['id'],
55
+ };
56
+ const orderbook = await this.watch(url, messageHash, this.extend(request, params), messageHash);
57
+ return orderbook.limit();
58
+ }
59
+ handleOrderBook(client, message) {
60
+ //
61
+ // initial snapshot is fetched with ccxt's fetchOrderBook
62
+ // the feed does not include a snapshot, just the deltas
63
+ //
64
+ // {
65
+ // "e": "book",
66
+ // "t": "ETH-USDT",
67
+ // "s": "10752324",
68
+ // "d": {
69
+ // "bids": { "1787.02497915": "0" },
70
+ // "asks": {}
71
+ // }
72
+ // }
73
+ //
74
+ const marketId = this.safeString(message, 't');
75
+ const symbol = this.safeSymbol(marketId);
76
+ if (!(symbol in this.orderbooks)) {
77
+ this.orderbooks[symbol] = this.orderBook({});
78
+ }
79
+ const storedOrderBook = this.orderbooks[symbol];
80
+ const nonce = this.safeInteger(storedOrderBook, 'nonce');
81
+ const deltaNonce = this.safeInteger(message, 's');
82
+ const messageHash = 'orderbook:' + symbol;
83
+ if (nonce === undefined) {
84
+ const cacheLength = storedOrderBook.cache.length;
85
+ const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 6);
86
+ if (cacheLength === snapshotDelay) {
87
+ this.spawn(this.loadOrderBook, client, messageHash, symbol, null, {});
88
+ }
89
+ storedOrderBook.cache.push(message);
90
+ return;
91
+ }
92
+ else if (nonce >= deltaNonce) {
93
+ return;
94
+ }
95
+ this.handleDelta(storedOrderBook, message);
96
+ client.resolve(storedOrderBook, messageHash);
97
+ }
98
+ handleDelta(orderbook, delta) {
99
+ // const timestamp = this.milliseconds (); // todo check if this is correct
100
+ // orderbook['timestamp'] = timestamp;
101
+ // orderbook['datetime'] = this.iso8601 (timestamp);
102
+ orderbook['nonce'] = this.safeInteger(delta, 's');
103
+ const data = this.safeDict(delta, 'd', {});
104
+ const bids = this.safeDict(data, 'bids', {});
105
+ const asks = this.safeDict(data, 'asks', {});
106
+ const storedBids = orderbook['bids'];
107
+ const storedAsks = orderbook['asks'];
108
+ this.handleBidAsks(storedBids, bids);
109
+ this.handleBidAsks(storedAsks, asks);
110
+ }
111
+ handleBidAsks(bookSide, bidAsks) {
112
+ const keys = Object.keys(bidAsks);
113
+ for (let i = 0; i < keys.length; i++) {
114
+ const price = this.safeString(keys, i);
115
+ const amount = this.safeNumber(bidAsks, price);
116
+ const bidAsk = [this.parseNumber(price), amount];
117
+ bookSide.storeArray(bidAsk);
118
+ // for (let i = 0; i < bidAsks.length; i++) {
119
+ // const bidAsk = this.parseBidAsk (bidAsks[i]);
120
+ // bookSide.storeArray (bidAsk);
121
+ // }
122
+ }
123
+ }
124
+ getCacheIndex(orderbook, deltas) {
125
+ const firstElement = deltas[0];
126
+ const firstElementNonce = this.safeInteger(firstElement, 's');
127
+ const nonce = this.safeInteger(orderbook, 'nonce');
128
+ if (nonce < firstElementNonce) {
129
+ return -1;
130
+ }
131
+ for (let i = 0; i < deltas.length; i++) {
132
+ const delta = deltas[i];
133
+ const deltaNonce = this.safeInteger(delta, 's');
134
+ if (deltaNonce === nonce) {
135
+ return i + 1;
136
+ }
137
+ }
138
+ return deltas.length;
139
+ }
140
+ /**
141
+ * @method
142
+ * @name tradeogre#watchTrades
143
+ * @description watches information on multiple trades made in a market
144
+ * @see https://tradeogre.com/help/api
145
+ * @param {string} symbol unified market symbol of the market trades were made in
146
+ * @param {int} [since] the earliest time in ms to fetch trades for
147
+ * @param {int} [limit] the maximum number of trade structures to retrieve
148
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
149
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
150
+ */
151
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
152
+ await this.loadMarkets();
153
+ const market = this.market(symbol);
154
+ symbol = market['symbol'];
155
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
156
+ }
157
+ /**
158
+ * @method
159
+ * @name tradeogre#watchTradesForSymbols
160
+ * @see https://tradeogre.com/help/api
161
+ * @description get the list of most recent trades for a list of symbols
162
+ * @param {string[]} symbols unified symbol of the market to fetch trades for (empty array means all markets)
163
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
164
+ * @param {int} [limit] the maximum amount of trades to fetch
165
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
166
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
167
+ */
168
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
169
+ await this.loadMarkets();
170
+ symbols = this.marketSymbols(symbols, undefined, true);
171
+ const messageHashes = [];
172
+ let symbolsLength = 0;
173
+ if (symbols !== undefined) {
174
+ symbolsLength = symbols.length;
175
+ }
176
+ if (symbolsLength > 0) {
177
+ for (let i = 0; i < symbols.length; i++) {
178
+ const symbol = symbols[i];
179
+ const messageHash = 'trades:' + symbol;
180
+ messageHashes.push(messageHash);
181
+ }
182
+ }
183
+ else {
184
+ const messageHash = 'trades';
185
+ messageHashes.push(messageHash);
186
+ }
187
+ const request = {
188
+ 'a': 'subscribe',
189
+ 'e': 'trade',
190
+ 't': '*',
191
+ };
192
+ const url = this.urls['api']['ws'];
193
+ const trades = await this.watchMultiple(url, messageHashes, this.extend(request, params), ['trades']);
194
+ if (this.newUpdates) {
195
+ const first = this.safeDict(trades, 0);
196
+ const tradeSymbol = this.safeString(first, 'symbol');
197
+ limit = trades.getLimit(tradeSymbol, limit);
198
+ }
199
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
200
+ }
201
+ handleTrade(client, message) {
202
+ //
203
+ // {
204
+ // "e": "trade",
205
+ // "t": "LTC-USDT",
206
+ // "d": {
207
+ // "t": 0,
208
+ // "p": "84.50000000",
209
+ // "q": "1.28471270",
210
+ // "d": "1745392002"
211
+ // }
212
+ // }
213
+ //
214
+ const marketId = this.safeString(message, 't');
215
+ const market = this.safeMarket(marketId);
216
+ const data = this.safeDict(message, 'd', {});
217
+ const symbol = market['symbol'];
218
+ if (!(symbol in this.trades)) {
219
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
220
+ const stored = new ArrayCache(limit);
221
+ this.trades[symbol] = stored;
222
+ }
223
+ const cache = this.trades[symbol];
224
+ const trade = this.parseWsTrade(data, market);
225
+ cache.append(trade);
226
+ const messageHash = 'trades:' + symbol;
227
+ client.resolve(cache, messageHash);
228
+ client.resolve(cache, 'trades');
229
+ }
230
+ parseWsTrade(trade, market = undefined) {
231
+ //
232
+ // {
233
+ // "t": 0,
234
+ // "p": "84.50000000",
235
+ // "q": "1.28471270",
236
+ // "d": "1745392002"
237
+ // }
238
+ //
239
+ const timestamp = this.safeIntegerProduct(trade, 'd', 1000);
240
+ const sideEnum = this.safeString(trade, 't');
241
+ return this.safeTrade({
242
+ 'info': trade,
243
+ 'id': undefined,
244
+ 'timestamp': timestamp,
245
+ 'datetime': this.iso8601(timestamp),
246
+ 'symbol': this.safeString(market, 'symbol'),
247
+ 'order': undefined,
248
+ 'type': undefined,
249
+ 'side': this.parseWsTradeSide(sideEnum),
250
+ 'takerOrMaker': undefined,
251
+ 'price': this.safeString(trade, 'p'),
252
+ 'amount': this.safeString(trade, 'q'),
253
+ 'cost': undefined,
254
+ 'fee': {
255
+ 'currency': undefined,
256
+ 'cost': undefined,
257
+ },
258
+ }, market);
259
+ }
260
+ parseWsTradeSide(side) {
261
+ const sides = {
262
+ '0': 'buy',
263
+ '1': 'sell',
264
+ };
265
+ return this.safeString(sides, side, side);
266
+ }
267
+ handleMessage(client, message) {
268
+ const methods = {
269
+ 'book': this.handleOrderBook,
270
+ 'trade': this.handleTrade,
271
+ };
272
+ const event = this.safeString(message, 'e');
273
+ const method = this.safeValue(methods, event);
274
+ if (method !== undefined) {
275
+ method.call(this, client, message);
276
+ }
277
+ }
278
+ }