ccxt 4.1.87 → 4.1.89

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 (101) hide show
  1. package/CHANGELOG.md +8309 -5710
  2. package/README.md +10 -9
  3. package/changelog.js +101 -0
  4. package/dist/ccxt.browser.js +8628 -4849
  5. package/dist/ccxt.browser.min.js +3 -3
  6. package/dist/cjs/ccxt.js +6 -1
  7. package/dist/cjs/src/base/Exchange.js +95 -27
  8. package/dist/cjs/src/base/ws/Client.js +3 -3
  9. package/dist/cjs/src/base/ws/Future.js +9 -2
  10. package/dist/cjs/src/base/ws/WsClient.js +1 -1
  11. package/dist/cjs/src/bigone.js +8 -1
  12. package/dist/cjs/src/binance.js +4 -105
  13. package/dist/cjs/src/bit2c.js +8 -2
  14. package/dist/cjs/src/bitget.js +3455 -2480
  15. package/dist/cjs/src/bitmart.js +35 -9
  16. package/dist/cjs/src/coinbase.js +2 -0
  17. package/dist/cjs/src/coinbasepro.js +0 -43
  18. package/dist/cjs/src/coinex.js +14 -1
  19. package/dist/cjs/src/coinsph.js +0 -29
  20. package/dist/cjs/src/cryptocom.js +22 -10
  21. package/dist/cjs/src/gate.js +37 -39
  22. package/dist/cjs/src/gemini.js +1 -0
  23. package/dist/cjs/src/novadax.js +28 -16
  24. package/dist/cjs/src/okcoin.js +80 -21
  25. package/dist/cjs/src/phemex.js +105 -29
  26. package/dist/cjs/src/pro/binance.js +18 -215
  27. package/dist/cjs/src/pro/bitget.js +780 -736
  28. package/dist/cjs/src/pro/bitmart.js +8 -10
  29. package/dist/cjs/src/pro/bitmex.js +9 -34
  30. package/dist/cjs/src/pro/bitpanda.js +4 -4
  31. package/dist/cjs/src/pro/bybit.js +21 -97
  32. package/dist/cjs/src/pro/coinbasepro.js +36 -40
  33. package/dist/cjs/src/pro/cryptocom.js +10 -26
  34. package/dist/cjs/src/pro/gate.js +20 -17
  35. package/dist/cjs/src/pro/kucoin.js +39 -39
  36. package/dist/cjs/src/pro/kucoinfutures.js +40 -36
  37. package/dist/cjs/src/pro/okx.js +16 -29
  38. package/dist/cjs/src/tokocrypto.js +28 -14
  39. package/dist/cjs/src/woo.js +41 -14
  40. package/js/ccxt.d.ts +8 -2
  41. package/js/ccxt.js +6 -2
  42. package/js/src/abstract/bitget.d.ts +1 -1
  43. package/js/src/abstract/coinbasepro.d.ts +69 -0
  44. package/js/src/abstract/coinbasepro.js +11 -0
  45. package/js/src/abstract/phemex.d.ts +1 -0
  46. package/js/src/base/Exchange.d.ts +2 -3
  47. package/js/src/base/Exchange.js +96 -28
  48. package/js/src/base/ws/Client.d.ts +2 -2
  49. package/js/src/base/ws/Client.js +4 -4
  50. package/js/src/base/ws/Future.d.ts +5 -2
  51. package/js/src/base/ws/Future.js +8 -2
  52. package/js/src/base/ws/WsClient.d.ts +1 -1
  53. package/js/src/base/ws/WsClient.js +2 -2
  54. package/js/src/bigone.js +9 -2
  55. package/js/src/binance.d.ts +0 -9
  56. package/js/src/binance.js +4 -105
  57. package/js/src/bit2c.js +8 -2
  58. package/js/src/bitget.d.ts +13 -11
  59. package/js/src/bitget.js +3455 -2480
  60. package/js/src/bitmart.js +35 -9
  61. package/js/src/coinbase.js +2 -0
  62. package/js/src/coinbasepro.d.ts +0 -4
  63. package/js/src/coinbasepro.js +1 -44
  64. package/js/src/coinex.js +14 -1
  65. package/js/src/coinsph.d.ts +0 -1
  66. package/js/src/coinsph.js +0 -29
  67. package/js/src/cryptocom.js +22 -10
  68. package/js/src/gate.js +37 -39
  69. package/js/src/gemini.js +1 -0
  70. package/js/src/novadax.js +28 -16
  71. package/js/src/okcoin.d.ts +1 -0
  72. package/js/src/okcoin.js +81 -22
  73. package/js/src/phemex.d.ts +2 -108
  74. package/js/src/phemex.js +105 -29
  75. package/js/src/pro/binance.d.ts +0 -2
  76. package/js/src/pro/binance.js +19 -216
  77. package/js/src/pro/bitget.d.ts +3 -5
  78. package/js/src/pro/bitget.js +780 -736
  79. package/js/src/pro/bitmart.js +8 -10
  80. package/js/src/pro/bitmex.js +9 -34
  81. package/js/src/pro/bitpanda.d.ts +1 -1
  82. package/js/src/pro/bitpanda.js +4 -4
  83. package/js/src/pro/bybit.d.ts +1 -2
  84. package/js/src/pro/bybit.js +21 -97
  85. package/js/src/pro/coinbasepro.d.ts +2 -2
  86. package/js/src/pro/coinbasepro.js +36 -40
  87. package/js/src/pro/cryptocom.d.ts +1 -1
  88. package/js/src/pro/cryptocom.js +10 -26
  89. package/js/src/pro/gate.d.ts +1 -0
  90. package/js/src/pro/gate.js +20 -17
  91. package/js/src/pro/kucoin.d.ts +1 -0
  92. package/js/src/pro/kucoin.js +39 -39
  93. package/js/src/pro/kucoinfutures.d.ts +2 -1
  94. package/js/src/pro/kucoinfutures.js +40 -36
  95. package/js/src/pro/okx.d.ts +1 -1
  96. package/js/src/pro/okx.js +16 -29
  97. package/js/src/tokocrypto.js +28 -14
  98. package/js/src/woo.d.ts +1 -0
  99. package/js/src/woo.js +42 -15
  100. package/package.json +2 -2
  101. package/skip-tests.json +3 -14
@@ -40,7 +40,10 @@ class bitget extends bitget$1 {
40
40
  },
41
41
  'urls': {
42
42
  'api': {
43
- 'ws': 'wss://ws.bitget.com/spot/v1/stream',
43
+ 'ws': {
44
+ 'public': 'wss://ws.bitget.com/v2/ws/public',
45
+ 'private': 'wss://ws.bitget.com/v2/ws/private',
46
+ },
44
47
  },
45
48
  },
46
49
  'options': {
@@ -84,57 +87,25 @@ class bitget extends bitget$1 {
84
87
  },
85
88
  });
86
89
  }
