ccxt 4.4.88__py2.py3-none-any.whl → 4.4.90__py2.py3-none-any.whl

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 (63) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bitget.py +58 -0
  3. ccxt/abstract/bitrue.py +65 -65
  4. ccxt/abstract/cryptocom.py +2 -0
  5. ccxt/abstract/luno.py +1 -0
  6. ccxt/async_support/__init__.py +1 -1
  7. ccxt/async_support/base/exchange.py +1 -1
  8. ccxt/async_support/binance.py +1 -1
  9. ccxt/async_support/bingx.py +55 -29
  10. ccxt/async_support/bitget.py +469 -147
  11. ccxt/async_support/bitrue.py +72 -66
  12. ccxt/async_support/bitvavo.py +34 -0
  13. ccxt/async_support/btcalpha.py +35 -0
  14. ccxt/async_support/btcbox.py +35 -0
  15. ccxt/async_support/btcmarkets.py +35 -0
  16. ccxt/async_support/btcturk.py +35 -0
  17. ccxt/async_support/bybit.py +9 -3
  18. ccxt/async_support/coinbase.py +1 -3
  19. ccxt/async_support/cryptocom.py +49 -0
  20. ccxt/async_support/delta.py +2 -2
  21. ccxt/async_support/digifinex.py +39 -99
  22. ccxt/async_support/gate.py +12 -5
  23. ccxt/async_support/hashkey.py +15 -28
  24. ccxt/async_support/hollaex.py +27 -22
  25. ccxt/async_support/kraken.py +28 -49
  26. ccxt/async_support/luno.py +87 -1
  27. ccxt/async_support/okx.py +2 -1
  28. ccxt/async_support/phemex.py +16 -8
  29. ccxt/async_support/tradeogre.py +3 -3
  30. ccxt/async_support/xt.py +1 -1
  31. ccxt/base/exchange.py +13 -4
  32. ccxt/binance.py +1 -1
  33. ccxt/bingx.py +55 -29
  34. ccxt/bitget.py +469 -147
  35. ccxt/bitrue.py +72 -66
  36. ccxt/bitvavo.py +34 -0
  37. ccxt/btcalpha.py +35 -0
  38. ccxt/btcbox.py +35 -0
  39. ccxt/btcmarkets.py +35 -0
  40. ccxt/btcturk.py +35 -0
  41. ccxt/bybit.py +9 -3
  42. ccxt/coinbase.py +1 -3
  43. ccxt/cryptocom.py +49 -0
  44. ccxt/delta.py +2 -2
  45. ccxt/digifinex.py +39 -99
  46. ccxt/gate.py +12 -5
  47. ccxt/hashkey.py +15 -28
  48. ccxt/hollaex.py +27 -22
  49. ccxt/kraken.py +27 -49
  50. ccxt/luno.py +87 -1
  51. ccxt/okx.py +2 -1
  52. ccxt/phemex.py +16 -8
  53. ccxt/pro/__init__.py +1 -127
  54. ccxt/pro/coinbase.py +2 -0
  55. ccxt/pro/cryptocom.py +27 -0
  56. ccxt/pro/kraken.py +3 -9
  57. ccxt/tradeogre.py +3 -3
  58. ccxt/xt.py +1 -1
  59. {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/METADATA +62 -20
  60. {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/RECORD +63 -63
  61. {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/LICENSE.txt +0 -0
  62. {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/WHEEL +0 -0
  63. {ccxt-4.4.88.dist-info → ccxt-4.4.90.dist-info}/top_level.txt +0 -0
@@ -195,6 +195,7 @@ class bitget(Exchange, ImplicitAPI):
195
195
  'convert': 'https://api.{hostname}',
196
196
  'copy': 'https://api.{hostname}',
197
197
  'earn': 'https://api.{hostname}',
198
+ 'uta': 'https://api.{hostname}',
198
199
  },
199
200
  'www': 'https://www.bitget.com',
200
201
  'doc': [
@@ -311,6 +312,24 @@ class bitget(Exchange, ImplicitAPI):
311
312
  'v2/earn/loan/public/hour-interest': 2,
312
313
  },
313
314
  },
315
+ 'uta': {
316
+ 'get': {
317
+ 'v3/market/instruments': 1,
318
+ 'v3/market/tickers': 1,
319
+ 'v3/market/orderbook': 1,
320
+ 'v3/market/fills': 1,
321
+ 'v3/market/open-interest': 1,
322
+ 'v3/market/candles': 1,
323
+ 'v3/market/history-candles': 1,
324
+ 'v3/market/current-fund-rate': 1,
325
+ 'v3/market/history-fund-rate': 1,
326
+ 'v3/market/risk-reserve': 1,
327
+ 'v3/market/discount-rate': 1,
328
+ 'v3/market/margin-loans': 1,
329
+ 'v3/market/position-tier': 1,
330
+ 'v3/market/oi-limit': 2,
331
+ },
332
+ },
314
333
  },
315
334
  'private': {
316
335
  'spot': {
@@ -804,6 +823,56 @@ class bitget(Exchange, ImplicitAPI):
804
823
  'v2/common/trade-rate': 2,
805
824
  },
806
825
  },
826
+ 'uta': {
827
+ 'get': {
828
+ 'v3/account/assets': 1,
829
+ 'v3/account/settings': 1,
830
+ 'v3/account/financial-records': 1,
831
+ 'v3/account/repayable-coins': 2,
832
+ 'v3/account/payment-coins': 2,
833
+ 'v3/account/convert-records': 1,
834
+ 'v3/account/transferable-coins': 2,
835
+ 'v3/account/sub-transfer-record': 4,
836
+ 'v3/ins-loan/transfered': 6.6667,
837
+ 'v3/ins-loan/symbols': 6.6667,
838
+ 'v3/ins-loan/risk-unit': 6.6667,
839
+ 'v3/ins-loan/repaid-history': 6.6667,
840
+ 'v3/ins-loan/product-infos': 6.6667,
841
+ 'v3/ins-loan/loan-order': 6.6667,
842
+ 'v3/ins-loan/ltv-convert': 6.6667,
843
+ 'v3/ins-loan/ensure-coins-convert': 6.6667,
844
+ 'v3/position/current-position': 1,
845
+ 'v3/position/history-position': 1,
846
+ 'v3/trade/order-info': 1,
847
+ 'v3/trade/unfilled-orders': 1,
848
+ 'v3/trade/history-orders': 1,
849
+ 'v3/trade/fills': 1,
850
+ 'v3/user/sub-list': 2,
851
+ 'v3/user/sub-api-list': 2,
852
+ },
853
+ 'post': {
854
+ 'v3/account/set-leverage': 2,
855
+ 'v3/account/set-hold-mode': 2,
856
+ 'v3/account/repay': 4,
857
+ 'v3/account/transfer': 4,
858
+ 'v3/account/sub-transfer': 4,
859
+ 'v3/account/max-open-available': 4,
860
+ 'v3/ins-loan/bind-uid': 6.6667,
861
+ 'v3/trade/place-order': 2,
862
+ 'v3/trade/modify-order': 2,
863
+ 'v3/trade/cancel-order': 2,
864
+ 'v3/trade/place-batch': 4,
865
+ 'v3/trade/batch-modify-order': 2,
866
+ 'v3/trade/cancel-batch': 4,
867
+ 'v3/trade/cancel-symbol-order': 4,
868
+ 'v3/trade/close-positions': 4,
869
+ 'v3/user/create-sub': 2,
870
+ 'v3/user/freeze-sub': 2,
871
+ 'v3/user/create-sub-api': 2,
872
+ 'v3/user/update-sub-api': 2,
873
+ 'v3/user/delete-sub-api': 2,
874
+ },
875
+ },
807
876
  },
