ccxt 4.4.37__py2.py3-none-any.whl → 4.4.39__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 (49) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +0 -1
  3. ccxt/abstract/digifinex.py +1 -0
  4. ccxt/abstract/mexc.py +1 -0
  5. ccxt/abstract/woo.py +2 -2
  6. ccxt/alpaca.py +74 -3
  7. ccxt/async_support/__init__.py +1 -1
  8. ccxt/async_support/alpaca.py +74 -3
  9. ccxt/async_support/base/exchange.py +1 -1
  10. ccxt/async_support/binance.py +0 -2
  11. ccxt/async_support/bingx.py +89 -8
  12. ccxt/async_support/bitget.py +2 -4
  13. ccxt/async_support/bithumb.py +1 -1
  14. ccxt/async_support/bitmart.py +160 -13
  15. ccxt/async_support/bybit.py +3 -2
  16. ccxt/async_support/digifinex.py +57 -18
  17. ccxt/async_support/htx.py +154 -32
  18. ccxt/async_support/kucoin.py +76 -2
  19. ccxt/async_support/kucoinfutures.py +92 -5
  20. ccxt/async_support/mexc.py +36 -25
  21. ccxt/async_support/ndax.py +5 -1
  22. ccxt/async_support/okx.py +1 -1
  23. ccxt/async_support/probit.py +3 -1
  24. ccxt/async_support/woo.py +6 -6
  25. ccxt/base/exchange.py +24 -11
  26. ccxt/binance.py +0 -2
  27. ccxt/bingx.py +89 -8
  28. ccxt/bitget.py +2 -4
  29. ccxt/bithumb.py +1 -1
  30. ccxt/bitmart.py +160 -13
  31. ccxt/bybit.py +3 -2
  32. ccxt/digifinex.py +57 -18
  33. ccxt/htx.py +154 -32
  34. ccxt/kucoin.py +76 -2
  35. ccxt/kucoinfutures.py +92 -5
  36. ccxt/mexc.py +36 -25
  37. ccxt/ndax.py +5 -1
  38. ccxt/okx.py +1 -1
  39. ccxt/pro/__init__.py +1 -1
  40. ccxt/pro/woo.py +1 -1
  41. ccxt/probit.py +3 -1
  42. ccxt/test/tests_async.py +5 -1
  43. ccxt/test/tests_sync.py +5 -1
  44. ccxt/woo.py +6 -6
  45. {ccxt-4.4.37.dist-info → ccxt-4.4.39.dist-info}/METADATA +4 -4
  46. {ccxt-4.4.37.dist-info → ccxt-4.4.39.dist-info}/RECORD +49 -49
  47. {ccxt-4.4.37.dist-info → ccxt-4.4.39.dist-info}/LICENSE.txt +0 -0
  48. {ccxt-4.4.37.dist-info → ccxt-4.4.39.dist-info}/WHEEL +0 -0
  49. {ccxt-4.4.37.dist-info → ccxt-4.4.39.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.4.37'
25
+ __version__ = '4.4.39'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bingx.py CHANGED
@@ -35,7 +35,6 @@ class ImplicitAPI:
35
35
  swap_v1_public_get_market_markpriceklines = swapV1PublicGetMarketMarkPriceKlines = Entry('market/markPriceKlines', ['swap', 'v1', 'public'], 'GET', {'cost': 1})
36
36
  swap_v1_public_get_trade_multiassetsrules = swapV1PublicGetTradeMultiAssetsRules = Entry('trade/multiAssetsRules', ['swap', 'v1', 'public'], 'GET', {'cost': 1})
37
37
  swap_v1_private_get_positionside_dual = swapV1PrivateGetPositionSideDual = Entry('positionSide/dual', ['swap', 'v1', 'private'], 'GET', {'cost': 5})
38
- swap_v1_private_get_market_markpriceklines = swapV1PrivateGetMarketMarkPriceKlines = Entry('market/markPriceKlines', ['swap', 'v1', 'private'], 'GET', {'cost': 1})
39
38
  swap_v1_private_get_trade_batchcancelreplace = swapV1PrivateGetTradeBatchCancelReplace = Entry('trade/batchCancelReplace', ['swap', 'v1', 'private'], 'GET', {'cost': 5})
40
39
  swap_v1_private_get_trade_fullorder = swapV1PrivateGetTradeFullOrder = Entry('trade/fullOrder', ['swap', 'v1', 'private'], 'GET', {'cost': 2})
41
40
  swap_v1_private_get_maintmarginratio = swapV1PrivateGetMaintMarginRatio = Entry('maintMarginRatio', ['swap', 'v1', 'private'], 'GET', {'cost': 2})
@@ -71,6 +71,7 @@ class ImplicitAPI:
71
71
  private_swap_get_trade_history_trades = privateSwapGetTradeHistoryTrades = Entry('trade/history_trades', ['private', 'swap'], 'GET', {})
72
72
  private_swap_get_trade_open_orders = privateSwapGetTradeOpenOrders = Entry('trade/open_orders', ['private', 'swap'], 'GET', {})
73
73
  private_swap_get_trade_order_info = privateSwapGetTradeOrderInfo = Entry('trade/order_info', ['private', 'swap'], 'GET', {})
74
+ private_swap_post_account_transfer = privateSwapPostAccountTransfer = Entry('account/transfer', ['private', 'swap'], 'POST', {})
74
75
  private_swap_post_account_leverage = privateSwapPostAccountLeverage = Entry('account/leverage', ['private', 'swap'], 'POST', {})
75
76
  private_swap_post_account_position_mode = privateSwapPostAccountPositionMode = Entry('account/position_mode', ['private', 'swap'], 'POST', {})
76
77
  private_swap_post_account_position_margin = privateSwapPostAccountPositionMargin = Entry('account/position_margin', ['private', 'swap'], 'POST', {})
ccxt/abstract/mexc.py CHANGED
@@ -20,6 +20,7 @@ class ImplicitAPI:
20
20
  spot_private_get_allorders = spotPrivateGetAllOrders = Entry('allOrders', ['spot', 'private'], 'GET', {'cost': 10})
21
21
  spot_private_get_account = spotPrivateGetAccount = Entry('account', ['spot', 'private'], 'GET', {'cost': 10})
22
22
  spot_private_get_mytrades = spotPrivateGetMyTrades = Entry('myTrades', ['spot', 'private'], 'GET', {'cost': 10})
23
+ spot_private_get_tradefee = spotPrivateGetTradeFee = Entry('tradeFee', ['spot', 'private'], 'GET', {'cost': 10})
23
24
  spot_private_get_sub_account_list = spotPrivateGetSubAccountList = Entry('sub-account/list', ['spot', 'private'], 'GET', {'cost': 1})
24
25
  spot_private_get_sub_account_apikey = spotPrivateGetSubAccountApiKey = Entry('sub-account/apiKey', ['spot', 'private'], 'GET', {'cost': 1})
25
26
  spot_private_get_capital_config_getall = spotPrivateGetCapitalConfigGetall = Entry('capital/config/getall', ['spot', 'private'], 'GET', {'cost': 10})
ccxt/abstract/woo.py CHANGED
@@ -3,7 +3,7 @@ from ccxt.base.types import Entry
3
3
 
4
4
  class ImplicitAPI:
5
5
  v1_pub_get_hist_kline = v1PubGetHistKline = Entry('hist/kline', ['v1', 'pub'], 'GET', {'cost': 10})
6
- v1_pub_get_hist_trades = v1PubGetHistTrades = Entry('hist/trades', ['v1', 'pub'], 'GET', {'cost': 1})
6
+ v1_pub_get_hist_trades = v1PubGetHistTrades = Entry('hist/trades', ['v1', 'pub'], 'GET', {'cost': 10})
7
7
  v1_public_get_info = v1PublicGetInfo = Entry('info', ['v1', 'public'], 'GET', {'cost': 1})
8
8
  v1_public_get_info_symbol = v1PublicGetInfoSymbol = Entry('info/{symbol}', ['v1', 'public'], 'GET', {'cost': 1})
9
9
  v1_public_get_system_info = v1PublicGetSystemInfo = Entry('system_info', ['v1', 'public'], 'GET', {'cost': 1})
@@ -43,7 +43,7 @@ class ImplicitAPI:
43
43
  v1_private_get_position_symbol = v1PrivateGetPositionSymbol = Entry('position/{symbol}', ['v1', 'private'], 'GET', {'cost': 3.33})
44
44
  v1_private_get_client_transaction_history = v1PrivateGetClientTransactionHistory = Entry('client/transaction_history', ['v1', 'private'], 'GET', {'cost': 60})
45
45
  v1_private_get_client_futures_leverage = v1PrivateGetClientFuturesLeverage = Entry('client/futures_leverage', ['v1', 'private'], 'GET', {'cost': 60})
46
- v1_private_post_order = v1PrivatePostOrder = Entry('order', ['v1', 'private'], 'POST', {'cost': 5})
46
+ v1_private_post_order = v1PrivatePostOrder = Entry('order', ['v1', 'private'], 'POST', {'cost': 1})
47
47
  v1_private_post_order_cancel_all_after = v1PrivatePostOrderCancelAllAfter = Entry('order/cancel_all_after', ['v1', 'private'], 'POST', {'cost': 1})
48
48
  v1_private_post_asset_main_sub_transfer = v1PrivatePostAssetMainSubTransfer = Entry('asset/main_sub_transfer', ['v1', 'private'], 'POST', {'cost': 30})
49
49
  v1_private_post_asset_ltv = v1PrivatePostAssetLtv = Entry('asset/ltv', ['v1', 'private'], 'POST', {'cost': 30})
ccxt/alpaca.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.alpaca import ImplicitAPI
8
- from ccxt.base.types import Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
8
+ from ccxt.base.types import Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import PermissionDenied
@@ -44,7 +44,7 @@ class alpaca(Exchange, ImplicitAPI):
44
44
  'test': {
45
45
  'broker': 'https://broker-api.sandbox.{hostname}',
46
46
  'trader': 'https://paper-api.{hostname}',
47
- 'market': 'https://data.sandbox.{hostname}',
47
+ 'market': 'https://data.{hostname}',
48
48
  },
49
49
  'doc': 'https://alpaca.markets/docs/',
50
50
  'fees': 'https://docs.alpaca.markets/docs/crypto-fees',
@@ -64,7 +64,7 @@ class alpaca(Exchange, ImplicitAPI):
64
64
  'createStopOrder': True,
65
65
  'createTriggerOrder': True,
66
66
  'editOrder': True,
67
- 'fetchBalance': False,
67
+ 'fetchBalance': True,
68
68
  'fetchBidsAsks': False,
69
69
  'fetchClosedOrders': True,
70
70
  'fetchCurrencies': False,
@@ -1553,6 +1553,77 @@ class alpaca(Exchange, ImplicitAPI):
1553
1553
  }
