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
ccxt/bingx.py CHANGED
@@ -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,
@@ -527,37 +528,40 @@ class bingx(Exchange, ImplicitAPI):
527
528
  response = self.walletsV1PrivateGetCapitalConfigGetall(params)
528
529
  #
529
530
  # {
530
- # "code": 0,
531
- # "timestamp": 1688045966616,
532
- # "data": [
531
+ # "code": 0,
532
+ # "timestamp": 1702623271477,
533
+ # "data": [
534
+ # {
535
+ # "coin": "BTC",
536
+ # "name": "BTC",
537
+ # "networkList": [
533
538
  # {
534
- # "coin": "BTC",
535
539
  # "name": "BTC",
536
- # "networkList": [
537
- # {
538
- # "name": "BTC",
539
- # "network": "BTC",
540
- # "isDefault": True,
541
- # "minConfirm": "2",
542
- # "withdrawEnable": True,
543
- # "withdrawFee": "0.00035",
544
- # "withdrawMax": "1.62842",
545
- # "withdrawMin": "0.0005"
546
- # },
547
- # {
548
- # "name": "BTC",
549
- # "network": "BEP20",
550
- # "isDefault": False,
551
- # "minConfirm": "15",
552
- # "withdrawEnable": True,
553
- # "withdrawFee": "0.00001",
554
- # "withdrawMax": "1.62734",
555
- # "withdrawMin": "0.0001"
556
- # }
557
- # ]
558
- # },
559
- # ...
560
- # ],
540
+ # "network": "BTC",
541
+ # "isDefault": True,
542
+ # "minConfirm": 2,
543
+ # "withdrawEnable": True,
544
+ # "depositEnable": True,
545
+ # "withdrawFee": "0.0006",
546
+ # "withdrawMax": "1.17522",
547
+ # "withdrawMin": "0.0005",
548
+ # "depositMin": "0.0002"
549
+ # },
550
+ # {
551
+ # "name": "BTC",
552
+ # "network": "BEP20",
553
+ # "isDefault": False,
554
+ # "minConfirm": 15,
555
+ # "withdrawEnable": True,
556
+ # "depositEnable": True,
557
+ # "withdrawFee": "0.0000066",
558
+ # "withdrawMax": "1.17522",
559
+ # "withdrawMin": "0.0000066",
560
+ # "depositMin": "0.0002"
561
+ # }
562
+ # ]
563
+ # }
564
+ # ]
561
565
  # }
562
566
  #
563
567
  data = self.safe_list(response, 'data', [])
@@ -571,6 +575,7 @@ class bingx(Exchange, ImplicitAPI):
571
575
  networks: dict = {}
572
576
  fee = None
573
577
  active = None
578
+ depositEnabled = None
574
579
  withdrawEnabled = None
575
580
  defaultLimits: dict = {}
576
581
  for j in range(0, len(networkList)):
@@ -578,13 +583,17 @@ class bingx(Exchange, ImplicitAPI):
578
583
  network = self.safe_string(rawNetwork, 'network')
579
584
  networkCode = self.network_id_to_code(network)
580
585
  isDefault = self.safe_bool(rawNetwork, 'isDefault')
586
+ depositEnabled = self.safe_bool(rawNetwork, 'depositEnable')
581
587
  withdrawEnabled = self.safe_bool(rawNetwork, 'withdrawEnable')
582
588
  limits: dict = {
583
- 'amounts': {'min': self.safe_number(rawNetwork, 'withdrawMin'), 'max': self.safe_number(rawNetwork, 'withdrawMax')},
589
+ 'withdraw': {
590
+ 'min': self.safe_number(rawNetwork, 'withdrawMin'),
591
+ 'max': self.safe_number(rawNetwork, 'withdrawMax'),
592
+ },
584
593
  }
585
594
  if isDefault:
586
595
  fee = self.safe_number(rawNetwork, 'withdrawFee')
587
- active = withdrawEnabled
596
+ active = depositEnabled or withdrawEnabled
588
597
  defaultLimits = limits
