ccxt 4.3.62__py2.py3-none-any.whl → 4.3.64__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 (74) hide show
  1. ccxt/__init__.py +2 -1
  2. ccxt/abstract/binance.py +5 -5
  3. ccxt/abstract/binancecoinm.py +5 -5
  4. ccxt/abstract/binanceus.py +5 -5
  5. ccxt/abstract/binanceusdm.py +5 -5
  6. ccxt/abstract/cryptocom.py +11 -0
  7. ccxt/abstract/kucoin.py +1 -0
  8. ccxt/abstract/kucoinfutures.py +1 -0
  9. ccxt/abstract/woo.py +3 -0
  10. ccxt/ace.py +33 -15
  11. ccxt/alpaca.py +1 -0
  12. ccxt/async_support/__init__.py +2 -1
  13. ccxt/async_support/ace.py +33 -15
  14. ccxt/async_support/alpaca.py +1 -0
  15. ccxt/async_support/base/exchange.py +4 -4
  16. ccxt/async_support/binance.py +6 -9
  17. ccxt/async_support/bingx.py +534 -152
  18. ccxt/async_support/bitfinex.py +1 -1
  19. ccxt/async_support/bitfinex2.py +1 -1
  20. ccxt/async_support/coinbaseinternational.py +1 -1
  21. ccxt/async_support/cryptocom.py +17 -2
  22. ccxt/async_support/independentreserve.py +103 -1
  23. ccxt/async_support/kucoin.py +2 -0
  24. ccxt/async_support/mercado.py +5 -1
  25. ccxt/async_support/whitebit.py +1 -1
  26. ccxt/async_support/woo.py +321 -81
  27. ccxt/async_support/xt.py +3 -3
  28. ccxt/async_support/yobit.py +1 -1
  29. ccxt/async_support/zonda.py +1 -1
  30. ccxt/base/errors.py +8 -1
  31. ccxt/base/exchange.py +11 -5
  32. ccxt/binance.py +6 -9
  33. ccxt/bingx.py +534 -152
  34. ccxt/bitfinex.py +1 -1
  35. ccxt/bitfinex2.py +1 -1
  36. ccxt/coinbaseinternational.py +1 -1
  37. ccxt/cryptocom.py +17 -2
  38. ccxt/independentreserve.py +103 -1
  39. ccxt/kucoin.py +2 -0
  40. ccxt/mercado.py +5 -1
  41. ccxt/pro/__init__.py +1 -1
  42. ccxt/pro/binance.py +56 -35
  43. ccxt/pro/bitfinex2.py +6 -4
  44. ccxt/pro/bitget.py +5 -2
  45. ccxt/pro/bitmart.py +3 -3
  46. ccxt/pro/bitvavo.py +1 -1
  47. ccxt/pro/bybit.py +41 -18
  48. ccxt/pro/cryptocom.py +7 -2
  49. ccxt/pro/gate.py +7 -4
  50. ccxt/pro/gemini.py +4 -2
  51. ccxt/pro/htx.py +5 -1
  52. ccxt/pro/independentreserve.py +6 -4
  53. ccxt/pro/kraken.py +79 -6
  54. ccxt/pro/okx.py +5 -5
  55. ccxt/pro/onetrading.py +3 -2
  56. ccxt/pro/oxfun.py +1 -1
  57. ccxt/pro/poloniexfutures.py +5 -2
  58. ccxt/pro/vertex.py +3 -2
  59. ccxt/pro/woo.py +2 -1
  60. ccxt/pro/woofipro.py +3 -2
  61. ccxt/test/tests_async.py +3 -3
  62. ccxt/test/tests_helpers.py +1 -1
  63. ccxt/test/tests_init.py +3 -3
  64. ccxt/test/tests_sync.py +3 -3
  65. ccxt/whitebit.py +1 -1
  66. ccxt/woo.py +321 -81
  67. ccxt/xt.py +3 -3
  68. ccxt/yobit.py +1 -1
  69. ccxt/zonda.py +1 -1
  70. {ccxt-4.3.62.dist-info → ccxt-4.3.64.dist-info}/METADATA +4 -4
  71. {ccxt-4.3.62.dist-info → ccxt-4.3.64.dist-info}/RECORD +74 -74
  72. {ccxt-4.3.62.dist-info → ccxt-4.3.64.dist-info}/LICENSE.txt +0 -0
  73. {ccxt-4.3.62.dist-info → ccxt-4.3.64.dist-info}/WHEEL +0 -0
  74. {ccxt-4.3.62.dist-info → ccxt-4.3.64.dist-info}/top_level.txt +0 -0