1554
1554
  return self.safe_string(types, type, type)
1555
1555
 
1556
+ def fetch_balance(self, params={}) -> Balances:
1557
+ """
1558
+ query for balance and get the amount of funds available for trading or funds locked in orders
1559
+
1560
+ https://docs.alpaca.markets/reference/getaccount-1
1561
+
1562
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1563
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1564
+ """
1565
+ self.load_markets()
1566
+ response = self.traderPrivateGetV2Account(params)
1567
+ #
1568
+ # {
1569
+ # "id": "43a01bde-4eb1-64fssc26adb5",
1570
+ # "admin_configurations": {
1571
+ # "allow_instant_ach": True,
1572
+ # "max_margin_multiplier": "4"
1573
+ # },
1574
+ # "user_configurations": {
1575
+ # "fractional_trading": True,
1576
+ # "max_margin_multiplier": "4"
1577
+ # },
1578
+ # "account_number": "744873727",
1579
+ # "status": "ACTIVE",
1580
+ # "crypto_status": "ACTIVE",
1581
+ # "currency": "USD",
1582
+ # "buying_power": "5.92",
1583
+ # "regt_buying_power": "5.92",
1584
+ # "daytrading_buying_power": "0",
1585
+ # "effective_buying_power": "5.92",
1586
+ # "non_marginable_buying_power": "5.92",
1587
+ # "bod_dtbp": "0",
1588
+ # "cash": "5.92",
1589
+ # "accrued_fees": "0",
1590
+ # "portfolio_value": "48.6",
1591
+ # "pattern_day_trader": False,
1592
+ # "trading_blocked": False,
1593
+ # "transfers_blocked": False,
1594
+ # "account_blocked": False,
1595
+ # "created_at": "2022-06-13T14:59:18.318096Z",
1596
+ # "trade_suspended_by_user": False,
1597
+ # "multiplier": "1",
1598
+ # "shorting_enabled": False,
1599
+ # "equity": "48.6",
1600
+ # "last_equity": "48.8014266",
1601
+ # "long_market_value": "42.68",
1602
+ # "short_market_value": "0",
1603
+ # "position_market_value": "42.68",
1604
+ # "initial_margin": "0",
1605
+ # "maintenance_margin": "0",
1606
+ # "last_maintenance_margin": "0",
1607
+ # "sma": "5.92",
1608
+ # "daytrade_count": 0,
1609
+ # "balance_asof": "2024-12-10",
1610
+ # "crypto_tier": 1,
1611
+ # "intraday_adjustments": "0",
1612
+ # "pending_reg_taf_fees": "0"
1613
+ # }
1614
+ #
1615
+ return self.parse_balance(response)
1616
+
1617
+ def parse_balance(self, response) -> Balances:
1618
+ result: dict = {'info': response}
1619
+ account = self.account()
1620
+ currencyId = self.safe_string(response, 'currency')
1621
+ code = self.safe_currency_code(currencyId)
1622
+ account['free'] = self.safe_string(response, 'cash')
1623
+ account['total'] = self.safe_string(response, 'equity')
1624
+ result[code] = account
1625
+ return self.safe_balance(result)
1626
+
1556
1627
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1557
1628
  endpoint = '/' + self.implode_params(path, params)