589
598
  networks[networkCode] = {
590
599
  'info': rawNetwork,
@@ -592,7 +601,7 @@ class bingx(Exchange, ImplicitAPI):
592
601
  'network': networkCode,
593
602
  'fee': fee,
594
603
  'active': active,
595
- 'deposit': None,
604
+ 'deposit': depositEnabled,
596
605
  'withdraw': withdrawEnabled,
597
606
  'precision': None,
598
607
  'limits': limits,
@@ -604,7 +613,7 @@ class bingx(Exchange, ImplicitAPI):
604
613
  'precision': None,
605
614
  'name': name,
606
615
  'active': active,
607
- 'deposit': None,
616
+ 'deposit': depositEnabled,
608
617
  'withdraw': withdrawEnabled,
609
618
  'networks': networks,
610
619
  'fee': fee,
@@ -1690,6 +1699,7 @@ class bingx(Exchange, ImplicitAPI):
1690
1699
  :see: https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Assets
1691
1700
  :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Get%20Perpetual%20Swap%20Account%20Asset%20Information
1692
1701
  :see: https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1702
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20Account%20Assets
1693
1703
  :param dict [params]: extra parameters specific to the exchange API endpoint
1694
1704
  :param boolean [params.standard]: whether to fetch standard contract balances
1695
1705
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -1698,111 +1708,220 @@ class bingx(Exchange, ImplicitAPI):
1698
1708
  response = None
1699
1709
  standard = None
1700
1710
  standard, params = self.handle_option_and_params(params, 'fetchBalance', 'standard', False)
1711
+ subType = None
1712
+ subType, params = self.handle_sub_type_and_params('fetchBalance', None, params)
1701
1713
  marketType, marketTypeQuery = self.handle_market_type_and_params('fetchBalance', None, params)
1702
1714
  if standard:
1703
1715
  response = self.contractV1PrivateGetBalance(marketTypeQuery)
1716
+ #
1717
+ # {
1718
+ # "code": 0,
1719
+ # "timestamp": 1721192833454,
1720
+ # "data": [
1721
+ # {
1722
+ # "asset": "USDT",
1723
+ # "balance": "4.72644300000000000000",
1724
+ # "crossWalletBalance": "4.72644300000000000000",
1725
+ # "crossUnPnl": "0",
1726
+ # "availableBalance": "4.72644300000000000000",
1727
+ # "maxWithdrawAmount": "4.72644300000000000000",
1728
+ # "marginAvailable": False,
1729
+ # "updateTime": 1721192833443
1730
+ # },
1731
+ # ]
1732
+ # }
1733
+ #
1704
1734
  elif marketType == 'spot':
1705
1735
  response = self.spotV1PrivateGetAccountBalance(marketTypeQuery)
1736
+ #
1737
+ # {
1738
+ # "code": 0,
1739
+ # "msg": "",
1740
+ # "debugMsg": "",
1741
+ # "data": {
1742
+ # "balances": [
1743
+ # {
1744
+ # "asset": "USDT",
1745
+ # "free": "45.733046995800514",
1746
+ # "locked": "0"
1747
+ # },
1748
+ # ]
1749
+ # }
1750
+ # }
1751
+ #
1706
1752
  else:
1707
- response = self.swapV2PrivateGetUserBalance(marketTypeQuery)
1753
+ if subType == 'inverse':
1754
+ response = self.cswapV1PrivateGetUserBalance(marketTypeQuery)
1755
+ #
1756
+ # {
1757
+ # "code": 0,
1758
+ # "msg": "",
1759
+ # "timestamp": 1721191833813,
1760
+ # "data": [
1761
+ # {
1762
+ # "asset": "SOL",
1763
+ # "balance": "0.35707951",
1764
+ # "equity": "0.35791051",
1765
+ # "unrealizedProfit": "0.00083099",
1766
+ # "availableMargin": "0.35160653",
1767
+ # "usedMargin": "0.00630397",
1768
+ # "freezedMargin": "0",
1769
+ # "shortUid": "12851936"
1770
+ # }
1771
+ # ]
1772
+ # }
1773
+ #
1774
+ else:
1775
+ response = self.swapV2PrivateGetUserBalance(marketTypeQuery)
1776
+ #
1777
+ # {
1778
+ # "code": 0,
1779
+ # "msg": "",
1780
+ # "data": {
1781
+ # "balance": {
1782
+ # "userId": "1177064765068660742",
1783
+ # "asset": "USDT",
1784
+ # "balance": "51.5198",
1785
+ # "equity": "50.5349",
1786
+ # "unrealizedProfit": "-0.9849",
1787
+ # "realisedProfit": "-0.2134",
1788
+ # "availableMargin": "49.1428",
1789
+ # "usedMargin": "1.3922",
1790
+ # "freezedMargin": "0.0000",
1791
+ # "shortUid": "12851936"
1792
+ # }
1793
+ # }
1794
+ # }
1795
+ #
1796
+ return self.parse_balance(response)
1797
+
1798
+ def parse_balance(self, response) -> Balances:
1799
+ #
1800
+ # standard
1801
+ #
1802
+ # {
1803
+ # "code": 0,
1804
+ # "timestamp": 1721192833454,
1805
+ # "data": [
1806
+ # {
1807
+ # "asset": "USDT",
1808
+ # "balance": "4.72644300000000000000",
1809
+ # "crossWalletBalance": "4.72644300000000000000",
1810
+ # "crossUnPnl": "0",
1811
+ # "availableBalance": "4.72644300000000000000",
1812
+ # "maxWithdrawAmount": "4.72644300000000000000",
1813
+ # "marginAvailable": False,
1814
+ # "updateTime": 1721192833443
1815
+ # },
1816
+ # ]
1817
+ # }
1708
1818
  #
1709
1819
  # spot
1710
1820
  #
1711
- # {
1712
- # "code": 0,
1713
- # "msg": "",
1714
- # "ttl": 1,
1715
- # "data": {
1716
- # "balances": [
1717
- # {
1718
- # "asset": "USDT",
1719
- # "free": "16.73971130673954",
1720
- # "locked": "0"
1721
- # }
1722
- # ]
1723
- # }
1724
- # }
1821
+ # {
1822
+ # "code": 0,
1823
+ # "msg": "",
1824
+ # "debugMsg": "",
1825
+ # "data": {
1826
+ # "balances": [
1827
+ # {
1828
+ # "asset": "USDT",
1829
+ # "free": "45.733046995800514",
1830
+ # "locked": "0"
1831
+ # },
1832
+ # ]
1833
+ # }
1834
+ # }
1725
1835
  #
1726
- # swap
1836
+ # inverse swap
1727
1837
  #
1728
- # {
1729
- # "code": 0,
1730
- # "msg": "",
1731
- # "data": {
1732
- # "balance": {
1733
- # "asset": "USDT",
1734
- # "balance": "15.6128",
1735
- # "equity": "15.6128",
1736
- # "unrealizedProfit": "0.0000",
1737
- # "realisedProfit": "0.0000",
1738
- # "availableMargin": "15.6128",
1739
- # "usedMargin": "0.0000",
1740
- # "freezedMargin": "0.0000"
1741
- # }
1742
- # }
1743
- # }
1744
- # standard futures
1745
- # {
1746
- # "code":"0",
1747
- # "timestamp":"1691148990942",
1748
- # "data":[
1749
- # {
1750
- # "asset":"VST",
1751
- # "balance":"100000.00000000000000000000",
1752
- # "crossWalletBalance":"100000.00000000000000000000",
1753
- # "crossUnPnl":"0",
1754
- # "availableBalance":"100000.00000000000000000000",
1755
- # "maxWithdrawAmount":"100000.00000000000000000000",
1756
- # "marginAvailable":false,
1757
- # "updateTime":"1691148990902"
1758
- # },
1759
- # {
1760
- # "asset":"USDT",
1761
- # "balance":"0",
1762
- # "crossWalletBalance":"0",
1763
- # "crossUnPnl":"0",
1764
- # "availableBalance":"0",
1765
- # "maxWithdrawAmount":"0",
1766
- # "marginAvailable":false,
1767
- # "updateTime":"1691148990902"
1768
- # },
1769
- # ]
1838
+ # {
1839
+ # "code": 0,
1840
+ # "msg": "",
1841
+ # "timestamp": 1721191833813,
1842
+ # "data": [
1843
+ # {
1844
+ # "asset": "SOL",
1845
+ # "balance": "0.35707951",
1846
+ # "equity": "0.35791051",
1847
+ # "unrealizedProfit": "0.00083099",
1848
+ # "availableMargin": "0.35160653",
1849
+ # "usedMargin": "0.00630397",
1850
+ # "freezedMargin": "0",
1851
+ # "shortUid": "12851936"
1852
+ # }
1853
+ # ]
1854
+ # }
1855
+ #
1856
+ # linear swap
1857
+ #
1858
+ # {
1859
+ # "code": 0,
1860
+ # "msg": "",
1861
+ # "data": {
1862
+ # "balance": {
1863
+ # "userId": "1177064765068660742",
1864
+ # "asset": "USDT",
1865
+ # "balance": "51.5198",
1866
+ # "equity": "50.5349",
1867
+ # "unrealizedProfit": "-0.9849",
1868
+ # "realisedProfit": "-0.2134",
1869
+ # "availableMargin": "49.1428",
1870
+ # "usedMargin": "1.3922",
1871
+ # "freezedMargin": "0.0000",
1872
+ # "shortUid": "12851936"
1873
+ # }
1874
+ # }
1770
1875
  # }
1771
1876
  #
1772
- return self.parse_balance(response)
1773
-
1774
- def parse_balance(self, response) -> Balances:
1775
- data = self.safe_value(response, 'data')
1776
- balances = self.safe_value_2(data, 'balance', 'balances', data)
1777
1877
  result: dict = {'info': response}
1778
- if isinstance(balances, list):
1779
- for i in range(0, len(balances)):
1780
- balance = balances[i]
1878
+ standardAndInverseBalances = self.safe_list(response, 'data')
1879
+ firstStandardOrInverse = self.safe_dict(standardAndInverseBalances, 0)
1880
+ isStandardOrInverse = firstStandardOrInverse is not None
1881
+ spotData = self.safe_dict(response, 'data', {})
1882
+ spotBalances = self.safe_list(spotData, 'balances')
1883
+ firstSpot = self.safe_dict(spotBalances, 0)
1884
+ isSpot = firstSpot is not None
1885
+ if isStandardOrInverse:
1886
+ for i in range(0, len(standardAndInverseBalances)):
1887
+ balance = standardAndInverseBalances[i]
1888
+ currencyId = self.safe_string(balance, 'asset')
1889
+ code = self.safe_currency_code(currencyId)
1890
+ account = self.account()
1891
+ account['free'] = self.safe_string_2(balance, 'availableMargin', 'availableBalance')
1892
+ account['used'] = self.safe_string(balance, 'usedMargin')
1893
+ account['total'] = self.safe_string(balance, 'maxWithdrawAmount')
1894
+ result[code] = account
1895
+ elif isSpot:
1896
+ for i in range(0, len(spotBalances)):
1897
+ balance = spotBalances[i]
1781
1898
  currencyId = self.safe_string(balance, 'asset')
1782
1899
  code = self.safe_currency_code(currencyId)
1783
1900
  account = self.account()
1784
- account['free'] = self.safe_string_2(balance, 'free', 'availableBalance')
1901
+ account['free'] = self.safe_string(balance, 'free')
1785
1902
  account['used'] = self.safe_string(balance, 'locked')
1786
- account['total'] = self.safe_string(balance, 'balance')
1787
1903
  result[code] = account
1788
1904
  else:
1789
- currencyId = self.safe_string(balances, 'asset')
1905
+ linearSwapData = self.safe_dict(response, 'data', {})
1906
+ linearSwapBalance = self.safe_dict(linearSwapData, 'balance')
1907
+ currencyId = self.safe_string(linearSwapBalance, 'asset')
1790
1908
  code = self.safe_currency_code(currencyId)
1791
1909
  account = self.account()
1792
- account['free'] = self.safe_string(balances, 'availableMargin')
1793
- account['used'] = self.safe_string(balances, 'usedMargin')
1910
+ account['free'] = self.safe_string(linearSwapBalance, 'availableMargin')
1911
+ account['used'] = self.safe_string(linearSwapBalance, 'usedMargin')
1794
1912
  result[code] = account
1795
1913
  return self.safe_balance(result)
1796
1914
 
1797
1915
  def fetch_positions(self, symbols: Strings = None, params={}):
1798
1916
  """
1799
1917
  fetch all open positions
1800
- :see: https://bingx-api.github.io/docs/#/swapV2/account-api.html#Perpetual%20Swap%20Positions
1801
- :see: https://bingx-api.github.io/docs/#/standard/contract-interface.html#Query%20standard%20contract%20balance
1918
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/account-api.html#Query%20position%20data
1919
+ :see: https://bingx-api.github.io/docs/#/en-us/standard/contract-interface.html#position
1920
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20warehouse
1802
1921
  :param str[]|None symbols: list of unified market symbols
1803
1922
  :param dict [params]: extra parameters specific to the exchange API endpoint
1804
1923
  :param boolean [params.standard]: whether to fetch standard contract positions
1805
- :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1924
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
1806
1925
  """
1807
1926
  self.load_markets()
1808
1927
  symbols = self.market_symbols(symbols)
@@ -1812,54 +1931,207 @@ class bingx(Exchange, ImplicitAPI):
1812
1931
  if standard:
1813
1932
  response = self.contractV1PrivateGetAllPosition(params)
1814
1933
  else:
1815
- response = self.swapV2PrivateGetUserPositions(params)
1816
- #
1817
- # {
1818
- # "code": 0,
1819
- # "msg": "",
1820
- # "data": [
1821
- # {
1822
- # "symbol": "BTC-USDT",
1823
- # "positionId": "12345678",
1824
- # "positionSide": "LONG",
1825
- # "isolated": True,
1826
- # "positionAmt": "123.33",
1827
- # "availableAmt": "128.99",
1828
- # "unrealizedProfit": "1.22",
1829
- # "realisedProfit": "8.1",
1830
- # "initialMargin": "123.33",
1831
- # "avgPrice": "2.2",
1832
- # "leverage": 10,
1833
- # }
1834
- # ]
1835
- # }
1836
- #
1934
+ market = None
1935
+ if symbols is not None:
1936
+ symbols = self.market_symbols(symbols)
1937
+ firstSymbol = self.safe_string(symbols, 0)
1938
+ if firstSymbol is not None:
1939
+ market = self.market(firstSymbol)
1940
+ subType = None
1941
+ subType, params = self.handle_sub_type_and_params('fetchPositions', market, params)
1942
+ if subType == 'inverse':
1943
+ response = self.cswapV1PrivateGetUserPositions(params)
1944
+ #
1945
+ # {
1946
+ # "code": 0,
1947
+ # "msg": "",
1948
+ # "timestamp": 0,
1949
+ # "data": [
1950
+ # {
1951
+ # "symbol": "SOL-USD",
1952
+ # "positionId": "1813080351385337856",
1953
+ # "positionSide": "LONG",
1954
+ # "isolated": False,
1955
+ # "positionAmt": "1",
1956
+ # "availableAmt": "1",
1957
+ # "unrealizedProfit": "-0.00009074",
1958
+ # "initialMargin": "0.00630398",
1959
+ # "liquidationPrice": 23.968303426677032,
1960
+ # "avgPrice": "158.63",
1961
+ # "leverage": 10,
1962
+ # "markPrice": "158.402",
1963
+ # "riskRate": "0.00123783",
1964
+ # "maxMarginReduction": "0",
1965
+ # "updateTime": 1721107015848
1966
+ # }
1967
+ # ]
1968
+ # }
1969
+ #
1970
+ else:
1971
+ response = self.swapV2PrivateGetUserPositions(params)
1972
+ #
1973
+ # {
1974
+ # "code": 0,
1975
+ # "msg": "",
1976
+ # "data": [
1977
+ # {
1978
+ # "positionId": "1792480725958881280",
1979
+ # "symbol": "LTC-USDT",
1980
+ # "currency": "USDT",
1981
+ # "positionAmt": "0.1",
1982
+ # "availableAmt": "0.1",
1983
+ # "positionSide": "LONG",
1984
+ # "isolated": False,
1985
+ # "avgPrice": "83.53",
1986
+ # "initialMargin": "1.3922",
1987
+ # "margin": "0.3528",
1988
+ # "leverage": 6,
1989
+ # "unrealizedProfit": "-1.0393",
1990
+ # "realisedProfit": "-0.2119",
1991
+ # "liquidationPrice": 0,
1992
+ # "pnlRatio": "-0.7465",
1993
+ # "maxMarginReduction": "0.0000",
1994
+ # "riskRate": "0.0008",
1995
+ # "markPrice": "73.14",
1996
+ # "positionValue": "7.3136",
1997
+ # "onlyOnePosition": True,
1998
+ # "updateTime": 1721088016688
1999
+ # }
2000
+ # ]
2001
+ # }
2002
+ #
1837
2003
  positions = self.safe_list(response, 'data', [])
1838
2004
  return self.parse_positions(positions, symbols)
1839
2005
 
2006
+ def fetch_position(self, symbol: str, params={}):
2007
+ """
2008
+ fetch data on a single open contract trade position
2009
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/account-api.html#Query%20position%20data
2010
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20warehouse
2011
+ :param str symbol: unified market symbol of the market the position is held in
2012
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2013
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
2014
+ """
2015
+ self.load_markets()
2016
+ market = self.market(symbol)
2017
+ if not market['swap']:
2018
+ raise BadRequest(self.id + ' fetchPosition() supports swap markets only')
2019
+ request: dict = {
2020
+ 'symbol': market['id'],
2021
+ }
2022
+ response = None
2023
+ if market['inverse']:
2024
+ response = self.cswapV1PrivateGetUserPositions(self.extend(request, params))
2025
+ #
2026
+ # {
2027
+ # "code": 0,
2028
+ # "msg": "",
2029
+ # "timestamp": 0,
2030
+ # "data": [
2031
+ # {
2032
+ # "symbol": "SOL-USD",
2033
+ # "positionId": "1813080351385337856",
2034
+ # "positionSide": "LONG",
2035
+ # "isolated": False,
2036
+ # "positionAmt": "1",
2037
+ # "availableAmt": "1",
2038
+ # "unrealizedProfit": "-0.00009074",
2039
+ # "initialMargin": "0.00630398",
2040
+ # "liquidationPrice": 23.968303426677032,
2041
+ # "avgPrice": "158.63",
2042
+ # "leverage": 10,
2043
+ # "markPrice": "158.402",
2044
+ # "riskRate": "0.00123783",
2045
+ # "maxMarginReduction": "0",
2046
+ # "updateTime": 1721107015848
2047
+ # }
2048
+ # ]
2049
+ # }
2050
+ #
2051
+ else:
2052
+ response = self.swapV2PrivateGetUserPositions(self.extend(request, params))
2053
+ #
2054
+ # {
2055
+ # "code": 0,
2056
+ # "msg": "",
2057
+ # "data": [
2058
+ # {
2059
+ # "positionId": "1792480725958881280",
2060
+ # "symbol": "LTC-USDT",
2061
+ # "currency": "USDT",
2062
+ # "positionAmt": "0.1",
2063
+ # "availableAmt": "0.1",
2064
+ # "positionSide": "LONG",
2065
+ # "isolated": False,
2066
+ # "avgPrice": "83.53",
2067
+ # "initialMargin": "1.3922",
2068
+ # "margin": "0.3528",
2069
+ # "leverage": 6,
2070
+ # "unrealizedProfit": "-1.0393",
2071
+ # "realisedProfit": "-0.2119",
2072
+ # "liquidationPrice": 0,
2073
+ # "pnlRatio": "-0.7465",
2074
+ # "maxMarginReduction": "0.0000",
2075
+ # "riskRate": "0.0008",
2076
+ # "markPrice": "73.14",
2077
+ # "positionValue": "7.3136",
2078
+ # "onlyOnePosition": True,
2079
+ # "updateTime": 1721088016688
2080
+ # }
2081
+ # ]
2082
+ # }
2083
+ #
2084
+ data = self.safe_list(response, 'data', [])
2085
+ first = self.safe_dict(data, 0, {})
2086
+ return self.parse_position(first, market)
2087
+
1840
2088
  def parse_position(self, position: dict, market: Market = None):
1841
2089
  #
1842
- # {
1843
- # "positionId":"1773122376147623936",
1844
- # "symbol":"XRP-USDT",
1845
- # "currency":"USDT",
1846
- # "positionAmt":"3",
1847
- # "availableAmt":"3",
1848
- # "positionSide":"LONG",
1849
- # "isolated":false,
1850
- # "avgPrice":"0.6139",
1851
- # "initialMargin":"0.0897",
1852
- # "leverage":20,
1853
- # "unrealizedProfit":"-0.0023",
1854
- # "realisedProfit":"-0.0009",
1855
- # "liquidationPrice":0,
1856
- # "pnlRatio":"-0.0260",
1857
- # "maxMarginReduction":"",
1858
- # "riskRate":"",
1859
- # "markPrice":"",
1860
- # "positionValue":"",
1861
- # "onlyOnePosition":false
1862
- # }
2090
+ # inverse swap
2091
+ #
2092
+ # {
2093
+ # "symbol": "SOL-USD",
2094
+ # "positionId": "1813080351385337856",
2095
+ # "positionSide": "LONG",
2096
+ # "isolated": False,
2097
+ # "positionAmt": "1",
2098
+ # "availableAmt": "1",
2099
+ # "unrealizedProfit": "-0.00009074",
2100
+ # "initialMargin": "0.00630398",
2101
+ # "liquidationPrice": 23.968303426677032,
2102
+ # "avgPrice": "158.63",
2103
+ # "leverage": 10,
2104
+ # "markPrice": "158.402",
2105
+ # "riskRate": "0.00123783",
2106
+ # "maxMarginReduction": "0",
2107
+ # "updateTime": 1721107015848
2108
+ # }
2109
+ #
2110
+ # linear swap
2111
+ #
2112
+ # {
2113
+ # "positionId": "1792480725958881280",
2114
+ # "symbol": "LTC-USDT",
2115
+ # "currency": "USDT",
2116
+ # "positionAmt": "0.1",
2117
+ # "availableAmt": "0.1",
2118
+ # "positionSide": "LONG",
2119
+ # "isolated": False,
2120
+ # "avgPrice": "83.53",
2121
+ # "initialMargin": "1.3922",
2122
+ # "margin": "0.3528",
2123
+ # "leverage": 6,
2124
+ # "unrealizedProfit": "-1.0393",
2125
+ # "realisedProfit": "-0.2119",
2126
+ # "liquidationPrice": 0,
2127
+ # "pnlRatio": "-0.7465",
2128
+ # "maxMarginReduction": "0.0000",
2129
+ # "riskRate": "0.0008",
2130
+ # "markPrice": "73.14",
2131
+ # "positionValue": "7.3136",
2132
+ # "onlyOnePosition": True,
2133
+ # "updateTime": 1721088016688
2134
+ # }
1863
2135
  #
1864
2136
  # standard position
1865
2137
  #
@@ -1894,13 +2166,13 @@ class bingx(Exchange, ImplicitAPI):
1894
2166
  'percentage': None,
1895
2167
  'contracts': self.safe_number(position, 'positionAmt'),
1896
2168
  'contractSize': None,
1897
- 'markPrice': None,
2169
+ 'markPrice': self.safe_number(position, 'markPrice'),
1898
2170
  'lastPrice': None,
1899
2171
  'side': self.safe_string_lower(position, 'positionSide'),
1900
2172
  'hedged': None,
1901
2173
  'timestamp': None,
1902
2174
  'datetime': None,
1903
- 'lastUpdateTimestamp': None,
2175
+ 'lastUpdateTimestamp': self.safe_integer(position, 'updateTime'),
1904
2176
  'maintenanceMargin': None,
1905
2177
  'maintenanceMarginPercentage': None,
1906
2178
  'collateral': None,
@@ -4261,6 +4533,7 @@ class bingx(Exchange, ImplicitAPI):
4261
4533
  """
4262
4534
  retrieves the users liquidated positions
4263
4535
  :see: https://bingx-api.github.io/docs/#/swapV2/trade-api.html#User's%20Force%20Orders
4536
+ :see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20force%20orders
4264
4537
  :param str [symbol]: unified CCXT market symbol
4265
4538
  :param int [since]: the earliest time in ms to fetch liquidations for
4266
4539
  :param int [limit]: the maximum number of liquidation structures to retrieve
@@ -4281,38 +4554,73 @@ class bingx(Exchange, ImplicitAPI):
4281
4554
  request['startTime'] = since
4282
4555
  if limit is not None:
4283
4556
  request['limit'] = limit
4284
- response = self.swapV2PrivateGetTradeForceOrders(self.extend(request, params))
4285
- #
4286
- # {
4287
- # "code": 0,
4288
- # "msg": "",
4289
- # "data": {
4290
- # "orders": [
4291
- # {
4292
- # "time": "int64",
4293
- # "symbol": "string",
4294
- # "side": "string",
4295
- # "type": "string",
4296
- # "positionSide": "string",
4297
- # "cumQuote": "string",
4298
- # "status": "string",
4299
- # "stopPrice": "string",
4300
- # "price": "string",
4301
- # "origQty": "string",
4302
- # "avgPrice": "string",
4303
- # "executedQty": "string",
4304
- # "orderId": "int64",
4305
- # "profit": "string",
4306
- # "commission": "string",
4307
- # "workingType": "string",
4308
- # "updateTime": "int64"
4309
- # },
4310
- # ]
4311
- # }
4312
- # }
4313
- #
4314
- data = self.safe_dict(response, 'data', {})
4315
- liquidations = self.safe_list(data, 'orders', [])
4557
+ subType = None
4558
+ subType, params = self.handle_sub_type_and_params('fetchMyLiquidations', market, params)
4559
+ response = None
4560
+ liquidations = None
4561
+ if subType == 'inverse':
4562
+ response = self.cswapV1PrivateGetTradeForceOrders(self.extend(request, params))
4563
+ #
4564
+ # {
4565
+ # "code": 0,
4566
+ # "msg": "",
4567
+ # "timestamp": 1721280071678,
4568
+ # "data": [
4569
+ # {
4570
+ # "orderId": "string",
4571
+ # "symbol": "string",
4572
+ # "type": "string",
4573
+ # "side": "string",
4574
+ # "positionSide": "string",
4575
+ # "price": "string",
4576
+ # "quantity": "float64",
4577
+ # "stopPrice": "string",
4578
+ # "workingType": "string",
4579
+ # "status": "string",
4580
+ # "time": "int64",
4581
+ # "avgPrice": "string",
4582
+ # "executedQty": "string",
4583
+ # "profit": "string",
4584
+ # "commission": "string",
4585
+ # "updateTime": "string"
4586
+ # }
4587
+ # ]
4588
+ # }
4589
+ #
4590
+ liquidations = self.safe_list(response, 'data', [])
4591
+ else:
4592
+ response = self.swapV2PrivateGetTradeForceOrders(self.extend(request, params))
4593
+ #
4594
+ # {
4595
+ # "code": 0,
4596
+ # "msg": "",
4597
+ # "data": {
4598
+ # "orders": [
4599
+ # {
4600
+ # "time": "int64",
4601
+ # "symbol": "string",
4602
+ # "side": "string",
4603
+ # "type": "string",
4604
+ # "positionSide": "string",
4605
+ # "cumQuote": "string",
4606
+ # "status": "string",
4607
+ # "stopPrice": "string",
4608
+ # "price": "string",
4609
+ # "origQty": "string",
4610
+ # "avgPrice": "string",
4611
+ # "executedQty": "string",
4612
+ # "orderId": "int64",
4613
+ # "profit": "string",
4614
+ # "commission": "string",
4615
+ # "workingType": "string",
4616
+ # "updateTime": "int64"
4617
+ # },
4618
+ # ]
4619
+ # }
4620
+ # }
4621
+ #
4622
+ data = self.safe_dict(response, 'data', {})
4623
+ liquidations = self.safe_list(data, 'orders', [])
4316
4624
  return self.parse_liquidations(liquidations, market, since, limit)
4317
4625
 
4318
4626
  def parse_liquidation(self, liquidation, market: Market = None):