ccxt 4.5.0 → 4.5.2

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 (82) hide show
  1. package/README.md +110 -112
  2. package/dist/ccxt.browser.min.js +5 -5
  3. package/dist/cjs/ccxt.js +1 -9
  4. package/dist/cjs/src/ascendex.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +13 -0
  6. package/dist/cjs/src/binance.js +20 -14
  7. package/dist/cjs/src/bitget.js +1 -1
  8. package/dist/cjs/src/coinbase.js +46 -34
  9. package/dist/cjs/src/gate.js +39 -18
  10. package/dist/cjs/src/gemini.js +1 -1
  11. package/dist/cjs/src/hibachi.js +1 -1
  12. package/dist/cjs/src/hyperliquid.js +16 -2
  13. package/dist/cjs/src/indodax.js +11 -12
  14. package/dist/cjs/src/kraken.js +1 -12
  15. package/dist/cjs/src/krakenfutures.js +25 -25
  16. package/dist/cjs/src/mexc.js +2 -1
  17. package/dist/cjs/src/okx.js +2 -2
  18. package/dist/cjs/src/poloniex.js +1 -1
  19. package/dist/cjs/src/pro/bitget.js +352 -75
  20. package/dist/cjs/src/pro/bitmart.js +1 -1
  21. package/dist/cjs/src/pro/bybit.js +8 -15
  22. package/dist/cjs/src/pro/gate.js +6 -1
  23. package/dist/cjs/src/pro/gemini.js +7 -2
  24. package/dist/cjs/src/pro/hyperliquid.js +9 -1
  25. package/dist/cjs/src/pro/kraken.js +5 -6
  26. package/dist/cjs/src/pro/lbank.js +55 -1
  27. package/dist/cjs/src/pro/mexc.js +1 -1
  28. package/dist/cjs/src/timex.js +35 -0
  29. package/dist/cjs/src/tradeogre.js +32 -0
  30. package/dist/cjs/src/wavesexchange.js +33 -0
  31. package/dist/cjs/src/zonda.js +12 -0
  32. package/js/ccxt.d.ts +2 -11
  33. package/js/ccxt.js +2 -8
  34. package/js/src/ascendex.js +1 -1
  35. package/js/src/base/Exchange.d.ts +1 -0
  36. package/js/src/base/Exchange.js +14 -1
  37. package/js/src/binance.d.ts +1 -1
  38. package/js/src/binance.js +20 -14
  39. package/js/src/bitget.js +1 -1
  40. package/js/src/coinbase.js +46 -34
  41. package/js/src/gate.d.ts +2 -1
  42. package/js/src/gate.js +39 -18
  43. package/js/src/gemini.js +1 -1
  44. package/js/src/hibachi.js +1 -1
  45. package/js/src/hyperliquid.d.ts +1 -0
  46. package/js/src/hyperliquid.js +16 -2
  47. package/js/src/indodax.js +11 -12
  48. package/js/src/kraken.d.ts +0 -1
  49. package/js/src/kraken.js +1 -12
  50. package/js/src/krakenfutures.d.ts +24 -24
  51. package/js/src/krakenfutures.js +25 -25
  52. package/js/src/mexc.js +2 -1
  53. package/js/src/okx.js +2 -2
  54. package/js/src/poloniex.js +1 -1
  55. package/js/src/pro/bitget.d.ts +12 -2
  56. package/js/src/pro/bitget.js +358 -75
  57. package/js/src/pro/bitmart.js +1 -1
  58. package/js/src/pro/bybit.js +8 -15
  59. package/js/src/pro/gate.d.ts +5 -0
  60. package/js/src/pro/gate.js +6 -1
  61. package/js/src/pro/gemini.d.ts +1 -1
  62. package/js/src/pro/gemini.js +7 -2
  63. package/js/src/pro/hyperliquid.js +9 -1
  64. package/js/src/pro/kraken.js +5 -6
  65. package/js/src/pro/lbank.d.ts +11 -1
  66. package/js/src/pro/lbank.js +55 -1
  67. package/js/src/pro/mexc.js +1 -1
  68. package/js/src/timex.js +35 -0
  69. package/js/src/tradeogre.js +32 -0
  70. package/js/src/wavesexchange.js +33 -0
  71. package/js/src/zonda.js +12 -0
  72. package/package.json +2 -1
  73. package/js/src/abstract/ellipx.d.ts +0 -28
  74. package/js/src/abstract/ellipx.js +0 -11
  75. package/js/src/abstract/vertex.d.ts +0 -22
  76. package/js/src/abstract/vertex.js +0 -11
  77. package/js/src/ellipx.d.ts +0 -237
  78. package/js/src/ellipx.js +0 -2071
  79. package/js/src/pro/vertex.d.ts +0 -104
  80. package/js/src/pro/vertex.js +0 -999
  81. package/js/src/vertex.d.ts +0 -346
  82. package/js/src/vertex.js +0 -3146
