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
@@ -65,12 +65,12 @@ class binance extends binance$1 {
65
65
  'urls': {
66
66
  'test': {
67
67
  'ws': {
68
- 'spot': 'wss://testnet.binance.vision/ws',
69
- 'margin': 'wss://testnet.binance.vision/ws',
68
+ 'spot': 'wss://stream.testnet.binance.vision/ws',
69
+ 'margin': 'wss://stream.testnet.binance.vision/ws',
70
70
  'future': 'wss://fstream.binancefuture.com/ws',
71
71
  'delivery': 'wss://dstream.binancefuture.com/ws',
72
72
  'ws-api': {
73
- 'spot': 'wss://testnet.binance.vision/ws-api/v3',
73
+ 'spot': 'wss://ws-api.testnet.binance.vision/ws-api/v3',
74
74
  'future': 'wss://testnet.binancefuture.com/ws-fapi/v1',
75
75
  'delivery': 'wss://testnet.binancefuture.com/ws-dapi/v1',
76
76
  },
@@ -72,7 +72,7 @@ class coinbase extends coinbase$1 {
72
72
  }
73
73
  else if (symbol !== undefined) {
74
74
  market = this.market(symbol);
75
- messageHash = name + '::' + market['id'];
75
+ messageHash = name + '::' + symbol;
76
76
  productIds = [market['id']];
77
77
  }
78
78
  const url = this.urls['api']['ws'];
@@ -110,7 +110,7 @@ class coinbase extends coinbase$1 {
110
110
  const market = this.market(symbol);
111
111
  const marketId = market['id'];
112
112
  productIds.push(marketId);
113
- messageHashes.push(name + '::' + marketId);
113
+ messageHashes.push(name + '::' + symbol);
114
114
  }
115
115
  const url = this.urls['api']['ws'];
116
116
  let subscribe = {
@@ -178,8 +178,11 @@ class coinbase extends coinbase$1 {
178
178
  symbols = this.symbols;
179
179
  }
180
180
  const name = 'ticker_batch';
181
- const tickers = await this.subscribe(name, false, symbols, params);
181
+ const ticker = await this.subscribeMultiple(name, false, symbols, params);
182
182
  if (this.newUpdates) {
183
+ const tickers = {};
184
+ const symbol = ticker['symbol'];
185
+ tickers[symbol] = ticker;
183
186
  return tickers;
184
187
  }
185
188
  return this.tickers;
@@ -275,47 +278,28 @@ class coinbase extends coinbase$1 {
275
278
  //
276
279
  //
277
280
  const channel = this.safeString(message, 'channel');
278
- const events = this.safeValue(message, 'events', []);
281
+ const events = this.safeList(message, 'events', []);
279
282
  const datetime = this.safeString(message, 'timestamp');
280
283
  const timestamp = this.parse8601(datetime);
281
- const newTickers = [];
282
284
  for (let i = 0; i < events.length; i++) {
283
285
  const tickersObj = events[i];
284
286
  const tickers = this.safeList(tickersObj, 'tickers', []);
285
287
  for (let j = 0; j < tickers.length; j++) {
286
288
  const ticker = tickers[j];
289
+ const wsMarketId = this.safeString(ticker, 'product_id');
290
+ if (wsMarketId === undefined) {
291
+ continue;
292
+ }
287
293
  const result = this.parseWsTicker(ticker);
288
294
  result['timestamp'] = timestamp;
289
295
  result['datetime'] = datetime;
290
296
  const symbol = result['symbol'];
291
297
  this.tickers[symbol] = result;
292
- const wsMarketId = this.safeString(ticker, 'product_id');
293
- if (wsMarketId === undefined) {
294
- continue;
295
- }
296
- const messageHash = channel + '::' + wsMarketId;
297
- newTickers.push(result);
298
+ const messageHash = channel + '::' + symbol;
298
299
  client.resolve(result, messageHash);
299
- if (messageHash.endsWith('USD')) {
300
- client.resolve(result, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
301
- }
302
- }
303
- }
304
- const messageHashes = this.findMessageHashes(client, 'ticker_batch::');
305
- for (let i = 0; i < messageHashes.length; i++) {
306
- const messageHash = messageHashes[i];
307
- const parts = messageHash.split('::');
308
- const symbolsString = parts[1];
309
- const symbols = symbolsString.split(',');
310
- const tickers = this.filterByArray(newTickers, 'symbol', symbols);
311
- if (!this.isEmpty(tickers)) {
312
- client.resolve(tickers, messageHash);
313
- if (messageHash.endsWith('USD')) {
314
- client.resolve(tickers, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
315
- }
300
+ this.tryResolveUsdc(client, messageHash, result);
316
301
  }
317
302
  }
318
- return message;
319
303
  }
320
304
  parseWsTicker(ticker, market = undefined) {
321
305
  //
@@ -483,13 +467,13 @@ class coinbase extends coinbase$1 {
483
467
  // ]
484
468
  // }
485
469
  //
486
- const events = this.safeValue(message, 'events');
470
+ const events = this.safeList(message, 'events');
487
471
  const event = this.safeValue(events, 0);
488
- const trades = this.safeValue(event, 'trades');
489
- const trade = this.safeValue(trades, 0);
472
+ const trades = this.safeList(event, 'trades');
473
+ const trade = this.safeDict(trades, 0);
490
474
  const marketId = this.safeString(trade, 'product_id');
491
- const messageHash = 'market_trades::' + marketId;
492
475
  const symbol = this.safeSymbol(marketId);
476
+ const messageHash = 'market_trades::' + symbol;
493
477
  let tradesArray = this.safeValue(this.trades, symbol);
494
478
  if (tradesArray === undefined) {
495
479
  const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
@@ -498,17 +482,14 @@ class coinbase extends coinbase$1 {
498
482
  }
499
483
  for (let i = 0; i < events.length; i++) {
500
484
  const currentEvent = events[i];
501
- const currentTrades = this.safeValue(currentEvent, 'trades');
485
+ const currentTrades = this.safeList(currentEvent, 'trades');
502
486
  for (let j = 0; j < currentTrades.length; j++) {
503
487
  const item = currentTrades[i];
504
488
  tradesArray.append(this.parseTrade(item));
505
489
  }
506
490
  }
507
491
  client.resolve(tradesArray, messageHash);
508
- if (marketId.endsWith('USD')) {
509
- client.resolve(tradesArray, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
510
- }
511
- return message;
492
+ this.tryResolveUsdc(client, messageHash, tradesArray);
512
493
  }
513
494
  handleOrder(client, message) {
514
495
  //
@@ -539,7 +520,7 @@ class coinbase extends coinbase$1 {
539
520
  // ]
540
521
  // }
541
522
  //
542
- const events = this.safeValue(message, 'events');
523
+ const events = this.safeList(message, 'events');
543
524
  const marketIds = [];
544
525
  if (this.orders === undefined) {
545
526
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
@@ -547,7 +528,7 @@ class coinbase extends coinbase$1 {
547
528
  }
548
529
  for (let i = 0; i < events.length; i++) {
549
530
  const event = events[i];
550
- const responseOrders = this.safeValue(event, 'orders');
531
+ const responseOrders = this.safeList(event, 'orders');
551
532
  for (let j = 0; j < responseOrders.length; j++) {
552
533
  const responseOrder = responseOrders[j];
553
534
  const parsed = this.parseWsOrder(responseOrder);
@@ -561,14 +542,12 @@ class coinbase extends coinbase$1 {
561
542
  }
562
543
  for (let i = 0; i < marketIds.length; i++) {
563
544
  const marketId = marketIds[i];
564
- const messageHash = 'user::' + marketId;
545
+ const symbol = this.safeSymbol(marketId);
546
+ const messageHash = 'user::' + symbol;
565
547
  client.resolve(this.orders, messageHash);
566
- if (messageHash.endsWith('USD')) {
567
- client.resolve(this.orders, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
568
- }
548
+ this.tryResolveUsdc(client, messageHash, this.orders);
569
549
  }
570
550
  client.resolve(this.orders, 'user');
571
- return message;
572
551
  }
573
552
  parseWsOrder(order, market = undefined) {
574
553
  //
@@ -659,40 +638,38 @@ class coinbase extends coinbase$1 {
659
638
  // ]
660
639
  // }
661
640
  //
662
- const events = this.safeValue(message, 'events');
641
+ const events = this.safeList(message, 'events');
663
642
  const datetime = this.safeString(message, 'timestamp');
664
643
  for (let i = 0; i < events.length; i++) {
665
644
  const event = events[i];
666
- const updates = this.safeValue(event, 'updates', []);
645
+ const updates = this.safeList(event, 'updates', []);
667
646
  const marketId = this.safeString(event, 'product_id');
668
- const messageHash = 'level2::' + marketId;
647
+ // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD, as they are aliases
648
+ const market = this.safeMarket(marketId);
649
+ const symbol = market['symbol'];
650
+ const messageHash = 'level2::' + symbol;
669
651
  const subscription = this.safeValue(client.subscriptions, messageHash, {});
670
652
  const limit = this.safeInteger(subscription, 'limit');
671
- const symbol = this.safeSymbol(marketId);
672
653
  const type = this.safeString(event, 'type');
673
654
  if (type === 'snapshot') {
674
655
  this.orderbooks[symbol] = this.orderBook({}, limit);
675
- const orderbook = this.orderbooks[symbol];
676
- this.handleOrderBookHelper(orderbook, updates);
677
- orderbook['timestamp'] = this.parse8601(datetime);
678
- orderbook['datetime'] = datetime;
679
- orderbook['symbol'] = symbol;
680
- client.resolve(orderbook, messageHash);
681
- if (messageHash.endsWith('USD')) {
682
- client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
683
- }
684
656
  }
685
- else if (type === 'update') {
686
- const orderbook = this.orderbooks[symbol];
687
- this.handleOrderBookHelper(orderbook, updates);
688
- orderbook['datetime'] = datetime;
689
- orderbook['timestamp'] = this.parse8601(datetime);
690
- orderbook['symbol'] = symbol;
691
- client.resolve(orderbook, messageHash);
692
- if (messageHash.endsWith('USD')) {
693
- client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
694
- }
657
+ // unknown bug, can't reproduce, but sometimes orderbook is undefined
658
+ if (!(symbol in this.orderbooks) && this.orderbooks[symbol] === undefined) {
659
+ continue;
695
660
  }
661
+ const orderbook = this.orderbooks[symbol];
662
+ this.handleOrderBookHelper(orderbook, updates);
663
+ orderbook['timestamp'] = this.parse8601(datetime);
664
+ orderbook['datetime'] = datetime;
665
+ orderbook['symbol'] = symbol;
666
+ client.resolve(orderbook, messageHash);
667
+ this.tryResolveUsdc(client, messageHash, orderbook);
668
+ }
669
+ }
670
+ tryResolveUsdc(client, messageHash, result) {
671
+ if (messageHash.endsWith('/USD') || messageHash.endsWith('-USD')) {
672
+ client.resolve(result, messageHash + 'C'); // when subscribing to BTC/USDC and coinbase returns BTC/USD, so resolve USDC too
696
673
  }
697
674
  }
698
675
  handleSubscriptionStatus(client, message) {
@@ -1239,8 +1239,33 @@ class gate extends gate$1 {
1239
1239
  for (let i = 0; i < data.length; i++) {
1240
1240
  const rawPosition = data[i];
1241
1241
  const position = this.parsePosition(rawPosition);
1242
- newPositions.push(position);
1243
- cache.append(position);
1242
+ const symbol = this.safeString(position, 'symbol');
1243
+ const side = this.safeString(position, 'side');
1244
+ // Control when position is closed no side is returned
1245
+ if (side === undefined) {
1246
+ const prevLongPosition = this.safeDict(cache, symbol + 'long');
1247
+ if (prevLongPosition !== undefined) {
1248
+ position['side'] = prevLongPosition['side'];
1249
+ newPositions.push(position);
1250
+ cache.append(position);
1251
+ }
1252
+ const prevShortPosition = this.safeDict(cache, symbol + 'short');
1253
+ if (prevShortPosition !== undefined) {
1254
+ position['side'] = prevShortPosition['side'];
1255
+ newPositions.push(position);
1256
+ cache.append(position);
1257
+ }
1258
+ // if no prev position is found, default to long
1259
+ if (prevLongPosition === undefined && prevShortPosition === undefined) {
1260
+ position['side'] = 'long';
1261
+ newPositions.push(position);
1262
+ cache.append(position);
1263
+ }
1264
+ }
1265
+ else {
1266
+ newPositions.push(position);
1267
+ cache.append(position);
1268
+ }
1244
1269
  }
1245
1270
  const messageHashes = this.findMessageHashes(client, type + ':positions::');
1246
1271
  for (let i = 0; i < messageHashes.length; i++) {
@@ -592,11 +592,11 @@ class hollaex extends hollaex$1 {
592
592
  }
593
593
  onError(client, error) {
594
594
  this.options['ws-expires'] = undefined;
595
- this.onError(client, error);
595
+ super.onError(client, error);
596
596
  }
597
597
  onClose(client, error) {
598
598
  this.options['ws-expires'] = undefined;
599
- this.onClose(client, error);
599
+ super.onClose(client, error);
600
600
  }
601
601
  }
602
602
 
@@ -494,11 +494,11 @@ class p2b extends p2b$1 {
494
494
  }
495
495
  onError(client, error) {
496
496
  this.options['tickerSubs'] = this.createSafeDictionary();
497
- this.onError(client, error);
497
+ super.onError(client, error);
498
498
  }
499
499
  onClose(client, error) {
500
500
  this.options['tickerSubs'] = this.createSafeDictionary();
501
- this.onClose(client, error);
501
+ super.onClose(client, error);
502
502
  }
503
503
  }
504
504
 
@@ -0,0 +1,283 @@
1
+ 'use strict';
2
+
3
+ var tradeogre$1 = require('../tradeogre.js');
4
+ var Cache = require('../base/ws/Cache.js');
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // ---------------------------------------------------------------------------
8
+ class tradeogre extends tradeogre$1 {
9
+ describe() {
10
+ return this.deepExtend(super.describe(), {
11
+ 'has': {
12
+ 'ws': true,
13
+ 'watchTrades': true,
14
+ 'watchTradesForSymbols': true,
15
+ 'watchOrderBook': true,
16
+ 'watchOrderBookForSymbols': false,
17
+ 'watchOHLCV': false,
18
+ 'watchOHLCVForSymbols': false,
19
+ 'watchOrders': false,
20
+ 'watchMyTrades': false,
21
+ 'watchTicker': false,
22
+ 'watchTickers': false,
23
+ 'watchBidsAsks': false,
24
+ 'watchBalance': false,
25
+ 'createOrderWs': false,
26
+ 'editOrderWs': false,
27
+ 'cancelOrderWs': false,
28
+ 'cancelOrdersWs': false,
29
+ },
30
+ 'urls': {
31
+ 'api': {
32
+ 'ws': 'wss://tradeogre.com:8443',
33
+ },
34
+ },
35
+ 'options': {},
36
+ 'streaming': {},
37
+ });
38
+ }
39
+ /**
40
+ * @method
41
+ * @name tradeogre#watchOrderBook
42
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
43
+ * @see https://tradeogre.com/help/api
44
+ * @param {string} symbol unified symbol of the market to fetch the order book for
45
+ * @param {int} [limit] the maximum amount of order book entries to return (not used by the exchange)
46
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
47
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
48
+ */
49
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
50
+ await this.loadMarkets();
51
+ const market = this.market(symbol);
52
+ const url = this.urls['api']['ws'];
53
+ const messageHash = 'orderbook' + ':' + market['symbol'];
54
+ const request = {
55
+ 'a': 'subscribe',
56
+ 'e': 'book',
57
+ 't': market['id'],
58
+ };
59
+ const orderbook = await this.watch(url, messageHash, this.extend(request, params), messageHash);
60
+ return orderbook.limit();
61
+ }
62
+ handleOrderBook(client, message) {
63
+ //
64
+ // initial snapshot is fetched with ccxt's fetchOrderBook
65
+ // the feed does not include a snapshot, just the deltas
66
+ //
67
+ // {
68
+ // "e": "book",
69
+ // "t": "ETH-USDT",
70
+ // "s": "10752324",
71
+ // "d": {
72
+ // "bids": { "1787.02497915": "0" },
73
+ // "asks": {}
74
+ // }
75
+ // }
76
+ //
77
+ const marketId = this.safeString(message, 't');
78
+ const symbol = this.safeSymbol(marketId);
79
+ if (!(symbol in this.orderbooks)) {
80
+ this.orderbooks[symbol] = this.orderBook({});
81
+ }
82
+ const storedOrderBook = this.orderbooks[symbol];
83
+ const nonce = this.safeInteger(storedOrderBook, 'nonce');
84
+ const deltaNonce = this.safeInteger(message, 's');
85
+ const messageHash = 'orderbook:' + symbol;
86
+ if (nonce === undefined) {
87
+ const cacheLength = storedOrderBook.cache.length;
88
+ const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 6);
89
+ if (cacheLength === snapshotDelay) {
90
+ this.spawn(this.loadOrderBook, client, messageHash, symbol, null, {});
91
+ }
92
+ storedOrderBook.cache.push(message);
93
+ return;
94
+ }
95
+ else if (nonce >= deltaNonce) {
96
+ return;
97
+ }
98
+ this.handleDelta(storedOrderBook, message);
99
+ client.resolve(storedOrderBook, messageHash);
100
+ }
101
+ handleDelta(orderbook, delta) {
102
+ // const timestamp = this.milliseconds (); // todo check if this is correct
103
+ // orderbook['timestamp'] = timestamp;
104
+ // orderbook['datetime'] = this.iso8601 (timestamp);
105
+ orderbook['nonce'] = this.safeInteger(delta, 's');
106
+ const data = this.safeDict(delta, 'd', {});
107
+ const bids = this.safeDict(data, 'bids', {});
108
+ const asks = this.safeDict(data, 'asks', {});
109
+ const storedBids = orderbook['bids'];
110
+ const storedAsks = orderbook['asks'];
111
+ this.handleBidAsks(storedBids, bids);
112
+ this.handleBidAsks(storedAsks, asks);
113
+ }
114
+ handleBidAsks(bookSide, bidAsks) {
115
+ const keys = Object.keys(bidAsks);
116
+ for (let i = 0; i < keys.length; i++) {
117
+ const price = this.safeString(keys, i);
118
+ const amount = this.safeNumber(bidAsks, price);
119
+ const bidAsk = [this.parseNumber(price), amount];
120
+ bookSide.storeArray(bidAsk);
121
+ // for (let i = 0; i < bidAsks.length; i++) {
122
+ // const bidAsk = this.parseBidAsk (bidAsks[i]);
123
+ // bookSide.storeArray (bidAsk);
124
+ // }
125
+ }
126
+ }
127
+ getCacheIndex(orderbook, deltas) {
128
+ const firstElement = deltas[0];
129
+ const firstElementNonce = this.safeInteger(firstElement, 's');
130
+ const nonce = this.safeInteger(orderbook, 'nonce');
131
+ if (nonce < firstElementNonce) {
132
+ return -1;
133
+ }
134
+ for (let i = 0; i < deltas.length; i++) {
135
+ const delta = deltas[i];
136
+ const deltaNonce = this.safeInteger(delta, 's');
137
+ if (deltaNonce === nonce) {
138
+ return i + 1;
139
+ }
140
+ }
141
+ return deltas.length;
142
+ }
143
+ /**
144
+ * @method
145
+ * @name tradeogre#watchTrades
146
+ * @description watches information on multiple trades made in a market
147
+ * @see https://tradeogre.com/help/api
148
+ * @param {string} symbol unified market symbol of the market trades were made in
149
+ * @param {int} [since] the earliest time in ms to fetch trades for
150
+ * @param {int} [limit] the maximum number of trade structures to retrieve
151
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
152
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
153
+ */
154
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
155
+ await this.loadMarkets();
156
+ const market = this.market(symbol);
157
+ symbol = market['symbol'];
158
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
159
+ }
160
+ /**
161
+ * @method
162
+ * @name tradeogre#watchTradesForSymbols
163
+ * @see https://tradeogre.com/help/api
164
+ * @description get the list of most recent trades for a list of symbols
165
+ * @param {string[]} symbols unified symbol of the market to fetch trades for (empty array means all markets)
166
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
167
+ * @param {int} [limit] the maximum amount of trades to fetch
168
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
169
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
170
+ */
171
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
172
+ await this.loadMarkets();
173
+ symbols = this.marketSymbols(symbols, undefined, true);
174
+ const messageHashes = [];
175
+ let symbolsLength = 0;
176
+ if (symbols !== undefined) {
177
+ symbolsLength = symbols.length;
178
+ }
179
+ if (symbolsLength > 0) {
180
+ for (let i = 0; i < symbols.length; i++) {
181
+ const symbol = symbols[i];
182
+ const messageHash = 'trades:' + symbol;
183
+ messageHashes.push(messageHash);
184
+ }
185
+ }
186
+ else {
187
+ const messageHash = 'trades';
188
+ messageHashes.push(messageHash);
189
+ }
190
+ const request = {
191
+ 'a': 'subscribe',
192
+ 'e': 'trade',
193
+ 't': '*',
194
+ };
195
+ const url = this.urls['api']['ws'];
196
+ const trades = await this.watchMultiple(url, messageHashes, this.extend(request, params), ['trades']);
197
+ if (this.newUpdates) {
198
+ const first = this.safeDict(trades, 0);
199
+ const tradeSymbol = this.safeString(first, 'symbol');
200
+ limit = trades.getLimit(tradeSymbol, limit);
201
+ }
202
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
203
+ }
204
+ handleTrade(client, message) {
205
+ //
206
+ // {
207
+ // "e": "trade",
208
+ // "t": "LTC-USDT",
209
+ // "d": {
210
+ // "t": 0,
211
+ // "p": "84.50000000",
212
+ // "q": "1.28471270",
213
+ // "d": "1745392002"
214
+ // }
215
+ // }
216
+ //
217
+ const marketId = this.safeString(message, 't');
218
+ const market = this.safeMarket(marketId);
219
+ const data = this.safeDict(message, 'd', {});
220
+ const symbol = market['symbol'];
221
+ if (!(symbol in this.trades)) {
222
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
223
+ const stored = new Cache.ArrayCache(limit);
224
+ this.trades[symbol] = stored;
225
+ }
226
+ const cache = this.trades[symbol];
227
+ const trade = this.parseWsTrade(data, market);
228
+ cache.append(trade);
229
+ const messageHash = 'trades:' + symbol;
230
+ client.resolve(cache, messageHash);
231
+ client.resolve(cache, 'trades');
232
+ }
233
+ parseWsTrade(trade, market = undefined) {
234
+ //
235
+ // {
236
+ // "t": 0,
237
+ // "p": "84.50000000",
238
+ // "q": "1.28471270",
239
+ // "d": "1745392002"
240
+ // }
241
+ //
242
+ const timestamp = this.safeIntegerProduct(trade, 'd', 1000);
243
+ const sideEnum = this.safeString(trade, 't');
244
+ return this.safeTrade({
245
+ 'info': trade,
246
+ 'id': undefined,
247
+ 'timestamp': timestamp,
248
+ 'datetime': this.iso8601(timestamp),
249
+ 'symbol': this.safeString(market, 'symbol'),
250
+ 'order': undefined,
251
+ 'type': undefined,
252
+ 'side': this.parseWsTradeSide(sideEnum),
253
+ 'takerOrMaker': undefined,
254
+ 'price': this.safeString(trade, 'p'),
255
+ 'amount': this.safeString(trade, 'q'),
256
+ 'cost': undefined,
257
+ 'fee': {
258
+ 'currency': undefined,
259
+ 'cost': undefined,
260
+ },
261
+ }, market);
262
+ }
263
+ parseWsTradeSide(side) {
264
+ const sides = {
265
+ '0': 'buy',
266
+ '1': 'sell',
267
+ };
268
+ return this.safeString(sides, side, side);
269
+ }
270
+ handleMessage(client, message) {
271
+ const methods = {
272
+ 'book': this.handleOrderBook,
273
+ 'trade': this.handleTrade,
274
+ };
275
+ const event = this.safeString(message, 'e');
276
+ const method = this.safeValue(methods, event);
277
+ if (method !== undefined) {
278
+ method.call(this, client, message);
279
+ }
280
+ }
281
+ }
282
+
283
+ module.exports = tradeogre;
@@ -4,6 +4,7 @@ var upbit$1 = require('../upbit.js');
4
4
  var Cache = require('../base/ws/Cache.js');
5
5
  var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
6
6
  var rsa = require('../base/functions/rsa.js');
7
+ var errors = require('../base/errors.js');
7
8
 
8
9
  // ---------------------------------------------------------------------------
9
10
  // ---------------------------------------------------------------------------
@@ -17,6 +18,7 @@ class upbit extends upbit$1 {
17
18
  'watchTickers': true,
18
19
  'watchTrades': true,
19
20
  'watchTradesForSymbols': true,
21
+ 'watchOHLCV': true,
20
22
  'watchOrders': true,
21
23
  'watchMyTrades': true,
22
24
  'watchBalance': true,
@@ -192,6 +194,26 @@ class upbit extends upbit$1 {
192
194
  const orderbook = await this.watchPublic(symbol, 'orderbook');
193
195
  return orderbook.limit();
194
196
  }
197
+ /**
198
+ * @method
199
+ * @name upbit#watchOHLCV
200
+ * @description watches information an OHLCV with timestamp, openingPrice, highPrice, lowPrice, tradePrice, baseVolume in 1s.
201
+ * @see https://docs.upbit.com/kr/reference/websocket-candle for Upbit KR
202
+ * @see https://global-docs.upbit.com/reference/websocket-candle for Upbit Global
203
+ * @param {string} symbol unified market symbol of the market orders were made in
204
+ * @param {string} timeframe specifies the OHLCV candle interval to watch. As of now, Upbit only supports 1s candles.
205
+ * @param {int} [since] the earliest time in ms to fetch orders for
206
+ * @param {int} [limit] the maximum number of order structures to retrieve
207
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
208
+ * @returns {OHLCV[]} a list of [OHLCV structures]{@link https://docs.ccxt.com/#/?id=ohlcv-structure}
209
+ */
210
+ async watchOHLCV(symbol, timeframe = '1s', since = undefined, limit = undefined, params = {}) {
211
+ if (timeframe !== '1s') {
212
+ throw new errors.NotSupported(this.id + ' watchOHLCV does not support' + timeframe + ' candle.');
213
+ }
214
+ const timeFrameOHLCV = 'candle.' + timeframe;
215
+ return await this.watchPublic(symbol, timeFrameOHLCV);
216
+ }
195
217
  handleTicker(client, message) {
196
218
  // 2020-03-17T23:07:36.511Z "onMessage" <Buffer 7b 22 74 79 70 65 22 3a 22 74 69 63 6b 65 72 22 2c 22 63 6f 64 65 22 3a 22 42 54 43 2d 45 54 48 22 2c 22 6f 70 65 6e 69 6e 67 5f 70 72 69 63 65 22 3a ... >
197
219
  // { type: "ticker",
@@ -318,6 +340,26 @@ class upbit extends upbit$1 {
318
340
  const messageHash = 'trade:' + marketId;
319
341
  client.resolve(stored, messageHash);
320
342
  }
343
+ handleOHLCV(client, message) {
344
+ // {
345
+ // type: 'candle.1s',
346
+ // code: 'KRW-USDT',
347
+ // candle_date_time_utc: '2025-04-22T09:50:34',
348
+ // candle_date_time_kst: '2025-04-22T18:50:34',
349
+ // opening_price: 1438,
350
+ // high_price: 1438,
351
+ // low_price: 1438,
352
+ // trade_price: 1438,
353
+ // candle_acc_trade_volume: 1145.8935,
354
+ // candle_acc_trade_price: 1647794.853,
355
+ // timestamp: 1745315434125,
356
+ // stream_type: 'REALTIME'
357
+ // }
358
+ const marketId = this.safeString(message, 'code');
359
+ const messageHash = 'candle.1s:' + marketId;
360
+ const ohlcv = this.parseOHLCV(message);
361
+ client.resolve(ohlcv, messageHash);
362
+ }
321
363
  async authenticate(params = {}) {
322
364
  this.checkRequiredCredentials();
323
365
  const wsOptions = this.safeDict(this.options, 'ws', {});
@@ -633,6 +675,7 @@ class upbit extends upbit$1 {
633
675
  'trade': this.handleTrades,
634
676
  'myOrder': this.handleMyOrder,
635
677
  'myAsset': this.handleBalance,
678
+ 'candle.1s': this.handleOHLCV,
636
679
  };
637
680
  const methodName = this.safeString(message, 'type');
638
681
  const method = this.safeValue(methods, methodName);
@@ -554,6 +554,7 @@ class probit extends probit$1 {
554
554
  'active': active,
555
555
  'deposit': deposit,
556
556
  'withdraw': withdraw,
557
+ 'type': 'crypto',
557
558
  'fee': fee,
558
559
  'precision': this.parseNumber(this.parsePrecision(this.safeString(platform, 'precision'))),
559
560
  'limits': {