ccxt 4.3.61__py2.py3-none-any.whl → 4.3.63__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 (69) 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/woo.py +3 -0
  8. ccxt/ace.py +33 -15
  9. ccxt/async_support/__init__.py +2 -1
  10. ccxt/async_support/ace.py +33 -15
  11. ccxt/async_support/base/exchange.py +1 -1
  12. ccxt/async_support/base/ws/fast_client.py +2 -2
  13. ccxt/async_support/binance.py +43 -38
  14. ccxt/async_support/bingx.py +492 -184
  15. ccxt/async_support/bybit.py +1 -1
  16. ccxt/async_support/coinbaseinternational.py +1 -1
  17. ccxt/async_support/cryptocom.py +17 -2
  18. ccxt/async_support/mercado.py +5 -1
  19. ccxt/async_support/tradeogre.py +1 -1
  20. ccxt/async_support/woo.py +296 -81
  21. ccxt/async_support/xt.py +4 -4
  22. ccxt/base/errors.py +8 -1
  23. ccxt/base/exchange.py +8 -2
  24. ccxt/binance.py +43 -38
  25. ccxt/bingx.py +492 -184
  26. ccxt/bybit.py +1 -1
  27. ccxt/coinbaseinternational.py +1 -1
  28. ccxt/cryptocom.py +17 -2
  29. ccxt/mercado.py +5 -1
  30. ccxt/pro/__init__.py +1 -1
  31. ccxt/pro/alpaca.py +3 -3
  32. ccxt/pro/binance.py +58 -39
  33. ccxt/pro/bingx.py +2 -2
  34. ccxt/pro/bitfinex2.py +8 -6
  35. ccxt/pro/bitget.py +6 -3
  36. ccxt/pro/bitmex.py +1 -1
  37. ccxt/pro/bitopro.py +1 -1
  38. ccxt/pro/bitvavo.py +1 -1
  39. ccxt/pro/bybit.py +46 -23
  40. ccxt/pro/coinbaseexchange.py +2 -2
  41. ccxt/pro/coincheck.py +1 -1
  42. ccxt/pro/coinone.py +1 -1
  43. ccxt/pro/cryptocom.py +8 -3
  44. ccxt/pro/deribit.py +1 -1
  45. ccxt/pro/gate.py +8 -5
  46. ccxt/pro/hollaex.py +1 -1
  47. ccxt/pro/htx.py +6 -2
  48. ccxt/pro/hyperliquid.py +3 -3
  49. ccxt/pro/independentreserve.py +6 -4
  50. ccxt/pro/kraken.py +80 -7
  51. ccxt/pro/kucoin.py +1 -1
  52. ccxt/pro/mexc.py +1 -1
  53. ccxt/pro/okx.py +5 -5
  54. ccxt/pro/oxfun.py +1 -1
  55. ccxt/pro/phemex.py +1 -1
  56. ccxt/pro/poloniexfutures.py +5 -2
  57. ccxt/pro/upbit.py +1 -1
  58. ccxt/pro/vertex.py +2 -2
  59. ccxt/pro/whitebit.py +1 -1
  60. ccxt/pro/woo.py +1 -1
  61. ccxt/pro/woofipro.py +1 -1
  62. ccxt/tradeogre.py +1 -1
  63. ccxt/woo.py +296 -81
  64. ccxt/xt.py +4 -4
  65. {ccxt-4.3.61.dist-info → ccxt-4.3.63.dist-info}/METADATA +4 -4
  66. {ccxt-4.3.61.dist-info → ccxt-4.3.63.dist-info}/RECORD +69 -69
  67. {ccxt-4.3.61.dist-info → ccxt-4.3.63.dist-info}/LICENSE.txt +0 -0
  68. {ccxt-4.3.61.dist-info → ccxt-4.3.63.dist-info}/WHEEL +0 -0
  69. {ccxt-4.3.61.dist-info → ccxt-4.3.63.dist-info}/top_level.txt +0 -0
