ccxt 4.3.39 → 4.3.41
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 +4 -0
- package/dist/cjs/src/bitfinex2.js +1 -1
- package/dist/cjs/src/bithumb.js +9 -1
- package/dist/cjs/src/bitstamp.js +38 -2
- 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/hitbtc.js +2 -2
- package/dist/cjs/src/independentreserve.js +33 -1
- package/dist/cjs/src/indodax.js +43 -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 +6 -5
- 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/phemex.js +5 -5
- package/dist/cjs/src/pro/probit.js +4 -4
- package/dist/cjs/src/pro/upbit.js +318 -2
- package/dist/cjs/src/pro/wazirx.js +12 -12
- package/dist/cjs/src/upbit.js +17 -9
- package/dist/cjs/src/woo.js +6 -2
- package/dist/cjs/src/woofipro.js +8 -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 +4 -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/bitstamp.d.ts +2 -2
- package/js/src/bitstamp.js +38 -2
- 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/hitbtc.js +2 -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/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 +6 -5
- 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/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 +319 -3
- package/js/src/pro/wazirx.js +12 -12
- package/js/src/upbit.js +17 -9
- package/js/src/woo.d.ts +1 -1
- package/js/src/woo.js +6 -2
- package/js/src/woofipro.d.ts +4 -2
- package/js/src/woofipro.js +8 -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,7 +1015,7 @@ 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);
|
|
@@ -1075,9 +1075,10 @@ export default class bitget extends bitgetRest {
|
|
|
1075
1075
|
// "ts": 1701923982497
|
|
1076
1076
|
// }
|
|
1077
1077
|
//
|
|
1078
|
-
const arg = this.
|
|
1078
|
+
const arg = this.safeDict(message, 'arg', {});
|
|
1079
1079
|
const channel = this.safeString(arg, 'channel');
|
|
1080
1080
|
const instType = this.safeString(arg, 'instType');
|
|
1081
|
+
const argInstId = this.safeString(arg, 'instId');
|
|
1081
1082
|
let marketType = undefined;
|
|
1082
1083
|
if (instType === 'SPOT') {
|
|
1083
1084
|
marketType = 'spot';
|
|
@@ -1103,7 +1104,7 @@ export default class bitget extends bitgetRest {
|
|
|
1103
1104
|
const marketSymbols = {};
|
|
1104
1105
|
for (let i = 0; i < data.length; i++) {
|
|
1105
1106
|
const order = data[i];
|
|
1106
|
-
const marketId = this.safeString(order, 'instId');
|
|
1107
|
+
const marketId = this.safeString(order, 'instId', argInstId);
|
|
1107
1108
|
const market = this.safeMarket(marketId, undefined, undefined, marketType);
|
|
1108
1109
|
const parsed = this.parseWsOrder(order, market);
|
|
1109
1110
|
stored.append(parsed);
|
|
@@ -1314,7 +1315,7 @@ export default class bitget extends bitgetRest {
|
|
|
1314
1315
|
totalAmount = this.safeString(order, 'size');
|
|
1315
1316
|
cost = this.safeString(order, 'fillNotionalUsd');
|
|
1316
1317
|
}
|
|
1317
|
-
remaining =
|
|
1318
|
+
remaining = Precise.stringSub(totalAmount, totalFilled);
|
|
1318
1319
|
return this.safeOrder({
|
|
1319
1320
|
'info': order,
|
|
1320
1321
|
'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);
|
|
@@ -176,24 +176,24 @@ export default class independentreserve extends independentreserveRest {
|
|
|
176
176
|
const base = this.safeCurrencyCode(baseId);
|
|
177
177
|
const quote = this.safeCurrencyCode(quoteId);
|
|
178
178
|
const symbol = base + '/' + quote;
|
|
179
|
-
const orderBook = this.
|
|
179
|
+
const orderBook = this.safeDict(message, 'Data', {});
|
|
180
180
|
const messageHash = 'orderbook:' + symbol + ':' + depth;
|
|
181
181
|
const subscription = this.safeValue(client.subscriptions, messageHash, {});
|
|
182
182
|
const receivedSnapshot = this.safeBool(subscription, 'receivedSnapshot', false);
|
|
183
183
|
const timestamp = this.safeInteger(message, 'Time');
|
|
184
|
-
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
this.orderbooks[symbol] = orderbook;
|
|
184
|
+
// let orderbook = this.safeValue (this.orderbooks, symbol);
|
|
185
|
+
if (!(symbol in this.orderbooks)) {
|
|
186
|
+
this.orderbooks[symbol] = this.orderBook({});
|
|
188
187
|
}
|
|
188
|
+
const orderbook = this.orderbooks[symbol];
|
|
189
189
|
if (event === 'OrderBookSnapshot') {
|
|
190
190
|
const snapshot = this.parseOrderBook(orderBook, symbol, timestamp, 'Bids', 'Offers', 'Price', 'Volume');
|
|
191
191
|
orderbook.reset(snapshot);
|
|
192
192
|
subscription['receivedSnapshot'] = true;
|
|
193
193
|
}
|
|
194
194
|
else {
|
|
195
|
-
const asks = this.
|
|
196
|
-
const bids = this.
|
|
195
|
+
const asks = this.safeList(orderBook, 'Offers', []);
|
|
196
|
+
const bids = this.safeList(orderBook, 'Bids', []);
|
|
197
197
|
this.handleDeltas(orderbook['asks'], asks);
|
|
198
198
|
this.handleDeltas(orderbook['bids'], bids);
|
|
199
199
|
orderbook['timestamp'] = timestamp;
|
package/js/src/pro/lbank.js
CHANGED
|
@@ -781,11 +781,11 @@ export default class lbank extends lbankRest {
|
|
|
781
781
|
const orderBook = this.safeValue(message, 'depth', message);
|
|
782
782
|
const datetime = this.safeString(message, 'TS');
|
|
783
783
|
const timestamp = this.parse8601(datetime);
|
|
784
|
-
let orderbook = this.safeValue(this.orderbooks, symbol);
|
|
785
|
-
if (
|
|
786
|
-
|
|
787
|
-
this.orderbooks[symbol] = orderbook;
|
|
784
|
+
// let orderbook = this.safeValue (this.orderbooks, symbol);
|
|
785
|
+
if (!(symbol in this.orderbooks)) {
|
|
786
|
+
this.orderbooks[symbol] = this.orderBook({});
|
|
788
787
|
}
|
|
788
|
+
const orderbook = this.orderbooks[symbol];
|
|
789
789
|
const snapshot = this.parseOrderBook(orderBook, symbol, timestamp, 'bids', 'asks');
|
|
790
790
|
orderbook.reset(snapshot);
|
|
791
791
|
let messageHash = 'orderbook:' + symbol;
|