@@ -47,10 +47,14 @@ export default class bitget extends bitgetRest {
47
47
  'ws': {
48
48
  'public': 'wss://ws.bitget.com/v2/ws/public',
49
49
  'private': 'wss://ws.bitget.com/v2/ws/private',
50
+ 'utaPublic': 'wss://ws.bitget.com/v3/ws/public',
51
+ 'utaPrivate': 'wss://ws.bitget.com/v3/ws/private',
50
52
  },
51
53
  'demo': {
52
54
  'public': 'wss://wspap.bitget.com/v2/ws/public',
53
55
  'private': 'wss://wspap.bitget.com/v2/ws/private',
56
+ 'utaPublic': 'wss://wspap.bitget.com/v3/ws/public',
57
+ 'utaPrivate': 'wss://wspap.bitget.com/v3/ws/private',
54
58
  },
55
59
  },
56
60
  },
@@ -60,6 +64,7 @@ export default class bitget extends bitgetRest {
60
64
  // WS timeframes differ from REST timeframes
61
65
  'timeframes': {
62
66
  '1m': '1m',
67
+ '3m': '3m',
63
68
  '5m': '5m',
64
69
  '15m': '15m',
65
70
  '30m': '30m',
@@ -102,7 +107,10 @@ export default class bitget extends bitgetRest {
102
107
  },
103
108
  });
104
109
  }