@@ -86,6 +86,7 @@ class bingx(Exchange, ImplicitAPI):
86
86
  'fetchOrder': True,
87
87
  'fetchOrderBook': True,
88
88
  'fetchOrders': True,
89
+ 'fetchPosition': True,
89
90
  'fetchPositionHistory': False,
90
91
  'fetchPositionMode': True,
91
92
  'fetchPositions': True,
@@ -528,37 +529,40 @@ class bingx(Exchange, ImplicitAPI):
528
529
  response = await self.walletsV1PrivateGetCapitalConfigGetall(params)
529
530
  #
530
531
  # {
531
- # "code": 0,
532
- # "timestamp": 1688045966616,
533
- # "data": [
532
+ # "code": 0,
533
+ # "timestamp": 1702623271477,
534
+ # "data": [
535
+ # {
536
+ # "coin": "BTC",
537
+ # "name": "BTC",
538
+ # "networkList": [
534
539
  # {
535
- # "coin": "BTC",
536
540
  # "name": "BTC",
537
- # "networkList": [
538
- # {
539
- # "name": "BTC",
540
- # "network": "BTC",
541
- # "isDefault": True,
542
- # "minConfirm": "2",
543
- # "withdrawEnable": True,
544
- # "withdrawFee": "0.00035",
545
- # "withdrawMax": "1.62842",
546
- # "withdrawMin": "0.0005"
547
- # },
548
- # {
549
- # "name": "BTC",
550
- # "network": "BEP20",
551
- # "isDefault": False,
552
- # "minConfirm": "15",
553
- # "withdrawEnable": True,
554
- # "withdrawFee": "0.00001",
555
- # "withdrawMax": "1.62734",
556
- # "withdrawMin": "0.0001"
557
- # }
558
- # ]
559
- # },
560
- # ...
561
- # ],
541
+ # "network": "BTC",
542
+ # "isDefault": True,
543
+ # "minConfirm": 2,
544
+ # "withdrawEnable": True,
545
+ # "depositEnable": True,
546
+ # "withdrawFee": "0.0006",
547
+ # "withdrawMax": "1.17522",
548
+ # "withdrawMin": "0.0005",
549
+ # "depositMin": "0.0002"
550
+ # },
551
+ # {
552
+ # "name": "BTC",
553
+ # "network": "BEP20",
554
+ # "isDefault": False,
555
+ # "minConfirm": 15,
556
+ # "withdrawEnable": True,
557
+ # "depositEnable": True,
558
+ # "withdrawFee": "0.0000066",
559
+ # "withdrawMax": "1.17522",
560
+ # "withdrawMin": "0.0000066",
561
+ # "depositMin": "0.0002"
562
+ # }
563
+ # ]
564
+ # }
565
+ # ]
562
566
  # }
563
567
  #
564
568
  data = self.safe_list(response, 'data', [])
@@ -572,6 +576,7 @@ class bingx(Exchange, ImplicitAPI):
572
576
  networks: dict = {}
573
577
  fee = None
574
578
  active = None
579
+ depositEnabled = None
575
580
  withdrawEnabled = None
576
581
  defaultLimits: dict = {}
577
582
  for j in range(0, len(networkList)):
@@ -579,13 +584,17 @@ class bingx(Exchange, ImplicitAPI):
579
584
  network = self.safe_string(rawNetwork, 'network')
580
585
  networkCode = self.network_id_to_code(network)
581
586
  isDefault = self.safe_bool(rawNetwork, 'isDefault')
587
+ depositEnabled = self.safe_bool(rawNetwork, 'depositEnable')
582
588
  withdrawEnabled = self.safe_bool(rawNetwork, 'withdrawEnable')