1558
1629
  url = self.implode_hostname(self.urls['api'][api[0]])
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.37'
7
+ __version__ = '4.4.39'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.alpaca import ImplicitAPI
8
- from ccxt.base.types import Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
8
+ from ccxt.base.types import Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import PermissionDenied
@@ -44,7 +44,7 @@ class alpaca(Exchange, ImplicitAPI):
44
44
  'test': {
45
45
  'broker': 'https://broker-api.sandbox.{hostname}',
46
46
  'trader': 'https://paper-api.{hostname}',
47
- 'market': 'https://data.sandbox.{hostname}',
47
+ 'market': 'https://data.{hostname}',
48
48
  },
49
49
  'doc': 'https://alpaca.markets/docs/',
50
50
  'fees': 'https://docs.alpaca.markets/docs/crypto-fees',
@@ -64,7 +64,7 @@ class alpaca(Exchange, ImplicitAPI):
64
64
  'createStopOrder': True,
65
65
  'createTriggerOrder': True,
66
66
  'editOrder': True,
67
- 'fetchBalance': False,
67
+ 'fetchBalance': True,
68
68
  'fetchBidsAsks': False,
69
69
  'fetchClosedOrders': True,
70
70
  'fetchCurrencies': False,
@@ -1553,6 +1553,77 @@ class alpaca(Exchange, ImplicitAPI):
1553
1553
  }