105
- getInstType(market, params = {}) {
110
+ getInstType(market, uta = false, params = {}) {
111
+ if ((uta === undefined) || !uta) {
112
+ [uta, params] = this.handleOptionAndParams(params, 'getInstType', 'uta', false);
113
+ }
106
114
  let instType = undefined;
107
115
  if (market === undefined) {
108
116
  [instType, params] = this.handleProductTypeAndParams(undefined, params);
@@ -116,6 +124,9 @@ export default class bitget extends bitgetRest {
116
124
  let instypeAux = undefined;
117
125
  [instypeAux, params] = this.handleOptionAndParams(params, 'getInstType', 'instType', instType);
118
126
  instType = instypeAux;
127
+ if (uta) {
128
+ instType = instType.toLowerCase();
129
+ }
119
130
  return [instType, params];
120
131
  }
121
132
  /**
@@ -124,8 +135,10 @@ export default class bitget extends bitgetRest {
124
135
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
125
136
  * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
126
137
  * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
138
+ * @see https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
127
139
  * @param {string} symbol unified symbol of the market to watch the ticker for
128
140
  * @param {object} [params] extra parameters specific to the exchange API endpoint
141
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
129
142
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
130
143
  */
131
144
  async watchTicker(symbol, params = {}) {
@@ -134,12 +147,16 @@ export default class bitget extends bitgetRest {
134
147
  symbol = market['symbol'];
135
148
  const messageHash = 'ticker:' + symbol;
136
149
  let instType = undefined;
137
- [instType, params] = this.getInstType(market, params);
150
+ let uta = undefined;
151
+ [uta, params] = this.handleOptionAndParams(params, 'watchTicker', 'uta', false);
152
+ [instType, params] = this.getInstType(market, uta, params);
138
153
  const args = {
139
154
  'instType': instType,
140
- 'channel': 'ticker',
141
- 'instId': market['id'],
142
155
  };
156
+ const topicOrChannel = uta ? 'topic' : 'channel';
157
+ const symbolOrInstId = uta ? 'symbol' : 'instId';
158
+ args[topicOrChannel] = 'ticker';
159
+ args[symbolOrInstId] = market['id'];
143
160
  return await this.watchPublic(messageHash, args, params);
144
161
  }
145
162
  /**
@@ -162,8 +179,10 @@ export default class bitget extends bitgetRest {
162
179
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
163
180
  * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
164
181
  * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
182
+ * @see https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
165
183
  * @param {string[]} symbols unified symbol of the market to watch the tickers for
166
184
  * @param {object} [params] extra parameters specific to the exchange API endpoint
185
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
167
186
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
168
187
  */
169
188
  async watchTickers(symbols = undefined, params = {}) {
@@ -171,7 +190,9 @@ export default class bitget extends bitgetRest {
171
190
  symbols = this.marketSymbols(symbols, undefined, false);
172
191
  const market = this.market(symbols[0]);
173
192
  let instType = undefined;
174
- [instType, params] = this.getInstType(market, params);
193
+ let uta = undefined;
194
+ [uta, params] = this.handleOptionAndParams(params, 'watchTickers', 'uta', false);
195
+ [instType, params] = this.getInstType(market, uta, params);
175
196
  const topics = [];
176
197
  const messageHashes = [];
177
198
  for (let i = 0; i < symbols.length; i++) {
@@ -179,9 +200,11 @@ export default class bitget extends bitgetRest {
179
200
  const marketInner = this.market(symbol);
180
201
  const args = {
181
202
  'instType': instType,
182
- 'channel': 'ticker',
183
- 'instId': marketInner['id'],
184
203
  };
204
+ const topicOrChannel = uta ? 'topic' : 'channel';
205
+ const symbolOrInstId = uta ? 'symbol' : 'instId';
206
+ args[topicOrChannel] = 'ticker';
207
+ args[symbolOrInstId] = marketInner['id'];
185
208
  topics.push(args);
186
209
  messageHashes.push('ticker:' + symbol);
187
210
  }
@@ -194,6 +217,8 @@ export default class bitget extends bitgetRest {
194
217
  return this.filterByArray(this.tickers, 'symbol', symbols);
195
218
  }
196
219
  handleTicker(client, message) {
220
+ //
221
+ // default
197
222
  //
198
223
  // {
199
224
  // "action": "snapshot",
@@ -224,6 +249,29 @@ export default class bitget extends bitgetRest {
224
249
  // "ts": 1701842994341
225
250
  // }
226
251
  //
252
+ // uta
253
+ //
254
+ // {
255
+ // "action": "snapshot",
256
+ // "arg": { "instType": "spot", topic: "ticker", symbol: "BTCUSDT" },
257
+ // "data": [
258
+ // {
259
+ // "highPrice24h": "120255.61",
260
+ // "lowPrice24h": "116145.88",
261
+ // "openPrice24h": "118919.38",
262
+ // "lastPrice": "119818.83",
263
+ // "turnover24h": "215859996.272276",
264
+ // "volume24h": "1819.756798",
265
+ // "bid1Price": "119811.26",
266
+ // "ask1Price": "119831.18",
267
+ // "bid1Size": "0.008732",
268
+ // "ask1Size": "0.004297",
269
+ // "price24hPcnt": "0.02002"
270
+ // }
271
+ // ],
272
+ // "ts": 1753230479687
273
+ // }
274
+ //
227
275
  this.handleBidAsk(client, message);
228
276
  const ticker = this.parseWsTicker(message);
229
277
  const symbol = ticker['symbol'];
@@ -302,48 +350,75 @@ export default class bitget extends bitgetRest {
302
350
  // "ts": 1701843962812
303
351
  // }
304
352
  //
353
+ // uta
354
+ //
355
+ // {
356
+ // "action": "snapshot",
357
+ // "arg": { "instType": "spot", topic: "ticker", symbol: "BTCUSDT" },
358
+ // "data": [
359
+ // {
360
+ // "highPrice24h": "120255.61",
361
+ // "lowPrice24h": "116145.88",
362
+ // "openPrice24h": "118919.38",
363
+ // "lastPrice": "119818.83",
364
+ // "turnover24h": "215859996.272276",
365
+ // "volume24h": "1819.756798",
366
+ // "bid1Price": "119811.26",
367
+ // "ask1Price": "119831.18",
368
+ // "bid1Size": "0.008732",
369
+ // "ask1Size": "0.004297",
370
+ // "price24hPcnt": "0.02002"
371
+ // }
372
+ // ],
373
+ // "ts": 1753230479687
374
+ // }
375
+ //
305
376
  const arg = this.safeValue(message, 'arg', {});
306
377
  const data = this.safeValue(message, 'data', []);
307
378
  const ticker = this.safeValue(data, 0, {});
308
- const timestamp = this.safeInteger(ticker, 'ts');
309
- const instType = this.safeString(arg, 'instType');
310
- const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
311
- const marketId = this.safeString(ticker, 'instId');
379
+ const utaTimestamp = this.safeInteger(message, 'ts');
380
+ const timestamp = this.safeInteger(ticker, 'ts', utaTimestamp);
381
+ const instType = this.safeStringLower(arg, 'instType');
382
+ const marketType = (instType === 'spot') ? 'spot' : 'contract';
383
+ const utaMarketId = this.safeString(arg, 'symbol');
384
+ const marketId = this.safeString(ticker, 'instId', utaMarketId);
312
385
  market = this.safeMarket(marketId, market, undefined, marketType);
313
- const close = this.safeString(ticker, 'lastPr');
314
- const changeDecimal = this.safeString(ticker, 'change24h');
315
- const change = Precise.stringMul(changeDecimal, '100');
386
+ const close = this.safeString2(ticker, 'lastPr', 'lastPrice');
387
+ const changeDecimal = this.safeString(ticker, 'change24h', '');
388
+ const change = this.safeString(ticker, 'price24hPcnt', Precise.stringMul(changeDecimal, '100'));
316
389
  return this.safeTicker({
317
390
  'symbol': market['symbol'],
318
391
  'timestamp': timestamp,
319
392
  'datetime': this.iso8601(timestamp),
320
- 'high': this.safeString(ticker, 'high24h'),
321
- 'low': this.safeString(ticker, 'low24h'),
322
- 'bid': this.safeString(ticker, 'bidPr'),
323
- 'bidVolume': this.safeString(ticker, 'bidSz'),
324
- 'ask': this.safeString(ticker, 'askPr'),
325
- 'askVolume': this.safeString(ticker, 'askSz'),
393
+ 'high': this.safeString2(ticker, 'high24h', 'highPrice24h'),
394
+ 'low': this.safeString2(ticker, 'low24h', 'lowPrice24h'),
395
+ 'bid': this.safeString2(ticker, 'bidPr', 'bid1Price'),
396
+ 'bidVolume': this.safeString2(ticker, 'bidSz', 'bid1Size'),
397
+ 'ask': this.safeString2(ticker, 'askPr', 'ask1Price'),
398
+ 'askVolume': this.safeString2(ticker, 'askSz', 'ask1Size'),
326
399
  'vwap': undefined,
327
- 'open': this.safeString(ticker, 'open24h'),
400
+ 'open': this.safeString2(ticker, 'open24h', 'openPrice24h'),
328
401
  'close': close,
329
402
  'last': close,
330
403
  'previousClose': undefined,
331
404
  'change': undefined,
332
405
  'percentage': change,
333
406
  'average': undefined,
334
- 'baseVolume': this.safeString(ticker, 'baseVolume'),
335
- 'quoteVolume': this.safeString(ticker, 'quoteVolume'),
407
+ 'baseVolume': this.safeString2(ticker, 'baseVolume', 'volume24h'),
408
+ 'quoteVolume': this.safeString2(ticker, 'quoteVolume', 'turnover24h'),
336
409
  'info': ticker,
337
410
  }, market);
338
411
  }
339
412
  /**
340
413
  * @method
341
414
  * @name bitget#watchBidsAsks
415
+ * @description watches best bid & ask for symbols
342
416
  * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
343
417
  * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
344
- * @description watches best bid & ask for symbols
418
+ * @see https://www.bitget.com/api-doc/uta/websocket/public/Tickers-Channel
345
419
  * @param {string[]} symbols unified symbol of the market to fetch the ticker for
346
420
  * @param {object} [params] extra parameters specific to the exchange API endpoint
421
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
347
422
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
348
423
  */
349
424
  async watchBidsAsks(symbols = undefined, params = {}) {
@@ -351,7 +426,9 @@ export default class bitget extends bitgetRest {
351
426
  symbols = this.marketSymbols(symbols, undefined, false);
352
427
  const market = this.market(symbols[0]);
353
428
  let instType = undefined;
354
- [instType, params] = this.getInstType(market, params);
429
+ let uta = undefined;
430
+ [uta, params] = this.handleOptionAndParams(params, 'watchBidsAsks', 'uta', false);
431
+ [instType, params] = this.getInstType(market, uta, params);
355
432
  const topics = [];
356
433
  const messageHashes = [];
357
434
  for (let i = 0; i < symbols.length; i++) {
@@ -359,9 +436,11 @@ export default class bitget extends bitgetRest {
359
436
  const marketInner = this.market(symbol);
360
437
  const args = {
361
438
  'instType': instType,
362
- 'channel': 'ticker',
363
- 'instId': marketInner['id'],
364
439
  };
440
+ const topicOrChannel = uta ? 'topic' : 'channel';
441
+ const symbolOrInstId = uta ? 'symbol' : 'instId';
442
+ args[topicOrChannel] = 'ticker';
443
+ args[symbolOrInstId] = marketInner['id'];
365
444
  topics.push(args);
366
445
  messageHashes.push('bidask:' + symbol);
367
446
  }
@@ -384,19 +463,21 @@ export default class bitget extends bitgetRest {
384
463
  const arg = this.safeValue(message, 'arg', {});
385
464
  const data = this.safeValue(message, 'data', []);
386
465
  const ticker = this.safeValue(data, 0, {});
387
- const timestamp = this.safeInteger(ticker, 'ts');
388
- const instType = this.safeString(arg, 'instType');
389
- const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
390
- const marketId = this.safeString(ticker, 'instId');
466
+ const utaTimestamp = this.safeInteger(message, 'ts');
467
+ const timestamp = this.safeInteger(ticker, 'ts', utaTimestamp);
468
+ const instType = this.safeStringLower(arg, 'instType');
469
+ const marketType = (instType === 'spot') ? 'spot' : 'contract';
470
+ const utaMarketId = this.safeString(arg, 'symbol');
471
+ const marketId = this.safeString(ticker, 'instId', utaMarketId);
391
472
  market = this.safeMarket(marketId, market, undefined, marketType);
392
473
  return this.safeTicker({
393
474
  'symbol': market['symbol'],
394
475
  'timestamp': timestamp,
395
476
  'datetime': this.iso8601(timestamp),
396
- 'ask': this.safeString(ticker, 'askPr'),
397
- 'askVolume': this.safeString(ticker, 'askSz'),
398
- 'bid': this.safeString(ticker, 'bidPr'),
399
- 'bidVolume': this.safeString(ticker, 'bidSz'),
477
+ 'ask': this.safeString2(ticker, 'askPr', 'ask1Price'),
478
+ 'askVolume': this.safeString2(ticker, 'askSz', 'ask1Size'),
479
+ 'bid': this.safeString2(ticker, 'bidPr', 'bid1Price'),
480
+ 'bidVolume': this.safeString2(ticker, 'bidSz', 'bid1Size'),
400
481
  'info': ticker,
401
482
  }, market);
402
483
  }
@@ -406,11 +487,13 @@ export default class bitget extends bitgetRest {
406
487
  * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
407
488
  * @see https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
408
489
  * @see https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
490
+ * @see https://www.bitget.com/api-doc/uta/websocket/public/Candlesticks-Channel
409
491
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
410
492
  * @param {string} timeframe the length of time each candle represents
411
493
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
412
494
  * @param {int} [limit] the maximum amount of candles to fetch
413
495
  * @param {object} [params] extra parameters specific to the exchange API endpoint
496
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
414
497
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
415
498
  */
416
499
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
@@ -419,14 +502,26 @@ export default class bitget extends bitgetRest {
419
502
  symbol = market['symbol'];
420
503
  const timeframes = this.safeValue(this.options, 'timeframes');
421
504
  const interval = this.safeString(timeframes, timeframe);
422
- const messageHash = 'candles:' + timeframe + ':' + symbol;
505
+ let messageHash = undefined;
423
506
  let instType = undefined;
424
- [instType, params] = this.getInstType(market, params);
507
+ let uta = undefined;
508
+ [uta, params] = this.handleOptionAndParams(params, 'watchOHLCV', 'uta', false);
509
+ [instType, params] = this.getInstType(market, uta, params);
425
510
  const args = {
426
511
  'instType': instType,
427
- 'channel': 'candle' + interval,
428
- 'instId': market['id'],
429
512
  };
513
+ if (uta) {
514
+ args['topic'] = 'kline';
515
+ args['symbol'] = market['id'];
516
+ args['interval'] = interval;
517
+ params['uta'] = true;
518
+ messageHash = 'kline:' + symbol;
519
+ }
520
+ else {
521
+ args['channel'] = 'candle' + interval;
522
+ args['instId'] = market['id'];
523
+ messageHash = 'candles:' + timeframe + ':' + symbol;
524
+ }
430
525
  const ohlcv = await this.watchPublic(messageHash, args, params);
431
526
  if (this.newUpdates) {
432
527
  limit = ohlcv.getLimit(symbol, limit);
@@ -439,17 +534,46 @@ export default class bitget extends bitgetRest {
439
534
  * @description unsubscribe from the ohlcv channel
440
535
  * @see https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
441
536
  * @see https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
537
+ * @see https://www.bitget.com/api-doc/uta/websocket/public/Candlesticks-Channel
442
538
  * @param {string} symbol unified symbol of the market to unwatch the ohlcv for
443
539
  * @param {string} [timeframe] the period for the ratio, default is 1 minute
444
540
  * @param {object} [params] extra parameters specific to the exchange API endpoint
541
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
445
542
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
446
543
  */
447
544
  async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
448
545
  await this.loadMarkets();
449
546
  const timeframes = this.safeDict(this.options, 'timeframes');
450
547
  const interval = this.safeString(timeframes, timeframe);
451
- const channel = 'candle' + interval;
452
- return await this.unWatchChannel(symbol, channel, 'candles:' + timeframe, params);
548
+ let channel = undefined;
549
+ let market = undefined;
550
+ if (symbol !== undefined) {
551
+ market = this.market(symbol);
552
+ }
553
+ let instType = undefined;
554
+ let messageHash = undefined;
555
+ let uta = undefined;
556
+ [uta, params] = this.handleOptionAndParams(params, 'unWatchOHLCV', 'uta', false);
557
+ [instType, params] = this.getInstType(market, uta, params);
558
+ const args = {
559
+ 'instType': instType,
560
+ };
561
+ if (uta) {
562
+ channel = 'kline';
563
+ args['topic'] = channel;
564
+ args['symbol'] = market['id'];
565
+ args['interval'] = interval;
566
+ params['uta'] = true;
567
+ params['interval'] = interval;
568
+ messageHash = channel + symbol;
569
+ }
570
+ else {
571
+ channel = 'candle' + interval;
572
+ args['channel'] = channel;
573
+ args['instId'] = market['id'];
574
+ messageHash = 'candles:' + interval;
575
+ }
576
+ return await this.unWatchChannel(symbol, channel, messageHash, params);
453
577
  }
454
578
  handleOHLCV(client, message) {
455
579
  //
@@ -485,15 +609,47 @@ export default class bitget extends bitgetRest {
485
609
  // "ts": 1701901610417
486
610
  // }
487
611
  //
612
+ // uta
613
+ //
614
+ // {
615
+ // "action": "snapshot",
616
+ // "arg": {
617
+ // "instType": "usdt-futures",
618
+ // "topic": "kline",
619
+ // "symbol": "BTCUSDT",
620
+ // "interval": "1m"
621
+ // },
622
+ // "data": [
623
+ // {
624
+ // "start": "1755564480000",
625
+ // "open": "116286",
626
+ // "close": "116256.2",
627
+ // "high": "116310.2",
628
+ // "low": "116232.8",
629
+ // "volume": "39.7062",
630
+ // "turnover": "4616746.46654"
631
+ // },
632
+ // ],
633
+ // "ts": 1755594421877
634
+ // }
635
+ //
488
636
  const arg = this.safeValue(message, 'arg', {});
489
- const instType = this.safeString(arg, 'instType');
490
- const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
491
- const marketId = this.safeString(arg, 'instId');
637
+ const instType = this.safeStringLower(arg, 'instType');
638
+ const marketType = (instType === 'spot') ? 'spot' : 'contract';
639
+ const marketId = this.safeString2(arg, 'instId', 'symbol');
492
640
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
493
641
  const symbol = market['symbol'];
494
642
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
495
- const channel = this.safeString(arg, 'channel');
496
- const interval = channel.replace('candle', '');
643
+ const channel = this.safeString2(arg, 'channel', 'topic');
644
+ let interval = this.safeString(arg, 'interval');
645
+ let isUta = undefined;
646
+ if (interval === undefined) {
647
+ isUta = false;
648
+ interval = channel.replace('candle', '');
649
+ }
650
+ else {
651
+ isUta = true;
652
+ }
497
653
  const timeframes = this.safeValue(this.options, 'timeframes');
498
654
  const timeframe = this.findTimeframe(interval, timeframes);
499
655
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
@@ -507,7 +663,13 @@ export default class bitget extends bitgetRest {
507
663
  const parsed = this.parseWsOHLCV(data[i], market);
508
664
  stored.append(parsed);
509
665
  }
510
- const messageHash = 'candles:' + timeframe + ':' + symbol;
666
+ let messageHash = undefined;
667
+ if (isUta) {
668
+ messageHash = 'kline:' + symbol;
669
+ }
670
+ else {
671
+ messageHash = 'candles:' + timeframe + ':' + symbol;
672
+ }
511
673
  client.resolve(stored, messageHash);
512
674
  }
513
675
  parseWsOHLCV(ohlcv, market = undefined) {
@@ -523,14 +685,26 @@ export default class bitget extends bitgetRest {
523
685
  // "437404.105512" // USDT volume
524
686
  // ]
525
687
  //
688
+ // uta
689
+ //
690
+ // {
691
+ // "start": "1755564480000",
692
+ // "open": "116286",
693
+ // "close": "116256.2",
694
+ // "high": "116310.2",
695
+ // "low": "116232.8",
696
+ // "volume": "39.7062",
697
+ // "turnover": "4616746.46654"
698
+ // }
699
+ //
526
700
  const volumeIndex = (market['inverse']) ? 6 : 5;
527
701
  return [
528
- this.safeInteger(ohlcv, 0),
529
- this.safeNumber(ohlcv, 1),
530
- this.safeNumber(ohlcv, 2),
531
- this.safeNumber(ohlcv, 3),
532
- this.safeNumber(ohlcv, 4),
533
- this.safeNumber(ohlcv, volumeIndex),
702
+ this.safeInteger2(ohlcv, 'start', 0),
703
+ this.safeNumber2(ohlcv, 'open', 1),
704
+ this.safeNumber2(ohlcv, 'high', 2),
705
+ this.safeNumber2(ohlcv, 'low', 3),
706
+ this.safeNumber2(ohlcv, 'close', 4),
707
+ this.safeNumber2(ohlcv, 'volume', volumeIndex),
534
708
  ];
535
709
  }
536
710
  /**
@@ -573,12 +747,23 @@ export default class bitget extends bitgetRest {
573
747
  const market = this.market(symbol);
574
748
  const messageHash = 'unsubscribe:' + messageHashTopic + ':' + market['symbol'];
575
749
  let instType = undefined;
576
- [instType, params] = this.getInstType(market, params);
750
+ let uta = undefined;
751
+ [uta, params] = this.handleOptionAndParams(params, 'unWatchChannel', 'uta', false);
752
+ [instType, params] = this.getInstType(market, uta, params);
577
753
  const args = {
578
754
  'instType': instType,
579
- 'channel': channel,
580
- 'instId': market['id'],
581
755
  };
756
+ if (uta) {
757
+ args['topic'] = channel;
758
+ args['symbol'] = market['id'];
759
+ args['interval'] = this.safeString(params, 'interval', '1m');
760
+ params['uta'] = true;
761
+ params = this.omit(params, 'interval');
762
+ }
763
+ else {
764
+ args['channel'] = channel;
765
+ args['instId'] = market['id'];
766
+ }
582
767
  return await this.unWatchPublic(messageHash, args, params);
583
768
  }
584
769
  /**
@@ -607,7 +792,7 @@ export default class bitget extends bitgetRest {
607
792
  const symbol = symbols[i];
608
793
  const market = this.market(symbol);
609
794
  let instType = undefined;
610
- [instType, params] = this.getInstType(market, params);
795
+ [instType, params] = this.getInstType(market, false, params);
611
796
  const args = {
612
797
  'instType': instType,
613
798
  'channel': channel,
@@ -778,7 +963,7 @@ export default class bitget extends bitgetRest {
778
963
  const symbol = symbols[i];
779
964
  const market = this.market(symbol);
780
965
  let instType = undefined;
781
- [instType, params] = this.getInstType(market, params);
966
+ [instType, params] = this.getInstType(market, false, params);
782
967
  const args = {
783
968
  'instType': instType,
784
969
  'channel': 'trade',
@@ -969,7 +1154,7 @@ export default class bitget extends bitgetRest {
969
1154
  symbols = this.marketSymbols(symbols);
970
1155
  if (!this.isEmpty(symbols)) {
971
1156
  market = this.getMarketFromSymbols(symbols);
972
- [instType, params] = this.getInstType(market, params);
1157
+ [instType, params] = this.getInstType(market, false, params);
973
1158
  }
974
1159
  messageHash = instType + ':positions' + messageHash;
975
1160
  const args = {
@@ -1179,7 +1364,7 @@ export default class bitget extends bitgetRest {
1179
1364
  instType = 'SPOT';
1180
1365
  }
1181
1366
  else {
1182
- [instType, params] = this.getInstType(market, params);
1367
+ [instType, params] = this.getInstType(market, false, params);
1183
1368
  }
1184
1369
  if (type === 'spot' && (symbol !== undefined)) {
1185
1370
  subscriptionHash = subscriptionHash + ':' + symbol;
@@ -1563,7 +1748,7 @@ export default class bitget extends bitgetRest {
1563
1748
  instType = 'spot';
1564
1749
  }
1565
1750
  else {
1566
- [instType, params] = this.getInstType(market, params);
1751
+ [instType, params] = this.getInstType(market, false, params);
1567
1752
  }
1568
1753
  const subscriptionHash = 'fill:' + instType;
1569
1754
  const args = {
@@ -1795,12 +1980,25 @@ export default class bitget extends bitgetRest {
1795
1980
  client.resolve(this.balance, messageHash);
1796
1981
  }
1797
1982
  async watchPublic(messageHash, args, params = {}) {
1798
- let url = this.urls['api']['ws']['public'];
1983
+ let uta = undefined;
1984
+ let url = undefined;
1985
+ [uta, params] = this.handleOptionAndParams(params, 'watchPublic', 'uta', false);
1986
+ if (uta) {
1987
+ url = this.urls['api']['ws']['utaPublic'];
1988
+ }
1989
+ else {
1990
+ url = this.urls['api']['ws']['public'];
1991
+ }
1799
1992
  const sandboxMode = this.safeBool2(this.options, 'sandboxMode', 'sandbox', false);
1800
1993
  if (sandboxMode) {
1801
1994
  const instType = this.safeString(args, 'instType');
1802
1995
  if ((instType !== 'SCOIN-FUTURES') && (instType !== 'SUSDT-FUTURES') && (instType !== 'SUSDC-FUTURES')) {
1803
- url = this.urls['api']['demo']['public'];
1996
+ if (uta) {
1997
+ url = this.urls['api']['demo']['utaPublic'];
1998
+ }
1999
+ else {
2000
+ url = this.urls['api']['demo']['public'];
2001
+ }
1804
2002
  }
1805
2003
  }
1806
2004
  const request = {
@@ -1811,12 +2009,25 @@ export default class bitget extends bitgetRest {
1811
2009
  return await this.watch(url, messageHash, message, messageHash);
1812
2010
  }
1813
2011
  async unWatchPublic(messageHash, args, params = {}) {
1814
- let url = this.urls['api']['ws']['public'];
2012
+ let uta = undefined;
2013
+ let url = undefined;
2014
+ [uta, params] = this.handleOptionAndParams(params, 'unWatchPublic', 'uta', false);
2015
+ if (uta) {
2016
+ url = this.urls['api']['ws']['utaPublic'];
2017
+ }
2018
+ else {
2019
+ url = this.urls['api']['ws']['public'];
2020
+ }
1815
2021
  const sandboxMode = this.safeBool2(this.options, 'sandboxMode', 'sandbox', false);
1816
2022
  if (sandboxMode) {
1817
2023
  const instType = this.safeString(args, 'instType');
1818
2024
  if ((instType !== 'SCOIN-FUTURES') && (instType !== 'SUSDT-FUTURES') && (instType !== 'SUSDC-FUTURES')) {
1819
- url = this.urls['api']['demo']['public'];
2025
+ if (uta) {
2026
+ url = this.urls['api']['demo']['utaPublic'];
2027
+ }
2028
+ else {
2029
+ url = this.urls['api']['demo']['public'];
2030
+ }
1820
2031
  }
1821
2032
  }
1822
2033
  const request = {
@@ -1827,13 +2038,26 @@ export default class bitget extends bitgetRest {
1827
2038
  return await this.watch(url, messageHash, message, messageHash);
1828
2039
  }
1829
2040
  async watchPublicMultiple(messageHashes, argsArray, params = {}) {
1830
- let url = this.urls['api']['ws']['public'];
2041
+ let uta = undefined;
2042
+ let url = undefined;
2043
+ [uta, params] = this.handleOptionAndParams(params, 'watchPublicMultiple', 'uta', false);
2044
+ if (uta) {
2045
+ url = this.urls['api']['ws']['utaPublic'];
2046
+ }
2047
+ else {
2048
+ url = this.urls['api']['ws']['public'];
2049
+ }
1831
2050
  const sandboxMode = this.safeBool2(this.options, 'sandboxMode', 'sandbox', false);
1832
2051
  if (sandboxMode) {
1833
2052
  const argsArrayFirst = this.safeDict(argsArray, 0, {});
1834
2053
  const instType = this.safeString(argsArrayFirst, 'instType');
1835
2054
  if ((instType !== 'SCOIN-FUTURES') && (instType !== 'SUSDT-FUTURES') && (instType !== 'SUSDC-FUTURES')) {
1836
- url = this.urls['api']['demo']['public'];
2055
+ if (uta) {
2056
+ url = this.urls['api']['demo']['utaPublic'];
2057
+ }
2058
+ else {
2059
+ url = this.urls['api']['demo']['public'];
2060
+ }
1837
2061
  }
1838
2062
  }
1839
2063
  const request = {
@@ -1973,6 +2197,41 @@ export default class bitget extends bitgetRest {
1973
2197
  // ]
1974
2198
  // }
1975
2199
  //
2200
+ // uta
2201
+ //
2202
+ // {
2203
+ // "action": "snapshot",
2204
+ // "arg": { "instType": "spot", topic: "ticker", symbol: "BTCUSDT" },
2205
+ // "data": [
2206
+ // {
2207
+ // "highPrice24h": "120255.61",
2208
+ // "lowPrice24h": "116145.88",
2209
+ // "openPrice24h": "118919.38",
2210
+ // "lastPrice": "119818.83",
2211
+ // "turnover24h": "215859996.272276",
2212
+ // "volume24h": "1819.756798",
2213
+ // "bid1Price": "119811.26",
2214
+ // "ask1Price": "119831.18",
2215
+ // "bid1Size": "0.008732",
2216
+ // "ask1Size": "0.004297",
2217
+ // "price24hPcnt": "0.02002"
2218
+ // }
2219
+ // ],
2220
+ // "ts": 1753230479687
2221
+ // }
2222
+ //
2223
+ // unsubscribe
2224
+ //
2225
+ // {
2226
+ // "event": "unsubscribe",
2227
+ // "arg": {
2228
+ // "instType": "spot",
2229
+ // "topic": "kline",
2230
+ // "symbol": "BTCUSDT",
2231
+ // "interval": "1m"
2232
+ // }
2233
+ // }
2234
+ //
1976
2235
  if (this.handleErrorMessage(client, message)) {
1977
2236
  return;
1978
2237
  }
@@ -2011,9 +2270,10 @@ export default class bitget extends bitgetRest {
2011
2270
  'positions': this.handlePositions,
2012
2271
  'account-isolated': this.handleBalance,
2013
2272
  'account-crossed': this.handleBalance,
2273
+ 'kline': this.handleOHLCV,
2014
2274
  };
2015
2275
  const arg = this.safeValue(message, 'arg', {});
2016
- const topic = this.safeValue(arg, 'channel', '');
2276
+ const topic = this.safeValue2(arg, 'channel', 'topic', '');
2017
2277
  const method = this.safeValue(methods, topic);
2018
2278
  if (method !== undefined) {
2019
2279
  method.call(this, client, message);
@@ -2098,7 +2358,7 @@ export default class bitget extends bitgetRest {
2098
2358
  const arg = this.safeDict(message, 'arg', {});
2099
2359
  const instType = this.safeStringLower(arg, 'instType');
2100
2360
  const type = (instType === 'spot') ? 'spot' : 'contract';
2101
- const instId = this.safeString(arg, 'instId');
2361
+ const instId = this.safeString2(arg, 'instId', 'symbol');
2102
2362
  const market = this.safeMarket(instId, undefined, undefined, type);
2103
2363
  const symbol = market['symbol'];
2104
2364
  const messageHash = 'unsubscribe:ticker:' + market['symbol'];
@@ -2120,18 +2380,38 @@ export default class bitget extends bitgetRest {
2120
2380
  //
2121
2381
  // {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"candle1m","instId":"BTCUSDT"}}
2122
2382
  //
2383
+ // UTA
2384
+ //
2385
+ // {"event":"unsubscribe","arg":{"instType":"spot","topic":"kline","symbol":"BTCUSDT","interval":"1m"}}
2386
+ //
2123
2387
  const arg = this.safeDict(message, 'arg', {});
2124
2388
  const instType = this.safeStringLower(arg, 'instType');
2125
2389
  const type = (instType === 'spot') ? 'spot' : 'contract';
2126
- const instId = this.safeString(arg, 'instId');
2127
- const channel = this.safeString(arg, 'channel');
2128
- const interval = channel.replace('candle', '');
2390
+ const instId = this.safeString2(arg, 'instId', 'symbol');
2391
+ const channel = this.safeString2(arg, 'channel', 'topic');
2392
+ let interval = this.safeString(arg, 'interval');
2393
+ let isUta = undefined;
2394
+ if (interval === undefined) {
2395
+ isUta = false;
2396
+ interval = channel.replace('candle', '');
2397
+ }
2398
+ else {
2399
+ isUta = true;
2400
+ }
2129
2401
  const timeframes = this.safeValue(this.options, 'timeframes');
2130
2402
  const timeframe = this.findTimeframe(interval, timeframes);
2131
2403
  const market = this.safeMarket(instId, undefined, undefined, type);
2132
2404
  const symbol = market['symbol'];
2133
- const messageHash = 'unsubscribe:candles:' + timeframe + ':' + market['symbol'];
2134
- const subMessageHash = 'candles:' + timeframe + ':' + symbol;
2405
+ let messageHash = undefined;
2406
+ let subMessageHash = undefined;
2407
+ if (isUta) {
2408
+ messageHash = 'unsubscribe:kline:' + symbol;
2409
+ subMessageHash = 'kline:' + symbol;
2410
+ }
2411
+ else {
2412
+ messageHash = 'unsubscribe:candles:' + timeframe + ':' + symbol;
2413
+ subMessageHash = 'candles:' + timeframe + ':' + symbol;
2414
+ }
2135
2415
  if (symbol in this.ohlcvs) {
2136
2416
  if (timeframe in this.ohlcvs[symbol]) {
2137
2417
  delete this.ohlcvs[symbol][timeframe];
@@ -2165,7 +2445,7 @@ export default class bitget extends bitgetRest {
2165
2445
  }
2166
2446
  for (let i = 0; i < argsList.length; i++) {
2167
2447
  const arg = argsList[i];
2168
- const channel = this.safeString(arg, 'channel');
2448
+ const channel = this.safeString2(arg, 'channel', 'topic');
2169
2449
  if (channel === 'books') {
2170
2450
  // for now only unWatchOrderBook is supporteod
2171
2451
  this.handleOrderBookUnSubscription(client, message);
@@ -2179,6 +2459,9 @@ export default class bitget extends bitgetRest {
2179
2459
  else if (channel.startsWith('candle')) {
2180
2460
  this.handleOHLCVUnSubscription(client, message);
2181
2461
  }
2462
+ else if (channel.startsWith('kline')) {
2463
+ this.handleOHLCVUnSubscription(client, message);
2464
+ }
2182
2465
  }
2183
2466
  return message;
2184
2467
  }