ccxt 4.2.93 → 4.2.95

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 (60) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1055 -366
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +22 -1
  6. package/dist/cjs/src/base/errors.js +25 -64
  7. package/dist/cjs/src/base/ws/OrderBookSide.js +5 -0
  8. package/dist/cjs/src/binance.js +63 -2
  9. package/dist/cjs/src/bitget.js +139 -0
  10. package/dist/cjs/src/bitstamp.js +6 -0
  11. package/dist/cjs/src/coinex.js +61 -55
  12. package/dist/cjs/src/gemini.js +2 -1
  13. package/dist/cjs/src/htx.js +127 -125
  14. package/dist/cjs/src/okx.js +193 -40
  15. package/dist/cjs/src/pro/coinbase.js +18 -0
  16. package/dist/cjs/src/pro/kraken.js +107 -17
  17. package/dist/cjs/src/pro/krakenfutures.js +117 -40
  18. package/dist/cjs/src/pro/kucoin.js +30 -19
  19. package/dist/cjs/src/woo.js +139 -0
  20. package/examples/js/cli.js +4 -1
  21. package/examples/ts/cli.ts +4 -1
  22. package/js/ccxt.d.ts +4 -4
  23. package/js/ccxt.js +3 -3
  24. package/js/src/abstract/binance.d.ts +1 -0
  25. package/js/src/abstract/binancecoinm.d.ts +1 -0
  26. package/js/src/abstract/binanceus.d.ts +1 -0
  27. package/js/src/abstract/binanceusdm.d.ts +1 -0
  28. package/js/src/abstract/bitstamp.d.ts +6 -0
  29. package/js/src/base/Exchange.d.ts +8 -2
  30. package/js/src/base/Exchange.js +22 -1
  31. package/js/src/base/errorHierarchy.d.ts +1 -1
  32. package/js/src/base/errorHierarchy.js +1 -1
  33. package/js/src/base/errors.d.ts +26 -26
  34. package/js/src/base/errors.js +26 -66
  35. package/js/src/base/types.d.ts +12 -0
  36. package/js/src/base/ws/OrderBook.d.ts +7 -0
  37. package/js/src/base/ws/OrderBook.js +1 -6
  38. package/js/src/base/ws/OrderBookSide.d.ts +9 -3
  39. package/js/src/base/ws/OrderBookSide.js +6 -1
  40. package/js/src/binance.d.ts +1 -0
  41. package/js/src/binance.js +63 -2
  42. package/js/src/bitget.d.ts +4 -1
  43. package/js/src/bitget.js +139 -0
  44. package/js/src/bitstamp.js +6 -0
  45. package/js/src/coinex.js +61 -55
  46. package/js/src/gemini.js +2 -1
  47. package/js/src/htx.d.ts +1 -0
  48. package/js/src/htx.js +128 -126
  49. package/js/src/okx.d.ts +4 -1
  50. package/js/src/okx.js +193 -40
  51. package/js/src/pro/coinbase.js +18 -0
  52. package/js/src/pro/kraken.d.ts +6 -1
  53. package/js/src/pro/kraken.js +107 -17
  54. package/js/src/pro/krakenfutures.d.ts +8 -2
  55. package/js/src/pro/krakenfutures.js +117 -40
  56. package/js/src/pro/kucoin.js +30 -19
  57. package/js/src/woo.d.ts +4 -1
  58. package/js/src/woo.js +139 -0
  59. package/package.json +1 -1
  60. package/skip-tests.json +5 -0