583
589
  limits: dict = {
584
- 'amounts': {'min': self.safe_number(rawNetwork, 'withdrawMin'), 'max': self.safe_number(rawNetwork, 'withdrawMax')},
590
+ 'withdraw': {
591
+ 'min': self.safe_number(rawNetwork, 'withdrawMin'),
592
+ 'max': self.safe_number(rawNetwork, 'withdrawMax'),
593
+ },
585
594
  }
586
595
  if isDefault:
587
596
  fee = self.safe_number(rawNetwork, 'withdrawFee')
588
- active = withdrawEnabled
597
+ active = depositEnabled or withdrawEnabled
589
598
  defaultLimits = limits
590
599
  networks[networkCode] = {
591
600
  'info': rawNetwork,
@@ -593,7 +602,7 @@ class bingx(Exchange, ImplicitAPI):
593
602
  'network': networkCode,
594
603
  'fee': fee,
595
604
  'active': active,
596
- 'deposit': None,
605
+ 'deposit': depositEnabled,
597
606
  'withdraw': withdrawEnabled,
598
607
  'precision': None,
599
608
  'limits': limits,
@@ -605,7 +614,7 @@ class bingx(Exchange, ImplicitAPI):
605
614
  'precision': None,
606
615
  'name': name,
607
616
  'active': active,
608
- 'deposit': None,
617
+ 'deposit': depositEnabled,
609
618
  'withdraw': withdrawEnabled,
610
619
  'networks': networks,
611
620
  'fee': fee,
@@ -1691,6 +1700,7 @@ class bingx(Exchange, ImplicitAPI):
1691
1700
  :see: https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Assets
1692
1701
  :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Get%20Perpetual%20Swap%20Account%20Asset%20Information
1693
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
1694
1704
  :param dict [params]: extra parameters specific to the exchange API endpoint
1695
1705
  :param boolean [params.standard]: whether to fetch standard contract balances
1696
1706
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -1699,111 +1709,220 @@ class bingx(Exchange, ImplicitAPI):
1699
1709
  response = None
1700
1710
  standard = None
1701
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)
1702
1714
  marketType, marketTypeQuery = self.handle_market_type_and_params('fetchBalance', None, params)
1703
1715
  if standard:
1704
1716
  response = await 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
+ #
1705
1735
  elif marketType == 'spot':
1706
1736
  response = await 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
+ #
1707
1753
  else:
1708
- response = await self.swapV2PrivateGetUserBalance(marketTypeQuery)
1754
+ if subType == 'inverse':
1755
+ response = await 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 = await 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
+ # }
1709
1819
  #
1710
1820
  # spot
1711
1821
  #
1712
- # {
1713
- # "code": 0,
1714
- # "msg": "",
1715
- # "ttl": 1,
1716
- # "data": {
1717
- # "balances": [
1718
- # {
1719
- # "asset": "USDT",
1720
- # "free": "16.73971130673954",
1721
- # "locked": "0"
1722
- # }
1723
- # ]
1724
- # }
1725
- # }
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
+ # }
1726
1836
  #
1727
- # swap
1837
+ # inverse swap
1728
1838
  #
1729
- # {
1730
- # "code": 0,
1731
- # "msg": "",
1732
- # "data": {
1733
- # "balance": {
1734
- # "asset": "USDT",
1735
- # "balance": "15.6128",
1736
- # "equity": "15.6128",
1737
- # "unrealizedProfit": "0.0000",
1738
- # "realisedProfit": "0.0000",
1739
- # "availableMargin": "15.6128",
1740
- # "usedMargin": "0.0000",
1741
- # "freezedMargin": "0.0000"
1742
- # }
1743
- # }
1744
- # }
1745
- # standard futures
1746
- # {
1747
- # "code":"0",
1748
- # "timestamp":"1691148990942",
1749
- # "data":[
1750
- # {
1751
- # "asset":"VST",
1752
- # "balance":"100000.00000000000000000000",
1753
- # "crossWalletBalance":"100000.00000000000000000000",
1754
- # "crossUnPnl":"0",
1755
- # "availableBalance":"100000.00000000000000000000",
1756
- # "maxWithdrawAmount":"100000.00000000000000000000",
1757
- # "marginAvailable":false,
1758
- # "updateTime":"1691148990902"
1759
- # },
1760
- # {
1761
- # "asset":"USDT",
1762
- # "balance":"0",
1763
- # "crossWalletBalance":"0",
1764
- # "crossUnPnl":"0",
1765
- # "availableBalance":"0",
1766
- # "maxWithdrawAmount":"0",
1767
- # "marginAvailable":false,
1768
- # "updateTime":"1691148990902"
1769
- # },
1770
- # ]
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
+ # }
1771
1876
  # }