ccxt/bingx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bingx import ImplicitAPI
8
8
  import hashlib
9
9
  import numbers
10
- from ccxt.base.types import Balances, Currencies, Currency, Int, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry, TransferEntries
10
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Leverage, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry, TransferEntries
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -85,6 +85,7 @@ class bingx(Exchange, ImplicitAPI):
85
85
  'fetchOrder': True,
86
86
  'fetchOrderBook': True,
87
87
  'fetchOrders': True,
88
+ 'fetchPosition': True,
88
89
  'fetchPositionHistory': False,
89
90
  'fetchPositionMode': True,
90
91
  'fetchPositions': True,
@@ -93,6 +94,7 @@ class bingx(Exchange, ImplicitAPI):
93
94
  'fetchTickers': True,
94
95
  'fetchTime': True,
95
96
  'fetchTrades': True,
97
+ 'fetchTradingFee': True,
96
98
  'fetchTransfers': True,
97
99
  'fetchWithdrawals': True,
98
100
  'reduceMargin': True,
@@ -1698,6 +1700,7 @@ class bingx(Exchange, ImplicitAPI):
1698
1700
  :see: https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Assets
1699
1701
  :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Get%20Perpetual%20Swap%20Account%20Asset%20Information
1700
1702
  :see: https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1703
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20Account%20Assets
1701
1704
  :param dict [params]: extra parameters specific to the exchange API endpoint
1702
1705
  :param boolean [params.standard]: whether to fetch standard contract balances
1703
1706
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -1706,111 +1709,220 @@ class bingx(Exchange, ImplicitAPI):
1706
1709
  response = None
1707
1710
  standard = None
1708
1711
  standard, params = self.handle_option_and_params(params, 'fetchBalance', 'standard', False)
1712
+ subType = None
1713
+ subType, params = self.handle_sub_type_and_params('fetchBalance', None, params)
1709
1714
  marketType, marketTypeQuery = self.handle_market_type_and_params('fetchBalance', None, params)
1710
1715
  if standard:
1711
1716
  response = self.contractV1PrivateGetBalance(marketTypeQuery)
1717
+ #
1718
+ # {
1719
+ # "code": 0,
1720
+ # "timestamp": 1721192833454,
1721
+ # "data": [
1722
+ # {
1723
+ # "asset": "USDT",
1724
+ # "balance": "4.72644300000000000000",
1725
+ # "crossWalletBalance": "4.72644300000000000000",
1726
+ # "crossUnPnl": "0",
1727
+ # "availableBalance": "4.72644300000000000000",
1728
+ # "maxWithdrawAmount": "4.72644300000000000000",
1729
+ # "marginAvailable": False,
1730
+ # "updateTime": 1721192833443
1731
+ # },
1732
+ # ]
1733
+ # }
1734
+ #
1712
1735
  elif marketType == 'spot':
1713
1736
  response = self.spotV1PrivateGetAccountBalance(marketTypeQuery)
1737
+ #
1738
+ # {
1739
+ # "code": 0,
1740
+ # "msg": "",
1741
+ # "debugMsg": "",
1742
+ # "data": {
1743
+ # "balances": [
1744
+ # {
1745
+ # "asset": "USDT",
1746
+ # "free": "45.733046995800514",
1747
+ # "locked": "0"
1748
+ # },
1749
+ # ]
1750
+ # }
1751
+ # }
1752
+ #
1714
1753
  else:
