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
@@ -940,14 +940,8 @@ class htx extends htx$1 {
940
940
  'fetchMarkets': {
941
941
  'types': {
942
942
  'spot': true,
943
- 'future': {
944
- 'linear': true,
945
- 'inverse': true,
946
- },
947
- 'swap': {
948
- 'linear': true,
949
- 'inverse': true,
950
- },
943
+ 'linear': true,
944
+ 'inverse': true,
951
945
  },
952
946
  },
953
947
  'fetchOHLCV': {
@@ -1614,25 +1608,23 @@ class htx extends htx$1 {
1614
1608
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1615
1609
  * @returns {object[]} an array of objects representing market data
1616
1610
  */
1617
- const options = this.safeValue(this.options, 'fetchMarkets', {});
1618
- const types = this.safeValue(options, 'types', {});
1611
+ let types = undefined;
1612
+ [types, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'types', {});
1619
1613
  let allMarkets = [];
1620
1614
  let promises = [];
1621
1615
  const keys = Object.keys(types);
1622
1616
  for (let i = 0; i < keys.length; i++) {
1623
- const type = keys[i];
1624
- const value = this.safeValue(types, type);
1625
- if (value === true) {
1626
- promises.push(this.fetchMarketsByTypeAndSubType(type, undefined, params));
1627
- }
1628
- else if (value) {
1629
- const subKeys = Object.keys(value);
1630
- for (let j = 0; j < subKeys.length; j++) {
1631
- const subType = subKeys[j];
1632
- const subValue = this.safeValue(value, subType);
1633
- if (subValue) {
1634
- promises.push(this.fetchMarketsByTypeAndSubType(type, subType, params));
1635
- }
1617
+ const key = keys[i];
1618
+ if (this.safeBool(types, key)) {
1619
+ if (key === 'spot') {
1620
+ promises.push(this.fetchMarketsByTypeAndSubType('spot', undefined, params));
1621
+ }
1622
+ else if (key === 'linear') {
1623
+ promises.push(this.fetchMarketsByTypeAndSubType(undefined, 'linear', params));
1624
+ }
1625
+ else if (key === 'inverse') {
1626
+ promises.push(this.fetchMarketsByTypeAndSubType('swap', 'inverse', params));
1627
+ promises.push(this.fetchMarketsByTypeAndSubType('future', 'inverse', params));
1636
1628
  }
1637
1629
  }
1638
1630
  }
@@ -1643,35 +1635,25 @@ class htx extends htx$1 {
1643
1635
  return allMarkets;
1644
1636
  }
1645
1637
  async fetchMarketsByTypeAndSubType(type, subType, params = {}) {
1646
- const query = this.omit(params, ['type', 'subType']);
1647
- const spot = (type === 'spot');
1648
- const contract = (type !== 'spot');
1649
- const future = (type === 'future');
1650
- const swap = (type === 'swap');
1651
- let linear = undefined;
1652
- let inverse = undefined;
1638
+ const isSpot = (type === 'spot');
1653
1639
  const request = {};
1654
1640
  let response = undefined;
1655
- if (contract) {
1656
- linear = (subType === 'linear');
1657
- inverse = (subType === 'inverse');
1658
- if (linear) {
1659
- if (future) {
1660
- request['business_type'] = 'futures';
1661
- }
1662
- response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, query));
1641
+ if (!isSpot) {
1642
+ if (subType === 'linear') {
1643
+ request['business_type'] = 'all'; // override default to fetch all linear markets
1644
+ response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, params));
1663
1645
  }
1664
- else if (inverse) {
1665
- if (future) {
1666
- response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, query));
1646
+ else if (subType === 'inverse') {
1647
+ if (type === 'future') {
1648
+ response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, params));
1667
1649
  }
1668
- else if (swap) {
1669
- response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, query));
1650
+ else if (type === 'swap') {
1651
+ response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, params));
1670
1652
  }
1671
1653
  }
1672
1654
  }
1673
1655
  else {
1674
- response = await this.spotPublicGetV1CommonSymbols(this.extend(request, query));
1656
+ response = await this.spotPublicGetV1CommonSymbols(this.extend(request, params));
1675
1657
  }
1676
1658
  //
1677
1659
  // spot