1772
1877
  #
1773
- return self.parse_balance(response)
1774
-
1775
- def parse_balance(self, response) -> Balances:
1776
- data = self.safe_value(response, 'data')
1777
- balances = self.safe_value_2(data, 'balance', 'balances', data)
1778
1878
  result: dict = {'info': response}
1779
- if isinstance(balances, list):
1780
- for i in range(0, len(balances)):
1781
- 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]
1782
1899
  currencyId = self.safe_string(balance, 'asset')
1783
1900
  code = self.safe_currency_code(currencyId)
1784
1901
  account = self.account()
1785
- account['free'] = self.safe_string_2(balance, 'free', 'availableBalance')
1902
+ account['free'] = self.safe_string(balance, 'free')
1786
1903
  account['used'] = self.safe_string(balance, 'locked')
1787
- account['total'] = self.safe_string(balance, 'balance')
1788
1904
  result[code] = account
1789
1905
  else:
1790
- 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')
1791
1909
  code = self.safe_currency_code(currencyId)
1792
1910
  account = self.account()
1793
- account['free'] = self.safe_string(balances, 'availableMargin')
1794
- account['used'] = self.safe_string(balances, 'usedMargin')
1911
+ account['free'] = self.safe_string(linearSwapBalance, 'availableMargin')
1912
+ account['used'] = self.safe_string(linearSwapBalance, 'usedMargin')
1795
1913
  result[code] = account
1796
1914
  return self.safe_balance(result)
1797
1915
 
1798
1916
  async def fetch_positions(self, symbols: Strings = None, params={}):
1799
1917
  """
1800
1918
  fetch all open positions
1801
- :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Perpetual%20Swap%20Positions
1802
- :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
1803
1922
  :param str[]|None symbols: list of unified market symbols
1804
1923
  :param dict [params]: extra parameters specific to the exchange API endpoint
1805
1924
  :param boolean [params.standard]: whether to fetch standard contract positions
1806
- :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>`
1807
1926
  """
1808
1927
  await self.load_markets()
1809
1928
  symbols = self.market_symbols(symbols)
@@ -1813,54 +1932,207 @@ class bingx(Exchange, ImplicitAPI):
1813
1932
  if standard:
1814
1933
  response = await self.contractV1PrivateGetAllPosition(params)
1815
1934
  else:
1816
- response = await self.swapV2PrivateGetUserPositions(params)
1817
- #
1818
- # {
1819
- # "code": 0,
1820
- # "msg": "",
1821
- # "data": [
1822
- # {
1823
- # "symbol": "BTC-USDT",
1824
- # "positionId": "12345678",
1825
- # "positionSide": "LONG",
1826
- # "isolated": True,
1827
- # "positionAmt": "123.33",
1828
- # "availableAmt": "128.99",
1829
- # "unrealizedProfit": "1.22",
1830
- # "realisedProfit": "8.1",
1831
- # "initialMargin": "123.33",
1832
- # "avgPrice": "2.2",
1833
- # "leverage": 10,
1834
- # }
1835
- # ]
1836
- # }
1837
- #
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 = await 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 = await 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
+ #
1838
2004
  positions = self.safe_list(response, 'data', [])
