ccxt 4.3.40 → 4.3.42
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.
- package/README.md +3 -3
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/binance.js +3 -0
- package/dist/cjs/src/bitfinex2.js +1 -1
- package/dist/cjs/src/bithumb.js +9 -1
- package/dist/cjs/src/bitmart.js +196 -100
- package/dist/cjs/src/bitstamp.js +38 -2
- package/dist/cjs/src/blockchaincom.js +11 -7
- package/dist/cjs/src/coinex.js +1 -1
- package/dist/cjs/src/coinlist.js +20 -1
- package/dist/cjs/src/coinmate.js +19 -3
- package/dist/cjs/src/coinone.js +1 -1
- package/dist/cjs/src/coinspot.js +13 -2
- package/dist/cjs/src/independentreserve.js +33 -1
- package/dist/cjs/src/indodax.js +43 -2
- package/dist/cjs/src/kraken.js +30 -3
- package/dist/cjs/src/krakenfutures.js +56 -1
- package/dist/cjs/src/kucoin.js +59 -2
- package/dist/cjs/src/okx.js +7 -0
- package/dist/cjs/src/pro/alpaca.js +5 -5
- package/dist/cjs/src/pro/ascendex.js +3 -3
- package/dist/cjs/src/pro/bingx.js +293 -47
- package/dist/cjs/src/pro/bitget.js +14 -6
- package/dist/cjs/src/pro/bitrue.js +3 -4
- package/dist/cjs/src/pro/currencycom.js +6 -5
- package/dist/cjs/src/pro/exmo.js +5 -6
- package/dist/cjs/src/pro/gemini.js +4 -3
- package/dist/cjs/src/pro/independentreserve.js +7 -7
- package/dist/cjs/src/pro/lbank.js +4 -4
- package/dist/cjs/src/pro/mexc.js +1 -1
- package/dist/cjs/src/pro/phemex.js +5 -5
- package/dist/cjs/src/pro/probit.js +4 -4
- package/dist/cjs/src/pro/upbit.js +322 -2
- package/dist/cjs/src/pro/wazirx.js +12 -12
- package/dist/cjs/src/pro/woo.js +2 -2
- package/dist/cjs/src/upbit.js +17 -9
- package/dist/cjs/src/woo.js +6 -2
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/binance.d.ts +2 -0
- package/js/src/abstract/binancecoinm.d.ts +2 -0
- package/js/src/abstract/binanceus.d.ts +2 -0
- package/js/src/abstract/binanceusdm.d.ts +2 -0
- package/js/src/abstract/okx.d.ts +7 -0
- package/js/src/binance.js +3 -0
- package/js/src/bitfinex2.js +1 -1
- package/js/src/bithumb.d.ts +2 -2
- package/js/src/bithumb.js +9 -1
- package/js/src/bitmart.js +196 -100
- package/js/src/bitstamp.d.ts +2 -2
- package/js/src/bitstamp.js +38 -2
- package/js/src/blockchaincom.d.ts +2 -8
- package/js/src/blockchaincom.js +11 -7
- package/js/src/coinex.js +1 -1
- package/js/src/coinlist.d.ts +1 -1
- package/js/src/coinlist.js +20 -1
- package/js/src/coinmate.d.ts +1 -3
- package/js/src/coinmate.js +19 -3
- package/js/src/coinone.d.ts +1 -1
- package/js/src/coinone.js +1 -1
- package/js/src/coinspot.d.ts +1 -1
- package/js/src/coinspot.js +13 -2
- package/js/src/independentreserve.d.ts +1 -1
- package/js/src/independentreserve.js +33 -1
- package/js/src/indodax.d.ts +1 -1
- package/js/src/indodax.js +43 -2
- package/js/src/kraken.d.ts +3 -3
- package/js/src/kraken.js +30 -3
- package/js/src/krakenfutures.d.ts +1 -1
- package/js/src/krakenfutures.js +56 -1
- package/js/src/kucoin.d.ts +1 -1
- package/js/src/kucoin.js +59 -2
- package/js/src/okx.js +7 -0
- package/js/src/pro/alpaca.js +5 -5
- package/js/src/pro/ascendex.js +3 -3
- package/js/src/pro/bingx.d.ts +6 -1
- package/js/src/pro/bingx.js +294 -48
- package/js/src/pro/bitget.js +14 -6
- package/js/src/pro/bitrue.js +3 -4
- package/js/src/pro/currencycom.js +6 -5
- package/js/src/pro/exmo.js +5 -6
- package/js/src/pro/gemini.js +4 -3
- package/js/src/pro/independentreserve.js +7 -7
- package/js/src/pro/lbank.js +4 -4
- package/js/src/pro/mexc.js +1 -1
- package/js/src/pro/phemex.js +5 -5
- package/js/src/pro/probit.js +4 -4
- package/js/src/pro/upbit.d.ts +13 -1
- package/js/src/pro/upbit.js +323 -3
- package/js/src/pro/wazirx.js +12 -12
- package/js/src/pro/woo.js +2 -2
- package/js/src/upbit.js +17 -9
- package/js/src/woo.d.ts +1 -1
- package/js/src/woo.js +6 -2
- package/package.json +1 -1
package/js/src/pro/bingx.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
import bingxRest from '../bingx.js';
|
|
9
|
-
import { BadRequest, NetworkError } from '../base/errors.js';
|
|
9
|
+
import { BadRequest, NetworkError, NotSupported, ArgumentsRequired } from '../base/errors.js';
|
|
10
10
|
import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
|
|
11
11
|
import { Precise } from '../base/Precise.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -17,11 +17,13 @@ export default class bingx extends bingxRest {
|
|
|
17
17
|
'ws': true,
|
|
18
18
|
'watchTrades': true,
|
|
19
19
|
'watchOrderBook': true,
|
|
20
|
+
'watchOrderBookForSymbols': true,
|
|
20
21
|
'watchOHLCV': true,
|
|
22
|
+
'watchOHLCVForSymbols': true,
|
|
21
23
|
'watchOrders': true,
|
|
22
24
|
'watchMyTrades': true,
|
|
23
25
|
'watchTicker': true,
|
|
24
|
-
'watchTickers':
|
|
26
|
+
'watchTickers': true,
|
|
25
27
|
'watchBalance': true,
|
|
26
28
|
},
|
|
27
29
|
'urls': {
|
|
@@ -69,6 +71,14 @@ export default class bingx extends bingxRest {
|
|
|
69
71
|
'fetchBalanceSnapshot': true,
|
|
70
72
|
'awaitBalanceSnapshot': false, // whether to wait for the balance snapshot before providing updates
|
|
71
73
|
},
|
|
74
|
+
'watchOrderBook': {
|
|
75
|
+
'depth': 100,
|
|
76
|
+
'interval': 500, // 100, 200, 500, 1000
|
|
77
|
+
},
|
|
78
|
+
'watchOrderBookForSymbols': {
|
|
79
|
+
'depth': 100,
|
|
80
|
+
'interval': 500, // 100, 200, 500, 1000
|
|
81
|
+
},
|
|
72
82
|
},
|
|
73
83
|
'streaming': {
|
|
74
84
|
'keepAlive': 1800000, // 30 minutes
|
|
@@ -92,16 +102,17 @@ export default class bingx extends bingxRest {
|
|
|
92
102
|
if (url === undefined) {
|
|
93
103
|
throw new BadRequest(this.id + ' watchTrades is not supported for ' + marketType + ' markets.');
|
|
94
104
|
}
|
|
95
|
-
const
|
|
105
|
+
const subscriptionHash = market['id'] + '@ticker';
|
|
106
|
+
const messageHash = this.getMessageHash('ticker', market['symbol']);
|
|
96
107
|
const uuid = this.uuid();
|
|
97
108
|
const request = {
|
|
98
109
|
'id': uuid,
|
|
99
|
-
'dataType':
|
|
110
|
+
'dataType': subscriptionHash,
|
|
100
111
|
};
|
|
101
112
|
if (marketType === 'swap') {
|
|
102
113
|
request['reqType'] = 'sub';
|
|
103
114
|
}
|
|
104
|
-
return await this.watch(url, messageHash, this.extend(request, query),
|
|
115
|
+
return await this.watch(url, messageHash, this.extend(request, query), subscriptionHash);
|
|
105
116
|
}
|
|
106
117
|
handleTicker(client, message) {
|
|
107
118
|
//
|
|
@@ -167,8 +178,10 @@ export default class bingx extends bingxRest {
|
|
|
167
178
|
const symbol = market['symbol'];
|
|
168
179
|
const ticker = this.parseWsTicker(data, market);
|
|
169
180
|
this.tickers[symbol] = ticker;
|
|
170
|
-
|
|
171
|
-
|
|
181
|
+
client.resolve(ticker, this.getMessageHash('ticker', symbol));
|
|
182
|
+
if (this.safeString(message, 'dataType') === 'all@ticker') {
|
|
183
|
+
client.resolve(ticker, this.getMessageHash('ticker'));
|
|
184
|
+
}
|
|
172
185
|
}
|
|
173
186
|
parseWsTicker(message, market = undefined) {
|
|
174
187
|
//
|
|
@@ -220,6 +233,206 @@ export default class bingx extends bingxRest {
|
|
|
220
233
|
'info': message,
|
|
221
234
|
}, market);
|
|
222
235
|
}
|
|
236
|
+
async watchTickers(symbols = undefined, params = {}) {
|
|
237
|
+
/**
|
|
238
|
+
* @method
|
|
239
|
+
* @name bingx#watchTickers
|
|
240
|
+
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
241
|
+
* @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
|
|
242
|
+
* @param {string[]} symbols unified symbol of the market to watch the tickers for
|
|
243
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
244
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
245
|
+
*/
|
|
246
|
+
await this.loadMarkets();
|
|
247
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, false);
|
|
248
|
+
let firstMarket = undefined;
|
|
249
|
+
let marketType = undefined;
|
|
250
|
+
const symbolsDefined = (symbols !== undefined);
|
|
251
|
+
if (symbolsDefined) {
|
|
252
|
+
firstMarket = this.market(symbols[0]);
|
|
253
|
+
}
|
|
254
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchTickers', firstMarket, params);
|
|
255
|
+
if (marketType === 'spot') {
|
|
256
|
+
throw new NotSupported(this.id + ' watchTickers is not supported for spot markets yet');
|
|
257
|
+
}
|
|
258
|
+
const messageHashes = [];
|
|
259
|
+
const subscriptionHashes = ['all@ticker'];
|
|
260
|
+
if (symbolsDefined) {
|
|
261
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
262
|
+
const symbol = symbols[i];
|
|
263
|
+
const market = this.market(symbol);
|
|
264
|
+
messageHashes.push(this.getMessageHash('ticker', market['symbol']));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
messageHashes.push(this.getMessageHash('ticker'));
|
|
269
|
+
}
|
|
270
|
+
const url = this.safeString(this.urls['api']['ws'], marketType);
|
|
271
|
+
const uuid = this.uuid();
|
|
272
|
+
const request = {
|
|
273
|
+
'id': uuid,
|
|
274
|
+
'dataType': 'all@ticker',
|
|
275
|
+
};
|
|
276
|
+
if (marketType === 'swap') {
|
|
277
|
+
request['reqType'] = 'sub';
|
|
278
|
+
}
|
|
279
|
+
const result = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), subscriptionHashes);
|
|
280
|
+
if (this.newUpdates) {
|
|
281
|
+
const newDict = {};
|
|
282
|
+
newDict[result['symbol']] = result;
|
|
283
|
+
return newDict;
|
|
284
|
+
}
|
|
285
|
+
return this.tickers;
|
|
286
|
+
}
|
|
287
|
+
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
288
|
+
/**
|
|
289
|
+
* @method
|
|
290
|
+
* @name bingx#watchOrderBookForSymbols
|
|
291
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
292
|
+
* @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
|
|
293
|
+
* @param {string[]} symbols unified array of symbols
|
|
294
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
295
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
296
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
297
|
+
*/
|
|
298
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, false);
|
|
299
|
+
let firstMarket = undefined;
|
|
300
|
+
let marketType = undefined;
|
|
301
|
+
const symbolsDefined = (symbols !== undefined);
|
|
302
|
+
if (symbolsDefined) {
|
|
303
|
+
firstMarket = this.market(symbols[0]);
|
|
304
|
+
}
|
|
305
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchOrderBookForSymbols', firstMarket, params);
|
|
306
|
+
if (marketType === 'spot') {
|
|
307
|
+
throw new NotSupported(this.id + ' watchOrderBookForSymbols is not supported for spot markets yet');
|
|
308
|
+
}
|
|
309
|
+
limit = this.getOrderBookLimitByMarketType(marketType, limit);
|
|
310
|
+
let interval = undefined;
|
|
311
|
+
[interval, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'interval', 500);
|
|
312
|
+
this.checkRequiredArgument('watchOrderBookForSymbols', interval, 'interval', [100, 200, 500, 1000]);
|
|
313
|
+
const channelName = 'depth' + limit.toString() + '@' + interval.toString() + 'ms';
|
|
314
|
+
const subscriptionHash = 'all@' + channelName;
|
|
315
|
+
const messageHashes = [];
|
|
316
|
+
if (symbolsDefined) {
|
|
317
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
318
|
+
const symbol = symbols[i];
|
|
319
|
+
const market = this.market(symbol);
|
|
320
|
+
messageHashes.push(this.getMessageHash('orderbook', market['symbol']));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
messageHashes.push(this.getMessageHash('orderbook'));
|
|
325
|
+
}
|
|
326
|
+
const url = this.safeString(this.urls['api']['ws'], marketType);
|
|
327
|
+
const uuid = this.uuid();
|
|
328
|
+
const request = {
|
|
329
|
+
'id': uuid,
|
|
330
|
+
'dataType': subscriptionHash,
|
|
331
|
+
};
|
|
332
|
+
if (marketType === 'swap') {
|
|
333
|
+
request['reqType'] = 'sub';
|
|
334
|
+
}
|
|
335
|
+
const subscriptionArgs = {
|
|
336
|
+
'symbols': symbols,
|
|
337
|
+
'limit': limit,
|
|
338
|
+
'interval': interval,
|
|
339
|
+
'params': params,
|
|
340
|
+
};
|
|
341
|
+
const orderbook = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), [subscriptionHash], subscriptionArgs);
|
|
342
|
+
return orderbook.limit();
|
|
343
|
+
}
|
|
344
|
+
async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
|
|
345
|
+
/**
|
|
346
|
+
* @method
|
|
347
|
+
* @name bingx#watchOHLCVForSymbols
|
|
348
|
+
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
349
|
+
* @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
|
350
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
351
|
+
* @param {int} [limit] the maximum amount of candles to fetch
|
|
352
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
353
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
354
|
+
*/
|
|
355
|
+
const symbolsLength = symbolsAndTimeframes.length;
|
|
356
|
+
if (symbolsLength !== 0 && !Array.isArray(symbolsAndTimeframes[0])) {
|
|
357
|
+
throw new ArgumentsRequired(this.id + " watchOHLCVForSymbols() requires a an array like [['BTC/USDT:USDT', '1m'], ['LTC/USDT:USDT', '5m']]");
|
|
358
|
+
}
|
|
359
|
+
await this.loadMarkets();
|
|
360
|
+
const messageHashes = [];
|
|
361
|
+
let marketType = undefined;
|
|
362
|
+
let chosenTimeframe = undefined;
|
|
363
|
+
if (symbolsLength !== 0) {
|
|
364
|
+
let symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
|
|
365
|
+
symbols = this.marketSymbols(symbols, undefined, true, true, false);
|
|
366
|
+
const firstMarket = this.market(symbols[0]);
|
|
367
|
+
[marketType, params] = this.handleMarketTypeAndParams('watchOrderBookForSymbols', firstMarket, params);
|
|
368
|
+
if (marketType === 'spot') {
|
|
369
|
+
throw new NotSupported(this.id + ' watchOrderBookForSymbols is not supported for spot markets yet');
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const marketOptions = this.safeDict(this.options, marketType);
|
|
373
|
+
const timeframes = this.safeDict(marketOptions, 'timeframes', {});
|
|
374
|
+
for (let i = 0; i < symbolsAndTimeframes.length; i++) {
|
|
375
|
+
const symbolAndTimeframe = symbolsAndTimeframes[i];
|
|
376
|
+
const sym = symbolAndTimeframe[0];
|
|
377
|
+
const tf = symbolAndTimeframe[1];
|
|
378
|
+
const market = this.market(sym);
|
|
379
|
+
const rawTimeframe = this.safeString(timeframes, tf, tf);
|
|
380
|
+
if (chosenTimeframe === undefined) {
|
|
381
|
+
chosenTimeframe = rawTimeframe;
|
|
382
|
+
}
|
|
383
|
+
else if (chosenTimeframe !== rawTimeframe) {
|
|
384
|
+
throw new BadRequest(this.id + ' watchOHLCVForSymbols requires all timeframes to be the same');
|
|
385
|
+
}
|
|
386
|
+
messageHashes.push(this.getMessageHash('ohlcv', market['symbol'], chosenTimeframe));
|
|
387
|
+
}
|
|
388
|
+
const subscriptionHash = 'all@kline_' + chosenTimeframe;
|
|
389
|
+
const url = this.safeString(this.urls['api']['ws'], marketType);
|
|
390
|
+
const uuid = this.uuid();
|
|
391
|
+
const request = {
|
|
392
|
+
'id': uuid,
|
|
393
|
+
'dataType': subscriptionHash,
|
|
394
|
+
};
|
|
395
|
+
if (marketType === 'swap') {
|
|
396
|
+
request['reqType'] = 'sub';
|
|
397
|
+
}
|
|
398
|
+
const subscriptionArgs = {
|
|
399
|
+
'limit': limit,
|
|
400
|
+
'params': params,
|
|
401
|
+
};
|
|
402
|
+
const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, request, [subscriptionHash], subscriptionArgs);
|
|
403
|
+
if (this.newUpdates) {
|
|
404
|
+
limit = candles.getLimit(symbol, limit);
|
|
405
|
+
}
|
|
406
|
+
const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
|
|
407
|
+
return this.createOHLCVObject(symbol, timeframe, filtered);
|
|
408
|
+
}
|
|
409
|
+
getOrderBookLimitByMarketType(marketType, limit = undefined) {
|
|
410
|
+
if (limit === undefined) {
|
|
411
|
+
limit = 100;
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
if (marketType === 'swap' || marketType === 'future') {
|
|
415
|
+
limit = this.findNearestCeiling([5, 10, 20, 50, 100], limit);
|
|
416
|
+
}
|
|
417
|
+
else if (marketType === 'spot') {
|
|
418
|
+
limit = this.findNearestCeiling([20, 100], limit);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return limit;
|
|
422
|
+
}
|
|
423
|
+
getMessageHash(unifiedChannel, symbol = undefined, extra = undefined) {
|
|
424
|
+
let hash = unifiedChannel;
|
|
425
|
+
if (symbol !== undefined) {
|
|
426
|
+
hash += '::' + symbol;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
hash += 's'; // tickers, orderbooks, ohlcvs ...
|
|
430
|
+
}
|
|
431
|
+
if (extra !== undefined) {
|
|
432
|
+
hash += '::' + extra;
|
|
433
|
+
}
|
|
434
|
+
return hash;
|
|
435
|
+
}
|
|
223
436
|
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
224
437
|
/**
|
|
225
438
|
* @method
|
|
@@ -355,35 +568,34 @@ export default class bingx extends bingxRest {
|
|
|
355
568
|
await this.loadMarkets();
|
|
356
569
|
const market = this.market(symbol);
|
|
357
570
|
const [marketType, query] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
if (marketType === 'swap') {
|
|
363
|
-
if ((limit !== 5) && (limit !== 10) && (limit !== 20) && (limit !== 50) && (limit !== 100)) {
|
|
364
|
-
throw new BadRequest(this.id + ' watchOrderBook() (swap) only supports limit 5, 10, 20, 50, and 100');
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
else if (marketType === 'spot') {
|
|
368
|
-
if ((limit !== 20) && (limit !== 100)) {
|
|
369
|
-
throw new BadRequest(this.id + ' watchOrderBook() (spot) only supports limit 20, and 100');
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
571
|
+
limit = this.getOrderBookLimitByMarketType(marketType, limit);
|
|
572
|
+
let channelName = 'depth' + limit.toString();
|
|
373
573
|
const url = this.safeValue(this.urls['api']['ws'], marketType);
|
|
374
574
|
if (url === undefined) {
|
|
375
575
|
throw new BadRequest(this.id + ' watchOrderBook is not supported for ' + marketType + ' markets.');
|
|
376
576
|
}
|
|
377
|
-
|
|
577
|
+
let interval = undefined;
|
|
578
|
+
if (marketType !== 'spot') {
|
|
579
|
+
[interval, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'interval', 500);
|
|
580
|
+
this.checkRequiredArgument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000]);
|
|
581
|
+
channelName = channelName + '@' + interval.toString() + 'ms';
|
|
582
|
+
}
|
|
583
|
+
const subscriptionHash = market['id'] + '@' + channelName;
|
|
584
|
+
const messageHash = this.getMessageHash('orderbook', market['symbol']);
|
|
378
585
|
const uuid = this.uuid();
|
|
379
586
|
const request = {
|
|
380
587
|
'id': uuid,
|
|
381
|
-
'dataType':
|
|
588
|
+
'dataType': subscriptionHash,
|
|
382
589
|
};
|
|
383
590
|
if (marketType === 'swap') {
|
|
384
591
|
request['reqType'] = 'sub';
|
|
385
592
|
}
|
|
386
|
-
const
|
|
593
|
+
const subscriptionArgs = {
|
|
594
|
+
'limit': limit,
|
|
595
|
+
'interval': interval,
|
|
596
|
+
'params': params,
|
|
597
|
+
};
|
|
598
|
+
const orderbook = await this.watch(url, messageHash, this.deepExtend(request, query), subscriptionHash, subscriptionArgs);
|
|
387
599
|
return orderbook.limit();
|
|
388
600
|
}
|
|
389
601
|
handleDelta(bookside, delta) {
|
|
@@ -418,7 +630,7 @@ export default class bingx extends bingxRest {
|
|
|
418
630
|
//
|
|
419
631
|
// {
|
|
420
632
|
// "code": 0,
|
|
421
|
-
// "dataType": "BTC-USDT@depth20",
|
|
633
|
+
// "dataType": "BTC-USDT@depth20@100ms", //or "all@depth20@100ms"
|
|
422
634
|
// "data": {
|
|
423
635
|
// "bids": [
|
|
424
636
|
// [ '28852.9', "34.2621" ],
|
|
@@ -427,25 +639,39 @@ export default class bingx extends bingxRest {
|
|
|
427
639
|
// "asks": [
|
|
428
640
|
// [ '28864.9', "23.4079" ],
|
|
429
641
|
// ...
|
|
430
|
-
// ]
|
|
642
|
+
// ],
|
|
643
|
+
// "symbol": "BTC-USDT", // this key exists only in "all" subscription
|
|
431
644
|
// }
|
|
432
645
|
// }
|
|
433
646
|
//
|
|
434
|
-
const data = this.
|
|
435
|
-
const
|
|
436
|
-
const
|
|
647
|
+
const data = this.safeDict(message, 'data', {});
|
|
648
|
+
const dataType = this.safeString(message, 'dataType');
|
|
649
|
+
const parts = dataType.split('@');
|
|
650
|
+
const firstPart = parts[0];
|
|
651
|
+
const isAllEndpoint = (firstPart === 'all');
|
|
652
|
+
const marketId = this.safeString(data, 'symbol', firstPart);
|
|
437
653
|
const isSwap = client.url.indexOf('swap') >= 0;
|
|
438
654
|
const marketType = isSwap ? 'swap' : 'spot';
|
|
439
655
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
440
656
|
const symbol = market['symbol'];
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
657
|
+
if (this.safeValue(this.orderbooks, symbol) === undefined) {
|
|
658
|
+
// const limit = [ 5, 10, 20, 50, 100 ]
|
|
659
|
+
const subscriptionHash = dataType;
|
|
660
|
+
const subscription = client.subscriptions[subscriptionHash];
|
|
661
|
+
const limit = this.safeInteger(subscription, 'limit');
|
|
662
|
+
this.orderbooks[symbol] = this.orderBook({}, limit);
|
|
444
663
|
}
|
|
664
|
+
const orderbook = this.orderbooks[symbol];
|
|
445
665
|
const snapshot = this.parseOrderBook(data, symbol, undefined, 'bids', 'asks', 0, 1);
|
|
446
666
|
orderbook.reset(snapshot);
|
|
447
667
|
this.orderbooks[symbol] = orderbook;
|
|
668
|
+
const messageHash = this.getMessageHash('orderbook', symbol);
|
|
448
669
|
client.resolve(orderbook, messageHash);
|
|
670
|
+
// resolve for "all"
|
|
671
|
+
if (isAllEndpoint) {
|
|
672
|
+
const messageHashForAll = this.getMessageHash('orderbook');
|
|
673
|
+
client.resolve(orderbook, messageHashForAll);
|
|
674
|
+
}
|
|
449
675
|
}
|
|
450
676
|
parseWsOHLCV(ohlcv, market = undefined) {
|
|
451
677
|
//
|
|
@@ -516,34 +742,48 @@ export default class bingx extends bingxRest {
|
|
|
516
742
|
// ]
|
|
517
743
|
// }
|
|
518
744
|
//
|
|
519
|
-
const data = this.
|
|
745
|
+
const data = this.safeList(message, 'data', []);
|
|
520
746
|
let candles = undefined;
|
|
521
747
|
if (Array.isArray(data)) {
|
|
522
748
|
candles = data;
|
|
523
749
|
}
|
|
524
750
|
else {
|
|
525
|
-
candles = [this.
|
|
751
|
+
candles = [this.safeList(data, 'K', [])];
|
|
526
752
|
}
|
|
527
|
-
const
|
|
528
|
-
const timeframeId = messageHash.split('_')[1];
|
|
529
|
-
const marketId = messageHash.split('@')[0];
|
|
753
|
+
const dataType = this.safeString(message, 'dataType');
|
|
530
754
|
const isSwap = client.url.indexOf('swap') >= 0;
|
|
755
|
+
const parts = dataType.split('@');
|
|
756
|
+
const firstPart = parts[0];
|
|
757
|
+
const isAllEndpoint = (firstPart === 'all');
|
|
758
|
+
const marketId = this.safeString(message, 's', firstPart);
|
|
531
759
|
const marketType = isSwap ? 'swap' : 'spot';
|
|
532
760
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
533
761
|
const symbol = market['symbol'];
|
|
534
762
|
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
763
|
+
const rawTimeframe = dataType.split('_')[1];
|
|
764
|
+
const marketOptions = this.safeDict(this.options, marketType);
|
|
765
|
+
const timeframes = this.safeDict(marketOptions, 'timeframes', {});
|
|
766
|
+
const unifiedTimeframe = this.findTimeframe(rawTimeframe, timeframes);
|
|
767
|
+
if (this.safeValue(this.ohlcvs[symbol], rawTimeframe) === undefined) {
|
|
768
|
+
const subscriptionHash = dataType;
|
|
769
|
+
const subscription = client.subscriptions[subscriptionHash];
|
|
770
|
+
const limit = this.safeInteger(subscription, 'limit');
|
|
771
|
+
this.ohlcvs[symbol][unifiedTimeframe] = new ArrayCacheByTimestamp(limit);
|
|
540
772
|
}
|
|
773
|
+
const stored = this.ohlcvs[symbol][unifiedTimeframe];
|
|
541
774
|
for (let i = 0; i < candles.length; i++) {
|
|
542
775
|
const candle = candles[i];
|
|
543
776
|
const parsed = this.parseWsOHLCV(candle, market);
|
|
544
777
|
stored.append(parsed);
|
|
545
778
|
}
|
|
546
|
-
|
|
779
|
+
const resolveData = [symbol, unifiedTimeframe, stored];
|
|
780
|
+
const messageHash = this.getMessageHash('ohlcv', symbol, unifiedTimeframe);
|
|
781
|
+
client.resolve(resolveData, messageHash);
|
|
782
|
+
// resolve for "all"
|
|
783
|
+
if (isAllEndpoint) {
|
|
784
|
+
const messageHashForAll = this.getMessageHash('ohlcv', undefined, unifiedTimeframe);
|
|
785
|
+
client.resolve(resolveData, messageHashForAll);
|
|
786
|
+
}
|
|
547
787
|
}
|
|
548
788
|
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
549
789
|
/**
|
|
@@ -568,17 +808,23 @@ export default class bingx extends bingxRest {
|
|
|
568
808
|
}
|
|
569
809
|
const options = this.safeValue(this.options, marketType, {});
|
|
570
810
|
const timeframes = this.safeValue(options, 'timeframes', {});
|
|
571
|
-
const
|
|
572
|
-
const messageHash = market['
|
|
811
|
+
const rawTimeframe = this.safeString(timeframes, timeframe, timeframe);
|
|
812
|
+
const messageHash = this.getMessageHash('ohlcv', market['symbol'], timeframe);
|
|
813
|
+
const subscriptionHash = market['id'] + '@kline_' + rawTimeframe;
|
|
573
814
|
const uuid = this.uuid();
|
|
574
815
|
const request = {
|
|
575
816
|
'id': uuid,
|
|
576
|
-
'dataType':
|
|
817
|
+
'dataType': subscriptionHash,
|
|
577
818
|
};
|
|
578
819
|
if (marketType === 'swap') {
|
|
579
820
|
request['reqType'] = 'sub';
|
|
580
821
|
}
|
|
581
|
-
const
|
|
822
|
+
const subscriptionArgs = {
|
|
823
|
+
'limit': limit,
|
|
824
|
+
'params': params,
|
|
825
|
+
};
|
|
826
|
+
const result = await this.watch(url, messageHash, this.extend(request, query), subscriptionHash, subscriptionArgs);
|
|
827
|
+
const ohlcv = result[2];
|
|
582
828
|
if (this.newUpdates) {
|
|
583
829
|
limit = ohlcv.getLimit(symbol, limit);
|
|
584
830
|
}
|
package/js/src/pro/bitget.js
CHANGED
|
@@ -992,7 +992,7 @@ export default class bitget extends bitgetRest {
|
|
|
992
992
|
[type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
|
|
993
993
|
let subType = undefined;
|
|
994
994
|
[subType, params] = this.handleSubTypeAndParams('watchOrders', market, params, 'linear');
|
|
995
|
-
if ((type === 'spot') && (symbol === undefined)) {
|
|
995
|
+
if ((type === 'spot' || type === 'margin') && (symbol === undefined)) {
|
|
996
996
|
throw new ArgumentsRequired(this.id + ' watchOrders requires a symbol argument for ' + type + ' markets.');
|
|
997
997
|
}
|
|
998
998
|
if ((productType === undefined) && (type !== 'spot') && (symbol === undefined)) {
|
|
@@ -1015,12 +1015,13 @@ export default class bitget extends bitgetRest {
|
|
|
1015
1015
|
if (isTrigger) {
|
|
1016
1016
|
subscriptionHash = subscriptionHash + ':stop'; // we don't want to re-use the same subscription hash for stop orders
|
|
1017
1017
|
}
|
|
1018
|
-
const instId = (type === 'spot') ? marketId : 'default'; // different from other streams here the 'rest' id is required for spot markets, contract markets require default here
|
|
1018
|
+
const instId = (type === 'spot' || type === 'margin') ? marketId : 'default'; // different from other streams here the 'rest' id is required for spot markets, contract markets require default here
|
|
1019
1019
|
let channel = isTrigger ? 'orders-algo' : 'orders';
|
|
1020
1020
|
let marginMode = undefined;
|
|
1021
1021
|
[marginMode, params] = this.handleMarginModeAndParams('watchOrders', params);
|
|
1022
1022
|
if (marginMode !== undefined) {
|
|
1023
1023
|
instType = 'MARGIN';
|
|
1024
|
+
messageHash = messageHash + ':' + marginMode;
|
|
1024
1025
|
if (marginMode === 'isolated') {
|
|
1025
1026
|
channel = 'orders-isolated';
|
|
1026
1027
|
}
|
|
@@ -1075,9 +1076,10 @@ export default class bitget extends bitgetRest {
|
|
|
1075
1076
|
// "ts": 1701923982497
|
|
1076
1077
|
// }
|
|
1077
1078
|
//
|
|
1078
|
-
const arg = this.
|
|
1079
|
+
const arg = this.safeDict(message, 'arg', {});
|
|
1079
1080
|
const channel = this.safeString(arg, 'channel');
|
|
1080
1081
|
const instType = this.safeString(arg, 'instType');
|
|
1082
|
+
const argInstId = this.safeString(arg, 'instId');
|
|
1081
1083
|
let marketType = undefined;
|
|
1082
1084
|
if (instType === 'SPOT') {
|
|
1083
1085
|
marketType = 'spot';
|
|
@@ -1103,7 +1105,7 @@ export default class bitget extends bitgetRest {
|
|
|
1103
1105
|
const marketSymbols = {};
|
|
1104
1106
|
for (let i = 0; i < data.length; i++) {
|
|
1105
1107
|
const order = data[i];
|
|
1106
|
-
const marketId = this.safeString(order, 'instId');
|
|
1108
|
+
const marketId = this.safeString(order, 'instId', argInstId);
|
|
1107
1109
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
1108
1110
|
const parsed = this.parseWsOrder(order, market);
|
|
1109
1111
|
stored.append(parsed);
|
|
@@ -1113,7 +1115,13 @@ export default class bitget extends bitgetRest {
|
|
|
1113
1115
|
const keys = Object.keys(marketSymbols);
|
|
1114
1116
|
for (let i = 0; i < keys.length; i++) {
|
|
1115
1117
|
const symbol = keys[i];
|
|
1116
|
-
|
|
1118
|
+
let innerMessageHash = messageHash + ':' + symbol;
|
|
1119
|
+
if (channel === 'orders-crossed') {
|
|
1120
|
+
innerMessageHash = innerMessageHash + ':cross';
|
|
1121
|
+
}
|
|
1122
|
+
else if (channel === 'orders-isolated') {
|
|
1123
|
+
innerMessageHash = innerMessageHash + ':isolated';
|
|
1124
|
+
}
|
|
1117
1125
|
client.resolve(stored, innerMessageHash);
|
|
1118
1126
|
}
|
|
1119
1127
|
client.resolve(stored, messageHash);
|
|
@@ -1314,7 +1322,7 @@ export default class bitget extends bitgetRest {
|
|
|
1314
1322
|
totalAmount = this.safeString(order, 'size');
|
|
1315
1323
|
cost = this.safeString(order, 'fillNotionalUsd');
|
|
1316
1324
|
}
|
|
1317
|
-
remaining =
|
|
1325
|
+
remaining = Precise.stringSub(totalAmount, totalFilled);
|
|
1318
1326
|
return this.safeOrder({
|
|
1319
1327
|
'info': order,
|
|
1320
1328
|
'symbol': symbol,
|
package/js/src/pro/bitrue.js
CHANGED
|
@@ -349,13 +349,12 @@ export default class bitrue extends bitrueRest {
|
|
|
349
349
|
const symbol = market['symbol'];
|
|
350
350
|
const timestamp = this.safeInteger(message, 'ts');
|
|
351
351
|
const tick = this.safeValue(message, 'tick', {});
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
orderbook = this.orderBook();
|
|
352
|
+
if (!(symbol in this.orderbooks)) {
|
|
353
|
+
this.orderbooks[symbol] = this.orderBook();
|
|
355
354
|
}
|
|
355
|
+
const orderbook = this.orderbooks[symbol];
|
|
356
356
|
const snapshot = this.parseOrderBook(tick, symbol, timestamp, 'buys', 'asks');
|
|
357
357
|
orderbook.reset(snapshot);
|
|
358
|
-
this.orderbooks[symbol] = orderbook;
|
|
359
358
|
const messageHash = 'orderbook:' + symbol;
|
|
360
359
|
client.resolve(orderbook, messageHash);
|
|
361
360
|
}
|
|
@@ -458,17 +458,18 @@ export default class currencycom extends currencycomRest {
|
|
|
458
458
|
const destination = 'depthMarketData.subscribe';
|
|
459
459
|
const messageHash = destination + ':' + symbol;
|
|
460
460
|
const timestamp = this.safeInteger(data, 'ts');
|
|
461
|
-
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
462
|
-
if (
|
|
463
|
-
|
|
461
|
+
// let orderbook = this.safeValue (this.orderbooks, symbol);
|
|
462
|
+
if (!(symbol in this.orderbooks)) {
|
|
463
|
+
this.orderbooks[symbol] = this.orderBook();
|
|
464
464
|
}
|
|
465
|
+
const orderbook = this.orderbooks[symbol];
|
|
465
466
|
orderbook.reset({
|
|
466
467
|
'symbol': symbol,
|
|
467
468
|
'timestamp': timestamp,
|
|
468
469
|
'datetime': this.iso8601(timestamp),
|
|
469
470
|
});
|
|
470
|
-
const bids = this.
|
|
471
|
-
const asks = this.
|
|
471
|
+
const bids = this.safeDict(data, 'bid', {});
|
|
472
|
+
const asks = this.safeDict(data, 'ofr', {});
|
|
472
473
|
this.handleDeltas(orderbook['bids'], bids);
|
|
473
474
|
this.handleDeltas(orderbook['asks'], asks);
|
|
474
475
|
this.orderbooks[symbol] = orderbook;
|
package/js/src/pro/exmo.js
CHANGED
|
@@ -515,19 +515,18 @@ export default class exmo extends exmoRest {
|
|
|
515
515
|
const orderBook = this.safeValue(message, 'data', {});
|
|
516
516
|
const messageHash = 'orderbook:' + symbol;
|
|
517
517
|
const timestamp = this.safeInteger(message, 'ts');
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
orderbook = this.orderBook({});
|
|
521
|
-
this.orderbooks[symbol] = orderbook;
|
|
518
|
+
if (!(symbol in this.orderbooks)) {
|
|
519
|
+
this.orderbooks[symbol] = this.orderBook({});
|
|
522
520
|
}
|
|
521
|
+
const orderbook = this.orderbooks[symbol];
|
|
523
522
|
const event = this.safeString(message, 'event');
|
|
524
523
|
if (event === 'snapshot') {
|
|
525
524
|
const snapshot = this.parseOrderBook(orderBook, symbol, timestamp, 'bid', 'ask');
|
|
526
525
|
orderbook.reset(snapshot);
|
|
527
526
|
}
|
|
528
527
|
else {
|
|
529
|
-
const asks = this.
|
|
530
|
-
const bids = this.
|
|
528
|
+
const asks = this.safeList(orderBook, 'ask', []);
|
|
529
|
+
const bids = this.safeList(orderBook, 'bid', []);
|
|
531
530
|
this.handleDeltas(orderbook['asks'], asks);
|
|
532
531
|
this.handleDeltas(orderbook['bids'], bids);
|
|
533
532
|
orderbook['timestamp'] = timestamp;
|
package/js/src/pro/gemini.js
CHANGED
|
@@ -387,10 +387,11 @@ export default class gemini extends geminiRest {
|
|
|
387
387
|
const market = this.safeMarket(marketId);
|
|
388
388
|
const symbol = market['symbol'];
|
|
389
389
|
const messageHash = 'orderbook:' + symbol;
|
|
390
|
-
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
391
|
-
if (
|
|
392
|
-
|
|
390
|
+
// let orderbook = this.safeValue (this.orderbooks, symbol);
|
|
391
|
+
if (!(symbol in this.orderbooks)) {
|
|
392
|
+
this.orderbooks[symbol] = this.orderBook();
|
|
393
393
|
}
|
|
394
|
+
const orderbook = this.orderbooks[symbol];
|
|
394
395
|
for (let i = 0; i < changes.length; i++) {
|
|
395
396
|
const delta = changes[i];
|
|
396
397
|
const price = this.safeNumber(delta, 1);
|