package/js/src/coinex.js CHANGED
@@ -1091,8 +1091,8 @@ export default class coinex extends Exchange {
1091
1091
  * @method
1092
1092
  * @name coinex#fetchOrderBook
1093
1093
  * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
1094
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market004_market_depth
1095
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http010_market_depth
1094
+ * @see https://docs.coinex.com/api/v2/spot/market/http/list-market-depth
1095
+ * @see https://docs.coinex.com/api/v2/futures/market/http/list-market-depth
1096
1096
  * @param {string} symbol unified symbol of the market to fetch the order book for
1097
1097
  * @param {int} [limit] the maximum amount of order book entries to return
1098
1098
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -1104,65 +1104,71 @@ export default class coinex extends Exchange {
1104
1104
  limit = 20; // default
1105
1105
  }
1106
1106
  const request = {
1107
- 'market': this.marketId(symbol),
1108
- 'merge': '0',
1109
- 'limit': limit.toString(),
1107
+ 'market': market['id'],
1108
+ 'limit': limit,
1109
+ 'interval': '0',
1110
1110
  };
1111
1111
  let response = undefined;
1112
1112
  if (market['swap']) {
1113
- response = await this.v1PerpetualPublicGetMarketDepth(this.extend(request, params));
1113
+ response = await this.v2PublicGetFuturesDepth(this.extend(request, params));
1114
+ //
1115
+ // {
1116
+ // "code": 0,
1117
+ // "data": {
1118
+ // "depth": {
1119
+ // "asks": [
1120
+ // ["70851.94", "0.2119"],
1121
+ // ["70851.95", "0.0004"],
1122
+ // ["70851.96", "0.0004"]
1123
+ // ],
1124
+ // "bids": [
1125
+ // ["70851.93", "1.0314"],
1126
+ // ["70850.93", "0.0021"],
1127
+ // ["70850.42", "0.0306"]
1128
+ // ],
1129
+ // "checksum": 2956436260,
1130
+ // "last": "70851.94",
1131
+ // "updated_at": 1712824003252
1132
+ // },
1133
+ // "is_full": true,
1134
+ // "market": "BTCUSDT"
1135
+ // },
1136
+ // "message": "OK"
1137
+ // }
1138
+ //
1114
1139
  }
1115
1140
  else {
1116
- response = await this.v1PublicGetMarketDepth(this.extend(request, params));
1141
+ response = await this.v2PublicGetSpotDepth(this.extend(request, params));
1142
+ //
1143
+ // {
1144
+ // "code": 0,
1145
+ // "data": {
1146
+ // "depth": {
1147
+ // "asks": [
1148
+ // ["70875.31", "0.28670282"],
1149
+ // ["70875.32", "0.31008114"],
1150
+ // ["70875.42", "0.05876653"]
1151
+ // ],
1152
+ // "bids": [
1153
+ // ["70855.3", "0.00632222"],
1154
+ // ["70855.29", "0.36216834"],
1155
+ // ["70855.17", "0.10166802"]
1156
+ // ],
1157
+ // "checksum": 2313816665,
1158
+ // "last": "70857.19",
1159
+ // "updated_at": 1712823790987
1160
+ // },
1161
+ // "is_full": true,
1162
+ // "market": "BTCUSDT"
1163
+ // },
1164
+ // "message": "OK"
1165
+ // }
1166
+ //
1117
1167
  }
1118
- //
1119
- // Spot
1120
- //
1121
- // {
1122
- // "code": 0,
1123
- // "data": {
1124
- // "asks": [
1125
- // ["41056.33", "0.31727613"],
1126
- // ["41056.34", "1.05657294"],
1127
- // ["41056.35", "0.02346648"]
1128
- // ],
1129
- // "bids": [
1130
- // ["41050.61", "0.40618608"],
1131
- // ["41046.98", "0.13800000"],
1132
- // ["41046.56", "0.22579234"]
1133
- // ],
1134
- // "last": "41050.61",
1135
- // "time": 1650573220346
1136
- // },
1137
- // "message": "OK"
1138
- // }
1139
- //
1140
- // Swap
1141
- //
1142
- // {
1143
- // "code": 0,
1144
- // "data": {
1145
- // "asks": [
1146
- // ["40620.90", "0.0384"],
1147
- // ["40625.50", "0.0219"],
1148
- // ["40625.90", "0.3506"]
1149
- // ],
1150
- // "bids": [
1151
- // ["40620.89", "19.6861"],
1152
- // ["40620.80", "0.0012"],
1153
- // ["40619.87", "0.0365"]
1154
- // ],
1155
- // "last": "40620.89",
1156
- // "time": 1650587672406,
1157
- // "sign_price": "40619.32",
1158
- // "index_price": "40609.93"
1159
- // },
1160
- // "message": "OK"
1161
- // }
1162
- //
1163
- const result = this.safeValue(response, 'data', {});
1164
- const timestamp = this.safeInteger(result, 'time');
1165
- return this.parseOrderBook(result, symbol, timestamp);
1168
+ const data = this.safeDict(response, 'data', {});
1169
+ const depth = this.safeDict(data, 'depth', {});
1170
+ const timestamp = this.safeInteger(depth, 'updated_at');
1171
+ return this.parseOrderBook(depth, symbol, timestamp);
1166
1172
  }