1839
2005
  return self.parse_positions(positions, symbols)
1840
2006
 
2007
+ async 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
+ await 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 = await 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 = await 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
+
1841
2089
  def parse_position(self, position: dict, market: Market = None):
1842
2090
  #
1843
- # {
1844
- # "positionId":"1773122376147623936",
1845
- # "symbol":"XRP-USDT",
1846
- # "currency":"USDT",
1847
- # "positionAmt":"3",
1848
- # "availableAmt":"3",
1849
- # "positionSide":"LONG",
1850
- # "isolated":false,
1851
- # "avgPrice":"0.6139",
1852
- # "initialMargin":"0.0897",
1853
- # "leverage":20,
1854
- # "unrealizedProfit":"-0.0023",
1855
- # "realisedProfit":"-0.0009",
1856
- # "liquidationPrice":0,
1857
- # "pnlRatio":"-0.0260",
1858
- # "maxMarginReduction":"",
1859
- # "riskRate":"",
1860
- # "markPrice":"",
1861
- # "positionValue":"",
1862
- # "onlyOnePosition":false
1863
- # }
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
+ # }
1864
2136
  #
1865
2137
  # standard position
1866
2138
  #
@@ -1895,13 +2167,13 @@ class bingx(Exchange, ImplicitAPI):
1895
2167
  'percentage': None,
1896
2168
  'contracts': self.safe_number(position, 'positionAmt'),
1897
2169
  'contractSize': None,
1898
- 'markPrice': None,
2170
+ 'markPrice': self.safe_number(position, 'markPrice'),
1899
2171
  'lastPrice': None,
1900
2172
  'side': self.safe_string_lower(position, 'positionSide'),
1901
2173
  'hedged': None,
1902
2174
  'timestamp': None,
1903
2175
  'datetime': None,
1904
- 'lastUpdateTimestamp': None,
2176
+ 'lastUpdateTimestamp': self.safe_integer(position, 'updateTime'),
1905
2177
  'maintenanceMargin': None,
1906
2178
  'maintenanceMarginPercentage': None,
1907
2179
  'collateral': None,
@@ -4262,6 +4534,7 @@ class bingx(Exchange, ImplicitAPI):
4262
4534
  """
4263
4535
  retrieves the users liquidated positions
4264
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
4265
4538
  :param str [symbol]: unified CCXT market symbol
4266
4539
  :param int [since]: the earliest time in ms to fetch liquidations for
4267
4540
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -4282,38 +4555,73 @@ class bingx(Exchange, ImplicitAPI):
4282
4555
  request['startTime'] = since
4283
4556
  if limit is not None:
4284
4557
  request['limit'] = limit
4285
- response = await self.swapV2PrivateGetTradeForceOrders(self.extend(request, params))
4286
- #
4287
- # {
4288
- # "code": 0,
4289
- # "msg": "",
4290
- # "data": {
4291
- # "orders": [
4292
- # {
4293
- # "time": "int64",
4294
- # "symbol": "string",
4295
- # "side": "string",
4296
- # "type": "string",
4297
- # "positionSide": "string",
4298
- # "cumQuote": "string",
4299
- # "status": "string",
4300
- # "stopPrice": "string",
4301
- # "price": "string",
4302
- # "origQty": "string",
4303
- # "avgPrice": "string",
4304
- # "executedQty": "string",
4305
- # "orderId": "int64",
4306
- # "profit": "string",
4307
- # "commission": "string",
4308
- # "workingType": "string",
4309
- # "updateTime": "int64"
4310
- # },
4311
- # ]
4312
- # }
4313
- # }
4314
- #
4315
- data = self.safe_dict(response, 'data', {})
4316
- 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 = await 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 = await 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', [])
4317
4625
  return self.parse_liquidations(liquidations, market, since, limit)
4318
4626
 
4319
4627
  def parse_liquidation(self, liquidation, market: Market = None):