1554
1554
  return self.safe_string(types, type, type)
1555
1555
 
1556
+ async def fetch_balance(self, params={}) -> Balances:
1557
+ """
1558
+ query for balance and get the amount of funds available for trading or funds locked in orders
1559
+
1560
+ https://docs.alpaca.markets/reference/getaccount-1
1561
+
1562
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1563
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1564
+ """
1565
+ await self.load_markets()
1566
+ response = await self.traderPrivateGetV2Account(params)
1567
+ #
1568
+ # {
1569
+ # "id": "43a01bde-4eb1-64fssc26adb5",
1570
+ # "admin_configurations": {
1571
+ # "allow_instant_ach": True,
1572
+ # "max_margin_multiplier": "4"
1573
+ # },
1574
+ # "user_configurations": {
1575
+ # "fractional_trading": True,
1576
+ # "max_margin_multiplier": "4"
1577
+ # },
1578
+ # "account_number": "744873727",
1579
+ # "status": "ACTIVE",
1580
+ # "crypto_status": "ACTIVE",
1581
+ # "currency": "USD",
1582
+ # "buying_power": "5.92",
1583
+ # "regt_buying_power": "5.92",
1584
+ # "daytrading_buying_power": "0",
1585
+ # "effective_buying_power": "5.92",
1586
+ # "non_marginable_buying_power": "5.92",
1587
+ # "bod_dtbp": "0",
1588
+ # "cash": "5.92",
1589
+ # "accrued_fees": "0",
1590
+ # "portfolio_value": "48.6",
1591
+ # "pattern_day_trader": False,
1592
+ # "trading_blocked": False,
1593
+ # "transfers_blocked": False,
1594
+ # "account_blocked": False,
1595
+ # "created_at": "2022-06-13T14:59:18.318096Z",
1596
+ # "trade_suspended_by_user": False,
1597
+ # "multiplier": "1",
1598
+ # "shorting_enabled": False,
1599
+ # "equity": "48.6",
1600
+ # "last_equity": "48.8014266",
1601
+ # "long_market_value": "42.68",
1602
+ # "short_market_value": "0",
1603
+ # "position_market_value": "42.68",
1604
+ # "initial_margin": "0",
1605
+ # "maintenance_margin": "0",
1606
+ # "last_maintenance_margin": "0",
1607
+ # "sma": "5.92",
1608
+ # "daytrade_count": 0,
1609
+ # "balance_asof": "2024-12-10",
1610
+ # "crypto_tier": 1,
1611
+ # "intraday_adjustments": "0",
1612
+ # "pending_reg_taf_fees": "0"
1613
+ # }
1614
+ #
1615
+ return self.parse_balance(response)
1616
+
1617
+ def parse_balance(self, response) -> Balances:
1618
+ result: dict = {'info': response}
1619
+ account = self.account()
1620
+ currencyId = self.safe_string(response, 'currency')
1621
+ code = self.safe_currency_code(currencyId)
1622
+ account['free'] = self.safe_string(response, 'cash')
1623
+ account['total'] = self.safe_string(response, 'equity')
1624
+ result[code] = account
1625
+ return self.safe_balance(result)
1626
+
1556
1627
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1557
1628
  endpoint = '/' + self.implode_params(path, params)