1715
- response = self.swapV2PrivateGetUserBalance(marketTypeQuery)
1754
+ if subType == 'inverse':
1755
+ response = self.cswapV1PrivateGetUserBalance(marketTypeQuery)
1756
+ #
1757
+ # {
1758
+ # "code": 0,
1759
+ # "msg": "",
1760
+ # "timestamp": 1721191833813,
1761
+ # "data": [
1762
+ # {
1763
+ # "asset": "SOL",
1764
+ # "balance": "0.35707951",
1765
+ # "equity": "0.35791051",
1766
+ # "unrealizedProfit": "0.00083099",
1767
+ # "availableMargin": "0.35160653",
1768
+ # "usedMargin": "0.00630397",
1769
+ # "freezedMargin": "0",
1770
+ # "shortUid": "12851936"
1771
+ # }
1772
+ # ]
1773
+ # }
1774
+ #
1775
+ else:
1776
+ response = self.swapV2PrivateGetUserBalance(marketTypeQuery)
1777
+ #
1778
+ # {
1779
+ # "code": 0,
1780
+ # "msg": "",
1781
+ # "data": {
1782
+ # "balance": {
1783
+ # "userId": "1177064765068660742",
1784
+ # "asset": "USDT",
1785
+ # "balance": "51.5198",
1786
+ # "equity": "50.5349",
1787
+ # "unrealizedProfit": "-0.9849",
1788
+ # "realisedProfit": "-0.2134",
1789
+ # "availableMargin": "49.1428",
1790
+ # "usedMargin": "1.3922",
1791
+ # "freezedMargin": "0.0000",
1792
+ # "shortUid": "12851936"
1793
+ # }
1794
+ # }
1795
+ # }
1796
+ #
1797
+ return self.parse_balance(response)
1798
+
1799
+ def parse_balance(self, response) -> Balances:
1800
+ #
1801
+ # standard
1802
+ #
1803
+ # {
1804
+ # "code": 0,
1805
+ # "timestamp": 1721192833454,
1806
+ # "data": [
1807
+ # {
1808
+ # "asset": "USDT",
1809
+ # "balance": "4.72644300000000000000",
1810
+ # "crossWalletBalance": "4.72644300000000000000",
1811
+ # "crossUnPnl": "0",
1812
+ # "availableBalance": "4.72644300000000000000",
1813
+ # "maxWithdrawAmount": "4.72644300000000000000",
1814
+ # "marginAvailable": False,
1815
+ # "updateTime": 1721192833443
1816
+ # },
1817
+ # ]
1818
+ # }
1716
1819
  #
1717
1820
  # spot
1718
1821
  #
1719
- # {
1720
- # "code": 0,
1721
- # "msg": "",
1722
- # "ttl": 1,
1723
- # "data": {
1724
- # "balances": [
1725
- # {
1726
- # "asset": "USDT",
1727
- # "free": "16.73971130673954",
1728
- # "locked": "0"
1729
- # }
1730
- # ]
1731
- # }
1732
- # }
1822
+ # {
1823
+ # "code": 0,
1824
+ # "msg": "",
1825
+ # "debugMsg": "",
1826
+ # "data": {
1827
+ # "balances": [
1828
+ # {
1829
+ # "asset": "USDT",
1830
+ # "free": "45.733046995800514",
1831
+ # "locked": "0"
1832
+ # },
1833
+ # ]
1834
+ # }
1835
+ # }
1733
1836
  #
1734
- # swap
1837
+ # inverse swap
1735
1838
  #
1736
- # {
1737
- # "code": 0,
1738
- # "msg": "",
1739
- # "data": {
1740
- # "balance": {
1741
- # "asset": "USDT",
1742
- # "balance": "15.6128",
1743
- # "equity": "15.6128",
1744
- # "unrealizedProfit": "0.0000",
1745
- # "realisedProfit": "0.0000",
1746
- # "availableMargin": "15.6128",
1747
- # "usedMargin": "0.0000",
1748
- # "freezedMargin": "0.0000"
1749
- # }
1750
- # }
1751
- # }
1752
- # standard futures
1753
- # {
1754
- # "code":"0",
1755
- # "timestamp":"1691148990942",
1756
- # "data":[
1757
- # {
1758
- # "asset":"VST",
1759
- # "balance":"100000.00000000000000000000",
1760
- # "crossWalletBalance":"100000.00000000000000000000",
1761
- # "crossUnPnl":"0",
1762
- # "availableBalance":"100000.00000000000000000000",
1763
- # "maxWithdrawAmount":"100000.00000000000000000000",
1764
- # "marginAvailable":false,
1765
- # "updateTime":"1691148990902"
1766
- # },
1767
- # {
1768
- # "asset":"USDT",
1769
- # "balance":"0",
1770
- # "crossWalletBalance":"0",
1771
- # "crossUnPnl":"0",
1772
- # "availableBalance":"0",
1773
- # "maxWithdrawAmount":"0",
1774
- # "marginAvailable":false,
1775
- # "updateTime":"1691148990902"
1776
- # },
1777
- # ]
1839
+ # {
1840
+ # "code": 0,
1841
+ # "msg": "",
1842
+ # "timestamp": 1721191833813,
1843
+ # "data": [
1844
+ # {
1845
+ # "asset": "SOL",
1846
+ # "balance": "0.35707951",
1847
+ # "equity": "0.35791051",
1848
+ # "unrealizedProfit": "0.00083099",
1849
+ # "availableMargin": "0.35160653",
1850
+ # "usedMargin": "0.00630397",
1851
+ # "freezedMargin": "0",
1852
+ # "shortUid": "12851936"
1853
+ # }
1854
+ # ]
1855
+ # }
1856
+ #
1857
+ # linear swap
1858
+ #
1859
+ # {
1860
+ # "code": 0,
1861
+ # "msg": "",
1862
+ # "data": {
1863
+ # "balance": {
1864
+ # "userId": "1177064765068660742",
1865
+ # "asset": "USDT",
1866
+ # "balance": "51.5198",
1867
+ # "equity": "50.5349",
1868
+ # "unrealizedProfit": "-0.9849",
1869
+ # "realisedProfit": "-0.2134",
1870
+ # "availableMargin": "49.1428",
1871
+ # "usedMargin": "1.3922",
1872
+ # "freezedMargin": "0.0000",
1873
+ # "shortUid": "12851936"
1874
+ # }
1875
+ # }
1778
1876
  # }