808
877
  },
809
878
  'fees': {
@@ -1347,6 +1416,7 @@ class bitget(Exchange, ImplicitAPI):
1347
1416
  'TONCOIN': 'TON',
1348
1417
  },
1349
1418
  'options': {
1419
+ 'uta': False,
1350
1420
  'timeDifference': 0, # the difference between system clock and Binance clock
1351
1421
  'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
1352
1422
  'timeframes': {
@@ -1381,10 +1451,9 @@ class bitget(Exchange, ImplicitAPI):
1381
1451
  '1M': '1Mutc',
1382
1452
  },
1383
1453
  },
1384
- 'fetchMarkets': [
1385
- 'spot',
1386
- 'swap', # there is future markets but they use the same endpoints
1387
- ],
1454
+ 'fetchMarkets': {
1455
+ 'types': ['spot', 'swap'], # there is future markets but they use the same endpoints
1456
+ },
1388
1457
  'defaultType': 'spot', # 'spot', 'swap', 'future'
1389
1458
  'defaultSubType': 'linear', # 'linear', 'inverse'
1390
1459
  'createMarketBuyOrderRequiresPrice': True,
@@ -1774,13 +1843,30 @@ class bitget(Exchange, ImplicitAPI):
1774
1843
  https://www.bitget.com/api-doc/spot/market/Get-Symbols