@@ -1711,75 +1693,58 @@ class htx extends htx$1 {
1711
1693
  // ]
1712
1694
  // }
1713
1695
  //
1714
- // inverse future
1696
+ // inverse (swap & future)
1715
1697
  //
1716
1698
  // {
1717
1699
  // "status":"ok",
1718
1700
  // "data":[
1719
1701
  // {
1720
1702
  // "symbol":"BTC",
1721
- // "contract_code":"BTC211126",
1722
- // "contract_type":"this_week",
1723
- // "contract_size":100.000000000000000000,
1724
- // "price_tick":0.010000000000000000,
1725
- // "delivery_date":"20211126",
1726
- // "delivery_time":"1637913600000",
1703
+ // "contract_code":"BTC211126", /// BTC-USD in swap
1704
+ // "contract_type":"this_week", // only in future
1705
+ // "contract_size":100,
1706
+ // "price_tick":0.1,
1707
+ // "delivery_date":"20211126", // only in future
1708
+ // "delivery_time":"1637913600000", // empty in swap
1727
1709
  // "create_date":"20211112",
1728
1710
  // "contract_status":1,
1729
- // "settlement_time":"1637481600000"
1711
+ // "settlement_time":"1637481600000" // only in future
1712
+ // "settlement_date":"16xxxxxxxxxxx" // only in swap
1730
1713
  // },
1714
+ // ...
1731
1715
  // ],
1732
1716
  // "ts":1637474595140
1733
1717
  // }
1734
1718
  //
1735
- // linear futures
1719
+ // linear (swap & future)
1736
1720
  //
1737
1721
  // {
1738
1722
  // "status":"ok",
1739
1723
  // "data":[
1740
1724
  // {
1741
1725
  // "symbol":"BTC",
1742
- // "contract_code":"BTC-USDT-211231",
1743
- // "contract_size":0.001000000000000000,
1744
- // "price_tick":0.100000000000000000,
1745
- // "delivery_date":"20211231",
1746
- // "delivery_time":"1640937600000",
1726
+ // "contract_code":"BTC-USDT-211231", // or "BTC-USDT" in swap
1727
+ // "contract_size":0.001,
1728
+ // "price_tick":0.1,
1729
+ // "delivery_date":"20211231", // empty in swap
1730
+ // "delivery_time":"1640937600000", // empty in swap
1747
1731
  // "create_date":"20211228",
1748
1732
  // "contract_status":1,
1749
1733
  // "settlement_date":"1640764800000",
1750
- // "support_margin_mode":"cross",
1751
- // "business_type":"futures",
1734
+ // "support_margin_mode":"cross", // "all" or "cross"
1735
+ // "business_type":"futures", // "swap" or "futures"
1752
1736
  // "pair":"BTC-USDT",
1753
- // "contract_type":"this_week" // next_week, quarter
1754
- // },
1737
+ // "contract_type":"this_week", // "swap", "this_week", "next_week", "quarter"
1738
+ // "trade_partition":"USDT",
1739
+ // }
1755
1740
  // ],
1756
1741
  // "ts":1640736207263
1757
1742
  // }
1758
1743
  //
1759
- // swaps
1760
- //
1761
- // {
1762
- // "status":"ok",
1763
- // "data":[
1764
- // {
1765
- // "symbol":"BTC",
1766
- // "contract_code":"BTC-USDT",
1767
- // "contract_size":0.001000000000000000,
1768
- // "price_tick":0.100000000000000000,
1769
- // "delivery_time":"",
1770
- // "create_date":"20201021",
1771
- // "contract_status":1,
1772
- // "settlement_date":"1637481600000",
1773
- // "support_margin_mode":"all", // isolated
1774
- // },
1775
- // ],
1776
- // "ts":1637474774467
1777
- // }
1778
- //
1779
- const markets = this.safeValue(response, 'data', []);
1744
+ const markets = this.safeList(response, 'data', []);
1780
1745
  const numMarkets = markets.length;
1781
1746
  if (numMarkets < 1) {
1782
- throw new errors.NetworkError(this.id + ' fetchMarkets() returned an empty response: ' + this.json(markets));
1747
+ throw new errors.OperationFailed(this.id + ' fetchMarkets() returned an empty response: ' + this.json(response));
1783
1748
  }
1784
1749
  const result = [];
1785
1750
  for (let i = 0; i < markets.length; i++) {
@@ -1789,16 +1754,31 @@ class htx extends htx$1 {
1789
1754
  let settleId = undefined;
1790
1755
  let id = undefined;
1791
1756
  let lowercaseId = undefined;
1757
+ const contract = ('contract_code' in market);
1758
+ const spot = !contract;
1759
+ let swap = false;
1760
+ let future = false;
1761
+ let linear = undefined;
1762
+ let inverse = undefined;
1763
+ // check if parsed market is contract
1792
1764
  if (contract) {
1793
1765
  id = this.safeString(market, 'contract_code');
1794
1766
  lowercaseId = id.toLowerCase();
1767
+ const delivery_date = this.safeString(market, 'delivery_date');
1768
+ const business_type = this.safeString(market, 'business_type');
1769
+ future = delivery_date !== undefined;
1770
+ swap = !future;
1771
+ linear = business_type !== undefined;
1772
+ inverse = !linear;
1795
1773
  if (swap) {
1774
+ type = 'swap';
1796
1775
  const parts = id.split('-');
1797
1776
  baseId = this.safeStringLower(market, 'symbol');
1798
1777
  quoteId = this.safeStringLower(parts, 1);
1799
1778
  settleId = inverse ? baseId : quoteId;
1800
1779
  }
1801
1780
  else if (future) {
1781
+ type = 'future';
1802
1782
  baseId = this.safeStringLower(market, 'symbol');
1803
1783
  if (inverse) {
1804
1784
  quoteId = 'USD';
@@ -1813,6 +1793,7 @@ class htx extends htx$1 {
1813
1793
  }
1814
1794
  }
1815
1795
  else {
1796
+ type = 'spot';
1816
1797
  baseId = this.safeString(market, 'base-currency');
1817
1798
  quoteId = this.safeString(market, 'quote-currency');
1818
1799
  id = baseId + quoteId;
@@ -1947,6 +1928,45 @@ class htx extends htx$1 {
1947
1928
  }
1948
1929
  return result;
1949
1930
  }
1931
+ tryGetSymbolFromFutureMarkets(symbolOrMarketId) {
1932
+ if (symbolOrMarketId in this.markets) {
1933
+ return symbolOrMarketId;
1934
+ }
1935
+ // only on "future" market type (inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker"
1936
+ // so we have to create a mapping
1937
+ // - market-id from fetchMarkts: `BTC-USDT-240419` (linear future) or `BTC240412` (inverse future)
1938
+ // - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future)
1939
+ if (!('futureMarketIdsForSymbols' in this.options)) {
1940
+ this.options['futureMarketIdsForSymbols'] = {};
1941
+ }
1942
+ const futureMarketIdsForSymbols = this.safeDict(this.options, 'futureMarketIdsForSymbols', {});
1943
+ if (symbolOrMarketId in futureMarketIdsForSymbols) {
1944
+ return futureMarketIdsForSymbols[symbolOrMarketId];
1945
+ }
1946
+ const futureMarkets = this.filterBy(this.markets, 'future', true);
1947
+ const futuresCharsMaps = {
1948
+ 'this_week': 'CW',
1949
+ 'next_week': 'NW',
1950
+ 'quarter': 'CQ',
1951
+ 'next_quarter': 'NQ',
1952
+ };
1953
+ for (let i = 0; i < futureMarkets.length; i++) {
1954
+ const market = futureMarkets[i];
1955
+ const info = this.safeValue(market, 'info', {});
1956
+ const contractType = this.safeString(info, 'contract_type');
1957
+ const contractSuffix = futuresCharsMaps[contractType];
1958
+ // see comment on formats a bit above
1959
+ const constructedId = market['linear'] ? market['base'] + '-' + market['quote'] + '-' + contractSuffix : market['base'] + '_' + contractSuffix;
1960
+ if (constructedId === symbolOrMarketId) {
1961
+ const symbol = market['symbol'];
1962
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbol;
1963
+ return symbol;
1964
+ }
1965
+ }
1966
+ // if not found, just save it to avoid unnecessary future iterations
1967
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbolOrMarketId;
1968
+ return symbolOrMarketId;
1969
+ }
1950
1970
  parseTicker(ticker, market = undefined) {
1951
1971
  //
1952
1972
  // fetchTicker
@@ -1994,7 +2014,8 @@ class htx extends htx$1 {
1994
2014
  // }
1995
2015
  //
1996
2016
  const marketId = this.safeString2(ticker, 'symbol', 'contract_code');
1997
- const symbol = this.safeSymbol(marketId, market);
2017
+ let symbol = this.safeSymbol(marketId, market);
2018
+ symbol = this.tryGetSymbolFromFutureMarkets(symbol);
1998
2019
  const timestamp = this.safeInteger2(ticker, 'ts', 'quoteTime');
1999
2020
  let bid = undefined;
2000
2021
  let bidVolume = undefined;
@@ -2137,7 +2158,7 @@ class htx extends htx$1 {
2137
2158
  * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
2138
2159
  * @see https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
2139
2160
  * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
2140
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2161
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2141
2162
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2142
2163
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
2143
2164
  */
@@ -2148,22 +2169,30 @@ class htx extends htx$1 {
2148
2169
  if (first !== undefined) {
2149
2170
  market = this.market(first);
2150
2171
  }
2172
+ const isSubTypeRequested = ('subType' in params) || ('business_type' in params);
2151
2173
  let type = undefined;
2152
2174
  let subType = undefined;
2153
2175
  [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
2154
2176
  [subType, params] = this.handleSubTypeAndParams('fetchTickers', market, params);
2155
2177
  const request = {};
2178
+ const isSpot = (type === 'spot');
2156
2179
  const future = (type === 'future');
2157
2180
  const swap = (type === 'swap');
2158
2181
  const linear = (subType === 'linear');
2159
2182
  const inverse = (subType === 'inverse');
2160
- params = this.omit(params, ['type', 'subType']);
2161
2183
  let response = undefined;
2162
- if (future || swap) {
2184
+ if (!isSpot || isSubTypeRequested) {
2163
2185
  if (linear) {
2186
+ // independently of type, supports calling all linear symbols i.e. fetchTickers(undefined, {subType:'linear'})
2164
2187
  if (future) {
2165
2188
  request['business_type'] = 'futures';
2166
2189
  }
2190
+ else if (swap) {
2191
+ request['business_type'] = 'swap';
2192
+ }
2193
+ else {
2194
+ request['business_type'] = 'all';
2195
+ }
2167
2196
  response = await this.contractPublicGetLinearSwapExMarketDetailBatchMerged(this.extend(request, params));
2168
2197
  }
2169
2198
  else if (inverse) {
@@ -2173,6 +2202,12 @@ class htx extends htx$1 {
2173
2202
  else if (swap) {
2174
2203
  response = await this.contractPublicGetSwapExMarketDetailBatchMerged(this.extend(request, params));
2175
2204
  }
2205
+ else {
2206
+ throw new errors.NotSupported(this.id + ' fetchTickers() you have to set params["type"] to either "swap" or "future" for inverse contracts');
2207
+ }
2208
+ }
2209
+ else {
2210
+ throw new errors.NotSupported(this.id + ' fetchTickers() you have to set params["subType"] to either "linear" or "inverse" for contracts');
2176
2211
  }
2177
2212
  }
2178
2213
  else {
@@ -2228,42 +2263,9 @@ class htx extends htx$1 {
2228
2263
  // "ts":1637504679376
2229
2264
  // }
2230
2265
  //
2231
- const tickers = this.safeValue2(response, 'data', 'ticks', []);
2232
- const timestamp = this.safeInteger(response, 'ts');
2233
- const result = {};
2234
- for (let i = 0; i < tickers.length; i++) {
2235
- const ticker = this.parseTicker(tickers[i]);
2236
- // the market ids for linear futures are non-standard and differ from all the other endpoints
2237
- // we are doing a linear-matching here
2238
- if (future && linear) {
2239
- for (let j = 0; j < this.symbols.length; j++) {
2240
- const symbolInner = this.symbols[j];
2241
- const marketInner = this.market(symbolInner);
2242
- const contractType = this.safeString(marketInner['info'], 'contract_type');
2243
- if ((contractType === 'this_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CW'))) {
2244
- ticker['symbol'] = marketInner['symbol'];
2245
- break;
2246
- }
2247
- else if ((contractType === 'next_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NW'))) {
2248
- ticker['symbol'] = marketInner['symbol'];
2249
- break;
2250
- }
2251
- else if ((contractType === 'this_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CQ'))) {
2252
- ticker['symbol'] = marketInner['symbol'];
2253
- break;
2254
- }
2255
- else if ((contractType === 'next_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NQ'))) {
2256
- ticker['symbol'] = marketInner['symbol'];
2257
- break;
2258
- }
2259
- }
2260
- }
2261
- const symbol = ticker['symbol'];
2262
- ticker['timestamp'] = timestamp;
2263
- ticker['datetime'] = this.iso8601(timestamp);
2264
- result[symbol] = ticker;
2265
- }
2266
- return this.filterByArrayTickers(result, 'symbol', symbols);
2266
+ const rawTickers = this.safeList2(response, 'data', 'ticks', []);
2267
+ const tickers = this.parseTickers(rawTickers, symbols, params);
2268
+ return this.filterByArrayTickers(tickers, 'symbol', symbols);
2267
2269
  }
2268
2270
  async fetchLastPrices(symbols = undefined, params = {}) {
2269
2271
  /**
@@ -2273,7 +2275,7 @@ class htx extends htx$1 {
2273
2275
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2274
2276
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2275
2277
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2276
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the last prices
2278
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the last prices
2277
2279
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2278
2280
  * @returns {object} a dictionary of lastprices structures
2279
2281
  */