1779
1877
  #
1780
- return self.parse_balance(response)
1781
-
1782
- def parse_balance(self, response) -> Balances:
1783
- data = self.safe_value(response, 'data')
1784
- balances = self.safe_value_2(data, 'balance', 'balances', data)
1785
1878
  result: dict = {'info': response}
1786
- if isinstance(balances, list):
1787
- for i in range(0, len(balances)):
1788
- balance = balances[i]
1879
+ standardAndInverseBalances = self.safe_list(response, 'data')
1880
+ firstStandardOrInverse = self.safe_dict(standardAndInverseBalances, 0)
1881
+ isStandardOrInverse = firstStandardOrInverse is not None
1882
+ spotData = self.safe_dict(response, 'data', {})
1883
+ spotBalances = self.safe_list(spotData, 'balances')
1884
+ firstSpot = self.safe_dict(spotBalances, 0)
1885
+ isSpot = firstSpot is not None
1886
+ if isStandardOrInverse:
1887
+ for i in range(0, len(standardAndInverseBalances)):
1888
+ balance = standardAndInverseBalances[i]
1889
+ currencyId = self.safe_string(balance, 'asset')
1890
+ code = self.safe_currency_code(currencyId)
1891
+ account = self.account()
1892
+ account['free'] = self.safe_string_2(balance, 'availableMargin', 'availableBalance')
1893
+ account['used'] = self.safe_string(balance, 'usedMargin')
1894
+ account['total'] = self.safe_string(balance, 'maxWithdrawAmount')
1895
+ result[code] = account
1896
+ elif isSpot:
1897
+ for i in range(0, len(spotBalances)):
1898
+ balance = spotBalances[i]
1789
1899
  currencyId = self.safe_string(balance, 'asset')
1790
1900
  code = self.safe_currency_code(currencyId)
1791
1901
  account = self.account()
1792
- account['free'] = self.safe_string_2(balance, 'free', 'availableBalance')
1902
+ account['free'] = self.safe_string(balance, 'free')
1793
1903
  account['used'] = self.safe_string(balance, 'locked')
1794
- account['total'] = self.safe_string(balance, 'balance')
1795
1904
  result[code] = account
1796
1905
  else:
1797
- currencyId = self.safe_string(balances, 'asset')
1906
+ linearSwapData = self.safe_dict(response, 'data', {})
1907
+ linearSwapBalance = self.safe_dict(linearSwapData, 'balance')
1908
+ currencyId = self.safe_string(linearSwapBalance, 'asset')
1798
1909
  code = self.safe_currency_code(currencyId)
1799
1910
  account = self.account()
1800
- account['free'] = self.safe_string(balances, 'availableMargin')
1801
- account['used'] = self.safe_string(balances, 'usedMargin')
1911
+ account['free'] = self.safe_string(linearSwapBalance, 'availableMargin')
1912
+ account['used'] = self.safe_string(linearSwapBalance, 'usedMargin')
1802
1913
  result[code] = account
1803
1914
  return self.safe_balance(result)
1804
1915
 
1805
1916
  def fetch_positions(self, symbols: Strings = None, params={}):
1806
1917
  """
1807
1918
  fetch all open positions
1808
- :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Perpetual%20Swap%20Positions
1809
- :see: https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1919
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/account-api.html#Query%20position%20data
1920
+ :see: https://bingx-api.github.io/docs/#/en-us/standard/contract-interface.html#position
1921
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20warehouse
1810
1922
  :param str[]|None symbols: list of unified market symbols
1811
1923
  :param dict [params]: extra parameters specific to the exchange API endpoint
1812
1924
  :param boolean [params.standard]: whether to fetch standard contract positions
1813
- :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1925
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
1814
1926
  """
1815
1927
  self.load_markets()
1816
1928
  symbols = self.market_symbols(symbols)
@@ -1820,54 +1932,207 @@ class bingx(Exchange, ImplicitAPI):
1820
1932
  if standard:
1821
1933
  response = self.contractV1PrivateGetAllPosition(params)
1822
1934
  else:
1823
- response = self.swapV2PrivateGetUserPositions(params)
1824
- #
1825
- # {
1826
- # "code": 0,
1827
- # "msg": "",
1828
- # "data": [
1829
- # {
1830
- # "symbol": "BTC-USDT",
1831
- # "positionId": "12345678",
1832
- # "positionSide": "LONG",
1833
- # "isolated": True,
1834
- # "positionAmt": "123.33",
1835
- # "availableAmt": "128.99",
1836
- # "unrealizedProfit": "1.22",
1837
- # "realisedProfit": "8.1",
1838
- # "initialMargin": "123.33",
1839
- # "avgPrice": "2.2",
1840
- # "leverage": 10,
1841
- # }
1842
- # ]
1843
- # }
1844
- #
1935
+ market = None
1936
+ if symbols is not None:
1937
+ symbols = self.market_symbols(symbols)
1938
+ firstSymbol = self.safe_string(symbols, 0)
1939
+ if firstSymbol is not None:
1940
+ market = self.market(firstSymbol)
1941
+ subType = None
1942
+ subType, params = self.handle_sub_type_and_params('fetchPositions', market, params)
1943
+ if subType == 'inverse':
1944
+ response = self.cswapV1PrivateGetUserPositions(params)
1945
+ #
1946
+ # {
1947
+ # "code": 0,
1948
+ # "msg": "",
1949
+ # "timestamp": 0,
1950
+ # "data": [
1951
+ # {
1952
+ # "symbol": "SOL-USD",
1953
+ # "positionId": "1813080351385337856",
1954
+ # "positionSide": "LONG",
1955
+ # "isolated": False,
1956
+ # "positionAmt": "1",
1957
+ # "availableAmt": "1",
1958
+ # "unrealizedProfit": "-0.00009074",
1959
+ # "initialMargin": "0.00630398",
1960
+ # "liquidationPrice": 23.968303426677032,
1961
+ # "avgPrice": "158.63",
1962
+ # "leverage": 10,
1963
+ # "markPrice": "158.402",
1964
+ # "riskRate": "0.00123783",
1965
+ # "maxMarginReduction": "0",
1966
+ # "updateTime": 1721107015848
1967
+ # }
1968
+ # ]
1969
+ # }
1970
+ #
1971
+ else:
1972
+ response = self.swapV2PrivateGetUserPositions(params)
1973
+ #
1974
+ # {
1975
+ # "code": 0,
1976
+ # "msg": "",
1977
+ # "data": [
1978
+ # {
1979
+ # "positionId": "1792480725958881280",
1980
+ # "symbol": "LTC-USDT",
1981
+ # "currency": "USDT",
1982
+ # "positionAmt": "0.1",
1983
+ # "availableAmt": "0.1",
1984
+ # "positionSide": "LONG",
1985
+ # "isolated": False,
1986
+ # "avgPrice": "83.53",
1987
+ # "initialMargin": "1.3922",
1988
+ # "margin": "0.3528",
1989
+ # "leverage": 6,
1990
+ # "unrealizedProfit": "-1.0393",
1991
+ # "realisedProfit": "-0.2119",
1992
+ # "liquidationPrice": 0,
1993
+ # "pnlRatio": "-0.7465",
1994
+ # "maxMarginReduction": "0.0000",
1995
+ # "riskRate": "0.0008",
1996
+ # "markPrice": "73.14",
1997
+ # "positionValue": "7.3136",
1998
+ # "onlyOnePosition": True,
1999
+ # "updateTime": 1721088016688
2000
+ # }
2001
+ # ]
2002
+ # }
2003
+ #
1845
2004
  positions = self.safe_list(response, 'data', [])
1846
2005
  return self.parse_positions(positions, symbols)
1847
2006
 
