ccxt 4.4.7 → 4.4.9

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 (61) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/bigone.js +35 -86
  5. package/dist/cjs/src/binance.js +51 -12
  6. package/dist/cjs/src/bingx.js +7 -2
  7. package/dist/cjs/src/bitget.js +3 -0
  8. package/dist/cjs/src/bybit.js +368 -1
  9. package/dist/cjs/src/gate.js +35 -1
  10. package/dist/cjs/src/htx.js +24 -0
  11. package/dist/cjs/src/kucoin.js +2 -1
  12. package/dist/cjs/src/kucoinfutures.js +162 -2
  13. package/dist/cjs/src/okx.js +4 -0
  14. package/dist/cjs/src/pro/binance.js +4 -4
  15. package/dist/cjs/src/pro/bitmart.js +81 -0
  16. package/dist/cjs/src/pro/bitvavo.js +92 -1
  17. package/dist/cjs/src/pro/blofin.js +64 -0
  18. package/dist/cjs/src/pro/hitbtc.js +122 -48
  19. package/dist/cjs/src/pro/hollaex.js +5 -0
  20. package/dist/cjs/src/pro/okx.js +19 -3
  21. package/dist/cjs/src/pro/p2b.js +35 -1
  22. package/dist/cjs/src/pro/whitebit.js +31 -0
  23. package/js/ccxt.d.ts +1 -1
  24. package/js/ccxt.js +1 -1
  25. package/js/src/abstract/bigone.d.ts +1 -1
  26. package/js/src/abstract/binance.d.ts +1 -0
  27. package/js/src/abstract/binancecoinm.d.ts +1 -0
  28. package/js/src/abstract/binanceus.d.ts +1 -0
  29. package/js/src/abstract/binanceusdm.d.ts +1 -0
  30. package/js/src/abstract/bybit.d.ts +5 -0
  31. package/js/src/abstract/kucoinfutures.d.ts +5 -0
  32. package/js/src/abstract/okx.d.ts +2 -0
  33. package/js/src/bigone.js +35 -86
  34. package/js/src/binance.d.ts +15 -15
  35. package/js/src/binance.js +51 -12
  36. package/js/src/bingx.js +7 -2
  37. package/js/src/bitget.js +3 -0
  38. package/js/src/bybit.d.ts +7 -1
  39. package/js/src/bybit.js +368 -1
  40. package/js/src/gate.js +35 -1
  41. package/js/src/htx.js +24 -0
  42. package/js/src/kucoin.js +2 -1
  43. package/js/src/kucoinfutures.d.ts +7 -1
  44. package/js/src/kucoinfutures.js +162 -2
  45. package/js/src/okx.js +4 -0
  46. package/js/src/pro/binance.js +4 -4
  47. package/js/src/pro/bitmart.d.ts +3 -0
  48. package/js/src/pro/bitmart.js +81 -0
  49. package/js/src/pro/bitvavo.d.ts +7 -2
  50. package/js/src/pro/bitvavo.js +92 -1
  51. package/js/src/pro/blofin.d.ts +3 -0
  52. package/js/src/pro/blofin.js +64 -0
  53. package/js/src/pro/hitbtc.d.ts +4 -1
  54. package/js/src/pro/hitbtc.js +122 -48
  55. package/js/src/pro/hollaex.js +5 -0
  56. package/js/src/pro/okx.js +19 -3
  57. package/js/src/pro/p2b.d.ts +2 -1
  58. package/js/src/pro/p2b.js +35 -1
  59. package/js/src/pro/whitebit.d.ts +2 -1
  60. package/js/src/pro/whitebit.js +31 -0
  61. package/package.json +1 -1