1775
1844
  https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
1776
1845
  https://www.bitget.com/api-doc/margin/common/support-currencies
1846
+ https://www.bitget.bike/api-doc/uta/public/Instruments
1777
1847
 
1778
1848
  :param dict [params]: extra parameters specific to the exchange API endpoint
1849
+ :param str [params.uta]: set to True to fetch markets for the unified trading account(uta), defaults to False
1779
1850
  :returns dict[]: an array of objects representing market data
1780
1851
  """
1781
1852
  if self.options['adjustForTimeDifference']:
1782
1853
  await self.load_time_difference()
1783
- types = self.safe_value(self.options, 'fetchMarkets', ['spot', 'swap'])
1854
+ uta = None
1855
+ uta, params = self.handle_option_and_params(params, 'fetchMarkets', 'uta', False)
1856
+ if uta:
1857
+ return await self.fetch_uta_markets(params)
1858
+ else:
1859
+ return await self.fetch_default_markets(params)
1860
+
1861
+ async def fetch_default_markets(self, params) -> List[Market]:
1862
+ types = None
1863
+ fetchMarketsOptions = self.safe_dict(self.options, 'fetchMarkets')
1864
+ defaultMarkets = ['spot', 'swap']
1865
+ if fetchMarketsOptions is not None:
1866
+ types = self.safe_list(fetchMarketsOptions, 'types', defaultMarkets)
1867
+ else:
1868
+ # for backward-compatibility
1869
+ types = self.safe_list(self.options, 'fetchMarkets', defaultMarkets)
1784
1870
  promises = []
1785
1871
  fetchMargins = False
1786
1872
  for i in range(0, len(types)):
@@ -1812,12 +1898,6 @@ class bitget(Exchange, ImplicitAPI):
1812
1898
  self.options['isolatedMarginPairsData'] = keysList
1813
1899
  else:
1814
1900
  markets = self.array_concat(markets, data)
1815
- result = []
1816
- for i in range(0, len(markets)):
1817
- result.append(self.parse_market(markets[i]))
1818
- return result
1819
-
1820
- def parse_market(self, market: dict) -> Market:
1821
1901
  #
1822
1902
  # spot
1823
1903
  #
@@ -1875,146 +1955,388 @@ class bitget(Exchange, ImplicitAPI):
1875
1955
  # "maintainTime": ""
1876
1956
  # }
1877
1957
  #
1878
- marketId = self.safe_string(market, 'symbol')
1879
- quoteId = self.safe_string(market, 'quoteCoin')
1880
- baseId = self.safe_string(market, 'baseCoin')
1881
- quote = self.safe_currency_code(quoteId)
1882
- base = self.safe_currency_code(baseId)
1883
- supportMarginCoins = self.safe_value(market, 'supportMarginCoins', [])
1884
- settleId = None
1885
- if self.in_array(baseId, supportMarginCoins):
1886
- settleId = baseId
1887
- elif self.in_array(quoteId, supportMarginCoins):
1888
- settleId = quoteId
1889
- else:
1890
- settleId = self.safe_string(supportMarginCoins, 0)
1891
- settle = self.safe_currency_code(settleId)
1892
- symbol = base + '/' + quote
1893
- type = None
1894
- swap = False
1895
- spot = False
1896
- future = False
1897
- contract = False
1898
- pricePrecision = None
1899
- amountPrecision = None
1900
- linear = None
1901
- inverse = None
1902
- expiry = None
1903
- expiryDatetime = None
1904
- symbolType = self.safe_string(market, 'symbolType')
1905
- marginModes = None
1906
- isMarginTradingAllowed = False
1907
- if symbolType is None:
1908
- type = 'spot'
1909
- spot = True
1910
- pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'pricePrecision')))
1911
- amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityPrecision')))
1912
- hasCrossMargin = self.in_array(marketId, self.options['crossMarginPairsData'])
1913
- hasIsolatedMargin = self.in_array(marketId, self.options['isolatedMarginPairsData'])
1914
- marginModes = {
1915
- 'cross': hasCrossMargin,
1916
- 'isolated': hasIsolatedMargin,
1917
- }
1918
- isMarginTradingAllowed = hasCrossMargin or hasCrossMargin
1919
- else:
1920
- if symbolType == 'perpetual':
1921
- type = 'swap'
1922
- swap = True
1923
- symbol = symbol + ':' + settle
1924
- elif symbolType == 'delivery':
1925
- expiry = self.safe_integer(market, 'deliveryTime')
1926
- expiryDatetime = self.iso8601(expiry)
1927
- expiryParts = expiryDatetime.split('-')
1928
- yearPart = self.safe_string(expiryParts, 0)
1929
- dayPart = self.safe_string(expiryParts, 2)
1930
- year = yearPart[2:4]
1931
- month = self.safe_string(expiryParts, 1)
1932
- day = dayPart[0:2]
1933
- expiryString = year + month + day
1934
- type = 'future'
1935
- future = True
1936
- symbol = symbol + ':' + settle + '-' + expiryString
1937
- contract = True
1938
- inverse = (base == settle)
1939
- linear = not inverse
1940
- priceDecimals = self.safe_integer(market, 'pricePlace')
1941
- amountDecimals = self.safe_integer(market, 'volumePlace')
1942
- priceStep = self.safe_string(market, 'priceEndStep')
1943
- amountStep = self.safe_string(market, 'sizeMultiplier')
1944
- precise = Precise(priceStep)
1945
- precise.decimals = max(precise.decimals, priceDecimals)
1946
- precise.reduce()
1947
- priceString = str(precise)
1948
- pricePrecision = self.parse_number(priceString)
1949
- preciseAmount = Precise(amountStep)
1950
- preciseAmount.decimals = max(preciseAmount.decimals, amountDecimals)
1951
- preciseAmount.reduce()
1952
- amountString = str(preciseAmount)
1953
- amountPrecision = self.parse_number(amountString)
1954
- marginModes = {
1955
- 'cross': True,
1956
- 'isolated': True,
1957
- }
1958
- status = self.safe_string_2(market, 'status', 'symbolStatus')
1959
- active = None
1960
- if status is not None:
1961
- active = ((status == 'online') or (status == 'normal'))
1962
- minCost = None
1963
- if quote == 'USDT':
1964
- minCost = self.safe_number(market, 'minTradeUSDT')
1965
- contractSize = 1 if contract else None
1966
- return {
1967
- 'id': marketId,
1968
- 'symbol': symbol,
1969
- 'base': base,
1970
- 'quote': quote,
1971
- 'settle': settle,
1972
- 'baseId': baseId,
1973
- 'quoteId': quoteId,
1974
- 'settleId': settleId,
1975
- 'type': type,
1976
- 'spot': spot,
1977
- 'margin': spot and isMarginTradingAllowed,
1978
- 'marginModes': marginModes,
1979
- 'swap': swap,
1980
- 'future': future,
1981
- 'option': False,
1982
- 'active': active,
1983
- 'contract': contract,
1984
- 'linear': linear,
1985
- 'inverse': inverse,
1986
- 'taker': self.safe_number(market, 'takerFeeRate'),
1987
- 'maker': self.safe_number(market, 'makerFeeRate'),
1988
- 'contractSize': contractSize,
1989
- 'expiry': expiry,
1990
- 'expiryDatetime': expiryDatetime,
1991
- 'strike': None,
1992
- 'optionType': None,
1993
- 'precision': {
1994
- 'amount': amountPrecision,
1995
- 'price': pricePrecision,
1996
- },
1997
- 'limits': {
1998
- 'leverage': {
1999
- 'min': self.safe_number(market, 'minLever'),
2000
- 'max': self.safe_number(market, 'maxLever'),
1958
+ result = []
1959
+ for i in range(0, len(markets)):
1960
+ market = markets[i]
1961
+ marketId = self.safe_string(market, 'symbol')
1962
+ quoteId = self.safe_string(market, 'quoteCoin')
1963
+ baseId = self.safe_string(market, 'baseCoin')
1964
+ quote = self.safe_currency_code(quoteId)
1965
+ base = self.safe_currency_code(baseId)
1966
+ supportMarginCoins = self.safe_value(market, 'supportMarginCoins', [])
1967
+ settleId = None
1968
+ if self.in_array(baseId, supportMarginCoins):
1969
+ settleId = baseId
1970
+ elif self.in_array(quoteId, supportMarginCoins):
1971
+ settleId = quoteId
1972
+ else:
1973
+ settleId = self.safe_string(supportMarginCoins, 0)
1974
+ settle = self.safe_currency_code(settleId)
1975
+ symbol = base + '/' + quote
1976
+ type = None
1977
+ swap = False
1978
+ spot = False
1979
+ future = False
1980
+ contract = False
1981
+ pricePrecision = None
1982
+ amountPrecision = None
1983
+ linear = None
1984
+ inverse = None
1985
+ expiry = None
1986
+ expiryDatetime = None
1987
+ symbolType = self.safe_string(market, 'symbolType')
1988
+ marginModes = None
1989
+ isMarginTradingAllowed = False
1990
+ if symbolType is None:
1991
+ type = 'spot'
1992
+ spot = True
1993
+ pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'pricePrecision')))
1994
+ amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityPrecision')))
1995
+ hasCrossMargin = self.in_array(marketId, self.options['crossMarginPairsData'])
1996
+ hasIsolatedMargin = self.in_array(marketId, self.options['isolatedMarginPairsData'])
1997
+ marginModes = {
1998
+ 'cross': hasCrossMargin,
1999
+ 'isolated': hasIsolatedMargin,
2000
+ }
2001
+ isMarginTradingAllowed = hasCrossMargin or hasCrossMargin
2002
+ else:
2003
+ if symbolType == 'perpetual':
2004
+ type = 'swap'
2005
+ swap = True
2006
+ symbol = symbol + ':' + settle
2007
+ elif symbolType == 'delivery':
2008
+ expiry = self.safe_integer(market, 'deliveryTime')
2009
+ expiryDatetime = self.iso8601(expiry)
2010
+ expiryParts = expiryDatetime.split('-')
2011
+ yearPart = self.safe_string(expiryParts, 0)
2012
+ dayPart = self.safe_string(expiryParts, 2)
2013
+ year = yearPart[2:4]
2014
+ month = self.safe_string(expiryParts, 1)
2015
+ day = dayPart[0:2]
2016
+ expiryString = year + month + day
2017
+ type = 'future'
2018
+ future = True
2019
+ symbol = symbol + ':' + settle + '-' + expiryString
2020
+ contract = True
2021
+ inverse = (base == settle)
2022
+ linear = not inverse
2023
+ priceDecimals = self.safe_integer(market, 'pricePlace')
2024
+ amountDecimals = self.safe_integer(market, 'volumePlace')
2025
+ priceStep = self.safe_string(market, 'priceEndStep')
2026
+ amountStep = self.safe_string(market, 'sizeMultiplier')
2027
+ precise = Precise(priceStep)
2028
+ precise.decimals = max(precise.decimals, priceDecimals)
2029
+ precise.reduce()
2030
+ priceString = str(precise)
2031
+ pricePrecision = self.parse_number(priceString)
2032
+ preciseAmount = Precise(amountStep)
2033
+ preciseAmount.decimals = max(preciseAmount.decimals, amountDecimals)
2034
+ preciseAmount.reduce()
2035
+ amountString = str(preciseAmount)
2036
+ amountPrecision = self.parse_number(amountString)
2037
+ marginModes = {
2038
+ 'cross': True,
2039
+ 'isolated': True,
2040
+ }
2041
+ status = self.safe_string_2(market, 'status', 'symbolStatus')
2042
+ active = None
2043
+ if status is not None:
2044
+ active = ((status == 'online') or (status == 'normal'))
2045
+ minCost = None
2046
+ if quote == 'USDT':
2047
+ minCost = self.safe_number(market, 'minTradeUSDT')
2048
+ contractSize = 1 if contract else None
2049
+ result.append(self.safe_market_structure({
2050
+ 'id': marketId,
2051
+ 'symbol': symbol,
2052
+ 'base': base,
2053
+ 'quote': quote,
2054
+ 'settle': settle,
2055
+ 'baseId': baseId,
2056
+ 'quoteId': quoteId,
2057
+ 'settleId': settleId,
2058
+ 'type': type,
2059
+ 'spot': spot,
2060
+ 'margin': spot and isMarginTradingAllowed,
2061
+ 'marginModes': marginModes,
2062
+ 'swap': swap,
2063
+ 'future': future,
2064
+ 'option': False,
2065
+ 'active': active,
2066
+ 'contract': contract,
2067
+ 'linear': linear,
2068
+ 'inverse': inverse,
2069
+ 'taker': self.safe_number(market, 'takerFeeRate'),
2070
+ 'maker': self.safe_number(market, 'makerFeeRate'),
2071
+ 'contractSize': contractSize,
2072
+ 'expiry': expiry,
2073
+ 'expiryDatetime': expiryDatetime,
2074
+ 'strike': None,
2075
+ 'optionType': None,
2076
+ 'precision': {
2077
+ 'amount': amountPrecision,
2078
+ 'price': pricePrecision,
2001
2079
  },
2002
- 'amount': {
2003
- 'min': self.safe_number_2(market, 'minTradeNum', 'minTradeAmount'),
2004
- 'max': self.safe_number(market, 'maxTradeAmount'),
2080
+ 'limits': {
2081
+ 'leverage': {
2082
+ 'min': self.safe_number(market, 'minLever'),
2083
+ 'max': self.safe_number(market, 'maxLever'),
2084
+ },
2085
+ 'amount': {
2086
+ 'min': self.safe_number_2(market, 'minTradeNum', 'minTradeAmount'),
2087
+ 'max': self.safe_number(market, 'maxTradeAmount'),
2088
+ },
2089
+ 'price': {
2090
+ 'min': None,
2091
+ 'max': None,
2092
+ },
2093
+ 'cost': {
2094
+ 'min': minCost,
2095
+ 'max': None,
2096
+ },
2005
2097
  },
2006
- 'price': {
2007
- 'min': None,
2008
- 'max': None,
2098
+ 'created': self.safe_integer(market, 'launchTime'),
2099
+ 'info': market,
2100
+ }))
2101
+ return result
2102
+
2103
+ async def fetch_uta_markets(self, params) -> List[Market]:
2104
+ subTypes = ['SPOT', 'USDT-FUTURES', 'COIN-FUTURES', 'USDC-FUTURES']
2105
+ promises = []
2106
+ for i in range(0, len(subTypes)):
2107
+ req = self.extend(params, {
2108
+ 'category': subTypes[i],
2109
+ })
2110
+ promises.append(self.publicUtaGetV3MarketInstruments(req))
2111
+ results = await asyncio.gather(*promises)
2112
+ markets = []
2113
+ for i in range(0, len(results)):
2114
+ res = self.safe_dict(results, i)
2115
+ data = self.safe_list(res, 'data', [])
2116
+ markets = self.array_concat(markets, data)
2117
+ #
2118
+ # spot uta
2119
+ #
2120
+ # {
2121
+ # "symbol": "BTCUSDT",
2122
+ # "category": "SPOT",
2123
+ # "baseCoin": "BTC",
2124
+ # "quoteCoin": "USDT",
2125
+ # "buyLimitPriceRatio": "0.05",
2126
+ # "sellLimitPriceRatio": "0.05",
2127
+ # "minOrderQty": "0.000001",
2128
+ # "maxOrderQty": "0",
2129
+ # "pricePrecision": "2",
2130
+ # "quantityPrecision": "6",
2131
+ # "quotePrecision": "8",
2132
+ # "minOrderAmount": "1",
2133
+ # "maxSymbolOrderNum": "400",
2134
+ # "maxProductOrderNum": "400",
2135
+ # "status": "online",
2136
+ # "maintainTime": ""
2137
+ # }
2138
+ #
2139
+ # margin uta
2140
+ #
2141
+ # {
2142
+ # "symbol": "BTCUSDC",
2143
+ # "category": "MARGIN",
2144
+ # "baseCoin": "BTC",
2145
+ # "quoteCoin": "USDC",
2146
+ # "buyLimitPriceRatio": "0.05",
2147
+ # "sellLimitPriceRatio": "0.05",
2148
+ # "minOrderQty": "0.00001",
2149
+ # "maxOrderQty": "0",
2150
+ # "pricePrecision": "2",
2151
+ # "quantityPrecision": "5",
2152
+ # "quotePrecision": "7",
2153
+ # "minOrderAmount": "1",
2154
+ # "maxSymbolOrderNum": "400",
2155
+ # "maxProductOrderNum": "400",
2156
+ # "status": "online",
2157
+ # "maintainTime": "",
2158
+ # "isIsolatedBaseBorrowable": "NO",
2159
+ # "isIsolatedQuotedBorrowable": "NO",
2160
+ # "warningRiskRatio": "0.8",
2161
+ # "liquidationRiskRatio": "1",
2162
+ # "maxCrossedLeverage": "3",
2163
+ # "maxIsolatedLeverage": "0",
2164
+ # "userMinBorrow": "0.00000001",
2165
+ # "areaSymbol": "no"
2166
+ # }
2167
+ #
2168
+ # swap and future uta
2169
+ #
2170
+ # {
2171
+ # "symbol": "BTCPERP",
2172
+ # "category": "USDC-FUTURES",
2173
+ # "baseCoin": "BTC",
2174
+ # "quoteCoin": "USDC",
2175
+ # "buyLimitPriceRatio": "0.02",
2176
+ # "sellLimitPriceRatio": "0.02",
2177
+ # "feeRateUpRatio": "0.005",
2178
+ # "makerFeeRate": "0.0002",
2179
+ # "takerFeeRate": "0.0006",
2180
+ # "openCostUpRatio": "0.01",
2181
+ # "minOrderQty": "0.0001",
2182
+ # "maxOrderQty": "",
2183
+ # "pricePrecision": "1",
2184
+ # "quantityPrecision": "4",
2185
+ # "quotePrecision": null,
2186
+ # "priceMultiplier": "0.5",
2187
+ # "quantityMultiplier": "0.0001",
2188
+ # "type": "perpetual",
2189
+ # "minOrderAmount": "5",
2190
+ # "maxSymbolOrderNum": "200",
2191
+ # "maxProductOrderNum": "1000",
2192
+ # "maxPositionNum": "150",
2193
+ # "status": "online",
2194
+ # "offTime": "-1",
2195
+ # "limitOpenTime": "-1",
2196
+ # "deliveryTime": "",
2197
+ # "deliveryStartTime": "",
2198
+ # "deliveryPeriod": "",
2199
+ # "launchTime": "",
2200
+ # "fundInterval": "8",
2201
+ # "minLeverage": "1",
2202
+ # "maxLeverage": "125",
2203
+ # "maintainTime": ""
2204
+ # }
2205
+ #
2206
+ result = []
2207
+ for i in range(0, len(markets)):
2208
+ market = markets[i]
2209
+ category = self.safe_string(market, 'category')
2210
+ marketId = self.safe_string(market, 'symbol')
2211
+ quoteId = self.safe_string(market, 'quoteCoin')
2212
+ baseId = self.safe_string(market, 'baseCoin')
2213
+ quote = self.safe_currency_code(quoteId)
2214
+ base = self.safe_currency_code(baseId)
2215
+ settleId = None
2216
+ settle = None
2217
+ if category == 'USDT-FUTURES':
2218
+ settleId = 'USDT'
2219
+ elif category == 'USDC-FUTURES':
2220
+ settleId = 'USDC'
2221
+ elif category == 'COIN-FUTURES':
2222
+ settleId = base
2223
+ if settleId is not None:
2224
+ settle = self.safe_currency_code(settleId)
2225
+ symbol = base + '/' + quote
2226
+ type = None
2227
+ swap = False
2228
+ spot = False
2229
+ future = False
2230
+ contract = False
2231
+ pricePrecision = None
2232
+ amountPrecision = None
2233
+ linear = None
2234
+ inverse = None
2235
+ expiry = None
2236
+ expiryDatetime = None
2237
+ symbolType = self.safe_string(market, 'type')
2238
+ marginModes = None
2239
+ isMarginTradingAllowed = False
2240
+ isUtaMargin = (category == 'MARGIN')
2241
+ if isUtaMargin or (category == 'SPOT'):
2242
+ type = 'spot'
2243
+ spot = True
2244
+ if isUtaMargin:
2245
+ isolatedBase = self.safe_string(market, 'isIsolatedBaseBorrowable')
2246
+ isolatedQuote = self.safe_string(market, 'isIsolatedQuotedBorrowable')
2247
+ isolated = (isolatedBase == 'YES') or (isolatedQuote == 'YES')
2248
+ maxCrossLeverage = self.safe_string(market, 'maxCrossedLeverage')
2249
+ cross = (maxCrossLeverage != '0')
2250
+ marginModes = {
2251
+ 'cross': cross,
2252
+ 'isolated': isolated,
2253
+ }
2254
+ isMarginTradingAllowed = True
2255
+ else:
2256
+ if symbolType == 'perpetual':
2257
+ type = 'swap'
2258
+ swap = True
2259
+ symbol = symbol + ':' + settle
2260
+ elif symbolType == 'delivery':
2261
+ expiry = self.safe_integer(market, 'deliveryTime')
2262
+ expiryDatetime = self.iso8601(expiry)
2263
+ expiryParts = expiryDatetime.split('-')
2264
+ yearPart = self.safe_string(expiryParts, 0)
2265
+ dayPart = self.safe_string(expiryParts, 2)
2266
+ year = yearPart[2:4]
2267
+ month = self.safe_string(expiryParts, 1)
2268
+ day = dayPart[0:2]
2269
+ expiryString = year + month + day
2270
+ type = 'future'
2271
+ future = True
2272
+ symbol = symbol + ':' + settle + '-' + expiryString
2273
+ contract = True
2274
+ inverse = (base == settle)
2275
+ linear = not inverse
2276
+ marginModes = {
2277
+ 'cross': True,
2278
+ 'isolated': True,
2279
+ }
2280
+ pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'pricePrecision')))
2281
+ amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityPrecision')))
2282
+ status = self.safe_string(market, 'status')
2283
+ active = None
2284
+ if status is not None:
2285
+ active = ((status == 'online') or (status == 'normal'))
2286
+ contractSize = 1 if contract else None
2287
+ result.append(self.safe_market_structure({
2288
+ 'id': marketId,
2289
+ 'symbol': symbol,
2290
+ 'base': base,
2291
+ 'quote': quote,
2292
+ 'settle': settle,
2293
+ 'baseId': baseId,
2294
+ 'quoteId': quoteId,
2295
+ 'settleId': settleId,
2296
+ 'type': type,
2297
+ 'spot': spot,
2298
+ 'margin': spot and isMarginTradingAllowed,
2299
+ 'marginModes': marginModes,
2300
+ 'swap': swap,
2301
+ 'future': future,
2302
+ 'option': False,
2303
+ 'active': active,
2304
+ 'contract': contract,
2305
+ 'linear': linear,
2306
+ 'inverse': inverse,
2307
+ 'taker': self.safe_number(market, 'takerFeeRate'),
2308
+ 'maker': self.safe_number(market, 'makerFeeRate'),
2309
+ 'contractSize': contractSize,
2310
+ 'expiry': expiry,
2311
+ 'expiryDatetime': expiryDatetime,
2312
+ 'strike': None,
2313
+ 'optionType': None,
2314
+ 'precision': {
2315
+ 'amount': amountPrecision,
2316
+ 'price': pricePrecision,
2009
2317
  },
2010
- 'cost': {
2011
- 'min': minCost,
2012
- 'max': None,
2318
+ 'limits': {
2319
+ 'leverage': {
2320
+ 'min': self.safe_number(market, 'minLeverage'),
2321
+ 'max': self.safe_number(market, 'maxLeverage'),
2322
+ },
2323
+ 'amount': {
2324
+ 'min': self.safe_number(market, 'minOrderQty'),
2325
+ 'max': self.safe_number(market, 'maxOrderQty'),
2326
+ },
2327
+ 'price': {
2328
+ 'min': None,
2329
+ 'max': None,
2330
+ },
2331
+ 'cost': {
2332
+ 'min': None,
2333
+ 'max': None,
2334
+ },
2013
2335
  },
2014
- },
2015
- 'created': self.safe_integer(market, 'launchTime'),
2016
- 'info': market,
2017
- }
2336
+ 'created': self.safe_integer(market, 'launchTime'),
2337
+ 'info': market,
2338
+ }))
2339
+ return result
2018
2340
 
2019
2341
  async def fetch_currencies(self, params={}) -> Currencies:
2020
2342
  """