2007
+ def fetch_position(self, symbol: str, params={}):
2008
+ """
2009
+ fetch data on a single open contract trade position
2010
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/account-api.html#Query%20position%20data
2011
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20warehouse
2012
+ :param str symbol: unified market symbol of the market the position is held in
2013
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2014
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2015
+ """
2016
+ self.load_markets()
2017
+ market = self.market(symbol)
2018
+ if not market['swap']:
2019
+ raise BadRequest(self.id + ' fetchPosition() supports swap markets only')
2020
+ request: dict = {
2021
+ 'symbol': market['id'],
2022
+ }
2023
+ response = None
2024
+ if market['inverse']:
2025
+ response = self.cswapV1PrivateGetUserPositions(self.extend(request, params))
2026
+ #
2027
+ # {
2028
+ # "code": 0,
2029
+ # "msg": "",
2030
+ # "timestamp": 0,
2031
+ # "data": [
2032
+ # {
2033
+ # "symbol": "SOL-USD",
2034
+ # "positionId": "1813080351385337856",
2035
+ # "positionSide": "LONG",
2036
+ # "isolated": False,
2037
+ # "positionAmt": "1",
2038
+ # "availableAmt": "1",
2039
+ # "unrealizedProfit": "-0.00009074",
2040
+ # "initialMargin": "0.00630398",
2041
+ # "liquidationPrice": 23.968303426677032,
2042
+ # "avgPrice": "158.63",
2043
+ # "leverage": 10,
2044
+ # "markPrice": "158.402",
2045
+ # "riskRate": "0.00123783",
2046
+ # "maxMarginReduction": "0",
2047
+ # "updateTime": 1721107015848
2048
+ # }
2049
+ # ]
2050
+ # }
2051
+ #
2052
+ else:
2053
+ response = self.swapV2PrivateGetUserPositions(self.extend(request, params))
2054
+ #
2055
+ # {
2056
+ # "code": 0,
2057
+ # "msg": "",
2058
+ # "data": [
2059
+ # {
2060
+ # "positionId": "1792480725958881280",
2061
+ # "symbol": "LTC-USDT",
2062
+ # "currency": "USDT",
2063
+ # "positionAmt": "0.1",
2064
+ # "availableAmt": "0.1",
2065
+ # "positionSide": "LONG",
2066
+ # "isolated": False,
2067
+ # "avgPrice": "83.53",
2068
+ # "initialMargin": "1.3922",
2069
+ # "margin": "0.3528",
2070
+ # "leverage": 6,
2071
+ # "unrealizedProfit": "-1.0393",
2072
+ # "realisedProfit": "-0.2119",
2073
+ # "liquidationPrice": 0,
2074
+ # "pnlRatio": "-0.7465",
2075
+ # "maxMarginReduction": "0.0000",
2076
+ # "riskRate": "0.0008",
2077
+ # "markPrice": "73.14",
2078
+ # "positionValue": "7.3136",
2079
+ # "onlyOnePosition": True,
2080
+ # "updateTime": 1721088016688
2081
+ # }
2082
+ # ]
2083
+ # }
2084
+ #
2085
+ data = self.safe_list(response, 'data', [])
2086
+ first = self.safe_dict(data, 0, {})
2087
+ return self.parse_position(first, market)
2088
+
1848
2089
  def parse_position(self, position: dict, market: Market = None):
1849
2090
  #
1850
- # {
1851
- # "positionId":"1773122376147623936",
1852
- # "symbol":"XRP-USDT",
1853
- # "currency":"USDT",
1854
- # "positionAmt":"3",
1855
- # "availableAmt":"3",
1856
- # "positionSide":"LONG",
1857
- # "isolated":false,
1858
- # "avgPrice":"0.6139",
1859
- # "initialMargin":"0.0897",
1860
- # "leverage":20,
1861
- # "unrealizedProfit":"-0.0023",
1862
- # "realisedProfit":"-0.0009",
1863
- # "liquidationPrice":0,
1864
- # "pnlRatio":"-0.0260",
1865
- # "maxMarginReduction":"",
1866
- # "riskRate":"",
1867
- # "markPrice":"",
1868
- # "positionValue":"",
1869
- # "onlyOnePosition":false
1870
- # }
2091
+ # inverse swap
2092
+ #
2093
+ # {
2094
+ # "symbol": "SOL-USD",
2095
+ # "positionId": "1813080351385337856",
2096
+ # "positionSide": "LONG",
2097
+ # "isolated": False,
2098
+ # "positionAmt": "1",
2099
+ # "availableAmt": "1",
2100
+ # "unrealizedProfit": "-0.00009074",
2101
+ # "initialMargin": "0.00630398",
2102
+ # "liquidationPrice": 23.968303426677032,
2103
+ # "avgPrice": "158.63",
2104
+ # "leverage": 10,
2105
+ # "markPrice": "158.402",
2106
+ # "riskRate": "0.00123783",
2107
+ # "maxMarginReduction": "0",
2108
+ # "updateTime": 1721107015848
2109
+ # }
2110
+ #
2111
+ # linear swap
2112
+ #
2113
+ # {
2114
+ # "positionId": "1792480725958881280",
2115
+ # "symbol": "LTC-USDT",
2116
+ # "currency": "USDT",
2117
+ # "positionAmt": "0.1",
2118
+ # "availableAmt": "0.1",
2119
+ # "positionSide": "LONG",
2120
+ # "isolated": False,
2121
+ # "avgPrice": "83.53",
2122
+ # "initialMargin": "1.3922",
2123
+ # "margin": "0.3528",
2124
+ # "leverage": 6,
2125
+ # "unrealizedProfit": "-1.0393",
2126
+ # "realisedProfit": "-0.2119",
2127
+ # "liquidationPrice": 0,
2128
+ # "pnlRatio": "-0.7465",
2129
+ # "maxMarginReduction": "0.0000",
2130
+ # "riskRate": "0.0008",
2131
+ # "markPrice": "73.14",
2132
+ # "positionValue": "7.3136",
2133
+ # "onlyOnePosition": True,
2134
+ # "updateTime": 1721088016688
2135
+ # }
1871
2136
  #
