ccxt 4.2.9 → 4.2.11

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 (56) hide show
  1. package/README.md +3 -3
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +322 -164
  4. package/dist/ccxt.browser.min.js +7 -7
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +48 -8
  7. package/dist/cjs/src/binance.js +6 -1
  8. package/dist/cjs/src/bingx.js +0 -10
  9. package/dist/cjs/src/bitget.js +14 -5
  10. package/dist/cjs/src/bl3p.js +1 -1
  11. package/dist/cjs/src/btcalpha.js +1 -1
  12. package/dist/cjs/src/bybit.js +1 -1
  13. package/dist/cjs/src/cryptocom.js +3 -1
  14. package/dist/cjs/src/deribit.js +39 -22
  15. package/dist/cjs/src/kraken.js +1 -1
  16. package/dist/cjs/src/kucoin.js +30 -6
  17. package/dist/cjs/src/lykke.js +1 -1
  18. package/dist/cjs/src/ndax.js +1 -1
  19. package/dist/cjs/src/pro/bitmart.js +49 -27
  20. package/dist/cjs/src/pro/blockchaincom.js +2 -28
  21. package/dist/cjs/src/pro/coinbasepro.js +9 -16
  22. package/dist/cjs/src/pro/cryptocom.js +110 -28
  23. package/dist/cjs/src/pro/luno.js +5 -5
  24. package/js/ccxt.d.ts +1 -1
  25. package/js/ccxt.js +1 -1
  26. package/js/src/base/Exchange.d.ts +5 -3
  27. package/js/src/base/Exchange.js +48 -8
  28. package/js/src/binance.js +6 -1
  29. package/js/src/bingx.d.ts +0 -1
  30. package/js/src/bingx.js +0 -10
  31. package/js/src/bitget.js +14 -5
  32. package/js/src/bl3p.d.ts +2 -2
  33. package/js/src/bl3p.js +1 -1
  34. package/js/src/btcalpha.d.ts +2 -2
  35. package/js/src/btcalpha.js +1 -1
  36. package/js/src/bybit.js +1 -1
  37. package/js/src/cryptocom.js +3 -1
  38. package/js/src/deribit.js +39 -22
  39. package/js/src/kraken.d.ts +2 -2
  40. package/js/src/kraken.js +1 -1
  41. package/js/src/kucoin.js +30 -6
  42. package/js/src/lykke.d.ts +2 -2
  43. package/js/src/lykke.js +1 -1
  44. package/js/src/ndax.d.ts +2 -2
  45. package/js/src/ndax.js +1 -1
  46. package/js/src/pro/bitmart.d.ts +1 -0
  47. package/js/src/pro/bitmart.js +49 -27
  48. package/js/src/pro/blockchaincom.d.ts +1 -11
  49. package/js/src/pro/blockchaincom.js +2 -28
  50. package/js/src/pro/coinbasepro.js +9 -16
  51. package/js/src/pro/cryptocom.d.ts +3 -1
  52. package/js/src/pro/cryptocom.js +111 -29
  53. package/js/src/pro/luno.d.ts +4 -4
  54. package/js/src/pro/luno.js +5 -5
  55. package/package.json +11 -11
  56. package/tests-manager.sh +2 -2