@@ -70,9 +70,10 @@ export default class kucoinfutures extends kucoin {
70
70
  'fetchIsolatedBorrowRates': false,
71
71
  'fetchL3OrderBook': true,
72
72
  'fetchLedger': true,
73
+ 'fetchLeverage': true,
73
74
  'fetchLeverageTiers': false,
74
75
  'fetchMarginAdjustmentHistory': false,
75
- 'fetchMarginMode': false,
76
+ 'fetchMarginMode': true,
76
77
  'fetchMarketLeverageTiers': true,
77
78
  'fetchMarkets': true,
78
79
  'fetchMarkOHLCV': false,
@@ -96,7 +97,7 @@ export default class kucoinfutures extends kucoin {
96
97
  'fetchTransactionFee': false,
97
98
  'fetchWithdrawals': true,
98
99
  'setLeverage': false,
99
- 'setMarginMode': false,
100
+ 'setMarginMode': true,
100
101
  'transfer': true,
101
102
  'withdraw': undefined,
102
103
  },
@@ -173,12 +174,15 @@ export default class kucoinfutures extends kucoin {
173
174
  'trade-fees': 1,
174
175
  'history-positions': 1,
175
176
  'getMaxOpenSize': 1,
177
+ 'getCrossUserLeverage': 1,
178
+ 'position/getMarginMode': 1,
176
179
  },
177
180
  'post': {
178
181
  'withdrawals': 1,
179
182
  'transfer-out': 1,
180
183
  'transfer-in': 1,
181
184
  'orders': 1.33,
185
+ 'st-orders': 1.33,
182
186
  'orders/test': 1.33,
183
187
  'position/margin/auto-deposit-status': 1,
184
188
  'position/margin/deposit-margin': 1,
@@ -186,6 +190,8 @@ export default class kucoinfutures extends kucoin {
186
190
  'bullet-private': 1,
187
191
  'sub/api-key': 1,
188
192
  'sub/api-key/update': 1,
193
+ 'changeCrossUserLeverage': 1,
194
+ 'position/changeMarginMode': 1,
189
195
  },
190
196
  'delete': {
191
197
  'withdrawals/{withdrawalId}': 1,
@@ -320,9 +326,13 @@ export default class kucoinfutures extends kucoin {
320
326
  'futuresPrivate': {
321
327
  'GET': {
322
328
  'getMaxOpenSize': 'v2',
329
+ 'getCrossUserLeverage': 'v2',
330
+ 'position/getMarginMode': 'v2',
323
331
  },
324
332
  'POST': {
325
333
  'transfer-out': 'v2',
334
+ 'changeCrossUserLeverage': 'v2',
335
+ 'position/changeMarginMode': 'v2',
326
336
  },
327
337
  },
328
338
  'futuresPublic': {
@@ -2881,4 +2891,154 @@ export default class kucoinfutures extends kucoin {
2881
2891
  'tierBased': true,
2882
2892
  };
2883
2893
  }
2894
+ async fetchMarginMode(symbol, params = {}) {
2895
+ /**
2896
+ * @method
2897
+ * @name kucoinfutures#fetchMarginMode
2898
+ * @description fetches the margin mode of a trading pair
2899
+ * @see https://www.kucoin.com/docs/rest/futures-trading/positions/get-margin-mode
2900
+ * @param {string} symbol unified symbol of the market to fetch the margin mode for
2901
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2902
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
2903
+ */
2904
+ await this.loadMarkets();
2905
+ const market = this.market(symbol);
2906
+ const request = {
2907
+ 'symbol': market['id'],
2908
+ };
2909
+ const response = await this.futuresPrivateGetPositionGetMarginMode(this.extend(request, params));
2910
+ //
2911
+ // {
2912
+ // "code": "200000",
2913
+ // "data": {
2914
+ // "symbol": "XBTUSDTM",
2915
+ // "marginMode": "ISOLATED"
2916
+ // }
2917
+ // }
2918
+ //
2919
+ const data = this.safeDict(response, 'data', {});
2920
+ return this.parseMarginMode(data, market);
2921
+ }
2922
+ parseMarginMode(marginMode, market = undefined) {
2923
+ let marginType = this.safeString(marginMode, 'marginMode');
2924
+ marginType = (marginType === 'ISOLATED') ? 'isolated' : 'cross';
2925
+ return {
2926
+ 'info': marginMode,
2927
+ 'symbol': market['symbol'],
2928
+ 'marginMode': marginType,
2929
+ };
2930
+ }
2931
+ async setMarginMode(marginMode, symbol = undefined, params = {}) {
2932
+ /**
2933
+ * @method
2934
+ * @name kucoinfutures#setMarginMode
2935
+ * @description set margin mode to 'cross' or 'isolated'
2936
+ * @see https://www.kucoin.com/docs/rest/futures-trading/positions/modify-margin-mode
2937
+ * @param {string} marginMode 'cross' or 'isolated'
2938
+ * @param {string} symbol unified market symbol
2939
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2940
+ * @returns {object} response from the exchange
2941
+ */
2942
+ if (symbol === undefined) {
2943
+ throw new ArgumentsRequired(this.id + ' setMarginMode() requires a symbol argument');
2944
+ }
2945
+ this.checkRequiredArgument('setMarginMode', marginMode, 'marginMode', ['cross', 'isolated']);
2946
+ await this.loadMarkets();
2947
+ const market = this.market(symbol);
2948
+ const request = {
2949
+ 'symbol': market['id'],
2950
+ 'marginMode': marginMode.toUpperCase(),
2951
+ };
2952
+ const response = await this.futuresPrivatePostPositionChangeMarginMode(this.extend(request, params));
2953
+ //
2954
+ // {
2955
+ // "code": "200000",
2956
+ // "data": {
2957
+ // "symbol": "XBTUSDTM",
2958
+ // "marginMode": "ISOLATED"
2959
+ // }
2960
+ // }
2961
+ //
2962
+ const data = this.safeDict(response, 'data', {});
2963
+ return this.parseMarginMode(data, market);
2964
+ }
2965
+ async fetchLeverage(symbol, params = {}) {
2966
+ /**
2967
+ * @method
2968
+ * @name kucoin#fetchLeverage
2969
+ * @description fetch the set leverage for a market
2970
+ * @see https://www.kucoin.com/docs/rest/futures-trading/positions/get-cross-margin-leverage
2971
+ * @param {string} symbol unified market symbol
2972
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2973
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
2974
+ */
2975
+ let marginMode = undefined;
2976
+ [marginMode, params] = this.handleMarginModeAndParams(symbol, params);
2977
+ if (marginMode !== 'cross') {
2978
+ throw new NotSupported(this.id + ' fetchLeverage() currently supports only params["marginMode"] = "cross"');
2979
+ }
2980
+ await this.loadMarkets();
2981
+ const market = this.market(symbol);
2982
+ const request = {
2983
+ 'symbol': market['id'],
2984
+ };
2985
+ const response = await this.futuresPrivateGetGetCrossUserLeverage(this.extend(request, params));
2986
+ //
2987
+ // {
2988
+ // "code": "200000",
2989
+ // "data": {
2990
+ // "symbol": "XBTUSDTM",
2991
+ // "leverage": "3"
2992
+ // }
2993
+ // }
2994
+ //
2995
+ const data = this.safeDict(response, 'data', {});
2996
+ const parsed = this.parseLeverage(data, market);
2997
+ return this.extend(parsed, {
2998
+ 'marginMode': marginMode,
2999
+ });
3000
+ }
3001
+ async setLeverage(leverage, symbol = undefined, params = {}) {
3002
+ /**
3003
+ * @method
3004
+ * @name kucoinfutures#setLeverage
3005
+ * @description set the level of leverage for a market
3006
+ * @see https://www.kucoin.com/docs/rest/futures-trading/positions/modify-cross-margin-leverage
3007
+ * @param {float} leverage the rate of leverage
3008
+ * @param {string} symbol unified market symbol
3009
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3010
+ * @returns {object} response from the exchange
3011
+ */
3012
+ let marginMode = undefined;
3013
+ [marginMode, params] = this.handleMarginModeAndParams(symbol, params);
3014
+ if (marginMode !== 'cross') {
3015
+ throw new NotSupported(this.id + ' setLeverage() currently supports only params["marginMode"] = "cross"');
3016
+ }
3017
+ await this.loadMarkets();
3018
+ const market = this.market(symbol);
3019
+ const request = {
3020
+ 'symbol': market['id'],
3021
+ 'leverage': leverage.toString(),
3022
+ };
3023
+ const response = await this.futuresPrivatePostChangeCrossUserLeverage(this.extend(request, params));
3024
+ //
3025
+ // {
3026
+ // "code": "200000",
3027
+ // "data": true
3028
+ // }
3029
+ //
3030
+ return this.parseLeverage(response, market);
3031
+ }
3032
+ parseLeverage(leverage, market = undefined) {
3033
+ const marketId = this.safeString(leverage, 'symbol');
3034
+ market = this.safeMarket(marketId, market);
3035
+ const leverageNum = this.safeInteger(leverage, 'leverage');
3036
+ return {
3037
+ 'info': leverage,
3038
+ 'symbol': market['symbol'],
3039
+ 'marginMode': undefined,
3040
+ 'longLeverage': leverageNum,
3041
+ 'shortLeverage': leverageNum,
3042
+ };
3043
+ }
2884
3044
  }
package/js/src/okx.js CHANGED
@@ -269,6 +269,7 @@ export default class okx extends Exchange {
269
269
  'copytrading/public-preference-currency': 4,
270
270
  'copytrading/public-current-subpositions': 4,
271
271
  'copytrading/public-subpositions-history': 4,
272
+ 'support/announcements-types': 20,
272
273
  },
273
274
  },
274
275
  'private': {
@@ -414,6 +415,7 @@ export default class okx extends Exchange {
414
415
  // affiliate
415
416
  'affiliate/invitee/detail': 1,
416
417
  'users/partner/if-rebate': 1,
418
+ 'support/announcements': 4,
417
419
  },
418
420
  'post': {
419
421
  // rfq
@@ -793,6 +795,8 @@ export default class okx extends Exchange {
793
795
  // SPOT/MARGIN error codes 54000-54999
794
796
  '54000': ExchangeError,
795
797
  '54001': ExchangeError,
798
+ '54008': InvalidOrder,
799
+ '54009': InvalidOrder,
796
800
  '54011': InvalidOrder,
797
801
  // Trading bot Error Code from 55100 to 55999
798
802
  '55100': InvalidOrder,
@@ -2649,16 +2649,16 @@ export default class binance extends binanceRest {
2649
2649
  [subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
2650
2650
  let isPortfolioMargin = undefined;
2651
2651
  [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchBalance', 'papi', 'portfolioMargin', false);
2652
- let urlType = type;
2653
- if (isPortfolioMargin) {
2654
- urlType = 'papi';
2655
- }
2656
2652
  if (this.isLinear(type, subType)) {
2657
2653
  type = 'future';
2658
2654
  }
2659
2655
  else if (this.isInverse(type, subType)) {
2660
2656
  type = 'delivery';
2661
2657
  }
2658
+ let urlType = type;
2659
+ if (isPortfolioMargin) {
2660
+ urlType = 'papi';
2661
+ }
2662
2662
  const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2663
2663
  const client = this.client(url);
2664
2664
  this.setBalanceCache(client, type, isPortfolioMargin);
@@ -14,6 +14,9 @@ export default class bitmart extends bitmartRest {
14
14
  getParamsForMultipleSub(methodName: string, symbols: string[], limit?: Int, params?: {}): any[];
15
15
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
16
16
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
17
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
18
+ handleBidAsk(client: Client, message: any): void;
19
+ parseWsBidAsk(ticker: any, market?: any): Ticker;
17
20
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
18
21
  handleOrders(client: Client, message: any): void;
19
22
  parseWsOrder(order: Dict, market?: Market): Order;
@@ -26,6 +26,7 @@ export default class bitmart extends bitmartRest {
26
26
  'watchBalance': true,
27
27
  'watchTicker': true,
28
28
  'watchTickers': true,
29
+ 'watchBidsAsks': true,
29
30
  'watchOrderBook': true,
30
31
  'watchOrderBookForSymbols': true,
31
32
  'watchOrders': true,
@@ -337,6 +338,7 @@ export default class bitmart extends bitmartRest {
337
338
  /**
338
339
  * @method
339
340
  * @name bitmart#watchTickers
341
+ * @see https://developer-pro.bitmart.com/en/spot/#public-ticker-channel
340
342
  * @see https://developer-pro.bitmart.com/en/futuresv2/#public-ticker-channel
341
343
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
342
344
  * @param {string[]} symbols unified symbol of the market to fetch the ticker for
@@ -355,6 +357,84 @@ export default class bitmart extends bitmartRest {
355
357
  }
356
358
  return this.filterByArray(this.tickers, 'symbol', symbols);
357
359
  }
360
+ async watchBidsAsks(symbols = undefined, params = {}) {
361
+ /**
362
+ * @method
363
+ * @name bitmart#watchBidsAsks
364
+ * @see https://developer-pro.bitmart.com/en/spot/#public-ticker-channel
365
+ * @see https://developer-pro.bitmart.com/en/futuresv2/#public-ticker-channel
366
+ * @description watches best bid & ask for symbols
367
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
368
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
369
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
370
+ */
371
+ await this.loadMarkets();
372
+ symbols = this.marketSymbols(symbols, undefined, false);
373
+ const firstMarket = this.getMarketFromSymbols(symbols);
374
+ let marketType = undefined;
375
+ [marketType, params] = this.handleMarketTypeAndParams('watchBidsAsks', firstMarket, params);
376
+ const url = this.implodeHostname(this.urls['api']['ws'][marketType]['public']);
377
+ const channelType = (marketType === 'spot') ? 'spot' : 'futures';
378
+ const actionType = (marketType === 'spot') ? 'op' : 'action';
379
+ let rawSubscriptions = [];
380
+ const messageHashes = [];
381
+ for (let i = 0; i < symbols.length; i++) {
382
+ const market = this.market(symbols[i]);
383
+ rawSubscriptions.push(channelType + '/ticker:' + market['id']);
384
+ messageHashes.push('bidask:' + symbols[i]);
385
+ }
386
+ if (marketType !== 'spot') {
387
+ rawSubscriptions = [channelType + '/ticker'];
388
+ }
389
+ const request = {
390
+ 'args': rawSubscriptions,
391
+ };
392
+ request[actionType] = 'subscribe';
393
+ const newTickers = await this.watchMultiple(url, messageHashes, request, rawSubscriptions);
394
+ if (this.newUpdates) {
395
+ const tickers = {};
396
+ tickers[newTickers['symbol']] = newTickers;
397
+ return tickers;
398
+ }
399
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
400
+ }
401
+ handleBidAsk(client, message) {
402
+ const table = this.safeString(message, 'table');
403
+ const isSpot = (table !== undefined);
404
+ let rawTickers = [];
405
+ if (isSpot) {
406
+ rawTickers = this.safeList(message, 'data', []);
407
+ }
408
+ else {
409
+ rawTickers = [this.safeValue(message, 'data', {})];
410
+ }
411
+ if (!rawTickers.length) {
412
+ return;
413
+ }
414
+ for (let i = 0; i < rawTickers.length; i++) {
415
+ const ticker = this.parseWsBidAsk(rawTickers[i]);
416
+ const symbol = ticker['symbol'];
417
+ this.bidsasks[symbol] = ticker;
418
+ const messageHash = 'bidask:' + symbol;
419
+ client.resolve(ticker, messageHash);
420
+ }
421
+ }
422
+ parseWsBidAsk(ticker, market = undefined) {
423
+ const marketId = this.safeString(ticker, 'symbol');
424
+ market = this.safeMarket(marketId, market);
425
+ const symbol = this.safeString(market, 'symbol');
426
+ const timestamp = this.safeInteger(ticker, 'ms_t');
427
+ return this.safeTicker({
428
+ 'symbol': symbol,
429
+ 'timestamp': timestamp,
430
+ 'datetime': this.iso8601(timestamp),
431
+ 'ask': this.safeString2(ticker, 'ask_px', 'ask_price'),
432
+ 'askVolume': this.safeString2(ticker, 'ask_sz', 'ask_vol'),
433
+ 'bid': this.safeString2(ticker, 'bid_px', 'bid_price'),
434
+ 'bidVolume': this.safeString2(ticker, 'bid_sz', 'bid_vol'),
435
+ 'info': ticker,
436
+ }, market);
437
+ }
358
438
  async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
359
439
  /**
360
440
  * @method
@@ -934,6 +1014,7 @@ export default class bitmart extends bitmartRest {
934
1014
  // }
935
1015
  // }
936
1016
  //
1017
+ this.handleBidAsk(client, message);
937
1018
  const table = this.safeString(message, 'table');
938
1019
  const isSpot = (table !== undefined);
939
1020
  let rawTickers = [];
@@ -1,11 +1,16 @@
1
1
  import bitvavoRest from '../bitvavo.js';
2
- import { Int, Str, OrderSide, OrderType, OrderBook, Ticker, Trade, Order, OHLCV, Balances, Num, TradingFees } from '../base/types.js';
2
+ import { Int, Str, OrderSide, OrderType, OrderBook, Ticker, Trade, Order, OHLCV, Balances, Num, TradingFees, Strings, Tickers } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class bitvavo extends bitvavoRest {
5
5
  describe(): any;
6
6
  watchPublic(name: any, symbol: any, params?: {}): Promise<any>;
7
+ watchPublicMultiple(methodName: any, channelName: string, symbols: any, params?: {}): Promise<any>;
7
8
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
8
- handleTicker(client: Client, message: any): any;
9
+ watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
10
+ handleTicker(client: Client, message: any): void;
11
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
12
+ handleBidAsk(client: Client, message: any): void;
13
+ parseWsBidAsk(ticker: any, market?: any): Ticker;
9
14
  watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
10
15
  handleTrade(client: Client, message: any): void;
11
16
  watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
@@ -20,6 +20,8 @@ export default class bitvavo extends bitvavoRest {
20
20
  'watchOrderBook': true,
21
21
  'watchTrades': true,
22
22
  'watchTicker': true,
23
+ 'watchTickers': true,
24
+ 'watchBidsAsks': true,
23
25
  'watchOHLCV': true,
24
26
  'watchOrders': true,
25
27
  'watchMyTrades': true,
@@ -80,17 +82,56 @@ export default class bitvavo extends bitvavoRest {
80
82
  const message = this.extend(request, params);
81
83
  return await this.watch(url, messageHash, message, messageHash);
82
84
  }
85
+ async watchPublicMultiple(methodName, channelName, symbols, params = {}) {
86
+ await this.loadMarkets();
87
+ symbols = this.marketSymbols(symbols);
88
+ const messageHashes = [methodName];
89
+ const args = [];
90
+ for (let i = 0; i < symbols.length; i++) {
91
+ const market = this.market(symbols[i]);
92
+ args.push(market['id']);
93
+ }
94
+ const url = this.urls['api']['ws'];
95
+ const request = {
96
+ 'action': 'subscribe',
97
+ 'channels': [
98
+ {
99
+ 'name': channelName,
100
+ 'markets': args,
101
+ },
102
+ ],
103
+ };
104
+ const message = this.extend(request, params);
105
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
106
+ }
83
107
  async watchTicker(symbol, params = {}) {
84
108
  /**
85
109
  * @method
86
110
  * @name bitvavo#watchTicker
87
111
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
112
+ * @see https://docs.bitvavo.com/#tag/Market-data-subscription-WebSocket/paths/~1subscribeTicker24h/post
88
113
  * @param {string} symbol unified symbol of the market to fetch the ticker for
89
114
  * @param {object} [params] extra parameters specific to the exchange API endpoint
90
115
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
91
116
  */
92
117
  return await this.watchPublic('ticker24h', symbol, params);
93
118
  }
119
+ async watchTickers(symbols = undefined, params = {}) {
120
+ /**
121
+ * @method
122
+ * @name bitvavo#watchTickers
123
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
124
+ * @see https://docs.bitvavo.com/#tag/Market-data-subscription-WebSocket/paths/~1subscribeTicker24h/post
125
+ * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
126
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
127
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
128
+ */
129
+ await this.loadMarkets();
130
+ symbols = this.marketSymbols(symbols, undefined, false);
131
+ const channel = 'ticker24h';
132
+ const tickers = await this.watchPublicMultiple(channel, channel, symbols, params);
133
+ return this.filterByArray(tickers, 'symbol', symbols);
134
+ }
94
135
  handleTicker(client, message) {
95
136
  //
96
137
  // {
@@ -113,8 +154,10 @@ export default class bitvavo extends bitvavoRest {
113
154
  // ]
114
155
  // }
115
156
  //
157
+ this.handleBidAsk(client, message);
116
158
  const event = this.safeString(message, 'event');
117
159
  const tickers = this.safeValue(message, 'data', []);
160
+ const result = [];
118
161
  for (let i = 0; i < tickers.length; i++) {
119
162
  const data = tickers[i];
120
163
  const marketId = this.safeString(data, 'market');
@@ -123,9 +166,57 @@ export default class bitvavo extends bitvavoRest {
123
166
  const ticker = this.parseTicker(data, market);
124
167
  const symbol = ticker['symbol'];
125
168
  this.tickers[symbol] = ticker;
169
+ result.push(ticker);
126
170
  client.resolve(ticker, messageHash);
127
171
  }
128
- return message;
172
+ client.resolve(result, event);
173
+ }
174
+ async watchBidsAsks(symbols = undefined, params = {}) {
175
+ /**
176
+ * @method
177
+ * @name mexc#watchBidsAsks
178
+ * @description watches best bid & ask for symbols
179
+ * @see https://docs.bitvavo.com/#tag/Market-data-subscription-WebSocket/paths/~1subscribeTicker24h/post
180
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
181
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
182
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
183
+ */
184
+ await this.loadMarkets();
185
+ symbols = this.marketSymbols(symbols, undefined, false);
186
+ const channel = 'ticker24h';
187
+ const tickers = await this.watchPublicMultiple('bidask', channel, symbols, params);
188
+ return this.filterByArray(tickers, 'symbol', symbols);
189
+ }
190
+ handleBidAsk(client, message) {
191
+ const event = 'bidask';
192
+ const tickers = this.safeValue(message, 'data', []);
193
+ const result = [];
194
+ for (let i = 0; i < tickers.length; i++) {
195
+ const data = tickers[i];
196
+ const ticker = this.parseWsBidAsk(data);
197
+ const symbol = ticker['symbol'];
198
+ this.bidsasks[symbol] = ticker;
199
+ result.push(ticker);
200
+ const messageHash = event + ':' + symbol;
201
+ client.resolve(ticker, messageHash);
202
+ }
203
+ client.resolve(result, event);
204
+ }
205
+ parseWsBidAsk(ticker, market = undefined) {
206
+ const marketId = this.safeString(ticker, 'market');
207
+ market = this.safeMarket(marketId, undefined, '-');
208
+ const symbol = this.safeString(market, 'symbol');
209
+ const timestamp = this.safeInteger(ticker, 'timestamp');
210
+ return this.safeTicker({
211
+ 'symbol': symbol,
212
+ 'timestamp': timestamp,
213
+ 'datetime': this.iso8601(timestamp),
214
+ 'ask': this.safeNumber(ticker, 'ask'),
215
+ 'askVolume': this.safeNumber(ticker, 'askSize'),
216
+ 'bid': this.safeNumber(ticker, 'bid'),
217
+ 'bidVolume': this.safeNumber(ticker, 'bidSize'),
218
+ 'info': ticker,
219
+ }, market);
129
220
  }
130
221
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
131
222
  /**
@@ -16,6 +16,9 @@ export default class blofin extends blofinRest {
16
16
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
17
17
  handleTicker(client: Client, message: any): void;
18
18
  parseWsTicker(ticker: any, market?: Market): Ticker;
19
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
20
+ handleBidAsk(client: Client, message: any): void;
21
+ parseWsBidAsk(ticker: any, market?: any): Ticker;
19
22
  watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
20
23
  watchOHLCVForSymbols(symbolsAndTimeframes: string[][], since?: Int, limit?: Int, params?: {}): Promise<import("../base/types.js").Dictionary<import("../base/types.js").Dictionary<OHLCV[]>>>;
21
24
  handleOHLCV(client: Client, message: any): void;
@@ -21,6 +21,7 @@ export default class blofin extends blofinRest {
21
21
  'watchOrderBookForSymbols': true,
22
22
  'watchTicker': true,
23
23
  'watchTickers': true,
24
+ 'watchBidsAsks': true,
24
25
  'watchOHLCV': true,
25
26
  'watchOHLCVForSymbols': true,
26
27
  'watchOrders': true,
@@ -273,6 +274,7 @@ export default class blofin extends blofinRest {
273
274
  // ],
274
275
  // }
275
276
  //
277
+ this.handleBidAsk(client, message);
276
278
  const arg = this.safeDict(message, 'arg');
277
279
  const channelName = this.safeString(arg, 'channel');
278
280
  const data = this.safeList(message, 'data');
@@ -287,6 +289,68 @@ export default class blofin extends blofinRest {
287
289
  parseWsTicker(ticker, market = undefined) {
288
290
  return this.parseTicker(ticker, market);
289
291
  }
292
+ async watchBidsAsks(symbols = undefined, params = {}) {
293
+ /**
294
+ * @method
295
+ * @name blofin#watchBidsAsks
296
+ * @description watches best bid & ask for symbols
297
+ * @see https://docs.blofin.com/index.html#ws-tickers-channel
298
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
299
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
300
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
301
+ */
302
+ await this.loadMarkets();
303
+ symbols = this.marketSymbols(symbols, undefined, false);
304
+ const firstMarket = this.market(symbols[0]);
305
+ const channel = 'tickers';
306
+ let marketType = undefined;
307
+ [marketType, params] = this.handleMarketTypeAndParams('watchBidsAsks', firstMarket, params);
308
+ const url = this.implodeHostname(this.urls['api']['ws'][marketType]['public']);
309
+ const messageHashes = [];
310
+ const args = [];
311
+ for (let i = 0; i < symbols.length; i++) {
312
+ const market = this.market(symbols[i]);
313
+ messageHashes.push('bidask:' + market['symbol']);
314
+ args.push({
315
+ 'channel': channel,
316
+ 'instId': market['id'],
317
+ });
318
+ }
319
+ const request = this.getSubscriptionRequest(args);
320
+ const ticker = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes);
321
+ if (this.newUpdates) {
322
+ const tickers = {};
323
+ tickers[ticker['symbol']] = ticker;
324
+ return tickers;
325
+ }
326
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
327
+ }
328
+ handleBidAsk(client, message) {
329
+ const data = this.safeList(message, 'data');
330
+ for (let i = 0; i < data.length; i++) {
331
+ const ticker = this.parseWsBidAsk(data[i]);
332
+ const symbol = ticker['symbol'];
333
+ const messageHash = 'bidask:' + symbol;
334
+ this.bidsasks[symbol] = ticker;
335
+ client.resolve(ticker, messageHash);
336
+ }
337
+ }
338
+ parseWsBidAsk(ticker, market = undefined) {
339
+ const marketId = this.safeString(ticker, 'instId');
340
+ market = this.safeMarket(marketId, market, '-');
341
+ const symbol = this.safeString(market, 'symbol');
342
+ const timestamp = this.safeInteger(ticker, 'ts');
343
+ return this.safeTicker({
344
+ 'symbol': symbol,
345
+ 'timestamp': timestamp,
346
+ 'datetime': this.iso8601(timestamp),
347
+ 'ask': this.safeString(ticker, 'askPrice'),
348
+ 'askVolume': this.safeString(ticker, 'askSize'),
349
+ 'bid': this.safeString(ticker, 'bidPrice'),
350
+ 'bidVolume': this.safeString(ticker, 'bidSize'),
351
+ 'info': ticker,
352
+ }, market);
353
+ }
290
354
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
291
355
  /**
292
356
  * @method
@@ -14,8 +14,11 @@ export default class hitbtc extends hitbtcRest {
14
14
  handleDeltas(bookside: any, deltas: any): void;
15
15
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
16
16
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
17
- handleTicker(client: Client, message: any): any;
17
+ handleTicker(client: Client, message: any): void;
18
18
  parseWsTicker(ticker: any, market?: any): Ticker;
19
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
20
+ handleBidAsk(client: Client, message: any): void;
21
+ parseWsBidAsk(ticker: any, market?: any): Ticker;
19
22
  watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
20
23
  handleTrades(client: Client, message: any): any;
21
24
  parseWsTrades(trades: any, market?: object, since?: Int, limit?: Int, params?: {}): Trade[];