1872
2137
  # standard position
1873
2138
  #
@@ -1902,13 +2167,13 @@ class bingx(Exchange, ImplicitAPI):
1902
2167
  'percentage': None,
1903
2168
  'contracts': self.safe_number(position, 'positionAmt'),
1904
2169
  'contractSize': None,
1905
- 'markPrice': None,
2170
+ 'markPrice': self.safe_number(position, 'markPrice'),
1906
2171
  'lastPrice': None,
1907
2172
  'side': self.safe_string_lower(position, 'positionSide'),
1908
2173
  'hedged': None,
1909
2174
  'timestamp': None,
1910
2175
  'datetime': None,
1911
- 'lastUpdateTimestamp': None,
2176
+ 'lastUpdateTimestamp': self.safe_integer(position, 'updateTime'),
1912
2177
  'maintenanceMargin': None,
1913
2178
  'maintenanceMarginPercentage': None,
1914
2179
  'collateral': None,
@@ -4269,6 +4534,7 @@ class bingx(Exchange, ImplicitAPI):
4269
4534
  """
4270
4535
  retrieves the users liquidated positions
4271
4536
  :see: https://bingx-api.github.io/docs/#/swapV2/trade-api.html#User's%20Force%20Orders
4537
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20force%20orders
4272
4538
  :param str [symbol]: unified CCXT market symbol
4273
4539
  :param int [since]: the earliest time in ms to fetch liquidations for
4274
4540
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -4289,38 +4555,73 @@ class bingx(Exchange, ImplicitAPI):
4289
4555
  request['startTime'] = since
4290
4556
  if limit is not None:
4291
4557
  request['limit'] = limit
4292
- response = self.swapV2PrivateGetTradeForceOrders(self.extend(request, params))
4293
- #
4294
- # {
4295
- # "code": 0,
4296
- # "msg": "",
4297
- # "data": {
4298
- # "orders": [
4299
- # {
4300
- # "time": "int64",
4301
- # "symbol": "string",
4302
- # "side": "string",
4303
- # "type": "string",
4304
- # "positionSide": "string",
4305
- # "cumQuote": "string",
4306
- # "status": "string",
4307
- # "stopPrice": "string",
4308
- # "price": "string",
4309
- # "origQty": "string",
4310
- # "avgPrice": "string",
4311
- # "executedQty": "string",
4312
- # "orderId": "int64",
4313
- # "profit": "string",
4314
- # "commission": "string",
4315
- # "workingType": "string",
4316
- # "updateTime": "int64"
4317
- # },
4318
- # ]
4319
- # }
4320
- # }
4321
- #
4322
- data = self.safe_dict(response, 'data', {})
4323
- liquidations = self.safe_list(data, 'orders', [])
4558
+ subType = None
4559
+ subType, params = self.handle_sub_type_and_params('fetchMyLiquidations', market, params)
4560
+ response = None
4561
+ liquidations = None
4562
+ if subType == 'inverse':
4563
+ response = self.cswapV1PrivateGetTradeForceOrders(self.extend(request, params))
4564
+ #
4565
+ # {
4566
+ # "code": 0,
4567
+ # "msg": "",
4568
+ # "timestamp": 1721280071678,
4569
+ # "data": [
4570
+ # {
4571
+ # "orderId": "string",
4572
+ # "symbol": "string",
4573
+ # "type": "string",
4574
+ # "side": "string",
4575
+ # "positionSide": "string",
4576
+ # "price": "string",
4577
+ # "quantity": "float64",
4578
+ # "stopPrice": "string",
4579
+ # "workingType": "string",
4580
+ # "status": "string",
4581
+ # "time": "int64",
4582
+ # "avgPrice": "string",
4583
+ # "executedQty": "string",
4584
+ # "profit": "string",
4585
+ # "commission": "string",
4586
+ # "updateTime": "string"
4587
+ # }
4588
+ # ]
4589
+ # }
4590
+ #
4591
+ liquidations = self.safe_list(response, 'data', [])
4592
+ else:
4593
+ response = self.swapV2PrivateGetTradeForceOrders(self.extend(request, params))
4594
+ #
4595
+ # {
4596
+ # "code": 0,
4597
+ # "msg": "",
4598
+ # "data": {
4599
+ # "orders": [
4600
+ # {
4601
+ # "time": "int64",
4602
+ # "symbol": "string",
4603
+ # "side": "string",
4604
+ # "type": "string",
4605
+ # "positionSide": "string",
4606
+ # "cumQuote": "string",
4607
+ # "status": "string",
4608
+ # "stopPrice": "string",
4609
+ # "price": "string",
4610
+ # "origQty": "string",
4611
+ # "avgPrice": "string",
4612
+ # "executedQty": "string",
4613
+ # "orderId": "int64",
4614
+ # "profit": "string",
4615
+ # "commission": "string",
4616
+ # "workingType": "string",
4617
+ # "updateTime": "int64"
4618
+ # },
4619
+ # ]
4620
+ # }
4621
+ # }
4622
+ #
4623
+ data = self.safe_dict(response, 'data', {})
4624
+ liquidations = self.safe_list(data, 'orders', [])
4324
4625
  return self.parse_liquidations(liquidations, market, since, limit)
4325
4626
 
4326
4627
  def parse_liquidation(self, liquidation, market: Market = None):
@@ -4710,6 +5011,87 @@ class bingx(Exchange, ImplicitAPI):
4710
5011
  'marginMode': marginType,
4711
5012
  }
4712
5013
 
5014
+ def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
5015
+ """
5016
+ fetch the trading fees for a market
5017
+ :see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Query%20Trading%20Commission%20Rate
5018
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/account-api.html#Query%20Trading%20Commission%20Rate
5019
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20Trade%20Commission%20Rate
5020
+ :param str symbol: unified market symbol
5021
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5022
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
5023
+ """
5024
+ self.load_markets()
5025
+ market = self.market(symbol)
5026
+ request: dict = {
5027
+ 'symbol': market['id'],
5028
+ }
5029
+ response = None
5030
+ commission: dict = {}
5031
+ data = self.safe_dict(response, 'data', {})
5032
+ if market['spot']:
5033
+ response = self.spotV1PrivateGetUserCommissionRate(self.extend(request, params))
5034
+ #
5035
+ # {
5036
+ # "code": 0,
5037
+ # "msg": "",
5038
+ # "debugMsg": "",
5039
+ # "data": {
5040
+ # "takerCommissionRate": 0.001,
5041
+ # "makerCommissionRate": 0.001
5042
+ # }
5043
+ # }
5044
+ #
5045
+ commission = data
5046
+ else:
5047
+ if market['inverse']:
5048
+ response = self.cswapV1PrivateGetUserCommissionRate(params)
5049
+ #
5050
+ # {
5051
+ # "code": 0,
5052
+ # "msg": "",
5053
+ # "timestamp": 1721365261438,
5054
+ # "data": {
5055
+ # "takerCommissionRate": "0.0005",
5056
+ # "makerCommissionRate": "0.0002"
5057
+ # }
5058
+ # }
5059
+ #
5060
+ commission = data
5061
+ else:
5062
+ response = self.swapV2PrivateGetUserCommissionRate(params)
5063
+ #
5064
+ # {
5065
+ # "code": 0,
5066
+ # "msg": "",
5067
+ # "data": {
5068
+ # "commission": {
5069
+ # "takerCommissionRate": 0.0005,
5070
+ # "makerCommissionRate": 0.0002
5071
+ # }
5072
+ # }
5073
+ # }
5074
+ #
5075
+ commission = self.safe_dict(data, 'commission', {})
5076
+ return self.parse_trading_fee(commission, market)
5077
+
5078
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
5079
+ #
5080
+ # {
5081
+ # "takerCommissionRate": 0.001,
5082
+ # "makerCommissionRate": 0.001
5083
+ # }
5084
+ #
5085
+ symbol = market['symbol'] if (market is not None) else None
5086
+ return {
5087
+ 'info': fee,
5088
+ 'symbol': symbol,
5089
+ 'maker': self.safe_number(fee, 'makerCommissionRate'),
5090
+ 'taker': self.safe_number(fee, 'takerCommissionRate'),
5091
+ 'percentage': False,
5092
+ 'tierBased': False,
5093
+ }
5094
+
4713
5095
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
4714
5096
  type = section[0]
4715
5097
  version = section[1]