87
- getWsMarketId(market) {
88
- // WS don't use the same 'id'
89
- // as the rest version
90
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
91
- if (market['spot']) {
92
- return market['info']['symbolName'];
93
- }
94
- else {
95
- if (!sandboxMode) {
96
- return market['id'].replace('_UMCBL', '').replace('_DMCBL', '').replace('_CMCBL', '');
97
- }
98
- else {
99
- return market['id'].replace('_SUMCBL', '').replace('_SDMCBL', '').replace('_SCMCBL', '');
100
- }
101
- }
102
- }
103
- getMarketIdFromArg(arg) {
104
- //
105
- // { arg: { instType: 'sp', channel: "ticker", instId: "BTCUSDT" }
106
- //
107
- const instType = this.safeString(arg, 'instType');
108
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
109
- let marketId = this.safeString(arg, 'instId');
110
- if (instType === 'sp') {
111
- marketId = marketId + '_SPBL';
90
+ getInstType(market, params = {}) {
91
+ let instType = undefined;
92
+ if ((market['swap']) || (market['future'])) {
93
+ [instType, params] = this.handleProductTypeAndParams(market, params);
112
94
  }
113
95
  else {
114
- let extension = sandboxMode ? '_S' : '_';
115
- const splitByUSDT = marketId.split('USDT');
116
- const splitByPERP = marketId.split('PERP');
117
- const splitByUSDTLength = splitByUSDT.length;
118
- const splitByPERPLength = splitByPERP.length;
119
- if (splitByUSDTLength > 1) {
120
- extension += 'UMCBL';
121
- }
122
- else if (splitByPERPLength > 1) {
123
- extension += 'CMCBL';
124
- }
125
- else {
126
- extension += 'DMCBL';
127
- }
128
- marketId = marketId + extension;
96
+ instType = 'SPOT';
129
97
  }
130
- return marketId;
98
+ [instType, params] = this.handleOptionAndParams(params, 'getInstType', 'instType', instType);
99
+ return [instType, params];
131
100
  }
132
101
  async watchTicker(symbol, params = {}) {
133
102
  /**
134
103
  * @method
135
104
  * @name bitget#watchTicker
136
105
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
137
- * @param {string} symbol unified symbol of the market to fetch the ticker for
106
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
107
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
108
+ * @param {string} symbol unified symbol of the market to watch the ticker for
138
109
  * @param {object} [params] extra parameters specific to the exchange API endpoint
139
110
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
140
111
  */
@@ -142,11 +113,12 @@ class bitget extends bitget$1 {
142
113
  const market = this.market(symbol);
143
114
  symbol = market['symbol'];
144
115
  const messageHash = 'ticker:' + symbol;
145
- const instType = market['spot'] ? 'sp' : 'mc';
116
+ let instType = undefined;
117
+ [instType, params] = this.getInstType(market, params);
146
118
  const args = {
147
119
  'instType': instType,
148
120
  'channel': 'ticker',
149
- 'instId': this.getWsMarketId(market),
121
+ 'instId': market['id'],
150
122
  };
151
123
  return await this.watchPublic(messageHash, args, params);
152
124
  }
@@ -155,28 +127,31 @@ class bitget extends bitget$1 {
155
127
  * @method
156
128
  * @name bitget#watchTickers
157
129
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
158
- * @param {string[]} symbols unified symbol of the market to fetch the ticker for
130
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
131
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
132
+ * @param {string[]} symbols unified symbol of the market to watch the tickers for
159
133
  * @param {object} [params] extra parameters specific to the exchange API endpoint
160
134
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
161
135
  */
162
136
  await this.loadMarkets();
163
137
  symbols = this.marketSymbols(symbols, undefined, false);
164
138
  const market = this.market(symbols[0]);
165
- const instType = market['spot'] ? 'sp' : 'mc';
166
- const messageHash = 'tickers::' + symbols.join(',');
167
- const marketIds = this.marketIds(symbols);
139
+ let instType = undefined;
140
+ [instType, params] = this.getInstType(market, params);
168
141
  const topics = [];
169
- for (let i = 0; i < marketIds.length; i++) {
170
- const marketId = marketIds[i];
171
- const marketInner = this.market(marketId);
142
+ const messageHashes = [];
143
+ for (let i = 0; i < symbols.length; i++) {
144
+ const symbol = symbols[i];
145
+ const marketInner = this.market(symbol);
172
146
  const args = {
173
147
  'instType': instType,
174
148
  'channel': 'ticker',
175
- 'instId': this.getWsMarketId(marketInner),
149
+ 'instId': marketInner['id'],
176
150
  };
177
151
  topics.push(args);
152
+ messageHashes.push('ticker:' + symbol);
178
153
  }
179
- const tickers = await this.watchPublicMultiple(messageHash, topics, params);
154
+ const tickers = await this.watchPublicMultiple(messageHashes, topics, params);
180
155
  if (this.newUpdates) {
181
156
  return tickers;
182
157
  }
@@ -184,131 +159,143 @@ class bitget extends bitget$1 {
184
159
  }
185
160
  handleTicker(client, message) {
186
161
  //
187
- // {
188
- // "action": "snapshot",
189
- // "arg": { instType: 'sp', channel: "ticker", instId: "BTCUSDT" },
190
- // "data": [
191
- // {
192
- // "instId": "BTCUSDT",
193
- // "last": "21150.53",
194
- // "open24h": "20759.65",
195
- // "high24h": "21202.29",
196
- // "low24h": "20518.82",
197
- // "bestBid": "21150.500000",
198
- // "bestAsk": "21150.600000",
199
- // "baseVolume": "25402.1961",
200
- // "quoteVolume": "530452554.2156",
201
- // "ts": 1656408934044,
202
- // "labeId": 0
203
- // }
204
- // ]
205
- // }
162
+ // {
163
+ // "action": "snapshot",
164
+ // "arg": {
165
+ // "instType": "SPOT",
166
+ // "channel": "ticker",
167
+ // "instId": "BTCUSDT"
168
+ // },
169
+ // "data": [
170
+ // {
171
+ // "instId": "BTCUSDT",
172
+ // "lastPr": "43528.19",
173
+ // "open24h": "42267.78",
174
+ // "high24h": "44490.00",
175
+ // "low24h": "41401.53",
176
+ // "change24h": "0.03879",
177
+ // "bidPr": "43528",
178
+ // "askPr": "43528.01",
179
+ // "bidSz": "0.0334",
180
+ // "askSz": "0.1917",
181
+ // "baseVolume": "15002.4216",
182
+ // "quoteVolume": "648006446.7164",
183
+ // "openUtc": "44071.18",
184
+ // "changeUtc24h": "-0.01232",
185
+ // "ts": "1701842994338"
186
+ // }
187
+ // ],
188
+ // "ts": 1701842994341
189
+ // }
206
190
  //
207
191
  const ticker = this.parseWsTicker(message);
208
192
  const symbol = ticker['symbol'];
209
193
  this.tickers[symbol] = ticker;
210
194
  const messageHash = 'ticker:' + symbol;
211
195
  client.resolve(ticker, messageHash);
212
- // watchTickers part
213
- const messageHashes = this.findMessageHashes(client, 'tickers::');
214
- for (let i = 0; i < messageHashes.length; i++) {
215
- const messageHashTicker = messageHashes[i];
216
- const parts = messageHashTicker.split('::');
217
- const symbolsString = parts[1];
218
- const symbols = symbolsString.split(',');
219
- if (this.inArray(symbol, symbols)) {
220
- client.resolve(ticker, messageHashTicker);
221
- }
222
- }
223
- return message;
224
196
  }
225
197
  parseWsTicker(message, market = undefined) {
226
198
  //
227
199
  // spot
200
+ //
228
201
  // {
229
202
  // "action": "snapshot",
230
- // "arg": { instType: 'sp', channel: "ticker", instId: "BTCUSDT" },
203
+ // "arg": {
204
+ // "instType": "SPOT",
205
+ // "channel": "ticker",
206
+ // "instId": "BTCUSDT"
207
+ // },
231
208
  // "data": [
232
- // {
233
- // "instId": "BTCUSDT",
234
- // "last": "21150.53",
235
- // "open24h": "20759.65",
236
- // "high24h": "21202.29",
237
- // "low24h": "20518.82",
238
- // "bestBid": "21150.500000",
239
- // "bestAsk": "21150.600000",
240
- // "baseVolume": "25402.1961",
241
- // "quoteVolume": "530452554.2156",
242
- // "ts": 1656408934044,
243
- // "labeId": 0
244
- // }
245
- // ]
209
+ // {
210
+ // "instId": "BTCUSDT",
211
+ // "lastPr": "43528.19",
212
+ // "open24h": "42267.78",
213
+ // "high24h": "44490.00",
214
+ // "low24h": "41401.53",
215
+ // "change24h": "0.03879",
216
+ // "bidPr": "43528",
217
+ // "askPr": "43528.01",
218
+ // "bidSz": "0.0334",
219
+ // "askSz": "0.1917",
220
+ // "baseVolume": "15002.4216",
221
+ // "quoteVolume": "648006446.7164",
222
+ // "openUtc": "44071.18",
223
+ // "changeUtc24h": "-0.01232",
224
+ // "ts": "1701842994338"
225
+ // }
226
+ // ],
227
+ // "ts": 1701842994341
246
228
  // }
247
229
  //
248
230
  // contract
249
231
  //
250
232
  // {
251
- // "action":"snapshot",
252
- // "arg":{
253
- // "instType":"mc",
254
- // "channel":"ticker",
255
- // "instId":"LTCUSDT"
233
+ // "action": "snapshot",
234
+ // "arg": {
235
+ // "instType": "USDT-FUTURES",
236
+ // "channel": "ticker",
237
+ // "instId": "BTCUSDT"
256
238
  // },
257
- // "data":[
258
- // {
259
- // "instId":"LTCUSDT",
260
- // "last":"52.77",
261
- // "bestAsk":"52.78",
262
- // "bestBid":"52.75",
263
- // "high24h":"54.83",
264
- // "low24h":"51.32",
265
- // "priceChangePercent":"-0.02",
266
- // "capitalRate":"-0.000100",
267
- // "nextSettleTime":1656514800000,
268
- // "systemTime":1656513146169,
269
- // "markPrice":"52.77",
270
- // "indexPrice":"52.80",
271
- // "holding":"269813.9",
272
- // "baseVolume":"75422.0",
273
- // "quoteVolume":"3986579.8"
274
- // }
275
- // ]
239
+ // "data": [
240
+ // {
241
+ // "instId": "BTCUSDT",
242
+ // "lastPr": "43480.4",
243
+ // "bidPr": "43476.3",
244
+ // "askPr": "43476.8",
245
+ // "bidSz": "0.1",
246
+ // "askSz": "3.055",
247
+ // "open24h": "42252.3",
248
+ // "high24h": "44518.2",
249
+ // "low24h": "41387.0",
250
+ // "change24h": "0.03875",
251
+ // "fundingRate": "0.000096",
252
+ // "nextFundingTime": "1701849600000",
253
+ // "markPrice": "43476.4",
254
+ // "indexPrice": "43478.4",
255
+ // "holdingAmount": "50670.787",
256
+ // "baseVolume": "120187.104",
257
+ // "quoteVolume": "5167385048.693",
258
+ // "openUtc": "44071.4",
259
+ // "symbolType": "1",
260
+ // "symbol": "BTCUSDT",
261
+ // "deliveryPrice": "0",
262
+ // "ts": "1701843962811"
263
+ // }
264
+ // ],
265
+ // "ts": 1701843962812
276
266
  // }
277
267
  //
278
268
  const arg = this.safeValue(message, 'arg', {});
279
269
  const data = this.safeValue(message, 'data', []);
280
270
  const ticker = this.safeValue(data, 0, {});
281
- const timestamp = this.safeInteger2(ticker, 'ts', 'systemTime');
282
- const marketId = this.getMarketIdFromArg(arg);
283
- market = this.safeMarket(marketId, market);
284
- const close = this.safeString(ticker, 'last');
285
- const open = this.safeString(ticker, 'open24h');
286
- const high = this.safeString(ticker, 'high24h');
287
- const low = this.safeString(ticker, 'low24h');
288
- const baseVolume = this.safeString(ticker, 'baseVolume');
289
- const quoteVolume = this.safeString(ticker, 'quoteVolume');
290
- const bid = this.safeString(ticker, 'bestBid');
291
- const ask = this.safeString(ticker, 'bestAsk');
271
+ const timestamp = this.safeInteger(ticker, 'ts');
272
+ const instType = this.safeString(arg, 'instType');
273
+ const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
274
+ const marketId = this.safeString(ticker, 'instId');
275
+ market = this.safeMarket(marketId, market, undefined, marketType);
276
+ const close = this.safeString(ticker, 'lastPr');
277
+ const changeDecimal = this.safeString(ticker, 'change24h');
278
+ const change = Precise["default"].stringMul(changeDecimal, '100');
292
279
  return this.safeTicker({
293
280
  'symbol': market['symbol'],
294
281
  'timestamp': timestamp,
295
282
  'datetime': this.iso8601(timestamp),
296
- 'high': high,
297
- 'low': low,
298
- 'bid': bid,
299
- 'bidVolume': undefined,
300
- 'ask': ask,
301
- 'askVolume': undefined,
283
+ 'high': this.safeString(ticker, 'high24h'),
284
+ 'low': this.safeString(ticker, 'low24h'),
285
+ 'bid': this.safeString(ticker, 'bidPr'),
286
+ 'bidVolume': this.safeString(ticker, 'bidSz'),
287
+ 'ask': this.safeString(ticker, 'askPr'),
288
+ 'askVolume': this.safeString(ticker, 'askSz'),
302
289
  'vwap': undefined,
303
- 'open': open,
290
+ 'open': this.safeString(ticker, 'open24h'),
304
291
  'close': close,
305
292
  'last': close,
306
293
  'previousClose': undefined,
307
294
  'change': undefined,
308
- 'percentage': undefined,
295
+ 'percentage': change,
309
296
  'average': undefined,
310
- 'baseVolume': baseVolume,
311
- 'quoteVolume': quoteVolume,
297
+ 'baseVolume': this.safeString(ticker, 'baseVolume'),
298
+ 'quoteVolume': this.safeString(ticker, 'quoteVolume'),
312
299
  'info': ticker,
313
300
  }, market);
314
301
  }
@@ -316,7 +303,9 @@ class bitget extends bitget$1 {
316
303
  /**
317
304
  * @method
318
305
  * @name bitget#watchOHLCV
319
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
306
+ * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
307
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
308
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
320
309
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
321
310
  * @param {string} timeframe the length of time each candle represents
322
311
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
@@ -330,11 +319,12 @@ class bitget extends bitget$1 {
330
319
  const timeframes = this.safeValue(this.options, 'timeframes');
331
320
  const interval = this.safeString(timeframes, timeframe);
332
321
  const messageHash = 'candles:' + timeframe + ':' + symbol;
333
- const instType = market['spot'] ? 'sp' : 'mc';
322
+ let instType = undefined;
323
+ [instType, params] = this.getInstType(market, params);
334
324
  const args = {
335
325
  'instType': instType,
336
326
  'channel': 'candle' + interval,
337
- 'instId': this.getWsMarketId(market),
327
+ 'instId': market['id'],
338
328
  };
339
329
  const ohlcv = await this.watchPublic(messageHash, args, params);
340
330
  if (this.newUpdates) {
@@ -342,81 +332,51 @@ class bitget extends bitget$1 {
342
332
  }
343
333
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
344
334
  }
345
- async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
346
- /**
347
- * @method
348
- * @name bitget#watchOHLCVForSymbols
349
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
350
- * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
351
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
352
- * @param {int} [limit] the maximum amount of candles to fetch
353
- * @param {object} [params] extra parameters specific to the exchange API endpoint
354
- * @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
355
- */
356
- await this.loadMarkets();
357
- const topics = [];
358
- const hashes = [];
359
- for (let i = 0; i < symbolsAndTimeframes.length; i++) {
360
- const data = symbolsAndTimeframes[i];
361
- const currentSymbol = this.safeString(data, 0);
362
- const currentTimeframe = this.safeString(data, 1);
363
- const market = this.market(currentSymbol);
364
- const interval = this.safeString(this.options['timeframes'], currentTimeframe);
365
- const instType = market['spot'] ? 'sp' : 'mc';
366
- const args = {
367
- 'instType': instType,
368
- 'channel': 'candle' + interval,
369
- 'instId': this.getWsMarketId(market),
370
- };
371
- topics.push(args);
372
- hashes.push(currentSymbol + '#' + currentSymbol);
373
- }
374
- const messageHash = 'multipleOHLCV::' + hashes.join(',');
375
- const [symbol, timeframe, stored] = await this.watchPublicMultiple(messageHash, topics, params);
376
- if (this.newUpdates) {
377
- limit = stored.getLimit(symbol, limit);
378
- }
379
- const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
380
- return this.createOHLCVObject(symbol, timeframe, filtered);
381
- }
382
335
  handleOHLCV(client, message) {
383
336
  //
384
- // {
385
- // "action":"snapshot",
386
- // "arg":{
387
- // "instType":"sp",
388
- // "channel":"candle1W",
389
- // "instId":"BTCUSDT"
390
- // },
391
- // "data":[
392
- // [
393
- // "1595779200000",
394
- // "9960.05",
395
- // "12099.95",
396
- // "9839.7",
397
- // "11088.68",
398
- // "462484.9738"
399
- // ],
400
- // [
401
- // "1596384000000",
402
- // "11088.68",
403
- // "11909.89",
404
- // "10937.54",
405
- // "11571.88",
406
- // "547596.6484"
407
- // ]
408
- // ]
409
- // }
337
+ // {
338
+ // "action": "snapshot",
339
+ // "arg": {
340
+ // "instType": "SPOT",
341
+ // "channel": "candle1m",
342
+ // "instId": "BTCUSDT"
343
+ // },
344
+ // "data": [
345
+ // [
346
+ // "1701871620000",
347
+ // "44080.23",
348
+ // "44080.23",
349
+ // "44028.5",
350
+ // "44028.51",
351
+ // "9.9287",
352
+ // "437404.105512",
353
+ // "437404.105512"
354
+ // ],
355
+ // [
356
+ // "1701871680000",
357
+ // "44028.51",
358
+ // "44108.11",
359
+ // "44028.5",
360
+ // "44108.11",
361
+ // "17.139",
362
+ // "755436.870643",
363
+ // "755436.870643"
364
+ // ],
365
+ // ],
366
+ // "ts": 1701901610417
367
+ // }
410
368
  //
411
369
  const arg = this.safeValue(message, 'arg', {});
412
- const marketId = this.getMarketIdFromArg(arg);
370
+ const instType = this.safeString(arg, 'instType');
371
+ const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
372
+ const marketId = this.safeString(arg, 'instId');
373
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
374
+ const symbol = market['symbol'];
375
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
413
376
  const channel = this.safeString(arg, 'channel');
414
377
  const interval = channel.replace('candle', '');
415
378
  const timeframes = this.safeValue(this.options, 'timeframes');
416
379
  const timeframe = this.findTimeframe(interval, timeframes);
417
- const market = this.safeMarket(marketId);
418
- const symbol = market['symbol'];
419
- this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
420
380
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
421
381
  if (stored === undefined) {
422
382
  const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
@@ -425,31 +385,33 @@ class bitget extends bitget$1 {
425
385
  }
426
386
  const data = this.safeValue(message, 'data', []);
427
387
  for (let i = 0; i < data.length; i++) {
428
- const parsed = this.parseWsOHLCV(data[i]);
388
+ const parsed = this.parseWsOHLCV(data[i], market);
429
389
  stored.append(parsed);
430
390
  }
431
391
  const messageHash = 'candles:' + timeframe + ':' + symbol;
432
392
  client.resolve(stored, messageHash);
433
- this.resolveMultipleOHLCV(client, 'multipleOHLCV::', symbol, timeframe, stored);
434
393
  }
435
394
  parseWsOHLCV(ohlcv, market = undefined) {
436
395
  //
437
- // [
438
- // "1595779200000", // timestamp
439
- // "9960.05", // open
440
- // "12099.95", // high
441
- // "9839.7", // low
442
- // "11088.68", // close
443
- // "462484.9738" // volume
444
- // ]
396
+ // [
397
+ // "1701871620000", // timestamp
398
+ // "44080.23", // open
399
+ // "44080.23", // high
400
+ // "44028.5", // low
401
+ // "44028.51", // close
402
+ // "9.9287", // base volume
403
+ // "437404.105512", // quote volume
404
+ // "437404.105512" // USDT volume
405
+ // ]
445
406
  //
407
+ const volumeIndex = (market['inverse']) ? 6 : 5;
446
408
  return [
447
409
  this.safeInteger(ohlcv, 0),
448
410
  this.safeNumber(ohlcv, 1),
449
411
  this.safeNumber(ohlcv, 2),
450
412
  this.safeNumber(ohlcv, 3),
451
413
  this.safeNumber(ohlcv, 4),
452
- this.safeNumber(ohlcv, 5),
414
+ this.safeNumber(ohlcv, volumeIndex),
453
415
  ];
454
416
  }
455
417
  async watchOrderBook(symbol, limit = undefined, params = {}) {
@@ -457,40 +419,22 @@ class bitget extends bitget$1 {
457
419
  * @method
458
420
  * @name bitget#watchOrderBook
459
421
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
422
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
423
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
460
424
  * @param {string} symbol unified symbol of the market to fetch the order book for
461
425
  * @param {int} [limit] the maximum amount of order book entries to return
462
426
  * @param {object} [params] extra parameters specific to the exchange API endpoint
463
427
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
464
428
  */
465
- await this.loadMarkets();
466
- const market = this.market(symbol);
467
- symbol = market['symbol'];
468
- const messageHash = 'orderbook' + ':' + symbol;
469
- const instType = market['spot'] ? 'sp' : 'mc';
470
- let channel = 'books';
471
- let incrementalFeed = true;
472
- if ((limit === 1) || (limit === 5) || (limit === 15)) {
473
- channel += limit.toString();
474
- incrementalFeed = false;
475
- }
476
- const args = {
477
- 'instType': instType,
478
- 'channel': channel,
479
- 'instId': this.getWsMarketId(market),
480
- };
481
- const orderbook = await this.watchPublic(messageHash, args, params);
482
- if (incrementalFeed) {
483
- return orderbook.limit();
484
- }
485
- else {
486
- return orderbook;
487
- }
429
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
488
430
  }
489
431
  async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
490
432
  /**
491
433
  * @method
492
434
  * @name bitget#watchOrderBookForSymbols
493
435
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
436
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
437
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
494
438
  * @param {string[]} symbols unified array of symbols
495
439
  * @param {int} [limit] the maximum amount of order book entries to return
496
440
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -505,18 +449,21 @@ class bitget extends bitget$1 {
505
449
  incrementalFeed = false;
506
450
  }
507
451
  const topics = [];
452
+ const messageHashes = [];
508
453
  for (let i = 0; i < symbols.length; i++) {
509
- const market = this.market(symbols[i]);
510
- const instType = market['spot'] ? 'sp' : 'mc';
454
+ const symbol = symbols[i];
455
+ const market = this.market(symbol);
456
+ let instType = undefined;
457
+ [instType, params] = this.getInstType(market, params);
511
458
  const args = {
512
459
  'instType': instType,
513
460
  'channel': channel,
514
- 'instId': this.getWsMarketId(market),
461
+ 'instId': market['id'],
515
462
  };
516
463
  topics.push(args);
464
+ messageHashes.push('orderbook:' + symbol);
517
465
  }
518
- const messageHash = 'multipleOrderbooks::' + symbols.join(',');
519
- const orderbook = await this.watchPublicMultiple(messageHash, topics, params);
466
+ const orderbook = await this.watchPublicMultiple(messageHashes, topics, params);
520
467
  if (incrementalFeed) {
521
468
  return orderbook.limit();
522
469
  }
@@ -529,7 +476,7 @@ class bitget extends bitget$1 {
529
476
  // {
530
477
  // "action":"snapshot",
531
478
  // "arg":{
532
- // "instType":"sp",
479
+ // "instType":"SPOT",
533
480
  // "channel":"books5",
534
481
  // "instId":"BTCUSDT"
535
482
  // },
@@ -549,6 +496,7 @@ class bitget extends bitget$1 {
549
496
  // ["21040.61","0.3004"],
550
497
  // ["21040.60","1.3357"]
551
498
  // ],
499
+ // "checksum": -1367582038,
552
500
  // "ts":"1656413855484"
553
501
  // }
554
502
  // ]
@@ -556,8 +504,10 @@ class bitget extends bitget$1 {
556
504
  //
557
505
  const arg = this.safeValue(message, 'arg');
558
506
  const channel = this.safeString(arg, 'channel');
559
- const marketId = this.getMarketIdFromArg(arg);
560
- const market = this.safeMarket(marketId);
507
+ const instType = this.safeString(arg, 'instType');
508
+ const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
509
+ const marketId = this.safeString(arg, 'instId');
510
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
561
511
  const symbol = market['symbol'];
562
512
  const messageHash = 'orderbook:' + symbol;
563
513
  const data = this.safeValue(message, 'data');
@@ -609,7 +559,6 @@ class bitget extends bitget$1 {
609
559
  }
610
560
  this.orderbooks[symbol] = storedOrderBook;
611
561
  client.resolve(storedOrderBook, messageHash);
612
- this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, storedOrderBook);
613
562
  }
614
563
  handleDelta(bookside, delta) {
615
564
  const bidAsk = this.parseBidAsk(delta, 0, 1);
@@ -628,35 +577,23 @@ class bitget extends bitget$1 {
628
577
  * @method
629
578
  * @name bitget#watchTrades
630
579
  * @description get the list of most recent trades for a particular symbol
631
- * @see https://bitgetlimited.github.io/apidoc/en/spot/#trades-channel
632
- * @see https://bitgetlimited.github.io/apidoc/en/mix/#trades-channel
580
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
581
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
633
582
  * @param {string} symbol unified symbol of the market to fetch trades for
634
583
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
635
584
  * @param {int} [limit] the maximum amount of trades to fetch
636
585
  * @param {object} [params] extra parameters specific to the exchange API endpoint
637
586
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
638
587
  */
639
- await this.loadMarkets();
640
- const market = this.market(symbol);
641
- symbol = market['symbol'];
642
- const messageHash = 'trade:' + symbol;
643
- const instType = market['spot'] ? 'sp' : 'mc';
644
- const args = {
645
- 'instType': instType,
646
- 'channel': 'trade',
647
- 'instId': this.getWsMarketId(market),
648
- };
649
- const trades = await this.watchPublic(messageHash, args, params);
650
- if (this.newUpdates) {
651
- limit = trades.getLimit(symbol, limit);
652
- }
653
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
588
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
654
589
  }
655
590
  async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
656
591
  /**
657
592
  * @method
658
593
  * @name bitget#watchTradesForSymbols
659
594
  * @description get the list of most recent trades for a particular symbol
595
+ * @see https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
596
+ * @see https://www.bitget.com/api-doc/contract/websocket/public/New-Trades-Channel
660
597
  * @param {string} symbol unified symbol of the market to fetch trades for
661
598
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
662
599
  * @param {int} [limit] the maximum amount of trades to fetch
@@ -670,18 +607,21 @@ class bitget extends bitget$1 {
670
607
  await this.loadMarkets();
671
608
  symbols = this.marketSymbols(symbols);
672
609
  const topics = [];
610
+ const messageHashes = [];
673
611
  for (let i = 0; i < symbols.length; i++) {
674
- const market = this.market(symbols[i]);
675
- const instType = market['spot'] ? 'sp' : 'mc';
612
+ const symbol = symbols[i];
613
+ const market = this.market(symbol);
614
+ let instType = undefined;
615
+ [instType, params] = this.getInstType(market, params);
676
616
  const args = {
677
617
  'instType': instType,
678
618
  'channel': 'trade',
679
- 'instId': this.getWsMarketId(market),
619
+ 'instId': market['id'],
680
620
  };
681
621
  topics.push(args);
622
+ messageHashes.push('trade:' + symbol);
682
623
  }
683
- const messageHash = 'multipleTrades::' + symbols.join(',');
684
- const trades = await this.watchPublicMultiple(messageHash, topics, params);
624
+ const trades = await this.watchPublicMultiple(messageHashes, topics, params);
685
625
  if (this.newUpdates) {
686
626
  const first = this.safeValue(trades, 0);
687
627
  const tradeSymbol = this.safeString(first, 'symbol');
@@ -691,24 +631,26 @@ class bitget extends bitget$1 {
691
631
  }
692
632
  handleTrades(client, message) {
693
633
  //
694
- // {
695
- // "action": "snapshot",
696
- // "arg": { instType: 'sp', channel: "trade", instId: "BTCUSDT" },
697
- // "data": [
698
- // [ '1656411148032', '21047.78', "2.2294", "buy" ],
699
- // [ '1656411142030', '21047.85', "2.1225", "buy" ],
700
- // [ '1656411133064', '21045.88', "1.7704", "sell" ],
701
- // [ '1656411126037', '21052.39', "2.6905", "buy" ],
702
- // [ '1656411118029', '21056.87', "1.2308", "sell" ],
703
- // [ '1656411108028', '21060.01', "1.7186", "sell" ],
704
- // [ '1656411100027', '21060.4', "1.3641", "buy" ],
705
- // [ '1656411093030', '21058.76', "1.5049", "sell" ]
706
- // ]
707
- // }
634
+ // {
635
+ // "action": "snapshot",
636
+ // "arg": { "instType": "SPOT", "channel": "trade", "instId": "BTCUSDT" },
637
+ // "data": [
638
+ // {
639
+ // "ts": "1701910980366",
640
+ // "price": "43854.01",
641
+ // "size": "0.0535",
642
+ // "side": "buy",
643
+ // "tradeId": "1116461060594286593"
644
+ // },
645
+ // ],
646
+ // "ts": 1701910980730
647
+ // }
708
648
  //
709
649
  const arg = this.safeValue(message, 'arg', {});
710
- const marketId = this.getMarketIdFromArg(arg);
711
- const market = this.safeMarket(marketId);
650
+ const instType = this.safeString(arg, 'instType');
651
+ const marketType = (instType === 'SPOT') ? 'spot' : 'contract';
652
+ const marketId = this.safeString(arg, 'instId');
653
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
712
654
  const symbol = market['symbol'];
713
655
  let stored = this.safeValue(this.trades, symbol);
714
656
  if (stored === undefined) {
@@ -724,36 +666,31 @@ class bitget extends bitget$1 {
724
666
  }
725
667
  const messageHash = 'trade:' + symbol;
726
668
  client.resolve(stored, messageHash);
727
- this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
728
669
  }
729
670
  parseWsTrade(trade, market = undefined) {
730
671
  //
731
- // public trade
732
- //
733
- // [
734
- // "1656411148032", // timestamp
735
- // "21047.78", // price
736
- // "2.2294", // size
737
- // "buy", // side
738
- // ]
672
+ // {
673
+ // "ts": "1701910980366",
674
+ // "price": "43854.01",
675
+ // "size": "0.0535",
676
+ // "side": "buy",
677
+ // "tradeId": "1116461060594286593"
678
+ // }
739
679
  //
740
680
  market = this.safeMarket(undefined, market);
741
- const timestamp = this.safeInteger(trade, 0);
742
- const side = this.safeString(trade, 3);
743
- const price = this.safeString(trade, 1);
744
- const amount = this.safeString(trade, 2);
681
+ const timestamp = this.safeInteger(trade, 'ts');
745
682
  return this.safeTrade({
746
683
  'info': trade,
747
- 'id': undefined,
684
+ 'id': this.safeString(trade, 'tradeId'),
748
685
  'order': undefined,
749
686
  'timestamp': timestamp,
750
687
  'datetime': this.iso8601(timestamp),
751
688
  'symbol': market['symbol'],
752
689
  'type': undefined,
753
- 'side': side,
690
+ 'side': this.safeString(trade, 'side'),
754
691
  'takerOrMaker': undefined,
755
- 'price': price,
756
- 'amount': amount,
692
+ 'price': this.safeString(trade, 'price'),
693
+ 'amount': this.safeString(trade, 'size'),
757
694
  'cost': undefined,
758
695
  'fee': undefined,
759
696
  }, market);
@@ -763,30 +700,22 @@ class bitget extends bitget$1 {
763
700
  * @method
764
701
  * @name bitget#watchPositions
765
702
  * @description watch all open positions
766
- * @see https://bitgetlimited.github.io/apidoc/en/mix/#positions-channel
703
+ * @see https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
767
704
  * @param {string[]|undefined} symbols list of unified market symbols
768
705
  * @param {object} params extra parameters specific to the exchange API endpoint
769
- * @param {string} params.instType Instrument Type umcbl:USDT Perpetual Contract Private Channel; dmcbl:Coin Margin Perpetual Contract Private Channel; cmcbl: USDC margin Perpetual Contract Private Channel
706
+ * @param {string} [params.instType] one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
770
707
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
771
708
  */
772
709
  await this.loadMarkets();
773
710
  let market = undefined;
774
711
  let messageHash = '';
775
712
  const subscriptionHash = 'positions';
776
- let instType = 'umcbl';
713
+ let instType = 'USDT-FUTURES';
777
714
  symbols = this.marketSymbols(symbols);
778
715
  if (!this.isEmpty(symbols)) {
779
- instType = 'dmcbl';
780
716
  market = this.getMarketFromSymbols(symbols);
781
- messageHash = '::' + symbols.join(',');
782
- if (market['settle'] === 'USDT') {
783
- instType = 'umcbl';
784
- }
785
- else if (market['settle'] === 'USDC') {
786
- instType = 'cmcbl';
787
- }
717
+ [instType, params] = this.getInstType(market, params);
788
718
  }
789
- [instType, params] = this.handleOptionAndParams(params, 'watchPositions', 'instType', instType);
790
719
  messageHash = instType + ':positions' + messageHash;
791
720
  const args = {
792
721
  'instType': instType,
@@ -801,41 +730,41 @@ class bitget extends bitget$1 {
801
730
  }
802
731
  handlePositions(client, message) {
803
732
  //
804
- // {
805
- // action: 'snapshot',
806
- // arg: {
807
- // instType: 'umcbl',
808
- // channel: 'positions',
809
- // instId: 'default'
810
- // },
811
- // data: [{
812
- // posId: '926036334386778112',
813
- // instId: 'LTCUSDT_UMCBL',
814
- // instName: 'LTCUSDT',
815
- // marginCoin: 'USDT',
816
- // margin: '9.667',
817
- // marginMode: 'crossed',
818
- // holdSide: 'long',
819
- // holdMode: 'double_hold',
820
- // total: '0.3',
821
- // available: '0.3',
822
- // locked: '0',
823
- // averageOpenPrice: '64.44',
824
- // leverage: 2,
825
- // achievedProfits: '0',
826
- // upl: '0.0759',
827
- // uplRate: '0.0078',
828
- // liqPx: '-153.32',
829
- // keepMarginRate: '0.010',
830
- // marginRate: '0.005910309637',
831
- // cTime: '1656510187717',
832
- // uTime: '1694880005480',
833
- // markPrice: '64.7',
834
- // autoMargin: 'off'
835
- // },
836
- // ...
837
- // ]
838
- // }
733
+ // {
734
+ // "action": "snapshot",
735
+ // "arg": {
736
+ // "instType": "USDT-FUTURES",
737
+ // "channel": "positions",
738
+ // "instId": "default"
739
+ // },
740
+ // "data": [
741
+ // {
742
+ // "posId": "926036334386778112",
743
+ // "instId": "BTCUSDT",
744
+ // "marginCoin": "USDT",
745
+ // "marginSize": "2.19245",
746
+ // "marginMode": "crossed",
747
+ // "holdSide": "long",
748
+ // "posMode": "hedge_mode",
749
+ // "total": "0.001",
750
+ // "available": "0.001",
751
+ // "frozen": "0",
752
+ // "openPriceAvg": "43849",
753
+ // "leverage": 20,
754
+ // "achievedProfits": "0",
755
+ // "unrealizedPL": "-0.0032",
756
+ // "unrealizedPLR": "-0.00145955438",
757
+ // "liquidationPrice": "17629.684814834",
758
+ // "keepMarginRate": "0.004",
759
+ // "marginRate": "0.007634649185",
760
+ // "cTime": "1652331666985",
761
+ // "uTime": "1701913016923",
762
+ // "autoMargin": "off"
763
+ // },
764
+ // ...
765
+ // ]
766
+ // "ts": 1701913043767
767
+ // }
839
768
  //
840
769
  const arg = this.safeValue(message, 'arg', {});
841
770
  const instType = this.safeString(arg, 'instType', '');
@@ -854,7 +783,9 @@ class bitget extends bitget$1 {
854
783
  const newPositions = [];
855
784
  for (let i = 0; i < rawPositions.length; i++) {
856
785
  const rawPosition = rawPositions[i];
857
- const position = this.parseWsPosition(rawPosition);
786
+ const marketId = this.safeString(rawPosition, 'instId');
787
+ const market = this.safeMarket(marketId, undefined, undefined, 'contract');
788
+ const position = this.parseWsPosition(rawPosition, market);
858
789
  newPositions.push(position);
859
790
  cache.append(position);
860
791
  }
@@ -873,57 +804,58 @@ class bitget extends bitget$1 {
873
804
  }
874
805
  parseWsPosition(position, market = undefined) {
875
806
  //
876
- // {
877
- // posId: '926036334386778112',
878
- // instId: 'LTCUSDT_UMCBL',
879
- // instName: 'LTCUSDT',
880
- // marginCoin: 'USDT',
881
- // margin: '9.667',
882
- // marginMode: 'crossed',
883
- // holdSide: 'long',
884
- // holdMode: 'double_hold',
885
- // total: '0.3',
886
- // available: '0.3',
887
- // locked: '0',
888
- // averageOpenPrice: '64.44',
889
- // leverage: 2,
890
- // achievedProfits: '0',
891
- // upl: '0.0759',
892
- // uplRate: '0.0078',
893
- // liqPx: '-153.32',
894
- // keepMarginRate: '0.010',
895
- // marginRate: '0.005910309637',
896
- // cTime: '1656510187717',
897
- // uTime: '1694880005480',
898
- // markPrice: '64.7',
899
- // autoMargin: 'off'
900
- // }
807
+ // {
808
+ // "posId": "926036334386778112",
809
+ // "instId": "BTCUSDT",
810
+ // "marginCoin": "USDT",
811
+ // "marginSize": "2.19245",
812
+ // "marginMode": "crossed",
813
+ // "holdSide": "long",
814
+ // "posMode": "hedge_mode",
815
+ // "total": "0.001",
816
+ // "available": "0.001",
817
+ // "frozen": "0",
818
+ // "openPriceAvg": "43849",
819
+ // "leverage": 20,
820
+ // "achievedProfits": "0",
821
+ // "unrealizedPL": "-0.0032",
822
+ // "unrealizedPLR": "-0.00145955438",
823
+ // "liquidationPrice": "17629.684814834",
824
+ // "keepMarginRate": "0.004",
825
+ // "marginRate": "0.007634649185",
826
+ // "cTime": "1652331666985",
827
+ // "uTime": "1701913016923",
828
+ // "autoMargin": "off"
829
+ // }
901
830
  //
902
831
  const marketId = this.safeString(position, 'instId');
903
832
  const marginModeId = this.safeString(position, 'marginMode');
904
833
  const marginMode = this.getSupportedMapping(marginModeId, {
905
834
  'crossed': 'cross',
906
- 'fixed': 'isolated',
907
- });
908
- const hedgedId = this.safeString(position, 'holdMode');
909
- const hedged = this.getSupportedMapping(hedgedId, {
910
- 'double_hold': true,
911
- 'single_hold': false,
835
+ 'isolated': 'isolated',
912
836
  });
837
+ const hedgedId = this.safeString(position, 'posMode');
838
+ const hedged = (hedgedId === 'hedge_mode') ? true : false;
913
839
  const timestamp = this.safeInteger2(position, 'uTime', 'cTime');
840
+ const percentageDecimal = this.safeString(position, 'unrealizedPLR');
841
+ const percentage = Precise["default"].stringMul(percentageDecimal, '100');
842
+ let contractSize = undefined;
843
+ if (market !== undefined) {
844
+ contractSize = market['contractSize'];
845
+ }
914
846
  return this.safePosition({
915
847
  'info': position,
916
848
  'id': this.safeString(position, 'posId'),
917
- 'symbol': this.safeSymbol(marketId, market),
849
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
918
850
  'notional': undefined,
919
851
  'marginMode': marginMode,
920
- 'liquidationPrice': undefined,
921
- 'entryPrice': this.safeNumber(position, 'averageOpenPrice'),
922
- 'unrealizedPnl': this.safeNumber(position, 'upl'),
923
- 'percentage': this.safeNumber(position, 'uplRate'),
852
+ 'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
853
+ 'entryPrice': this.safeNumber(position, 'openPriceAvg'),
854
+ 'unrealizedPnl': this.safeNumber(position, 'unrealizedPL'),
855
+ 'percentage': this.parseNumber(percentage),
924
856
  'contracts': this.safeNumber(position, 'total'),
925
- 'contractSize': undefined,
926
- 'markPrice': this.safeNumber(position, 'markPrice'),
857
+ 'contractSize': contractSize,
858
+ 'markPrice': undefined,
927
859
  'side': this.safeString(position, 'holdSide'),
928
860
  'hedged': hedged,
929
861
  'timestamp': timestamp,
@@ -941,14 +873,18 @@ class bitget extends bitget$1 {
941
873
  /**
942
874
  * @method
943
875
  * @name bitget#watchOrders
944
- * @see https://bitgetlimited.github.io/apidoc/en/spot/#order-channel
945
- * @see https://bitgetlimited.github.io/apidoc/en/mix/#order-channel
946
- * @see https://bitgetlimited.github.io/apidoc/en/mix/#plan-order-channel
947
876
  * @description watches information on multiple orders made by the user
877
+ * @see https://www.bitget.com/api-doc/spot/websocket/private/Order-Channel
878
+ * @see https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
879
+ * @see https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
880
+ * @see https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
881
+ * @see https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
948
882
  * @param {string} symbol unified market symbol of the market orders were made in
949
883
  * @param {int} [since] the earliest time in ms to fetch orders for
950
- * @param {int} [limit] the maximum number of orde structures to retrieve
884
+ * @param {int} [limit] the maximum number of order structures to retrieve
951
885
  * @param {object} [params] extra parameters specific to the exchange API endpoint
886
+ * @param {boolean} [params.stop] *contract only* set to true for watching trigger orders
887
+ * @param {string} [params.marginMode] 'isolated' or 'cross' for watching spot margin orders
952
888
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
953
889
  */
954
890
  await this.loadMarkets();
@@ -972,25 +908,27 @@ class bitget extends bitget$1 {
972
908
  if (isStop && type === 'spot') {
973
909
  throw new errors.NotSupported(this.id + ' watchOrders does not support stop orders for ' + type + ' markets.');
974
910
  }
975
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
976
911
  let instType = undefined;
912
+ [instType, params] = this.getInstType(market, params);
977
913
  if (type === 'spot') {
978
- instType = 'spbl';
979
914
  subscriptionHash = subscriptionHash + ':' + symbol;
980
915
  }
981
- else {
982
- if (!sandboxMode) {
983
- instType = 'UMCBL';
984
- }
985
- else {
986
- instType = 'SUMCBL';
987
- }
988
- }
989
916
  if (isStop) {
990
917
  subscriptionHash = subscriptionHash + ':stop'; // we don't want to re-use the same subscription hash for stop orders
991
918
  }
992
919
  const instId = (type === 'spot') ? marketId : 'default'; // different from other streams here the 'rest' id is required for spot markets, contract markets require default here
993
- const channel = isStop ? 'ordersAlgo' : 'orders';
920
+ let channel = isStop ? 'orders-algo' : 'orders';
921
+ let marginMode = undefined;
922
+ [marginMode, params] = this.handleMarginModeAndParams('watchOrders', params);
923
+ if (marginMode !== undefined) {
924
+ instType = 'MARGIN';
925
+ if (marginMode === 'isolated') {
926
+ channel = 'orders-isolated';
927
+ }
928
+ else {
929
+ channel = 'orders-crossed';
930
+ }
931
+ }
994
932
  const args = {
995
933
  'instType': instType,
996
934
  'channel': channel,
@@ -1004,71 +942,149 @@ class bitget extends bitget$1 {
1004
942
  }
1005
943
  handleOrder(client, message, subscription = undefined) {
1006
944
  //
945
+ // spot
1007
946
  //
1008
- // spot order
1009
- // {
1010
- // "action": "snapshot",
1011
- // "arg": { instType: 'spbl', channel: 'orders', instId: "LTCUSDT_SPBL" // instId="default" for contracts },
1012
- // "data": [
1013
- // {
1014
- // "instId": "LTCUSDT_SPBL",
1015
- // "ordId": "925999649898545152",
1016
- // "clOrdId": "8b2aa69a-6a09-46c0-a50d-7ed50277394c",
1017
- // "px": "20.00",
1018
- // "sz": "0.3000",
1019
- // "notional": "6.000000",
1020
- // "ordType": "limit",
1021
- // "force": "normal",
1022
- // "side": "buy",
1023
- // "accFillSz": "0.0000",
1024
- // "avgPx": "0.00",
1025
- // "status": "new",
1026
- // "cTime": 1656501441454,
1027
- // "uTime": 1656501441454,
1028
- // "orderFee": []
1029
- // }
1030
- // ]
1031
- // }
947
+ // {
948
+ // "action": "snapshot",
949
+ // "arg": { "instType": "SPOT", "channel": "orders", "instId": "BTCUSDT" },
950
+ // "data": [
951
+ // {
952
+ // "instId": "BTCUSDT",
953
+ // "orderId": "1116512721422422017",
954
+ // "clientOid": "798d1425-d31d-4ada-a51b-ec701e00a1d9",
955
+ // "price": "35000.00",
956
+ // "size": "7.0000",
957
+ // "notional": "7.000000",
958
+ // "orderType": "limit",
959
+ // "force": "gtc",
960
+ // "side": "buy",
961
+ // "accBaseVolume": "0.0000",
962
+ // "priceAvg": "0.00",
963
+ // "status": "live",
964
+ // "cTime": "1701923297267",
965
+ // "uTime": "1701923297267",
966
+ // "feeDetail": [],
967
+ // "enterPointSource": "WEB"
968
+ // }
969
+ // ],
970
+ // "ts": 1701923297285
971
+ // }
1032
972
  //
1033
- // {
1034
- // "action": "snapshot",
1035
- // "arg": { instType: 'umcbl', channel: "ordersAlgo", instId: "default" },
1036
- // "data": [
1037
- // {
1038
- // "actualPx": "55.000000000",
1039
- // "actualSz": "0.000000000",
1040
- // "cOid": "1104372235724890112",
1041
- // "cTime": "1699028779917",
1042
- // "eps": "web",
1043
- // "hM": "double_hold",
1044
- // "id": "1104372235724890113",
1045
- // "instId": "BTCUSDT_UMCBL",
1046
- // "key": "1104372235724890113",
1047
- // "ordPx": "55.000000000",
1048
- // "ordType": "limit",
1049
- // "planType": "pl",
1050
- // "posSide": "long",
1051
- // "side": "buy",
1052
- // "state": "not_trigger",
1053
- // "sz": "3.557000000",
1054
- // "tS": "open_long",
1055
- // "tgtCcy": "USDT",
1056
- // "triggerPx": "55.000000000",
1057
- // "triggerPxType": "last",
1058
- // "triggerTime": "1699028779917",
1059
- // "uTime": "1699028779917",
1060
- // "userId": "3704614084",
1061
- // "version": 1104372235586478100
1062
- // }
1063
- // ],
1064
- // "ts": 1699028780327
1065
- // }
973
+ // contract
974
+ //
975
+ // {
976
+ // "action": "snapshot",
977
+ // "arg": { "instType": "USDT-FUTURES", "channel": "orders", "instId": "default" },
978
+ // "data": [
979
+ // {
980
+ // "accBaseVolume": "0",
981
+ // "cTime": "1701920553759",
982
+ // "clientOid": "1116501214318198793",
983
+ // "enterPointSource": "WEB",
984
+ // "feeDetail": [{
985
+ // "feeCoin": "USDT",
986
+ // "fee": "-0.162003"
987
+ // }],
988
+ // "force": "gtc",
989
+ // "instId": "BTCUSDT",
990
+ // "leverage": "20",
991
+ // "marginCoin": "USDT",
992
+ // "marginMode": "isolated",
993
+ // "notionalUsd": "105",
994
+ // "orderId": "1116501214293032964",
995
+ // "orderType": "limit",
996
+ // "posMode": "hedge_mode",
997
+ // "posSide": "long",
998
+ // "price": "35000",
999
+ // "reduceOnly": "no",
1000
+ // "side": "buy",
1001
+ // "size": "0.003",
1002
+ // "status": "canceled",
1003
+ // "tradeSide": "open",
1004
+ // "uTime": "1701920595866"
1005
+ // }
1006
+ // ],
1007
+ // "ts": 1701920595879
1008
+ // }
1009
+ //
1010
+ // trigger
1011
+ //
1012
+ // {
1013
+ // "action": "snapshot",
1014
+ // "arg": {
1015
+ // "instType": "USDT-FUTURES",
1016
+ // "channel": "orders-algo",
1017
+ // "instId": "default"
1018
+ // },
1019
+ // "data": [
1020
+ // {
1021
+ // "instId": "BTCUSDT",
1022
+ // "orderId": "1116508960750899201",
1023
+ // "clientOid": "1116508960750899200",
1024
+ // "triggerPrice": "35000.000000000",
1025
+ // "triggerType": "mark_price",
1026
+ // "triggerTime": "1701922464373",
1027
+ // "planType": "pl",
1028
+ // "price": "35000.000000000",
1029
+ // "size": "0.001000000",
1030
+ // "actualSize": "0.000000000",
1031
+ // "orderType": "limit",
1032
+ // "side": "buy",
1033
+ // "tradeSide": "open",
1034
+ // "posSide": "long",
1035
+ // "marginCoin": "USDT",
1036
+ // "status": "cancelled",
1037
+ // "posMode": "hedge_mode",
1038
+ // "enterPointSource": "api",
1039
+ // "stopSurplusTriggerType": "fill_price",
1040
+ // "stopLossTriggerType": "fill_price",
1041
+ // "cTime": "1701922400653",
1042
+ // "uTime": "1701922464373"
1043
+ // }
1044
+ // ],
1045
+ // "ts": 1701922464417
1046
+ // }
1047
+ //
1048
+ // isolated and cross margin
1049
+ //
1050
+ // {
1051
+ // "action": "snapshot",
1052
+ // "arg": { "instType": "MARGIN", "channel": "orders-crossed", "instId": "BTCUSDT" },
1053
+ // "data": [
1054
+ // {
1055
+ // "enterPointSource": "web",
1056
+ // "force": "gtc",
1057
+ // "orderType": "limit",
1058
+ // "price": "35000.000000000",
1059
+ // "quoteSize": "10.500000000",
1060
+ // "side": "buy",
1061
+ // "status": "live",
1062
+ // "baseSize": "0.000300000",
1063
+ // "cTime": "1701923982427",
1064
+ // "clientOid": "4902047879864dc980c4840e9906db4e",
1065
+ // "fillPrice": "0.000000000",
1066
+ // "baseVolume": "0.000000000",
1067
+ // "fillTotalAmount": "0.000000000",
1068
+ // "loanType": "auto-loan-and-repay",
1069
+ // "orderId": "1116515595178356737"
1070
+ // }
1071
+ // ],
1072
+ // "ts": 1701923982497
1073
+ // }
1066
1074
  //
1067
1075
  const arg = this.safeValue(message, 'arg', {});
1068
1076
  const channel = this.safeString(arg, 'channel');
1069
1077
  const instType = this.safeString(arg, 'instType');
1070
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
1071
- const isContractUpdate = (!sandboxMode) ? (instType === 'umcbl') : (instType === 'sumcbl');
1078
+ let marketType = undefined;
1079
+ if (instType === 'SPOT') {
1080
+ marketType = 'spot';
1081
+ }
1082
+ else if (instType === 'MARGIN') {
1083
+ marketType = 'spot';
1084
+ }
1085
+ else {
1086
+ marketType = 'contract';
1087
+ }
1072
1088
  const data = this.safeValue(message, 'data', []);
1073
1089
  if (this.orders === undefined) {
1074
1090
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
@@ -1080,12 +1096,9 @@ class bitget extends bitget$1 {
1080
1096
  const marketSymbols = {};
1081
1097
  for (let i = 0; i < data.length; i++) {
1082
1098
  const order = data[i];
1083
- const execType = this.safeString(order, 'execType');
1084
- if ((execType === 'T') && isContractUpdate) {
1085
- // partial order updates have the trade info inside
1086
- this.handleMyTrades(client, order);
1087
- }
1088
- const parsed = this.parseWsOrder(order);
1099
+ const marketId = this.safeString(order, 'instId');
1100
+ const market = this.safeMarket(marketId, undefined, undefined, marketType);
1101
+ const parsed = this.parseWsOrder(order, market);
1089
1102
  stored.append(parsed);
1090
1103
  const symbol = parsed['symbol'];
1091
1104
  marketSymbols[symbol] = true;
@@ -1100,163 +1113,150 @@ class bitget extends bitget$1 {
1100
1113
  }
1101
1114
  parseWsOrder(order, market = undefined) {
1102
1115
  //
1103
- // spot order
1116
+ // spot
1117
+ //
1104
1118
  // {
1105
- // "instId": "LTCUSDT_SPBL",
1106
- // "ordId": "925999649898545152",
1107
- // "clOrdId": "8b2aa69a-6a09-46c0-a50d-7ed50277394c",
1108
- // "px": "20.00",
1109
- // "sz": "0.3000",
1110
- // "notional": "6.000000",
1111
- // "ordType": "limit",
1112
- // "force": "normal",
1119
+ // "instId": "BTCUSDT",
1120
+ // "orderId": "1116512721422422017",
1121
+ // "clientOid": "798d1425-d31d-4ada-a51b-ec701e00a1d9",
1122
+ // "price": "35000.00",
1123
+ // "size": "7.0000",
1124
+ // "notional": "7.000000",
1125
+ // "orderType": "limit",
1126
+ // "force": "gtc",
1113
1127
  // "side": "buy",
1114
- // "accFillSz": "0.0000",
1115
- // "avgPx": "0.00",
1116
- // "status": "new",
1117
- // "cTime": 1656501441454,
1118
- // "uTime": 1656501441454,
1119
- // "orderFee": []
1128
+ // "accBaseVolume": "0.0000",
1129
+ // "priceAvg": "0.00",
1130
+ // "status": "live",
1131
+ // "cTime": "1701923297267",
1132
+ // "uTime": "1701923297267",
1133
+ // "feeDetail": [],
1134
+ // "enterPointSource": "WEB"
1120
1135
  // }
1121
- // partial fill
1122
1136
  //
1123
- // {
1124
- // "instId": "LTCUSDT_SPBL",
1125
- // "ordId": "926006174213914625",
1126
- // "clOrdId": "7ce28714-0016-46d0-a971-9a713a9923c5",
1127
- // "notional": "5.000000",
1128
- // "ordType": "market",
1129
- // "force": "normal",
1130
- // "side": "buy",
1131
- // "fillPx": "52.11",
1132
- // "tradeId": "926006174514073601",
1133
- // "fillSz": "0.0959",
1134
- // "fillTime": "1656502997043",
1135
- // "fillFee": "-0.0000959",
1136
- // "fillFeeCcy": "LTC",
1137
- // "execType": "T",
1138
- // "accFillSz": "0.0959",
1139
- // "avgPx": "52.11",
1140
- // "status": "partial-fill",
1141
- // "cTime": 1656502996972,
1142
- // "uTime": 1656502997119,
1143
- // "orderFee": [Array]
1144
- // }
1137
+ // contract
1145
1138
  //
1146
- // contract order
1147
- // {
1148
- // "accFillSz": "0",
1149
- // "cTime": 1656510642518,
1150
- // "clOrdId": "926038241960431617",
1151
- // "force": "normal",
1152
- // "instId": "LTCUSDT_UMCBL",
1153
- // "lever": "20",
1154
- // "notionalUsd": "7.5",
1155
- // "ordId": "926038241859768320",
1156
- // "ordType": "limit",
1157
- // "orderFee": [
1158
- // {feeCcy: "USDT", fee: "0"}
1159
- // ]
1160
- // "posSide": "long",
1161
- // "px": "25",
1162
- // "side": "buy",
1163
- // "status": "new",
1164
- // "sz": "0.3",
1165
- // "tdMode": "cross",
1166
- // "tgtCcy": "USDT",
1167
- // "uTime": 1656510642518
1168
- // }
1169
- // algo order
1170
- // {
1171
- // "actualPx":"50.000000000",
1172
- // "actualSz":"0.000000000",
1173
- // "cOid":"1041588152132243456",
1174
- // "cTime":"1684059887917",
1175
- // "eps":"api",
1176
- // "hM":"double_hold",
1177
- // "id":"1041588152132243457",
1178
- // "instId":"LTCUSDT_UMCBL",
1179
- // "key":"1041588152132243457",
1180
- // "ordPx":"55.000000000",
1181
- // "ordType":"limit",
1182
- // "planType":"pl",
1183
- // "posSide":"long",
1184
- // "side":"buy",
1185
- // "state":"not_trigger",
1186
- // "sz":"0.100000000",
1187
- // "tS":"open_long",
1188
- // "tgtCcy":"USDT",
1189
- // "triggerPx":"55.000000000",
1190
- // "triggerPxType":"mark",
1191
- // "triggerTime":"1684059887917",
1192
- // "userId":"3704614084",
1193
- // "version":1041588152090300400
1194
- // }
1139
+ // {
1140
+ // "accBaseVolume": "0",
1141
+ // "cTime": "1701920553759",
1142
+ // "clientOid": "1116501214318198793",
1143
+ // "enterPointSource": "WEB",
1144
+ // "feeDetail": [{
1145
+ // "feeCoin": "USDT",
1146
+ // "fee": "-0.162003"
1147
+ // }],
1148
+ // "force": "gtc",
1149
+ // "instId": "BTCUSDT",
1150
+ // "leverage": "20",
1151
+ // "marginCoin": "USDT",
1152
+ // "marginMode": "isolated",
1153
+ // "notionalUsd": "105",
1154
+ // "orderId": "1116501214293032964",
1155
+ // "orderType": "limit",
1156
+ // "posMode": "hedge_mode",
1157
+ // "posSide": "long",
1158
+ // "price": "35000",
1159
+ // "reduceOnly": "no",
1160
+ // "side": "buy",
1161
+ // "size": "0.003",
1162
+ // "status": "canceled",
1163
+ // "tradeSide": "open",
1164
+ // "uTime": "1701920595866"
1165
+ // }
1166
+ //
1167
+ // trigger
1168
+ //
1169
+ // {
1170
+ // "instId": "BTCUSDT",
1171
+ // "orderId": "1116508960750899201",
1172
+ // "clientOid": "1116508960750899200",
1173
+ // "triggerPrice": "35000.000000000",
1174
+ // "triggerType": "mark_price",
1175
+ // "triggerTime": "1701922464373",
1176
+ // "planType": "pl",
1177
+ // "price": "35000.000000000",
1178
+ // "size": "0.001000000",
1179
+ // "actualSize": "0.000000000",
1180
+ // "orderType": "limit",
1181
+ // "side": "buy",
1182
+ // "tradeSide": "open",
1183
+ // "posSide": "long",
1184
+ // "marginCoin": "USDT",
1185
+ // "status": "cancelled",
1186
+ // "posMode": "hedge_mode",
1187
+ // "enterPointSource": "api",
1188
+ // "stopSurplusTriggerType": "fill_price",
1189
+ // "stopLossTriggerType": "fill_price",
1190
+ // "cTime": "1701922400653",
1191
+ // "uTime": "1701922464373"
1192
+ // }
1193
+ //
1194
+ // isolated and cross margin
1195
+ //
1196
+ // {
1197
+ // "enterPointSource": "web",
1198
+ // "force": "gtc",
1199
+ // "orderType": "limit",
1200
+ // "price": "35000.000000000",
1201
+ // "quoteSize": "10.500000000",
1202
+ // "side": "buy",
1203
+ // "status": "live",
1204
+ // "baseSize": "0.000300000",
1205
+ // "cTime": "1701923982427",
1206
+ // "clientOid": "4902047879864dc980c4840e9906db4e",
1207
+ // "fillPrice": "0.000000000",
1208
+ // "baseVolume": "0.000000000",
1209
+ // "fillTotalAmount": "0.000000000",
1210
+ // "loanType": "auto-loan-and-repay",
1211
+ // "orderId": "1116515595178356737"
1212
+ // }
1195
1213
  //
1196
1214
  const marketId = this.safeString(order, 'instId');
1197
1215
  market = this.safeMarket(marketId, market);
1198
- const id = this.safeString2(order, 'ordId', 'id');
1199
- const clientOrderId = this.safeString2(order, 'clOrdId', 'cOid');
1200
- const price = this.safeString2(order, 'px', 'actualPx');
1201
- const filled = this.safeString(order, 'fillSz');
1202
- const amount = this.safeString(order, 'sz');
1203
- const cost = this.safeString2(order, 'notional', 'notionalUsd');
1204
- const average = this.omitZero(this.safeString(order, 'avgPx'));
1205
- const type = this.safeString(order, 'ordType');
1206
1216
  const timestamp = this.safeInteger(order, 'cTime');
1207
1217
  const symbol = market['symbol'];
1208
- let side = this.safeString2(order, 'side', 'posSide');
1209
- if ((side === 'open_long') || (side === 'close_short')) {
1210
- side = 'buy';
1211
- }
1212
- else if ((side === 'close_long') || (side === 'open_short')) {
1213
- side = 'sell';
1214
- }
1215
- const rawStatus = this.safeString2(order, 'status', 'state');
1216
- const timeInForce = this.safeString(order, 'force');
1217
- const status = this.parseWsOrderStatus(rawStatus);
1218
- const orderFee = this.safeValue(order, 'orderFee', []);
1218
+ const rawStatus = this.safeString(order, 'status');
1219
+ const orderFee = this.safeValue(order, 'feeDetail', []);
1219
1220
  const fee = this.safeValue(orderFee, 0);
1220
1221
  const feeAmount = this.safeString(fee, 'fee');
1221
1222
  let feeObject = undefined;
1222
1223
  if (feeAmount !== undefined) {
1223
- const feeCurrency = this.safeString(fee, 'feeCcy');
1224
+ const feeCurrency = this.safeString(fee, 'feeCoin');
1224
1225
  feeObject = {
1225
1226
  'cost': Precise["default"].stringAbs(feeAmount),
1226
1227
  'currency': this.safeCurrencyCode(feeCurrency),
1227
1228
  };
1228
1229
  }
1229
- const stopPrice = this.safeString(order, 'triggerPx');
1230
+ const triggerPrice = this.safeNumber(order, 'triggerPrice');
1230
1231
  return this.safeOrder({
1231
1232
  'info': order,
1232
1233
  'symbol': symbol,
1233
- 'id': id,
1234
- 'clientOrderId': clientOrderId,
1234
+ 'id': this.safeString(order, 'orderId'),
1235
+ 'clientOrderId': this.safeString(order, 'clientOid'),
1235
1236
  'timestamp': timestamp,
1236
1237
  'datetime': this.iso8601(timestamp),
1237
- 'lastTradeTimestamp': undefined,
1238
- 'type': type,
1239
- 'timeInForce': timeInForce,
1238
+ 'lastTradeTimestamp': this.safeInteger(order, 'uTime'),
1239
+ 'type': this.safeString(order, 'orderType'),
1240
+ 'timeInForce': this.safeStringUpper(order, 'force'),
1240
1241
  'postOnly': undefined,
1241
- 'side': side,
1242
- 'price': price,
1243
- 'stopPrice': stopPrice,
1244
- 'triggerPrice': stopPrice,
1245
- 'amount': amount,
1246
- 'cost': cost,
1247
- 'average': average,
1248
- 'filled': filled,
1242
+ 'side': this.safeString(order, 'side'),
1243
+ 'price': this.safeString(order, 'price'),
1244
+ 'stopPrice': triggerPrice,
1245
+ 'triggerPrice': triggerPrice,
1246
+ 'amount': this.safeString2(order, 'size', 'baseSize'),
1247
+ 'cost': this.safeStringN(order, ['notional', 'notionalUsd', 'quoteSize']),
1248
+ 'average': this.omitZero(this.safeString2(order, 'priceAvg', 'fillPrice')),
1249
+ 'filled': this.safeString2(order, 'accBaseVolume', 'baseVolume'),
1249
1250
  'remaining': undefined,
1250
- 'status': status,
1251
+ 'status': this.parseWsOrderStatus(rawStatus),
1251
1252
  'fee': feeObject,
1252
1253
  'trades': undefined,
1253
1254
  }, market);
1254
1255
  }
1255
1256
  parseWsOrderStatus(status) {
1256
1257
  const statuses = {
1257
- 'new': 'open',
1258
- 'partial-fill': 'open',
1259
- 'full-fill': 'closed',
1258
+ 'live': 'open',
1259
+ 'partially_filled': 'open',
1260
1260
  'filled': 'closed',
1261
1261
  'cancelled': 'canceled',
1262
1262
  'not_trigger': 'open',
@@ -1268,6 +1268,7 @@ class bitget extends bitget$1 {
1268
1268
  * @method
1269
1269
  * @name bitget#watchMyTrades
1270
1270
  * @description watches trades made by the user
1271
+ * @see https://www.bitget.com/api-doc/contract/websocket/private/Order-Channel
1271
1272
  * @param {str} symbol unified market symbol
1272
1273
  * @param {int} [since] the earliest time in ms to fetch trades for
1273
1274
  * @param {int} [limit] the maximum number of trades structures to retrieve
@@ -1289,10 +1290,11 @@ class bitget extends bitget$1 {
1289
1290
  if (type === 'spot') {
1290
1291
  throw new errors.NotSupported(this.id + ' watchMyTrades is not supported for ' + type + ' markets.');
1291
1292
  }
1292
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
1293
+ let instType = undefined;
1294
+ [instType, params] = this.getInstType(market, params);
1293
1295
  const subscriptionHash = 'order:trades';
1294
1296
  const args = {
1295
- 'instType': (!sandboxMode) ? 'umcbl' : 'sumcbl',
1297
+ 'instType': instType,
1296
1298
  'channel': 'orders',
1297
1299
  'instId': 'default',
1298
1300
  };
@@ -1306,36 +1308,33 @@ class bitget extends bitget$1 {
1306
1308
  //
1307
1309
  // order and trade mixin (contract)
1308
1310
  //
1309
- // {
1310
- // "accFillSz": "0.1",
1311
- // "avgPx": "52.81",
1312
- // "cTime": 1656511777208,
1313
- // "clOrdId": "926043001195237376",
1314
- // "execType": "T",
1315
- // "fillFee": "-0.0031686",
1316
- // "fillFeeCcy": "USDT",
1317
- // "fillNotionalUsd": "5.281",
1318
- // "fillPx": "52.81",
1319
- // "fillSz": "0.1",
1320
- // "fillTime": "1656511777266",
1321
- // "force": "normal",
1322
- // "instId": "LTCUSDT_UMCBL",
1323
- // "lever": "1",
1324
- // "notionalUsd": "5.281",
1325
- // "ordId": "926043001132322816",
1326
- // "ordType": "market",
1327
- // "orderFee": [Array],
1328
- // "pnl": "0.004",
1329
- // "posSide": "long",
1330
- // "px": "0",
1331
- // "side": "sell",
1332
- // "status": "full-fill",
1333
- // "sz": "0.1",
1334
- // "tdMode": "cross",
1335
- // "tgtCcy": "USDT",
1336
- // "tradeId": "926043001438552105",
1337
- // "uTime": 1656511777266
1338
- // }
1311
+ // {
1312
+ // "accBaseVolume": "0",
1313
+ // "cTime": "1701920553759",
1314
+ // "clientOid": "1116501214318198793",
1315
+ // "enterPointSource": "WEB",
1316
+ // "feeDetail": [{
1317
+ // "feeCoin": "USDT",
1318
+ // "fee": "-0.162003"
1319
+ // }],
1320
+ // "force": "gtc",
1321
+ // "instId": "BTCUSDT",
1322
+ // "leverage": "20",
1323
+ // "marginCoin": "USDT",
1324
+ // "marginMode": "isolated",
1325
+ // "notionalUsd": "105",
1326
+ // "orderId": "1116501214293032964",
1327
+ // "orderType": "limit",
1328
+ // "posMode": "hedge_mode",
1329
+ // "posSide": "long",
1330
+ // "price": "35000",
1331
+ // "reduceOnly": "no",
1332
+ // "side": "buy",
1333
+ // "size": "0.003",
1334
+ // "status": "canceled",
1335
+ // "tradeSide": "open",
1336
+ // "uTime": "1701920595866"
1337
+ // }
1339
1338
  //
1340
1339
  if (this.myTrades === undefined) {
1341
1340
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
@@ -1354,67 +1353,62 @@ class bitget extends bitget$1 {
1354
1353
  //
1355
1354
  // order and trade mixin (contract)
1356
1355
  //
1357
- // {
1358
- // "accFillSz": "0.1",
1359
- // "avgPx": "52.81",
1360
- // "cTime": 1656511777208,
1361
- // "clOrdId": "926043001195237376",
1362
- // "execType": "T",
1363
- // "fillFee": "-0.0031686",
1364
- // "fillFeeCcy": "USDT",
1365
- // "fillNotionalUsd": "5.281",
1366
- // "fillPx": "52.81",
1367
- // "fillSz": "0.1",
1368
- // "fillTime": "1656511777266",
1369
- // "force": "normal",
1370
- // "instId": "LTCUSDT_UMCBL",
1371
- // "lever": "1",
1372
- // "notionalUsd": "5.281",
1373
- // "ordId": "926043001132322816",
1374
- // "ordType": "market",
1375
- // "orderFee": [Array],
1376
- // "pnl": "0.004",
1377
- // "posSide": "long",
1378
- // "px": "0",
1379
- // "side": "sell",
1380
- // "status": "full-fill",
1381
- // "sz": "0.1",
1382
- // "tdMode": "cross",
1383
- // "tgtCcy": "USDT",
1384
- // "tradeId": "926043001438552105",
1385
- // "uTime": 1656511777266
1386
- // }
1356
+ // {
1357
+ // "accBaseVolume": "0",
1358
+ // "cTime": "1701920553759",
1359
+ // "clientOid": "1116501214318198793",
1360
+ // "enterPointSource": "WEB",
1361
+ // "feeDetail": [{
1362
+ // "feeCoin": "USDT",
1363
+ // "fee": "-0.162003"
1364
+ // }],
1365
+ // "force": "gtc",
1366
+ // "instId": "BTCUSDT",
1367
+ // "leverage": "20",
1368
+ // "marginCoin": "USDT",
1369
+ // "marginMode": "isolated",
1370
+ // "notionalUsd": "105",
1371
+ // "orderId": "1116501214293032964",
1372
+ // "orderType": "limit",
1373
+ // "posMode": "hedge_mode",
1374
+ // "posSide": "long",
1375
+ // "price": "35000",
1376
+ // "reduceOnly": "no",
1377
+ // "side": "buy",
1378
+ // "size": "0.003",
1379
+ // "status": "canceled",
1380
+ // "tradeSide": "open",
1381
+ // "uTime": "1701920595866"
1382
+ // }
1387
1383
  //
1388
- const id = this.safeString(trade, 'tradeId');
1389
- const orderId = this.safeString(trade, 'ordId');
1390
1384
  const marketId = this.safeString(trade, 'instId');
1391
- market = this.safeMarket(marketId, market);
1392
- const timestamp = this.safeInteger(trade, 'fillTime');
1393
- const side = this.safeString(trade, 'side');
1394
- const price = this.safeString(trade, 'fillPx');
1395
- const amount = this.safeString(trade, 'fillSz');
1396
- const type = this.safeString(trade, 'ordType');
1397
- const cost = this.safeString(trade, 'notional');
1398
- const feeCurrency = this.safeString(trade, 'fillFeeCcy');
1399
- const feeAmount = Precise["default"].stringAbs(this.safeString(trade, 'fillFee'));
1400
- const fee = {
1401
- 'code': this.safeCurrencyCode(feeCurrency),
1402
- 'cost': feeAmount,
1403
- };
1385
+ market = this.safeMarket(marketId, market, undefined, 'contract');
1386
+ const timestamp = this.safeInteger2(trade, 'uTime', 'cTime');
1387
+ const orderFee = this.safeValue(trade, 'feeDetail', []);
1388
+ const fee = this.safeValue(orderFee, 0);
1389
+ const feeAmount = this.safeString(fee, 'fee');
1390
+ let feeObject = undefined;
1391
+ if (feeAmount !== undefined) {
1392
+ const feeCurrency = this.safeString(fee, 'feeCoin');
1393
+ feeObject = {
1394
+ 'cost': Precise["default"].stringAbs(feeAmount),
1395
+ 'currency': this.safeCurrencyCode(feeCurrency),
1396
+ };
1397
+ }
1404
1398
  return this.safeTrade({
1405
1399
  'info': trade,
1406
- 'id': id,
1407
- 'order': orderId,
1400
+ 'id': undefined,
1401
+ 'order': this.safeString(trade, 'orderId'),
1408
1402
  'timestamp': timestamp,
1409
1403
  'datetime': this.iso8601(timestamp),
1410
1404
  'symbol': market['symbol'],
1411
- 'type': type,
1412
- 'side': side,
1405
+ 'type': this.safeString(trade, 'orderType'),
1406
+ 'side': this.safeString(trade, 'side'),
1413
1407
  'takerOrMaker': undefined,
1414
- 'price': price,
1415
- 'amount': amount,
1416
- 'cost': cost,
1417
- 'fee': fee,
1408
+ 'price': this.safeString(trade, 'price'),
1409
+ 'amount': this.safeString(trade, 'size'),
1410
+ 'cost': this.safeString(trade, 'notionalUsd'),
1411
+ 'fee': feeObject,
1418
1412
  }, market);
1419
1413
  }
1420
1414
  async watchBalance(params = {}) {
@@ -1422,68 +1416,118 @@ class bitget extends bitget$1 {
1422
1416
  * @method
1423
1417
  * @name bitget#watchBalance
1424
1418
  * @description watch balance and get the amount of funds available for trading or funds locked in orders
1419
+ * @see https://www.bitget.com/api-doc/spot/websocket/private/Account-Channel
1420
+ * @see https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
1421
+ * @see https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
1422
+ * @see https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
1425
1423
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1426
1424
  * @param {str} [params.type] spot or contract if not provided this.options['defaultType'] is used
1425
+ * @param {string} [params.instType] one of 'SPOT', 'MARGIN', 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
1426
+ * @param {string} [params.marginMode] 'isolated' or 'cross' for watching spot margin balances
1427
1427
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1428
1428
  */
1429
1429
  let type = undefined;
1430
- [type, params] = this.handleMarketTypeAndParams('watchOrders', undefined, params);
1431
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
1432
- let instType = 'spbl';
1433
- if (type === 'swap') {
1434
- instType = 'UMCBL';
1435
- if (sandboxMode) {
1436
- instType = 'S' + instType;
1430
+ [type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
1431
+ let marginMode = undefined;
1432
+ [marginMode, params] = this.handleMarginModeAndParams('watchBalance', params);
1433
+ let instType = undefined;
1434
+ let channel = 'account';
1435
+ if ((type === 'swap') || (type === 'future')) {
1436
+ instType = 'USDT-FUTURES';
1437
+ }
1438
+ else if (marginMode !== undefined) {
1439
+ instType = 'MARGIN';
1440
+ if (marginMode === 'isolated') {
1441
+ channel = 'account-isolated';
1442
+ }
1443
+ else {
1444
+ channel = 'account-crossed';
1437
1445
  }
1438
1446
  }
1447
+ else {
1448
+ instType = 'SPOT';
1449
+ }
1450
+ [instType, params] = this.handleOptionAndParams(params, 'watchBalance', 'instType', instType);
1439
1451
  const args = {
1440
1452
  'instType': instType,
1441
- 'channel': 'account',
1442
- 'instId': 'default',
1453
+ 'channel': channel,
1454
+ 'coin': 'default',
1443
1455
  };
1444
1456
  const messageHash = 'balance:' + instType.toLowerCase();
1445
1457
  return await this.watchPrivate(messageHash, messageHash, args, params);
1446
1458
  }
1447
1459
  handleBalance(client, message) {
1460
+ //
1448
1461
  // spot
1449
1462
  //
1450
- // {
1451
- // "action": "snapshot",
1452
- // "arg": { instType: 'spbl', channel: "account", instId: "default" },
1453
- // "data": [
1454
- // { coinId: '5', coinName: "LTC", available: "0.1060938000000000" },
1455
- // { coinId: '2', coinName: "USDT", available: "13.4498240000000000" }
1456
- // ]
1457
- // }
1463
+ // {
1464
+ // "action": "snapshot",
1465
+ // "arg": { "instType": "SPOT", "channel": "account", "coin": "default" },
1466
+ // "data": [
1467
+ // {
1468
+ // "coin": "USDT",
1469
+ // "available": "19.1430952856087",
1470
+ // "frozen": "7",
1471
+ // "locked": "0",
1472
+ // "limitAvailable": "0",
1473
+ // "uTime": "1701931970487"
1474
+ // },
1475
+ // ],
1476
+ // "ts": 1701931970487
1477
+ // }
1458
1478
  //
1459
1479
  // swap
1460
- // {
1461
- // "action": "snapshot",
1462
- // "arg": {
1463
- // "instType": "umcbl",
1464
- // "channel": "account",
1465
- // "instId": "default"
1466
- // },
1467
- // "data": [
1468
- // {
1469
- // "marginCoin": "USDT",
1470
- // "locked": "0.00000000",
1471
- // "available": "3384.58046492",
1472
- // "maxOpenPosAvailable": "3384.58046492",
1473
- // "maxTransferOut": "3384.58046492",
1474
- // "equity": "3384.58046492",
1475
- // "usdtEquity": "3384.580464925690"
1476
- // }
1477
- // ]
1478
- // }
1480
+ //
1481
+ // {
1482
+ // "action": "snapshot",
1483
+ // "arg": { "instType": "USDT-FUTURES", "channel": "account", "coin": "default" },
1484
+ // "data": [
1485
+ // {
1486
+ // "marginCoin": "USDT",
1487
+ // "frozen": "5.36581500",
1488
+ // "available": "26.14309528",
1489
+ // "maxOpenPosAvailable": "20.77728028",
1490
+ // "maxTransferOut": "20.77728028",
1491
+ // "equity": "26.14309528",
1492
+ // "usdtEquity": "26.143095285166"
1493
+ // }
1494
+ // ],
1495
+ // "ts": 1701932570822
1496
+ // }
1497
+ //
1498
+ // margin
1499
+ //
1500
+ // {
1501
+ // "action": "snapshot",
1502
+ // "arg": { "instType": "MARGIN", "channel": "account-crossed", "coin": "default" },
1503
+ // "data": [
1504
+ // {
1505
+ // "uTime": "1701933110544",
1506
+ // "id": "1096916799926710272",
1507
+ // "coin": "USDT",
1508
+ // "available": "16.24309528",
1509
+ // "borrow": "0.00000000",
1510
+ // "frozen": "9.90000000",
1511
+ // "interest": "0.00000000",
1512
+ // "coupon": "0.00000000"
1513
+ // }
1514
+ // ],
1515
+ // "ts": 1701933110544
1516
+ // }
1479
1517
  //
1480
1518
  const data = this.safeValue(message, 'data', []);
1481
1519
  for (let i = 0; i < data.length; i++) {
1482
1520
  const rawBalance = data[i];
1483
- const currencyId = this.safeString2(rawBalance, 'coinName', 'marginCoin');
1521
+ const currencyId = this.safeString2(rawBalance, 'coin', 'marginCoin');
1484
1522
  const code = this.safeCurrencyCode(currencyId);
1485
1523
  const account = (code in this.balance) ? this.balance[code] : this.account();
1486
- account['free'] = this.safeString(rawBalance, 'available');
1524
+ const borrow = this.safeString(rawBalance, 'borrow');
1525
+ if (borrow !== undefined) {
1526
+ const interest = this.safeString(rawBalance, 'interest');
1527
+ account['debt'] = Precise["default"].stringAdd(borrow, interest);
1528
+ }
1529
+ const freeQuery = ('maxTransferOut' in rawBalance) ? 'maxTransferOut' : 'available';
1530
+ account['free'] = this.safeString(rawBalance, freeQuery);
1487
1531
  account['total'] = this.safeString(rawBalance, 'equity');
1488
1532
  account['used'] = this.safeString(rawBalance, 'frozen');
1489
1533
  this.balance[code] = account;
@@ -1495,7 +1539,7 @@ class bitget extends bitget$1 {
1495
1539
  client.resolve(this.balance, messageHash);
1496
1540
  }
1497
1541
  async watchPublic(messageHash, args, params = {}) {
1498
- const url = this.urls['api']['ws'];
1542
+ const url = this.urls['api']['ws']['public'];
1499
1543
  const request = {
1500
1544
  'op': 'subscribe',
1501
1545
  'args': [args],
@@ -1503,18 +1547,18 @@ class bitget extends bitget$1 {
1503
1547
  const message = this.extend(request, params);
1504
1548
  return await this.watch(url, messageHash, message, messageHash);
1505
1549
  }
1506
- async watchPublicMultiple(messageHash, argsArray, params = {}) {
1507
- const url = this.urls['api']['ws'];
1550
+ async watchPublicMultiple(messageHashes, argsArray, params = {}) {
1551
+ const url = this.urls['api']['ws']['public'];
1508
1552
  const request = {
1509
1553
  'op': 'subscribe',
1510
1554
  'args': argsArray,
1511
1555
  };
1512
1556
  const message = this.extend(request, params);
1513
- return await this.watch(url, messageHash, message, messageHash);
1557
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
1514
1558
  }
1515
1559
  async authenticate(params = {}) {
1516
1560
  this.checkRequiredCredentials();
1517
- const url = this.urls['api']['ws'];
1561
+ const url = this.urls['api']['ws']['private'];
1518
1562
  const client = this.client(url);
1519
1563
  const messageHash = 'authenticated';
1520
1564
  const future = client.future(messageHash);
@@ -1542,7 +1586,7 @@ class bitget extends bitget$1 {
1542
1586
  }
1543
1587
  async watchPrivate(messageHash, subscriptionHash, args, params = {}) {
1544
1588
  await this.authenticate();
1545
- const url = this.urls['api']['ws'];
1589
+ const url = this.urls['api']['ws']['private'];
1546
1590
  const request = {
1547
1591
  'op': 'subscribe',
1548
1592
  'args': [args],
@@ -1593,7 +1637,7 @@ class bitget extends bitget$1 {
1593
1637
  //
1594
1638
  // {
1595
1639
  // "action": "snapshot",
1596
- // "arg": { instType: 'sp', channel: "ticker", instId: "BTCUSDT" },
1640
+ // "arg": { instType: 'SPOT', channel: "ticker", instId: "BTCUSDT" },
1597
1641
  // "data": [
1598
1642
  // {
1599
1643
  // "instId": "BTCUSDT",
@@ -1621,7 +1665,7 @@ class bitget extends bitget$1 {
1621
1665
  //
1622
1666
  // {
1623
1667
  // "event": "subscribe",
1624
- // "arg": { instType: 'spbl', channel: "account", instId: "default" }
1668
+ // "arg": { instType: 'SPOT', channel: "account", instId: "default" }
1625
1669
  // }
1626
1670
  //
1627
1671
  if (this.handleErrorMessage(client, message)) {
@@ -1677,7 +1721,7 @@ class bitget extends bitget$1 {
1677
1721
  //
1678
1722
  // {
1679
1723
  // "event": "subscribe",
1680
- // "arg": { instType: 'spbl', channel: "account", instId: "default" }
1724
+ // "arg": { instType: 'SPOT', channel: "account", instId: "default" }
1681
1725
  // }
1682
1726
  //
1683
1727
  return message;