1167
1173
  parseTrade(trade, market = undefined) {
1168
1174
  //
package/js/src/gemini.js CHANGED
@@ -686,7 +686,8 @@ export default class gemini extends Exchange {
686
686
  for (let i = 0; i < quoteQurrencies.length; i++) {
687
687
  const quoteCurrency = quoteQurrencies[i];
688
688
  if (marketIdWithoutPerp.endsWith(quoteCurrency)) {
689
- baseId = marketIdWithoutPerp.replace(quoteCurrency, '');
689
+ const quoteLength = this.parseToInt(-1 * quoteCurrency.length);
690
+ baseId = marketIdWithoutPerp.slice(0, quoteLength);
690
691
  quoteId = quoteCurrency;
691
692
  if (isPerp) {
692
693
  settleId = quoteCurrency; // always same
package/js/src/htx.d.ts CHANGED
@@ -38,6 +38,7 @@ export default class htx extends Exchange {
38
38
  costToPrecision(symbol: any, cost: any): any;
39
39
  fetchMarkets(params?: {}): Promise<Market[]>;
40
40
  fetchMarketsByTypeAndSubType(type: any, subType: any, params?: {}): Promise<any[]>;
41
+ tryGetSymbolFromFutureMarkets(symbolOrMarketId: string): any;
41
42
  parseTicker(ticker: any, market?: Market): Ticker;
42
43
  fetchTicker(symbol: string, params?: {}): Promise<Ticker>;
43
44
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
package/js/src/htx.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/htx.js';
9
- import { AccountNotEnabled, ArgumentsRequired, AuthenticationError, ExchangeError, PermissionDenied, ExchangeNotAvailable, OnMaintenance, InvalidOrder, OrderNotFound, InsufficientFunds, BadSymbol, BadRequest, RateLimitExceeded, RequestTimeout, NetworkError, NotSupported } from './base/errors.js';
9
+ import { AccountNotEnabled, ArgumentsRequired, AuthenticationError, ExchangeError, PermissionDenied, ExchangeNotAvailable, OnMaintenance, InvalidOrder, OrderNotFound, InsufficientFunds, BadSymbol, BadRequest, RateLimitExceeded, RequestTimeout, OperationFailed, NotSupported } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TICK_SIZE, TRUNCATE } from './base/functions/number.js';
12
12
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
@@ -943,14 +943,8 @@ export default class htx extends Exchange {
943
943
  'fetchMarkets': {
944
944
  'types': {
945
945
  'spot': true,
946
- 'future': {
947
- 'linear': true,
948
- 'inverse': true,
949
- },
950
- 'swap': {
951
- 'linear': true,
952
- 'inverse': true,
953
- },
946
+ 'linear': true,
947
+ 'inverse': true,
954
948
  },
955
949
  },
956
950
  'fetchOHLCV': {
@@ -1617,25 +1611,23 @@ export default class htx extends Exchange {
1617
1611
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1618
1612
  * @returns {object[]} an array of objects representing market data
1619
1613
  */
1620
- const options = this.safeValue(this.options, 'fetchMarkets', {});
1621
- const types = this.safeValue(options, 'types', {});
1614
+ let types = undefined;
1615
+ [types, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'types', {});
1622
1616
  let allMarkets = [];
1623
1617
  let promises = [];
1624
1618
  const keys = Object.keys(types);
1625
1619
  for (let i = 0; i < keys.length; i++) {
1626
- const type = keys[i];
1627
- const value = this.safeValue(types, type);
1628
- if (value === true) {
1629
- promises.push(this.fetchMarketsByTypeAndSubType(type, undefined, params));
1630
- }
1631
- else if (value) {
1632
- const subKeys = Object.keys(value);
1633
- for (let j = 0; j < subKeys.length; j++) {
1634
- const subType = subKeys[j];
1635
- const subValue = this.safeValue(value, subType);
1636
- if (subValue) {
1637
- promises.push(this.fetchMarketsByTypeAndSubType(type, subType, params));
1638
- }
1620
+ const key = keys[i];
1621
+ if (this.safeBool(types, key)) {
1622
+ if (key === 'spot') {
1623
+ promises.push(this.fetchMarketsByTypeAndSubType('spot', undefined, params));
1624
+ }
1625
+ else if (key === 'linear') {
1626
+ promises.push(this.fetchMarketsByTypeAndSubType(undefined, 'linear', params));
1627
+ }
1628
+ else if (key === 'inverse') {
1629
+ promises.push(this.fetchMarketsByTypeAndSubType('swap', 'inverse', params));
1630
+ promises.push(this.fetchMarketsByTypeAndSubType('future', 'inverse', params));
1639
1631
  }
1640
1632
  }
1641
1633
  }
@@ -1646,35 +1638,25 @@ export default class htx extends Exchange {
1646
1638
  return allMarkets;
1647
1639
  }
1648
1640
  async fetchMarketsByTypeAndSubType(type, subType, params = {}) {
1649
- const query = this.omit(params, ['type', 'subType']);
1650
- const spot = (type === 'spot');
1651
- const contract = (type !== 'spot');
1652
- const future = (type === 'future');
1653
- const swap = (type === 'swap');
1654
- let linear = undefined;
1655
- let inverse = undefined;
1641
+ const isSpot = (type === 'spot');
1656
1642
  const request = {};
1657
1643
  let response = undefined;
1658
- if (contract) {
1659
- linear = (subType === 'linear');
1660
- inverse = (subType === 'inverse');
1661
- if (linear) {
1662
- if (future) {
1663
- request['business_type'] = 'futures';
1664
- }
1665
- response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, query));
1644
+ if (!isSpot) {
1645
+ if (subType === 'linear') {
1646
+ request['business_type'] = 'all'; // override default to fetch all linear markets
1647
+ response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, params));
1666
1648
  }
1667
- else if (inverse) {
1668
- if (future) {
1669
- response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, query));
1649
+ else if (subType === 'inverse') {
1650
+ if (type === 'future') {
1651
+ response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, params));
1670
1652
  }
1671
- else if (swap) {
1672
- response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, query));
1653
+ else if (type === 'swap') {
1654
+ response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, params));
1673
1655
  }
1674
1656
  }
1675
1657
  }
1676
1658
  else {
1677
- response = await this.spotPublicGetV1CommonSymbols(this.extend(request, query));
1659
+ response = await this.spotPublicGetV1CommonSymbols(this.extend(request, params));
1678
1660
  }
1679
1661
  //
1680
1662
  // spot
@@ -1714,75 +1696,58 @@ export default class htx extends Exchange {
1714
1696
  // ]
1715
1697
  // }
1716
1698
  //
1717
- // inverse future
1699
+ // inverse (swap & future)
1718
1700
  //
1719
1701
  // {
1720
1702
  // "status":"ok",
1721
1703
  // "data":[
1722
1704
  // {
1723
1705
  // "symbol":"BTC",
1724
- // "contract_code":"BTC211126",
1725
- // "contract_type":"this_week",
1726
- // "contract_size":100.000000000000000000,
1727
- // "price_tick":0.010000000000000000,
1728
- // "delivery_date":"20211126",
1729
- // "delivery_time":"1637913600000",
1706
+ // "contract_code":"BTC211126", /// BTC-USD in swap
1707
+ // "contract_type":"this_week", // only in future
1708
+ // "contract_size":100,
1709
+ // "price_tick":0.1,
1710
+ // "delivery_date":"20211126", // only in future
1711
+ // "delivery_time":"1637913600000", // empty in swap
1730
1712
  // "create_date":"20211112",
1731
1713
  // "contract_status":1,
1732
- // "settlement_time":"1637481600000"
1714
+ // "settlement_time":"1637481600000" // only in future
1715
+ // "settlement_date":"16xxxxxxxxxxx" // only in swap
1733
1716
  // },
1717
+ // ...
1734
1718
  // ],
1735
1719
  // "ts":1637474595140
1736
1720
  // }
1737
1721
  //
1738
- // linear futures
1722
+ // linear (swap & future)
1739
1723
  //
1740
1724
  // {
1741
1725
  // "status":"ok",
1742
1726
  // "data":[
1743
1727
  // {
1744
1728
  // "symbol":"BTC",
1745
- // "contract_code":"BTC-USDT-211231",
1746
- // "contract_size":0.001000000000000000,
1747
- // "price_tick":0.100000000000000000,
1748
- // "delivery_date":"20211231",
1749
- // "delivery_time":"1640937600000",
1729
+ // "contract_code":"BTC-USDT-211231", // or "BTC-USDT" in swap
1730
+ // "contract_size":0.001,
1731
+ // "price_tick":0.1,
1732
+ // "delivery_date":"20211231", // empty in swap
1733
+ // "delivery_time":"1640937600000", // empty in swap
1750
1734
  // "create_date":"20211228",
1751
1735
  // "contract_status":1,
1752
1736
  // "settlement_date":"1640764800000",
1753
- // "support_margin_mode":"cross",
1754
- // "business_type":"futures",
1737
+ // "support_margin_mode":"cross", // "all" or "cross"
1738
+ // "business_type":"futures", // "swap" or "futures"
1755
1739
  // "pair":"BTC-USDT",
1756
- // "contract_type":"this_week" // next_week, quarter
1757
- // },
1740
+ // "contract_type":"this_week", // "swap", "this_week", "next_week", "quarter"
1741
+ // "trade_partition":"USDT",
1742
+ // }
1758
1743
  // ],
1759
1744
  // "ts":1640736207263
1760
1745
  // }
1761
1746
  //
1762
- // swaps
1763
- //
1764
- // {
1765
- // "status":"ok",
1766
- // "data":[
1767
- // {
1768
- // "symbol":"BTC",
1769
- // "contract_code":"BTC-USDT",
1770
- // "contract_size":0.001000000000000000,
1771
- // "price_tick":0.100000000000000000,
1772
- // "delivery_time":"",
1773
- // "create_date":"20201021",
1774
- // "contract_status":1,
1775
- // "settlement_date":"1637481600000",
1776
- // "support_margin_mode":"all", // isolated
1777
- // },
1778
- // ],
1779
- // "ts":1637474774467
1780
- // }
1781
- //
1782
- const markets = this.safeValue(response, 'data', []);
1747
+ const markets = this.safeList(response, 'data', []);
1783
1748
  const numMarkets = markets.length;
1784
1749
  if (numMarkets < 1) {
1785
- throw new NetworkError(this.id + ' fetchMarkets() returned an empty response: ' + this.json(markets));
1750
+ throw new OperationFailed(this.id + ' fetchMarkets() returned an empty response: ' + this.json(response));
1786
1751
  }
1787
1752
  const result = [];
1788
1753
  for (let i = 0; i < markets.length; i++) {
@@ -1792,16 +1757,31 @@ export default class htx extends Exchange {
1792
1757
  let settleId = undefined;
1793
1758
  let id = undefined;
1794
1759
  let lowercaseId = undefined;
1760
+ const contract = ('contract_code' in market);
1761
+ const spot = !contract;
1762
+ let swap = false;
1763
+ let future = false;
1764
+ let linear = undefined;
1765
+ let inverse = undefined;
1766
+ // check if parsed market is contract
1795
1767
  if (contract) {
1796
1768
  id = this.safeString(market, 'contract_code');
1797
1769
  lowercaseId = id.toLowerCase();
1770
+ const delivery_date = this.safeString(market, 'delivery_date');
1771
+ const business_type = this.safeString(market, 'business_type');
1772
+ future = delivery_date !== undefined;
1773
+ swap = !future;
1774
+ linear = business_type !== undefined;
1775
+ inverse = !linear;
1798
1776
  if (swap) {
1777
+ type = 'swap';
1799
1778
  const parts = id.split('-');
1800
1779
  baseId = this.safeStringLower(market, 'symbol');
1801
1780
  quoteId = this.safeStringLower(parts, 1);
1802
1781
  settleId = inverse ? baseId : quoteId;
1803
1782
  }
1804
1783
  else if (future) {
1784
+ type = 'future';
1805
1785
  baseId = this.safeStringLower(market, 'symbol');
1806
1786
  if (inverse) {
1807
1787
  quoteId = 'USD';
@@ -1816,6 +1796,7 @@ export default class htx extends Exchange {
1816
1796
  }
1817
1797
  }
1818
1798
  else {
1799
+ type = 'spot';
1819
1800
  baseId = this.safeString(market, 'base-currency');
1820
1801
  quoteId = this.safeString(market, 'quote-currency');
1821
1802
  id = baseId + quoteId;
@@ -1950,6 +1931,45 @@ export default class htx extends Exchange {
1950
1931
  }
1951
1932
  return result;
1952
1933
  }
1934
+ tryGetSymbolFromFutureMarkets(symbolOrMarketId) {
1935
+ if (symbolOrMarketId in this.markets) {
1936
+ return symbolOrMarketId;
1937
+ }
1938
+ // only on "future" market type (inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker"
1939
+ // so we have to create a mapping
1940
+ // - market-id from fetchMarkts: `BTC-USDT-240419` (linear future) or `BTC240412` (inverse future)
1941
+ // - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future)
1942
+ if (!('futureMarketIdsForSymbols' in this.options)) {
1943
+ this.options['futureMarketIdsForSymbols'] = {};
1944
+ }
1945
+ const futureMarketIdsForSymbols = this.safeDict(this.options, 'futureMarketIdsForSymbols', {});
1946
+ if (symbolOrMarketId in futureMarketIdsForSymbols) {
1947
+ return futureMarketIdsForSymbols[symbolOrMarketId];
1948
+ }
1949
+ const futureMarkets = this.filterBy(this.markets, 'future', true);
1950
+ const futuresCharsMaps = {
1951
+ 'this_week': 'CW',
1952
+ 'next_week': 'NW',
1953
+ 'quarter': 'CQ',
1954
+ 'next_quarter': 'NQ',
1955
+ };
1956
+ for (let i = 0; i < futureMarkets.length; i++) {
1957
+ const market = futureMarkets[i];
1958
+ const info = this.safeValue(market, 'info', {});
1959
+ const contractType = this.safeString(info, 'contract_type');
1960
+ const contractSuffix = futuresCharsMaps[contractType];
1961
+ // see comment on formats a bit above
1962
+ const constructedId = market['linear'] ? market['base'] + '-' + market['quote'] + '-' + contractSuffix : market['base'] + '_' + contractSuffix;
1963
+ if (constructedId === symbolOrMarketId) {
1964
+ const symbol = market['symbol'];
1965
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbol;
1966
+ return symbol;
1967
+ }
1968
+ }
1969
+ // if not found, just save it to avoid unnecessary future iterations
1970
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbolOrMarketId;
1971
+ return symbolOrMarketId;
1972
+ }
1953
1973
  parseTicker(ticker, market = undefined) {
1954
1974
  //
1955
1975
  // fetchTicker
@@ -1997,7 +2017,8 @@ export default class htx extends Exchange {
1997
2017
  // }
1998
2018
  //
1999
2019
  const marketId = this.safeString2(ticker, 'symbol', 'contract_code');
2000
- const symbol = this.safeSymbol(marketId, market);
2020
+ let symbol = this.safeSymbol(marketId, market);
2021
+ symbol = this.tryGetSymbolFromFutureMarkets(symbol);
2001
2022
  const timestamp = this.safeInteger2(ticker, 'ts', 'quoteTime');
2002
2023
  let bid = undefined;
2003
2024
  let bidVolume = undefined;
@@ -2140,7 +2161,7 @@ export default class htx extends Exchange {
2140
2161
  * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2141
2162
  * @see https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2142
2163
  * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2143
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2164
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2144
2165
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2145
2166
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
2146
2167
  */
@@ -2151,22 +2172,30 @@ export default class htx extends Exchange {
2151
2172
  if (first !== undefined) {
2152
2173
  market = this.market(first);
2153
2174
  }
2175
+ const isSubTypeRequested = ('subType' in params) || ('business_type' in params);
2154
2176
  let type = undefined;
2155
2177
  let subType = undefined;
2156
2178
  [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
2157
2179
  [subType, params] = this.handleSubTypeAndParams('fetchTickers', market, params);
2158
2180
  const request = {};
2181
+ const isSpot = (type === 'spot');
2159
2182
  const future = (type === 'future');
2160
2183
  const swap = (type === 'swap');
2161
2184
  const linear = (subType === 'linear');
2162
2185
  const inverse = (subType === 'inverse');
2163
- params = this.omit(params, ['type', 'subType']);
2164
2186
  let response = undefined;
2165
- if (future || swap) {
2187
+ if (!isSpot || isSubTypeRequested) {
2166
2188
  if (linear) {
2189
+ // independently of type, supports calling all linear symbols i.e. fetchTickers(undefined, {subType:'linear'})
2167
2190
  if (future) {
2168
2191
  request['business_type'] = 'futures';
2169
2192
  }
2193
+ else if (swap) {
2194
+ request['business_type'] = 'swap';
2195
+ }
2196
+ else {
2197
+ request['business_type'] = 'all';
2198
+ }
2170
2199
  response = await this.contractPublicGetLinearSwapExMarketDetailBatchMerged(this.extend(request, params));
2171
2200
  }
2172
2201
  else if (inverse) {
@@ -2176,6 +2205,12 @@ export default class htx extends Exchange {
2176
2205
  else if (swap) {
2177
2206
  response = await this.contractPublicGetSwapExMarketDetailBatchMerged(this.extend(request, params));
2178
2207
  }
2208
+ else {
2209
+ throw new NotSupported(this.id + ' fetchTickers() you have to set params["type"] to either "swap" or "future" for inverse contracts');
2210
+ }
2211
+ }
2212
+ else {
2213
+ throw new NotSupported(this.id + ' fetchTickers() you have to set params["subType"] to either "linear" or "inverse" for contracts');
2179
2214
  }
2180
2215
  }
2181
2216
  else {
@@ -2231,42 +2266,9 @@ export default class htx extends Exchange {
2231
2266
  // "ts":1637504679376
2232
2267
  // }
2233
2268
  //
2234
- const tickers = this.safeValue2(response, 'data', 'ticks', []);
2235
- const timestamp = this.safeInteger(response, 'ts');
2236
- const result = {};
2237
- for (let i = 0; i < tickers.length; i++) {
2238
- const ticker = this.parseTicker(tickers[i]);
2239
- // the market ids for linear futures are non-standard and differ from all the other endpoints
2240
- // we are doing a linear-matching here
2241
- if (future && linear) {
2242
- for (let j = 0; j < this.symbols.length; j++) {
2243
- const symbolInner = this.symbols[j];
2244
- const marketInner = this.market(symbolInner);
2245
- const contractType = this.safeString(marketInner['info'], 'contract_type');
2246
- if ((contractType === 'this_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CW'))) {
2247
- ticker['symbol'] = marketInner['symbol'];
2248
- break;
2249
- }
2250
- else if ((contractType === 'next_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NW'))) {
2251
- ticker['symbol'] = marketInner['symbol'];
2252
- break;
2253
- }
2254
- else if ((contractType === 'this_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CQ'))) {
2255
- ticker['symbol'] = marketInner['symbol'];
2256
- break;
2257
- }
2258
- else if ((contractType === 'next_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NQ'))) {
2259
- ticker['symbol'] = marketInner['symbol'];
2260
- break;
2261
- }
2262
- }
2263
- }
2264
- const symbol = ticker['symbol'];
2265
- ticker['timestamp'] = timestamp;
2266
- ticker['datetime'] = this.iso8601(timestamp);
2267
- result[symbol] = ticker;
2268
- }
2269
- return this.filterByArrayTickers(result, 'symbol', symbols);
2269
+ const rawTickers = this.safeList2(response, 'data', 'ticks', []);
2270
+ const tickers = this.parseTickers(rawTickers, symbols, params);
2271
+ return this.filterByArrayTickers(tickers, 'symbol', symbols);
2270
2272
  }
2271
2273
  async fetchLastPrices(symbols = undefined, params = {}) {
2272
2274
  /**
@@ -2276,7 +2278,7 @@ export default class htx extends Exchange {
2276
2278
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2277
2279
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2278
2280
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2279
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the last prices
2281
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the last prices
2280
2282
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2281
2283
  * @returns {object} a dictionary of lastprices structures
2282
2284
  */
package/js/src/okx.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/okx.js';
2
- import type { TransferEntry, Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Balances, Tickers, Market, Greeks, Strings, MarketInterface, Currency, Leverage, Num, Account, OptionChain, Option, MarginModification, TradingFeeInterface, Currencies } from './base/types.js';
2
+ import type { TransferEntry, Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Balances, Tickers, Market, Greeks, Strings, MarketInterface, Currency, Leverage, Num, Account, OptionChain, Option, MarginModification, TradingFeeInterface, Currencies, Conversion } from './base/types.js';
3
3
  /**
4
4
  * @class okx
5
5
  * @augments Exchange
@@ -297,6 +297,9 @@ export default class okx extends Exchange {
297
297
  baseVolume: number;
298
298
  quoteVolume: any;
299
299
  };
300
+ fetchConvertQuote(fromCode: string, toCode: string, amount?: Num, params?: {}): Promise<Conversion>;
301
+ parseConversion(conversion: any, fromCurrency?: Currency, toCurrency?: Currency): Conversion;
302
+ fetchConvertCurrencies(params?: {}): Promise<Currencies>;
300
303
  handleErrors(httpCode: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
301
304
  fetchMarginAdjustmentHistory(symbol?: Str, type?: Str, since?: Num, limit?: Num, params?: {}): Promise<MarginModification[]>;
302
305
  }