package/js/src/deribit.js CHANGED
@@ -1726,27 +1726,18 @@ export default class deribit extends Exchange {
1726
1726
  * @param {string} symbol unified symbol of the market to create an order in
1727
1727
  * @param {string} type 'market' or 'limit'
1728
1728
  * @param {string} side 'buy' or 'sell'
1729
- * @param {float} amount how much of currency you want to trade. For perpetual and futures the amount is in USD. For options it is in corresponding cryptocurrency contracts currency.
1729
+ * @param {float} amount how much you want to trade in units of the base currency. For inverse perpetual and futures the amount is in the quote currency USD. For options it is in the underlying assets base currency.
1730
1730
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1731
1731
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1732
+ * @param {string} [params.trigger] the trigger type 'index_price', 'mark_price', or 'last_price', default is 'last_price'
1733
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
1732
1734
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1733
1735
  */
1734
1736
  await this.loadMarkets();
1735
1737
  const market = this.market(symbol);
1736
- if (market['inverse']) {
1737
- amount = this.amountToPrecision(symbol, amount);
1738
- }
1739
- else if (market['settle'] === 'USDC') {
1740
- amount = this.amountToPrecision(symbol, amount);
1741
- }
1742
- else {
1743
- amount = this.currencyToPrecision(symbol, amount);
1744
- }
1745
1738
  const request = {
1746
1739
  'instrument_name': market['id'],
1747
- // for perpetual and futures the amount is in USD
1748
- // for options it is in corresponding cryptocurrency contracts, e.g., BTC or ETH
1749
- 'amount': amount,
1740
+ 'amount': this.amountToPrecision(symbol, amount),
1750
1741
  'type': type, // limit, stop_limit, market, stop_market, default is limit
1751
1742
  // 'label': 'string', // user-defined label for the order (maximum 64 characters)
1752
1743
  // 'price': this.priceToPrecision (symbol, 123.45), // only for limit and stop_limit orders
@@ -1759,12 +1750,15 @@ export default class deribit extends Exchange {
1759
1750
  // 'trigger': 'index_price', // mark_price, last_price, required for stop_limit orders
1760
1751
  // 'advanced': 'usd', // 'implv', advanced option order type, options only
1761
1752
  };
1753
+ const trigger = this.safeString(params, 'trigger', 'last_price');
1762
1754
  const timeInForce = this.safeStringUpper(params, 'timeInForce');
1763
1755
  const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1764
1756
  // only stop loss sell orders are allowed when price crossed from above
1765
1757
  const stopLossPrice = this.safeValue(params, 'stopLossPrice');
1766
1758
  // only take profit buy orders are allowed when price crossed from below
1767
1759
  const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
1760
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trigger_offset');
1761
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1768
1762
  const isStopLimit = type === 'stop_limit';
1769
1763
  const isStopMarket = type === 'stop_market';
1770
1764
  const isTakeLimit = type === 'take_limit';
@@ -1786,10 +1780,15 @@ export default class deribit extends Exchange {
1786
1780
  else {
1787
1781
  request['type'] = 'market';
1788
1782
  }
1789
- if (isStopOrder) {
1783
+ if (isTrailingAmountOrder) {
1784
+ request['trigger'] = trigger;
1785
+ request['type'] = 'trailing_stop';
1786
+ request['trigger_offset'] = this.parseToNumeric(trailingAmount);
1787
+ }
1788
+ else if (isStopOrder) {
1790
1789
  const triggerPrice = (stopLossPrice !== undefined) ? stopLossPrice : takeProfitPrice;
1791
1790
  request['trigger_price'] = this.priceToPrecision(symbol, triggerPrice);
1792
- request['trigger'] = 'last_price'; // required
1791
+ request['trigger'] = trigger;
1793
1792
  if (isStopLossOrder) {
1794
1793
  if (isMarketOrder) {
1795
1794
  // stop_market (sell only)
@@ -1829,7 +1828,7 @@ export default class deribit extends Exchange {
1829
1828
  request['time_in_force'] = 'fill_or_kill';
1830
1829
  }
1831
1830
  }
1832
- params = this.omit(params, ['timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'reduceOnly']);
1831
+ params = this.omit(params, ['timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'reduceOnly', 'trailingAmount']);
1833
1832
  let response = undefined;
1834
1833
  if (this.capitalize(side) === 'Buy') {
1835
1834
  response = await this.privateGetBuy(this.extend(request, params));
@@ -1896,25 +1895,43 @@ export default class deribit extends Exchange {
1896
1895
  return this.parseOrder(order, market);
1897
1896
  }
1898
1897
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1898
+ /**
1899
+ * @method
1900
+ * @name deribit#editOrder
1901
+ * @description edit a trade order
1902
+ * @see https://docs.deribit.com/#private-edit
1903
+ * @param {string} id edit order id
1904
+ * @param {string} [symbol] unified symbol of the market to edit an order in
1905
+ * @param {string} [type] 'market' or 'limit'
1906
+ * @param {string} [side] 'buy' or 'sell'
1907
+ * @param {float} amount how much you want to trade in units of the base currency, inverse swap and future use the quote currency
1908
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1909
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1910
+ * @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
1911
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1912
+ */
1899
1913
  if (amount === undefined) {
1900
1914
  throw new ArgumentsRequired(this.id + ' editOrder() requires an amount argument');
1901
1915
  }
1902
- if (price === undefined) {
1903
- throw new ArgumentsRequired(this.id + ' editOrder() requires a price argument');
1904
- }
1905
1916
  await this.loadMarkets();
1906
1917
  const request = {
1907
1918
  'order_id': id,
1908
- // for perpetual and futures the amount is in USD
1909
- // for options it is in corresponding cryptocurrency contracts, e.g., BTC or ETH
1910
1919
  'amount': this.amountToPrecision(symbol, amount),
1911
- 'price': this.priceToPrecision(symbol, price), // required
1912
1920
  // 'post_only': false, // if the new price would cause the order to be filled immediately (as taker), the price will be changed to be just below the spread.
1913
1921
  // 'reject_post_only': false, // if true the order is put to order book unmodified or request is rejected
1914
1922
  // 'reduce_only': false, // if true, the order is intended to only reduce a current position
1915
1923
  // 'stop_price': false, // stop price, required for stop_limit orders
1916
1924
  // 'advanced': 'usd', // 'implv', advanced option order type, options only
1917
1925
  };
1926
+ if (price !== undefined) {
1927
+ request['price'] = this.priceToPrecision(symbol, price);
1928
+ }
1929
+ const trailingAmount = this.safeString2(params, 'trailingAmount', 'trigger_offset');
1930
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1931
+ if (isTrailingAmountOrder) {
1932
+ request['trigger_offset'] = this.parseToNumeric(trailingAmount);
1933
+ params = this.omit(params, 'trigger_offset');
1934
+ }
1918
1935
  const response = await this.privateGetEdit(this.extend(request, params));
1919
1936
  const result = this.safeValue(response, 'result', {});
1920
1937
  const order = this.safeValue(result, 'order');
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/kraken.js';
2
- import type { Int, OrderSide, OrderType, OHLCV, Trade, Order, Balances, Str, Transaction, Ticker, OrderBook, Tickers, Strings, Currency, Market } from './base/types.js';
2
+ import type { IndexType, Int, OrderSide, OrderType, OHLCV, Trade, Order, Balances, Str, Transaction, Ticker, OrderBook, Tickers, Strings, Currency, Market } from './base/types.js';
3
3
  /**
4
4
  * @class kraken
5
5
  * @augments Exchange
@@ -27,7 +27,7 @@ export default class kraken extends Exchange {
27
27
  percentage: boolean;
28
28
  tierBased: boolean;
29
29
  };
30
- parseBidAsk(bidask: any, priceKey?: number, amountKey?: number): number[];
30
+ parseBidAsk(bidask: any, priceKey?: IndexType, amountKey?: IndexType, countOrIdKey?: IndexType): number[];
31
31
  fetchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
32
32
  parseTicker(ticker: any, market?: Market): Ticker;
33
33
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
package/js/src/kraken.js CHANGED
@@ -754,7 +754,7 @@ export default class kraken extends Exchange {
754
754
  'tierBased': true,
755
755
  };
756
756
  }
757
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
757
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
758
758
  const price = this.safeNumber(bidask, priceKey);
759
759
  const amount = this.safeNumber(bidask, amountKey);
760
760
  const timestamp = this.safeInteger(bidask, 2);
package/js/src/kucoin.js CHANGED
@@ -2422,7 +2422,7 @@ export default class kucoin extends Exchange {
2422
2422
  // }
2423
2423
  // }
2424
2424
  const responseData = this.safeValue(response, 'data', {});
2425
- const orders = this.safeValue(responseData, 'items', []);
2425
+ const orders = this.safeValue(responseData, 'items', responseData);
2426
2426
  return this.parseOrders(orders, market, since, limit);
2427
2427
  }
2428
2428
  async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3448,10 +3448,12 @@ export default class kucoin extends Exchange {
3448
3448
  * @name kucoin#fetchBalance
3449
3449
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
3450
3450
  * @see https://docs.kucoin.com/#list-accounts
3451
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
3451
3452
  * @see https://docs.kucoin.com/#query-isolated-margin-account-info
3452
3453
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3453
3454
  * @param {object} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance
3454
3455
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
3456
+ * @param {object} [params.hf] *default if false* if true, the result includes the balance of the high frequency account
3455
3457
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
3456
3458
  */
3457
3459
  await this.loadMarkets();
@@ -3463,8 +3465,13 @@ export default class kucoin extends Exchange {
3463
3465
  const defaultType = this.safeString2(this.options, 'fetchBalance', 'defaultType', 'spot');
3464
3466
  const requestedType = this.safeString(params, 'type', defaultType);
3465
3467
  const accountsByType = this.safeValue(this.options, 'accountsByType');
3466
- const type = this.safeString(accountsByType, requestedType, requestedType);
3468
+ let type = this.safeString(accountsByType, requestedType, requestedType);
3467
3469
  params = this.omit(params, 'type');
3470
+ const isHf = this.safeValue(params, 'hf', false);
3471
+ if (isHf) {
3472
+ type = 'trade_hf';
3473
+ }
3474
+ params = this.omit(params, 'hf');
3468
3475
  const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
3469
3476
  let response = undefined;
3470
3477
  const request = {};
@@ -3546,7 +3553,7 @@ export default class kucoin extends Exchange {
3546
3553
  'datetime': undefined,
3547
3554
  };
3548
3555
  if (isolated) {
3549
- const assets = this.safeValue(data, 'assets', []);
3556
+ const assets = this.safeValue(data, 'assets', data);
3550
3557
  for (let i = 0; i < assets.length; i++) {
3551
3558
  const entry = assets[i];
3552
3559
  const marketId = this.safeString(entry, 'symbol');
@@ -3877,12 +3884,14 @@ export default class kucoin extends Exchange {
3877
3884
  * @method
3878
3885
  * @name kucoin#fetchLedger
3879
3886
  * @see https://docs.kucoin.com/#get-account-ledgers
3887
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
3888
+ * @see https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
3880
3889
  * @description fetch the history of changes, actions done by the user or operations that altered balance of the user
3881
- * @see https://docs.kucoin.com/#get-account-ledgers
3882
3890
  * @param {string} code unified currency code, default is undefined
3883
3891
  * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
3884
3892
  * @param {int} [limit] max number of ledger entrys to return, default is undefined
3885
3893
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3894
+ * @param {boolean} [params.hf] default false, when true will fetch ledger entries for the high frequency trading account
3886
3895
  * @param {int} [params.until] the latest time in ms to fetch entries for
3887
3896
  * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3888
3897
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
@@ -3891,6 +3900,8 @@ export default class kucoin extends Exchange {
3891
3900
  await this.loadAccounts();
3892
3901
  let paginate = false;
3893
3902
  [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
3903
+ const isHf = this.safeValue(params, 'hf');
3904
+ params = this.omit(params, 'hf');
3894
3905
  if (paginate) {
3895
3906
  return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
3896
3907
  }
@@ -3911,7 +3922,20 @@ export default class kucoin extends Exchange {
3911
3922
  request['currency'] = currency['id'];
3912
3923
  }
3913
3924
  [request, params] = this.handleUntilOption('endAt', request, params);
3914
- const response = await this.privateGetAccountsLedgers(this.extend(request, params));
3925
+ let marginMode = undefined;
3926
+ [marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
3927
+ let response = undefined;
3928
+ if (isHf) {
3929
+ if (marginMode !== undefined) {
3930
+ response = await this.privateGetHfMarginAccountLedgers(this.extend(request, params));
3931
+ }
3932
+ else {
3933
+ response = await this.privateGetHfAccountsLedgers(this.extend(request, params));
3934
+ }
3935
+ }
3936
+ else {
3937
+ response = await this.privateGetAccountsLedgers(this.extend(request, params));
3938
+ }
3915
3939
  //
3916
3940
  // {
3917
3941
  // "code":"200000",
@@ -3950,7 +3974,7 @@ export default class kucoin extends Exchange {
3950
3974
  // }
3951
3975
  //
3952
3976
  const data = this.safeValue(response, 'data');
3953
- const items = this.safeValue(data, 'items');
3977
+ const items = this.safeValue(data, 'items', data);
3954
3978
  return this.parseLedger(items, currency, since, limit);
3955
3979
  }
3956
3980
  calculateRateLimiterCost(api, method, path, params, config = {}) {
package/js/src/lykke.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/lykke.js';
2
- import type { Balances, Currency, Int, Market, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction } from './base/types.js';
2
+ import type { IndexType, Balances, Currency, Int, Market, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction } from './base/types.js';
3
3
  /**
4
4
  * @class lykke
5
5
  * @augments Exchange
@@ -25,7 +25,7 @@ export default class lykke extends Exchange {
25
25
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
26
26
  fetchClosedOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
27
27
  fetchMyTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
28
- parseBidAsk(bidask: any, priceKey?: number, amountKey?: number): number[];
28
+ parseBidAsk(bidask: any, priceKey?: IndexType, amountKey?: IndexType, countOrIdKey?: IndexType): number[];
29
29
  fetchDepositAddress(code: string, params?: {}): Promise<{
30
30
  currency: string;
31
31
  address: string;
package/js/src/lykke.js CHANGED
@@ -1081,7 +1081,7 @@ export default class lykke extends Exchange {
1081
1081
  //
1082
1082
  return this.parseTrades(payload, market, since, limit);
1083
1083
  }
1084
- parseBidAsk(bidask, priceKey = 0, amountKey = 1) {
1084
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
1085
1085
  const price = this.safeString(bidask, priceKey);
1086
1086
  const amount = Precise.stringAbs(this.safeString(bidask, amountKey));
1087
1087
  return [this.parseNumber(price), this.parseNumber(amount)];
package/js/src/ndax.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/ndax.js';
2
- import type { Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, Transaction } from './base/types.js';
2
+ import type { IndexType, Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, Transaction } from './base/types.js';
3
3
  /**
4
4
  * @class ndax
5
5
  * @augments Exchange
@@ -10,7 +10,7 @@ export default class ndax extends Exchange {
10
10
  fetchCurrencies(params?: {}): Promise<{}>;
11
11
  fetchMarkets(params?: {}): Promise<import("./base/types.js").MarketInterface[]>;
12
12
  parseMarket(market: any): Market;
13
- parseOrderBook(orderbook: any, symbol: any, timestamp?: any, bidsKey?: string, asksKey?: string, priceKey?: number, amountKey?: number): OrderBook;
13
+ parseOrderBook(orderbook: any, symbol: any, timestamp?: any, bidsKey?: string, asksKey?: string, priceKey?: IndexType, amountKey?: IndexType, countOrIdKey?: IndexType): OrderBook;
14
14
  fetchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
15
15
  parseTicker(ticker: any, market?: Market): Ticker;
16
16
  fetchTicker(symbol: string, params?: {}): Promise<Ticker>;
package/js/src/ndax.js CHANGED
@@ -521,7 +521,7 @@ export default class ndax extends Exchange {
521
521
  'info': market,
522
522
  };
523
523
  }
524
- parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 6, amountKey = 8) {
524
+ parseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 6, amountKey = 8, countOrIdKey = 2) {
525
525
  let nonce = undefined;
526
526
  const result = {
527
527
  'symbol': symbol,
@@ -22,6 +22,7 @@ export default class bitmart extends bitmartRest {
22
22
  handleTrade(client: Client, message: any): any;
23
23
  parseWsTrade(trade: any, market?: Market): Trade;
24
24
  handleTicker(client: Client, message: any): any;
25
+ resolveMessageHashesForSymbol(client: any, symbol: any, result: any, prexif: any): void;
25
26
  parseWsSwapTicker(ticker: any, market?: Market): Ticker;
26
27
  watchOHLCV(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OHLCV[]>;
27
28
  handleOHLCV(client: Client, message: any): void;
@@ -293,25 +293,39 @@ export default class bitmart extends bitmartRest {
293
293
  const market = this.getMarketFromSymbols(symbols);
294
294
  let type = 'spot';
295
295
  [type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
296
- symbols = this.marketSymbols(symbols);
297
- if (type === 'spot') {
298
- throw new NotSupported(this.id + ' watchTickers() does not support ' + type + ' markets. Use watchTicker() instead');
299
- }
300
296
  const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
301
- if (type === 'swap') {
302
- type = 'futures';
303
- }
304
- let messageHash = 'tickers';
297
+ symbols = this.marketSymbols(symbols);
298
+ let messageHash = 'tickers::' + type;
305
299
  if (symbols !== undefined) {
306
300
  messageHash += '::' + symbols.join(',');
307
301
  }
308
- const request = {
309
- 'action': 'subscribe',
310
- 'args': ['futures/ticker'],
311
- };
312
- const newTickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
302
+ let request = undefined;
303
+ let tickers = undefined;
304
+ const isSpot = (type === 'spot');
305
+ if (isSpot) {
306
+ if (symbols === undefined) {
307
+ throw new ArgumentsRequired(this.id + ' watchTickers() for ' + type + ' market type requires symbols argument to be provided');
308
+ }
309
+ const marketIds = this.marketIds(symbols);
310
+ const finalArray = [];
311
+ for (let i = 0; i < marketIds.length; i++) {
312
+ finalArray.push('spot/ticker:' + marketIds[i]);
313
+ }
314
+ request = {
315
+ 'op': 'subscribe',
316
+ 'args': finalArray,
317
+ };
318
+ tickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
319
+ }
320
+ else {
321
+ request = {
322
+ 'action': 'subscribe',
323
+ 'args': ['futures/ticker'],
324
+ };
325
+ tickers = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
326
+ }
313
327
  if (this.newUpdates) {
314
- return newTickers;
328
+ return tickers;
315
329
  }
316
330
  return this.filterByArray(this.tickers, 'symbol', symbols);
317
331
  }
@@ -896,28 +910,36 @@ export default class bitmart extends bitmartRest {
896
910
  const messageHash = table + ':' + marketId;
897
911
  this.tickers[symbol] = ticker;
898
912
  client.resolve(ticker, messageHash);
913
+ this.resolveMessageHashesForSymbol(client, symbol, ticker, 'tickers::');
899
914
  }
900
915
  }
901
916
  else {
917
+ // on each update for contract markets, single ticker is provided
902
918
  const ticker = this.parseWsSwapTicker(data);
903
919
  const symbol = this.safeString(ticker, 'symbol');
904
920
  this.tickers[symbol] = ticker;
905
- client.resolve(ticker, 'tickers');
906
- const messageHashes = this.findMessageHashes(client, 'tickers::');
907
- for (let i = 0; i < messageHashes.length; i++) {
908
- const messageHash = messageHashes[i];
909
- const parts = messageHash.split('::');
910
- const symbolsString = parts[1];
911
- const symbols = symbolsString.split(',');
912
- if (this.inArray(symbol, symbols)) {
913
- const response = {};
914
- response[symbol] = ticker;
915
- client.resolve(response, messageHash);
916
- }
917
- }
921
+ client.resolve(ticker, 'tickers::swap');
922
+ this.resolveMessageHashesForSymbol(client, symbol, ticker, 'tickers::');
918
923
  }
919
924
  return message;
920
925
  }
926
+ resolveMessageHashesForSymbol(client, symbol, result, prexif) {
927
+ const prefixSeparator = '::';
928
+ const symbolsSeparator = ',';
929
+ const messageHashes = this.findMessageHashes(client, prexif);
930
+ for (let i = 0; i < messageHashes.length; i++) {
931
+ const messageHash = messageHashes[i];
932
+ const parts = messageHash.split(prefixSeparator);
933
+ const length = parts.length;
934
+ const symbolsString = parts[length - 1];
935
+ const symbols = symbolsString.split(symbolsSeparator);
936
+ if (this.inArray(symbol, symbols)) {
937
+ const response = {};
938
+ response[symbol] = result;
939
+ client.resolve(response, messageHash);
940
+ }
941
+ }
942
+ }
921
943
  parseWsSwapTicker(ticker, market = undefined) {
922
944
  //
923
945
  // {
@@ -1,5 +1,5 @@
1
1
  import blockchaincomRest from '../blockchaincom.js';
2
- import type { IndexType, Int, Str, OrderBook, Order, Trade, Ticker, OHLCV, Balances } from '../base/types.js';
2
+ import type { Int, Str, OrderBook, Order, Trade, Ticker, OHLCV, Balances } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class blockchaincom extends blockchaincomRest {
5
5
  describe(): any;
@@ -19,16 +19,6 @@ export default class blockchaincom extends blockchaincomRest {
19
19
  parseWsOrderStatus(status: any): string;
20
20
  watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
21
21
  handleOrderBook(client: Client, message: any): any;
22
- parseCountedBidAsk(bidAsk: any, priceKey?: IndexType, amountKey?: IndexType, countKey?: IndexType): number[];
23
- parseCountedBidsAsks(bidasks: any, priceKey?: IndexType, amountKey?: IndexType, countKey?: IndexType): any[];
24
- parseCountedOrderBook(orderbook: any, symbol: string, timestamp?: Int, bidsKey?: IndexType, asksKey?: IndexType, priceKey?: IndexType, amountKey?: IndexType, countKey?: IndexType): {
25
- symbol: string;
26
- bids: any;
27
- asks: any;
28
- timestamp: number;
29
- datetime: string;
30
- nonce: any;
31
- };
32
22
  handleDelta(bookside: any, delta: any): void;
33
23
  handleDeltas(bookside: any, deltas: any): void;
34
24
  checkSequenceNumber(client: Client, message: any): void;
@@ -698,7 +698,7 @@ export default class blockchaincom extends blockchaincomRest {
698
698
  return message;
699
699
  }
700
700
  else if (event === 'snapshot') {
701
- const snapshot = this.parseCountedOrderBook(message, symbol, timestamp, 'bids', 'asks', 'px', 'qty', 'num');
701
+ const snapshot = this.parseOrderBook(message, symbol, timestamp, 'bids', 'asks', 'px', 'qty', 'num');
702
702
  storedOrderBook.reset(snapshot);
703
703
  }
704
704
  else if (event === 'updated') {
@@ -714,34 +714,8 @@ export default class blockchaincom extends blockchaincomRest {
714
714
  }
715
715
  client.resolve(storedOrderBook, messageHash);
716
716
  }
717
- parseCountedBidAsk(bidAsk, priceKey = 0, amountKey = 1, countKey = 2) {
718
- const price = this.safeNumber(bidAsk, priceKey);
719
- const amount = this.safeNumber(bidAsk, amountKey);
720
- const count = this.safeNumber(bidAsk, countKey);
721
- return [price, amount, count];
722
- }
723
- parseCountedBidsAsks(bidasks, priceKey = 0, amountKey = 1, countKey = 2) {
724
- bidasks = this.toArray(bidasks);
725
- const result = [];
726
- for (let i = 0; i < bidasks.length; i++) {
727
- result.push(this.parseCountedBidAsk(bidasks[i], priceKey, amountKey, countKey));
728
- }
729
- return result;
730
- }
731
- parseCountedOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 0, amountKey = 1, countKey = 2) {
732
- const bids = this.parseCountedBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, countKey);
733
- const asks = this.parseCountedBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, countKey);
734
- return {
735
- 'symbol': symbol,
736
- 'bids': this.sortBy(bids, 0, true),
737
- 'asks': this.sortBy(asks, 0),
738
- 'timestamp': timestamp,
739
- 'datetime': this.iso8601(timestamp),
740
- 'nonce': undefined,
741
- };
742
- }
743
717
  handleDelta(bookside, delta) {
744
- const bookArray = this.parseCountedBidAsk(delta, 'px', 'qty', 'num');
718
+ const bookArray = this.parseBidAsk(delta, 'px', 'qty', 'num');
745
719
  bookside.storeArray(bookArray);
746
720
  }
747
721
  handleDeltas(bookside, deltas) {
@@ -92,7 +92,7 @@ export default class coinbasepro extends coinbaseproRest {
92
92
  const symbol = symbols[i];
93
93
  market = this.market(symbol);
94
94
  productIds.push(market['id']);
95
- messageHashes.push(messageHashStart + ':' + market['id']);
95
+ messageHashes.push(messageHashStart + ':' + market['symbol']);
96
96
  }
97
97
  let url = this.urls['api']['ws'];
98
98
  if ('signature' in params) {
@@ -137,10 +137,12 @@ export default class coinbasepro extends coinbaseproRest {
137
137
  throw new BadSymbol(this.id + ' watchTickers requires a non-empty symbols array');
138
138
  }
139
139
  const channel = 'ticker';
140
- const messageHash = 'tickers::';
141
- const newTickers = await this.subscribeMultiple(channel, symbols, messageHash, params);
140
+ const messageHash = 'ticker';
141
+ const ticker = await this.subscribeMultiple(channel, symbols, messageHash, params);
142
142
  if (this.newUpdates) {
143
- return newTickers;
143
+ const result = {};
144
+ result[ticker['symbol']] = ticker;
145
+ return result;
144
146
  }
145
147
  return this.filterByArray(this.tickers, 'symbol', symbols);
146
148
  }
@@ -752,19 +754,10 @@ export default class coinbasepro extends coinbaseproRest {
752
754
  const ticker = this.parseTicker(message);
753
755
  const symbol = ticker['symbol'];
754
756
  this.tickers[symbol] = ticker;
755
- const type = this.safeString(message, 'type');
756
- const messageHash = type + ':' + marketId;
757
+ const messageHash = 'ticker:' + symbol;
758
+ const idMessageHash = 'ticker:' + marketId;
757
759
  client.resolve(ticker, messageHash);
758
- const messageHashes = this.findMessageHashes(client, 'tickers::');
759
- for (let i = 0; i < messageHashes.length; i++) {
760
- const currentMessageHash = messageHashes[i];
761
- const parts = currentMessageHash.split('::');
762
- const symbolsString = parts[1];
763
- const symbols = symbolsString.split(',');
764
- if (this.inArray(symbol, symbols)) {
765
- client.resolve(ticker, currentMessageHash);
766
- }
767
- }
760
+ client.resolve(ticker, idMessageHash);
768
761
  }
769
762
  return message;
770
763
  }
@@ -6,7 +6,9 @@ export default class cryptocom extends cryptocomRest {
6
6
  pong(client: any, message: any): Promise<void>;
7
7
  watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
8
8
  watchOrderBookForSymbols(symbols: string[], limit?: Int, params?: {}): Promise<OrderBook>;
9
- handleOrderBookSnapshot(client: Client, message: any): void;
9
+ handleDelta(bookside: any, delta: any): void;
10
+ handleDeltas(bookside: any, deltas: any): void;
11
+ handleOrderBook(client: Client, message: any): void;
10
12
  watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
11
13
  watchTradesForSymbols(symbols: string[], since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
12
14
  handleTrades(client: Client, message: any): void;