1558
1629
  url = self.implode_hostname(self.urls['api'][api[0]])
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.4.37'
5
+ __version__ = '4.4.39'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -1592,7 +1592,6 @@ class binance(Exchange, ImplicitAPI):
1592
1592
  'takeProfitPrice': True,
1593
1593
  'attachedStopLossTakeProfit': None, # not supported
1594
1594
  'timeInForce': {
1595
- 'GTC': True,
1596
1595
  'IOC': True,
1597
1596
  'FOK': True,
1598
1597
  'PO': True,
@@ -1659,7 +1658,6 @@ class binance(Exchange, ImplicitAPI):
1659
1658
  'takeProfitPrice': True,
1660
1659
  'attachedStopLossTakeProfit': None, # not supported
1661
1660
  'timeInForce': {
1662
- 'GTC': True,
1663
1661
  'IOC': True,
1664
1662
  'FOK': True,
1665
1663
  'PO': True,
@@ -96,7 +96,7 @@ class bingx(Exchange, ImplicitAPI):
96
96
  'fetchPositionHistory': False,
97
97
  'fetchPositionMode': True,
98
98
  'fetchPositions': True,
99
- 'fetchPositionsHistory': False,
99
+ 'fetchPositionsHistory': True,
100
100
  'fetchTicker': True,
101
101
  'fetchTickers': True,
102
102
  'fetchTime': True,
@@ -220,7 +220,6 @@ class bingx(Exchange, ImplicitAPI):
220
220
  'private': {
221
221
  'get': {
222
222
  'positionSide/dual': 5,
223
- 'market/markPriceKlines': 1,
224
223
  'trade/batchCancelReplace': 5,
225
224
  'trade/fullOrder': 2,
226
225
  'maintMarginRatio': 2,
@@ -554,7 +553,6 @@ class bingx(Exchange, ImplicitAPI):
554
553
  'limitPrice': True,
555
554
  },
556
555
  'timeInForce': {
557
- 'GTC': True,
558
556
  'IOC': True,
559
557
  'FOK': True,
560
558
  'PO': True,
@@ -1016,7 +1014,7 @@ class bingx(Exchange, ImplicitAPI):
1016
1014
  https://bingx-api.github.io/docs/#/swapV2/market-api.html#K-Line%20Data
1017
1015
  https://bingx-api.github.io/docs/#/spot/market-api.html#Candlestick%20chart%20data
1018
1016
  https://bingx-api.github.io/docs/#/swapV2/market-api.html#%20K-Line%20Data
1019
- https://bingx-api.github.io/docs/#/en-us/swapV2/market-api.html#K-Line%20Data%20-%20Mark%20Price
1017
+ https://bingx-api.github.io/docs/#/en-us/swapV2/market-api.html#Mark%20Price%20Kline/Candlestick%20Data
1020
1018
  https://bingx-api.github.io/docs/#/en-us/cswap/market-api.html#Get%20K-line%20Data
1021
1019
 
1022
1020
  :param str symbol: unified symbol of the market to fetch OHLCV data for
@@ -1056,7 +1054,7 @@ class bingx(Exchange, ImplicitAPI):
1056
1054
  price = self.safe_string(params, 'price')
1057
1055
  params = self.omit(params, 'price')
1058
1056
  if price == 'mark':
1059
- response = await self.swapV1PrivateGetMarketMarkPriceKlines(self.extend(request, params))
1057
+ response = await self.swapV1PublicGetMarketMarkPriceKlines(self.extend(request, params))
1060
1058
  else:
1061
1059
  response = await self.swapV3PublicGetQuoteKlines(self.extend(request, params))
1062
1060
  #
@@ -2265,6 +2263,67 @@ class bingx(Exchange, ImplicitAPI):
2265
2263
  result[code] = account
2266
2264
  return self.safe_balance(result)
2267
2265
 
2266
+ async def fetch_position_history(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Position]:
2267
+ """
2268
+ fetches historical positions
2269
+
2270
+ https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Position%20History
2271
+
2272
+ :param str symbol: unified contract symbol
2273
+ :param int [since]: the earliest time in ms to fetch positions for
2274
+ :param int [limit]: the maximum amount of records to fetch
2275
+ :param dict [params]: extra parameters specific to the exchange api endpoint
2276
+ :param int [params.until]: the latest time in ms to fetch positions for
2277
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
2278
+ """
2279
+ await self.load_markets()
2280
+ market = self.market(symbol)
2281
+ request: dict = {
2282
+ 'symbol': market['id'],
2283
+ }
2284
+ if limit is not None:
2285
+ request['pageSize'] = limit
2286
+ if since is not None:
2287
+ request['startTs'] = since
2288
+ request, params = self.handle_until_option('endTs', request, params)
2289
+ response = None
2290
+ if market['linear']:
2291
+ response = await self.swapV1PrivateGetTradePositionHistory(self.extend(request, params))
2292
+ else:
2293
+ raise NotSupported(self.id + ' fetchPositionHistory() is not supported for inverse swap positions')
2294
+ #
2295
+ # {
2296
+ # "code": 0,
2297
+ # "msg": "",
2298
+ # "data": {
2299
+ # "positionHistory": [
2300
+ # {
2301
+ # "positionId": "1861675561156571136",
2302
+ # "symbol": "LTC-USDT",
2303
+ # "isolated": False,
2304
+ # "positionSide": "LONG",
2305
+ # "openTime": 1732693017000,
2306
+ # "updateTime": 1733310292000,
2307
+ # "avgPrice": "95.18",
2308
+ # "avgClosePrice": "129.48",
2309
+ # "realisedProfit": "102.89",
2310
+ # "netProfit": "99.63",
2311
+ # "positionAmt": "30.0",
2312
+ # "closePositionAmt": "30.0",
2313
+ # "leverage": 6,
2314
+ # "closeAllPositions": True,
2315
+ # "positionCommission": "-0.33699650000000003",
2316
+ # "totalFunding": "-2.921461693902908"
2317
+ # },
2318
+ # ]
2319
+ # }
2320
+ # }
2321
+ #
2322
+ data = self.safe_dict(response, 'data', {})
2323
+ records = self.safe_list(data, 'positionHistory', [])
2324
+ positions = self.parse_positions(records)
2325
+ return self.filter_by_symbol_since_limit(positions, symbol, since, limit)
2326
+
2268
2327
  async def fetch_positions(self, symbols: Strings = None, params={}):
2269
2328
  """
2270
2329
  fetch all open positions
@@ -2504,12 +2563,34 @@ class bingx(Exchange, ImplicitAPI):
2504
2563
  # "positionAmt": "1.20365912",
2505
2564
  # }
2506
2565
  #
2566
+ # linear swap fetchPositionHistory
2567
+ #
2568
+ # {
2569
+ # "positionId": "1861675561156571136",
2570
+ # "symbol": "LTC-USDT",
2571
+ # "isolated": False,
2572
+ # "positionSide": "LONG",
2573
+ # "openTime": 1732693017000,
2574
+ # "updateTime": 1733310292000,
2575
+ # "avgPrice": "95.18",
2576
+ # "avgClosePrice": "129.48",
2577
+ # "realisedProfit": "102.89",
2578
+ # "netProfit": "99.63",
2579
+ # "positionAmt": "30.0",
2580
+ # "closePositionAmt": "30.0",
2581
+ # "leverage": 6,
2582
+ # "closeAllPositions": True,
2583
+ # "positionCommission": "-0.33699650000000003",
2584
+ # "totalFunding": "-2.921461693902908"
2585
+ # }
2586
+ #
2507
2587
  marketId = self.safe_string(position, 'symbol', '')
2508
2588
  marketId = marketId.replace('/', '-') # standard return different format
2509
2589
  isolated = self.safe_bool(position, 'isolated')
2510
2590
  marginMode = None
2511
2591
  if isolated is not None:
2512
2592
  marginMode = 'isolated' if isolated else 'cross'
2593
+ timestamp = self.safe_integer(position, 'openTime')
2513
2594
  return self.safe_position({
2514
2595
  'info': position,
2515
2596
  'id': self.safe_string(position, 'positionId'),
@@ -2527,8 +2608,8 @@ class bingx(Exchange, ImplicitAPI):
2527
2608
  'lastPrice': None,
2528
2609
  'side': self.safe_string_lower(position, 'positionSide'),
2529
2610
  'hedged': None,
2530
- 'timestamp': None,
2531
- 'datetime': None,
2611
+ 'timestamp': timestamp,
2612
+ 'datetime': self.iso8601(timestamp),
2532
2613
  'lastUpdateTimestamp': self.safe_integer(position, 'updateTime'),
2533
2614
  'maintenanceMargin': None,
2534
2615
  'maintenanceMarginPercentage': None,
@@ -6089,7 +6170,7 @@ class bingx(Exchange, ImplicitAPI):
6089
6170
  body = self.json(parsedParams)
6090
6171
  else:
6091
6172
  query = self.urlencode(parsedParams)
6092
- url += '?' + query + '&signature=' + signature
6173
+ url += '?' + query + '&' + 'signature=' + signature
6093
6174
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
6094
6175
 
6095
6176
  def nonce(self):
@@ -1474,8 +1474,8 @@ class bitget(Exchange, ImplicitAPI):
1474
1474
  'index': False, # not on spot
1475
1475
  },
1476
1476
  'triggerDirection': False,
1477
- 'stopLossPrice': True, # but not yet implemented in spot
1478
- 'takeProfitPrice': True, # but not yet implemented in spot
1477
+ 'stopLossPrice': True, # todo: not yet implemented in spot
1478
+ 'takeProfitPrice': True, # todo: not yet implemented in spot
1479
1479
  'attachedStopLossTakeProfit': {
1480
1480
  'triggerPriceType': {
1481
1481
  'last': False,
@@ -1485,7 +1485,6 @@ class bitget(Exchange, ImplicitAPI):
1485
1485
  'limitPrice': True,
1486
1486
  },
1487
1487
  'timeInForce': {
1488
- 'GTC': True,
1489
1488
  'IOC': True,
1490
1489
  'FOK': True,
1491
1490
  'PO': True,
@@ -1556,7 +1555,6 @@ class bitget(Exchange, ImplicitAPI):
1556
1555
  'limitPrice': False,
1557
1556
  },
1558
1557
  'timeInForce': {
1559
- 'GTC': True,
1560
1558
  'IOC': True,
1561
1559
  'FOK': True,
1562
1560
  'PO': True,
@@ -1028,7 +1028,7 @@ class bithumb(Exchange, ImplicitAPI):
1028
1028
  'address': address,
1029
1029
  'currency': currency['id'],
1030
1030
  }
1031
- if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM':
1031
+ if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM' or code == 'TON':
1032
1032
  destination = self.safe_string(params, 'destination')
1033
1033
  if (tag is None) and (destination is None):
1034
1034
  raise ArgumentsRequired(self.id + ' ' + code + ' withdraw() requires a tag argument or an extra destination param')