ccxt 4.2.63__py2.py3-none-any.whl → 4.2.65__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

Files changed (59) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/blofin.py +1 -0
  3. ccxt/abstract/krakenfutures.py +1 -0
  4. ccxt/abstract/kucoin.py +10 -0
  5. ccxt/abstract/kucoinfutures.py +10 -0
  6. ccxt/async_support/__init__.py +1 -1
  7. ccxt/async_support/base/exchange.py +2 -2
  8. ccxt/async_support/binance.py +32 -13
  9. ccxt/async_support/bingx.py +56 -49
  10. ccxt/async_support/bitget.py +66 -2
  11. ccxt/async_support/bitmex.py +2 -1
  12. ccxt/async_support/blofin.py +45 -12
  13. ccxt/async_support/btcmarkets.py +9 -0
  14. ccxt/async_support/bybit.py +90 -6
  15. ccxt/async_support/coinbase.py +9 -2
  16. ccxt/async_support/delta.py +92 -2
  17. ccxt/async_support/gate.py +1 -1
  18. ccxt/async_support/gemini.py +9 -5
  19. ccxt/async_support/hitbtc.py +1 -1
  20. ccxt/async_support/krakenfutures.py +1 -0
  21. ccxt/async_support/kucoin.py +85 -61
  22. ccxt/async_support/okx.py +1 -1
  23. ccxt/async_support/woo.py +1 -1
  24. ccxt/async_support/yobit.py +15 -15
  25. ccxt/base/exchange.py +14 -3
  26. ccxt/binance.py +32 -13
  27. ccxt/bingx.py +56 -49
  28. ccxt/bitget.py +66 -2
  29. ccxt/bitmex.py +2 -1
  30. ccxt/blofin.py +45 -12
  31. ccxt/btcmarkets.py +9 -0
  32. ccxt/bybit.py +90 -6
  33. ccxt/coinbase.py +9 -2
  34. ccxt/delta.py +92 -2
  35. ccxt/gate.py +1 -1
  36. ccxt/gemini.py +9 -5
  37. ccxt/hitbtc.py +1 -1
  38. ccxt/krakenfutures.py +1 -0
  39. ccxt/kucoin.py +85 -61
  40. ccxt/okx.py +1 -1
  41. ccxt/pro/__init__.py +1 -1
  42. ccxt/pro/bitget.py +4 -3
  43. ccxt/pro/coinex.py +4 -4
  44. ccxt/pro/currencycom.py +1 -1
  45. ccxt/pro/lbank.py +1 -1
  46. ccxt/static_dependencies/ethereum/utils/__init__.py +0 -6
  47. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +0 -4
  48. ccxt/test/base/test_shared_methods.py +1 -1
  49. ccxt/test/test_async.py +13 -1
  50. ccxt/test/test_sync.py +13 -1
  51. ccxt/woo.py +1 -1
  52. ccxt/yobit.py +15 -15
  53. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/METADATA +4 -4
  54. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/RECORD +56 -59
  55. ccxt/static_dependencies/ethereum/utils/__json/eth_networks.json +0 -1
  56. ccxt/static_dependencies/ethereum/utils/network.py +0 -88
  57. ccxt-4.2.63.data/data/ccxt/eth_networks.json +0 -1
  58. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/WHEEL +0 -0
  59. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/top_level.txt +0 -0
@@ -447,7 +447,7 @@ class bingx(Exchange, ImplicitAPI):
447
447
  # }
448
448
  # }
449
449
  #
450
- data = self.safe_value(response, 'data')
450
+ data = self.safe_dict(response, 'data')
451
451
  return self.safe_integer(data, 'serverTime')
452
452
 
453
453
  async def fetch_currencies(self, params={}):
@@ -498,14 +498,14 @@ class bingx(Exchange, ImplicitAPI):
498
498
  # ],
499
499
  # }
500
500
  #
501
- data = self.safe_value(response, 'data', [])
501
+ data = self.safe_list(response, 'data', [])
502
502
  result = {}
503
503
  for i in range(0, len(data)):
504
504
  entry = data[i]
505
505
  currencyId = self.safe_string(entry, 'coin')
506
506
  code = self.safe_currency_code(currencyId)
507
507
  name = self.safe_string(entry, 'name')
508
- networkList = self.safe_value(entry, 'networkList')
508
+ networkList = self.safe_list(entry, 'networkList')
509
509
  networks = {}
510
510
  fee = None
511
511
  active = None
@@ -515,8 +515,8 @@ class bingx(Exchange, ImplicitAPI):
515
515
  rawNetwork = networkList[j]
516
516
  network = self.safe_string(rawNetwork, 'network')
517
517
  networkCode = self.network_id_to_code(network)
518
- isDefault = self.safe_value(rawNetwork, 'isDefault')
519
- withdrawEnabled = self.safe_value(rawNetwork, 'withdrawEnable')
518
+ isDefault = self.safe_bool(rawNetwork, 'isDefault')
519
+ withdrawEnabled = self.safe_bool(rawNetwork, 'withdrawEnable')
520
520
  limits = {
521
521
  'amounts': {'min': self.safe_number(rawNetwork, 'withdrawMin'), 'max': self.safe_number(rawNetwork, 'withdrawMax')},
522
522
  }
@@ -574,8 +574,8 @@ class bingx(Exchange, ImplicitAPI):
574
574
  # }
575
575
  # }
576
576
  #
577
- data = self.safe_value(response, 'data')
578
- markets = self.safe_value(data, 'symbols', [])
577
+ data = self.safe_dict(response, 'data')
578
+ markets = self.safe_list(data, 'symbols', [])
579
579
  return self.parse_markets(markets)
580
580
 
581
581
  async def fetch_swap_markets(self, params):
@@ -603,7 +603,7 @@ class bingx(Exchange, ImplicitAPI):
603
603
  # ]
604
604
  # }
605
605
  #
606
- markets = self.safe_value(response, 'data', [])
606
+ markets = self.safe_list(response, 'data', [])
607
607
  return self.parse_markets(markets)
608
608
 
609
609
  def parse_market(self, market) -> Market:
@@ -627,7 +627,7 @@ class bingx(Exchange, ImplicitAPI):
627
627
  symbol = base + '/' + quote
628
628
  if settle is not None:
629
629
  symbol += ':' + settle
630
- fees = self.safe_value(self.fees, type, {})
630
+ fees = self.safe_dict(self.fees, type, {})
631
631
  contractSize = self.safe_number(market, 'size')
632
632
  isActive = self.safe_string(market, 'status') == '1'
633
633
  isInverse = None if (spot) else False
@@ -698,8 +698,8 @@ class bingx(Exchange, ImplicitAPI):
698
698
  if not isSandbox:
699
699
  requests.append(self.fetch_spot_markets(params)) # sandbox is swap only
700
700
  promises = await asyncio.gather(*requests)
701
- spotMarkets = self.safe_value(promises, 0, [])
702
- swapMarkets = self.safe_value(promises, 1, [])
701
+ spotMarkets = self.safe_list(promises, 0, [])
702
+ swapMarkets = self.safe_list(promises, 1, [])
703
703
  return self.array_concat(spotMarkets, swapMarkets)
704
704
 
705
705
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
@@ -896,7 +896,7 @@ class bingx(Exchange, ImplicitAPI):
896
896
  # ]
897
897
  # }
898
898
  #
899
- trades = self.safe_value(response, 'data', [])
899
+ trades = self.safe_list(response, 'data', [])
900
900
  return self.parse_trades(trades, market, since, limit)
901
901
 
902
902
  def parse_trade(self, trade, market: Market = None) -> Trade:
@@ -990,9 +990,9 @@ class bingx(Exchange, ImplicitAPI):
990
990
  type = 'spot' if (cost is None) else 'swap'
991
991
  currencyId = self.safe_string_n(trade, ['currency', 'N', 'commissionAsset'])
992
992
  currencyCode = self.safe_currency_code(currencyId)
993
- m = self.safe_value(trade, 'm')
993
+ m = self.safe_bool(trade, 'm')
994
994
  marketId = self.safe_string(trade, 's')
995
- isBuyerMaker = self.safe_value_2(trade, 'buyerMaker', 'isBuyerMaker')
995
+ isBuyerMaker = self.safe_bool_2(trade, 'buyerMaker', 'isBuyerMaker')
996
996
  takeOrMaker = None
997
997
  if (isBuyerMaker is not None) or (m is not None):
998
998
  takeOrMaker = 'maker' if (isBuyerMaker or m) else 'taker'
@@ -1001,10 +1001,10 @@ class bingx(Exchange, ImplicitAPI):
1001
1001
  if (isBuyerMaker is not None) or (m is not None):
1002
1002
  side = 'sell' if (isBuyerMaker or m) else 'buy'
1003
1003
  takeOrMaker = 'taker'
1004
- isBuyer = self.safe_value(trade, 'isBuyer')
1004
+ isBuyer = self.safe_bool(trade, 'isBuyer')
1005
1005
  if isBuyer is not None:
1006
1006
  side = 'buy' if isBuyer else 'sell'
1007
- isMaker = self.safe_value(trade, 'isMaker')
1007
+ isMaker = self.safe_bool(trade, 'isMaker')
1008
1008
  if isMaker is not None:
1009
1009
  takeOrMaker = 'maker' if isMaker else 'taker'
1010
1010
  return self.safe_trade({
@@ -1108,7 +1108,7 @@ class bingx(Exchange, ImplicitAPI):
1108
1108
  # ]}
1109
1109
  # }
1110
1110
  #
1111
- orderbook = self.safe_value(response, 'data', {})
1111
+ orderbook = self.safe_dict(response, 'data', {})
1112
1112
  timestamp = self.safe_integer_2(orderbook, 'T', 'ts')
1113
1113
  return self.parse_order_book(orderbook, market['symbol'], timestamp, 'bids', 'asks', 0, 1)
1114
1114
 
@@ -1142,7 +1142,7 @@ class bingx(Exchange, ImplicitAPI):
1142
1142
  # ]
1143
1143
  # }
1144
1144
  #
1145
- data = self.safe_value(response, 'data', {})
1145
+ data = self.safe_list(response, 'data', [])
1146
1146
  return self.parse_funding_rate(data, market)
1147
1147
 
1148
1148
  async def fetch_funding_rates(self, symbols: Strings = None, params={}):
@@ -1156,7 +1156,7 @@ class bingx(Exchange, ImplicitAPI):
1156
1156
  await self.load_markets()
1157
1157
  symbols = self.market_symbols(symbols, 'swap', True)
1158
1158
  response = await self.swapV2PublicGetQuotePremiumIndex(self.extend(params))
1159
- data = self.safe_value(response, 'data', [])
1159
+ data = self.safe_list(response, 'data', [])
1160
1160
  filteredResponse = []
1161
1161
  for i in range(0, len(data)):
1162
1162
  item = data[i]
@@ -1244,7 +1244,7 @@ class bingx(Exchange, ImplicitAPI):
1244
1244
  # ]
1245
1245
  # }
1246
1246
  #
1247
- data = self.safe_value(response, 'data', [])
1247
+ data = self.safe_list(response, 'data', [])
1248
1248
  rates = []
1249
1249
  for i in range(0, len(data)):
1250
1250
  entry = data[i]
@@ -1286,7 +1286,7 @@ class bingx(Exchange, ImplicitAPI):
1286
1286
  # }
1287
1287
  # }
1288
1288
  #
1289
- data = self.safe_value(response, 'data', {})
1289
+ data = self.safe_dict(response, 'data', {})
1290
1290
  return self.parse_open_interest(data, market)
1291
1291
 
1292
1292
  def parse_open_interest(self, interest, market: Market = None):
@@ -1597,7 +1597,7 @@ class bingx(Exchange, ImplicitAPI):
1597
1597
  # ]
1598
1598
  # }
1599
1599
  #
1600
- positions = self.safe_value(response, 'data', [])
1600
+ positions = self.safe_list(response, 'data', [])
1601
1601
  return self.parse_positions(positions, symbols)
1602
1602
 
1603
1603
  def parse_position(self, position, market: Market = None):
@@ -1632,7 +1632,7 @@ class bingx(Exchange, ImplicitAPI):
1632
1632
  #
1633
1633
  marketId = self.safe_string(position, 'symbol', '')
1634
1634
  marketId = marketId.replace('/', '-') # standard return different format
1635
- isolated = self.safe_value(position, 'isolated')
1635
+ isolated = self.safe_bool(position, 'isolated')
1636
1636
  marginMode = None
1637
1637
  if isolated is not None:
1638
1638
  marginMode = 'isolated' if isolated else 'cross'
@@ -1770,6 +1770,7 @@ class bingx(Exchange, ImplicitAPI):
1770
1770
  takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
1771
1771
  trailingAmount = self.safe_string(params, 'trailingAmount')
1772
1772
  trailingPercent = self.safe_string_2(params, 'trailingPercent', 'priceRate')
1773
+ trailingType = self.safe_string(params, 'trailingType', 'TRAILING_STOP_MARKET')
1773
1774
  isTriggerOrder = triggerPrice is not None
1774
1775
  isStopLossPriceOrder = stopLossPrice is not None
1775
1776
  isTakeProfitPriceOrder = takeProfitPrice is not None
@@ -1805,7 +1806,7 @@ class bingx(Exchange, ImplicitAPI):
1805
1806
  elif (type == 'LIMIT') or (type == 'TAKE_PROFIT'):
1806
1807
  request['type'] = 'TAKE_PROFIT'
1807
1808
  elif isTrailing:
1808
- request['type'] = 'TRAILING_STOP_MARKET'
1809
+ request['type'] = trailingType
1809
1810
  if isTrailingAmountOrder:
1810
1811
  request['price'] = self.parse_to_numeric(trailingAmount)
1811
1812
  elif isTrailingPercentOrder:
@@ -1850,7 +1851,7 @@ class bingx(Exchange, ImplicitAPI):
1850
1851
  positionSide = 'LONG' if (side == 'buy') else 'SHORT'
1851
1852
  request['positionSide'] = positionSide
1852
1853
  request['quantity'] = self.parse_to_numeric(self.amount_to_precision(symbol, amount))
1853
- params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'takeProfit', 'stopLoss', 'clientOrderId'])
1854
+ params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingType', 'takeProfit', 'stopLoss', 'clientOrderId'])
1854
1855
  return self.extend(request, params)
1855
1856
 
1856
1857
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: float = None, params={}):
@@ -1878,14 +1879,20 @@ class bingx(Exchange, ImplicitAPI):
1878
1879
  :param float [params.takeProfit.triggerPrice]: take profit trigger price
1879
1880
  :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
1880
1881
  :param float [params.stopLoss.triggerPrice]: stop loss trigger price
1882
+ :param boolean [params.test]: *swap only* whether to use the test endpoint or not, default is False
1881
1883
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1882
1884
  """
1883
1885
  await self.load_markets()
1884
1886
  market = self.market(symbol)
1887
+ test = self.safe_bool(params, 'test', False)
1888
+ params = self.omit(params, 'test')
1885
1889
  request = self.create_order_request(symbol, type, side, amount, price, params)
1886
1890
  response = None
1887
1891
  if market['swap']:
1888
- response = await self.swapV2PrivatePostTradeOrder(request)
1892
+ if test:
1893
+ response = await self.swapV2PrivatePostTradeOrderTest(request)
1894
+ else:
1895
+ response = await self.swapV2PrivatePostTradeOrder(request)
1889
1896
  else:
1890
1897
  response = await self.spotV1PrivatePostTradeOrder(request)
1891
1898
  #
@@ -1959,7 +1966,7 @@ class bingx(Exchange, ImplicitAPI):
1959
1966
  side = self.safe_string(rawOrder, 'side')
1960
1967
  amount = self.safe_number(rawOrder, 'amount')
1961
1968
  price = self.safe_number(rawOrder, 'price')
1962
- orderParams = self.safe_value(rawOrder, 'params', {})
1969
+ orderParams = self.safe_dict(rawOrder, 'params', {})
1963
1970
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
1964
1971
  ordersRequests.append(orderRequest)
1965
1972
  market = self.market(symbol)
@@ -2016,8 +2023,8 @@ class bingx(Exchange, ImplicitAPI):
2016
2023
  # }
2017
2024
  # }
2018
2025
  #
2019
- data = self.safe_value(response, 'data', {})
2020
- result = self.safe_value(data, 'orders', [])
2026
+ data = self.safe_dict(response, 'data', {})
2027
+ result = self.safe_list(data, 'orders', [])
2021
2028
  return self.parse_orders(result, market)
2022
2029
 
2023
2030
  def parse_order_side(self, side):
@@ -2705,8 +2712,8 @@ class bingx(Exchange, ImplicitAPI):
2705
2712
  # }
2706
2713
  # }
2707
2714
  #
2708
- data = self.safe_value(response, 'data', [])
2709
- orders = self.safe_value(data, 'orders', [])
2715
+ data = self.safe_dict(response, 'data', {})
2716
+ orders = self.safe_list(data, 'orders', [])
2710
2717
  return self.parse_orders(orders, market, since, limit)
2711
2718
 
2712
2719
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
@@ -2812,7 +2819,7 @@ class bingx(Exchange, ImplicitAPI):
2812
2819
  """
2813
2820
  await self.load_markets()
2814
2821
  currency = self.currency(code)
2815
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
2822
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
2816
2823
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
2817
2824
  toId = self.safe_string(accountsByType, toAccount, toAccount)
2818
2825
  request: dict = {
@@ -2852,7 +2859,7 @@ class bingx(Exchange, ImplicitAPI):
2852
2859
  currency = None
2853
2860
  if code is not None:
2854
2861
  currency = self.currency(code)
2855
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
2862
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
2856
2863
  fromAccount = self.safe_string(params, 'fromAccount')
2857
2864
  toAccount = self.safe_string(params, 'toAccount')
2858
2865
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
@@ -2882,7 +2889,7 @@ class bingx(Exchange, ImplicitAPI):
2882
2889
  # ]
2883
2890
  # }
2884
2891
  #
2885
- rows = self.safe_value(response, 'rows', [])
2892
+ rows = self.safe_list(response, 'rows', [])
2886
2893
  return self.parse_transfers(rows, currency, since, limit)
2887
2894
 
2888
2895
  def parse_transfer(self, transfer, currency: Currency = None):
@@ -2890,7 +2897,7 @@ class bingx(Exchange, ImplicitAPI):
2890
2897
  timestamp = self.safe_integer(transfer, 'timestamp')
2891
2898
  currencyCode = self.safe_currency_code(None, currency)
2892
2899
  status = self.safe_string(transfer, 'status')
2893
- accountsById = self.safe_value(self.options, 'accountsById', {})
2900
+ accountsById = self.safe_dict(self.options, 'accountsById', {})
2894
2901
  typeId = self.safe_string(transfer, 'type')
2895
2902
  typeIdSplit = typeId.split('_')
2896
2903
  fromId = self.safe_string(typeIdSplit, 0)
@@ -2946,7 +2953,7 @@ class bingx(Exchange, ImplicitAPI):
2946
2953
  # }
2947
2954
  # }
2948
2955
  #
2949
- data = self.safe_value(self.safe_value(response, 'data'), 'data')
2956
+ data = self.safe_list(self.safe_dict(response, 'data'), 'data')
2950
2957
  parsed = self.parse_deposit_addresses(data, [currency['code']], False)
2951
2958
  return self.index_by(parsed, 'network')
2952
2959
 
@@ -3360,8 +3367,8 @@ class bingx(Exchange, ImplicitAPI):
3360
3367
  fills = None
3361
3368
  if market['spot']:
3362
3369
  response = await self.spotV1PrivateGetTradeMyTrades(self.extend(request, params))
3363
- data = self.safe_value(response, 'data', [])
3364
- fills = self.safe_value(data, 'fills', [])
3370
+ data = self.safe_dict(response, 'data', {})
3371
+ fills = self.safe_list(data, 'fills', [])
3365
3372
  #
3366
3373
  # {
3367
3374
  # "code": 0,
@@ -3391,8 +3398,8 @@ class bingx(Exchange, ImplicitAPI):
3391
3398
  params = self.omit(params, 'tradingUnit')
3392
3399
  request['tradingUnit'] = tradingUnit
3393
3400
  response = await self.swapV2PrivateGetTradeAllFillOrders(self.extend(request, params))
3394
- data = self.safe_value(response, 'data', [])
3395
- fills = self.safe_value(data, 'fill_orders', [])
3401
+ data = self.safe_dict(response, 'data', {})
3402
+ fills = self.safe_list(data, 'fill_orders', [])
3396
3403
  #
3397
3404
  # {
3398
3405
  # "code": "0",
@@ -3444,7 +3451,7 @@ class bingx(Exchange, ImplicitAPI):
3444
3451
  # ]
3445
3452
  # }
3446
3453
  #
3447
- networkList = self.safe_value(fee, 'networkList', [])
3454
+ networkList = self.safe_list(fee, 'networkList', [])
3448
3455
  networkListLength = len(networkList)
3449
3456
  result = {
3450
3457
  'info': fee,
@@ -3462,7 +3469,7 @@ class bingx(Exchange, ImplicitAPI):
3462
3469
  for i in range(0, networkListLength):
3463
3470
  network = networkList[i]
3464
3471
  networkId = self.safe_string(network, 'network')
3465
- isDefault = self.safe_value(network, 'isDefault')
3472
+ isDefault = self.safe_bool(network, 'isDefault')
3466
3473
  currencyCode = self.safe_string(currency, 'code')
3467
3474
  networkCode = self.network_id_to_code(networkId, currencyCode)
3468
3475
  result['networks'][networkCode] = {
@@ -3598,8 +3605,8 @@ class bingx(Exchange, ImplicitAPI):
3598
3605
  # }
3599
3606
  # }
3600
3607
  #
3601
- data = self.safe_value(response, 'data', {})
3602
- liquidations = self.safe_value(data, 'orders', [])
3608
+ data = self.safe_dict(response, 'data', {})
3609
+ liquidations = self.safe_list(data, 'orders', [])
3603
3610
  return self.parse_liquidations(liquidations, market, since, limit)
3604
3611
 
3605
3612
  def parse_liquidation(self, liquidation, market: Market = None):
@@ -3670,7 +3677,7 @@ class bingx(Exchange, ImplicitAPI):
3670
3677
  # }
3671
3678
  # }
3672
3679
  #
3673
- data = self.safe_value(response, 'data')
3680
+ data = self.safe_dict(response, 'data')
3674
3681
  return self.parse_order(data)
3675
3682
 
3676
3683
  async def close_all_positions(self, params={}) -> List[Position]:
@@ -3705,8 +3712,8 @@ class bingx(Exchange, ImplicitAPI):
3705
3712
  # }
3706
3713
  # }
3707
3714
  #
3708
- data = self.safe_value(response, 'data', {})
3709
- success = self.safe_value(data, 'success', [])
3715
+ data = self.safe_dict(response, 'data', {})
3716
+ success = self.safe_list(data, 'success', [])
3710
3717
  positions = []
3711
3718
  for i in range(0, len(success)):
3712
3719
  position = self.parse_position({'positionId': success[i]})
@@ -3792,7 +3799,7 @@ class bingx(Exchange, ImplicitAPI):
3792
3799
  :param str [params.newClientOrderId]: custom order id consisting of letters, numbers, and _, 1-40 characters, different orders cannot use the same newClientOrderId.
3793
3800
  :param str [params.positionSide]: *contract only* position direction, required for single position, for both long and short positions only LONG or SHORT can be chosen, defaults to LONG if empty
3794
3801
  :param str [params.reduceOnly]: *contract only* True or False, default=false for single position mode. self parameter is not accepted for both long and short positions mode
3795
- :param float [params.priceRate]: *contract only* for type TRAILING_STOP_Market, Max = 1
3802
+ :param float [params.priceRate]: *contract only* for type TRAILING_STOP_Market or TRAILING_TP_SL, Max = 1
3796
3803
  :param str [params.workingType]: *contract only* StopPrice trigger price types, MARK_PRICE(default), CONTRACT_PRICE, or INDEX_PRICE
3797
3804
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3798
3805
  """
@@ -3906,7 +3913,7 @@ class bingx(Exchange, ImplicitAPI):
3906
3913
  :see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Margin%20Mode
3907
3914
  :param str symbol: unified symbol of the market to fetch the margin mode for
3908
3915
  :param dict [params]: extra parameters specific to the exchange API endpoint
3909
- :returns dict: Struct of MarginMode
3916
+ :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
3910
3917
  """
3911
3918
  await self.load_markets()
3912
3919
  market = self.market(symbol)
@@ -8,7 +8,7 @@ from ccxt.abstract.bitget import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
10
  import json
11
- from ccxt.base.types import Balances, Currency, Int, Liquidation, Leverage, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, FundingHistory, Str, Strings, Ticker, Tickers, Trade, Transaction
11
+ from ccxt.base.types import Balances, Currency, Int, Liquidation, Leverage, MarginMode, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, FundingHistory, Str, Strings, Ticker, Tickers, Trade, Transaction
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import PermissionDenied
@@ -106,7 +106,7 @@ class bitget(Exchange, ImplicitAPI):
106
106
  'fetchLeverage': True,
107
107
  'fetchLeverageTiers': False,
108
108
  'fetchLiquidations': False,
109
- 'fetchMarginMode': False,
109
+ 'fetchMarginMode': True,
110
110
  'fetchMarketLeverageTiers': True,
111
111
  'fetchMarkets': True,
112
112
  'fetchMarkOHLCV': True,
@@ -7727,6 +7727,70 @@ class bitget(Exchange, ImplicitAPI):
7727
7727
  orderInfo = self.safe_value(data, 'successList', [])
7728
7728
  return self.parse_positions(orderInfo, None, params)
7729
7729
 
7730
+ async def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
7731
+ """
7732
+ fetches the margin mode of a trading pair
7733
+ :see: https://www.bitget.com/api-doc/contract/account/Get-Single-Account
7734
+ :param str symbol: unified symbol of the market to fetch the margin mode for
7735
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7736
+ :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
7737
+ """
7738
+ await self.load_markets()
7739
+ sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
7740
+ market = None
7741
+ if sandboxMode:
7742
+ sandboxSymbol = self.convert_symbol_for_sandbox(symbol)
7743
+ market = self.market(sandboxSymbol)
7744
+ else:
7745
+ market = self.market(symbol)
7746
+ productType = None
7747
+ productType, params = self.handle_product_type_and_params(market, params)
7748
+ request = {
7749
+ 'symbol': market['id'],
7750
+ 'marginCoin': market['settleId'],
7751
+ 'productType': productType,
7752
+ }
7753
+ response = await self.privateMixGetV2MixAccountAccount(self.extend(request, params))
7754
+ #
7755
+ # {
7756
+ # "code": "00000",
7757
+ # "msg": "success",
7758
+ # "requestTime": 1709791216652,
7759
+ # "data": {
7760
+ # "marginCoin": "USDT",
7761
+ # "locked": "0",
7762
+ # "available": "19.88811074",
7763
+ # "crossedMaxAvailable": "19.88811074",
7764
+ # "isolatedMaxAvailable": "19.88811074",
7765
+ # "maxTransferOut": "19.88811074",
7766
+ # "accountEquity": "19.88811074",
7767
+ # "usdtEquity": "19.888110749166",
7768
+ # "btcEquity": "0.000302183391",
7769
+ # "crossedRiskRate": "0",
7770
+ # "crossedMarginLeverage": 20,
7771
+ # "isolatedLongLever": 20,
7772
+ # "isolatedShortLever": 20,
7773
+ # "marginMode": "crossed",
7774
+ # "posMode": "hedge_mode",
7775
+ # "unrealizedPL": "0",
7776
+ # "coupon": "0",
7777
+ # "crossedUnrealizedPL": "0",
7778
+ # "isolatedUnrealizedPL": ""
7779
+ # }
7780
+ # }
7781
+ #
7782
+ data = self.safe_dict(response, 'data', {})
7783
+ return self.parse_margin_mode(data, market)
7784
+
7785
+ def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
7786
+ marginType = self.safe_string(marginMode, 'marginMode')
7787
+ marginType = 'cross' if (marginType == 'crossed') else marginType
7788
+ return {
7789
+ 'info': marginMode,
7790
+ 'symbol': market['symbol'],
7791
+ 'marginMode': marginType,
7792
+ }
7793
+
7730
7794
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
7731
7795
  if not response:
7732
7796
  return None # fallback to default error handler
@@ -2388,7 +2388,8 @@ class bitmex(Exchange, ImplicitAPI):
2388
2388
  params = self.omit(params, ['until', 'till'])
2389
2389
  if until is not None:
2390
2390
  request['endTime'] = self.iso8601(until)
2391
- request['reverse'] = True
2391
+ if (since is None) and (until is None):
2392
+ request['reverse'] = True
2392
2393
  response = await self.publicGetFunding(self.extend(request, params))
2393
2394
  #
2394
2395
  # [
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.blofin import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, MarginMode, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -91,6 +91,8 @@ class blofin(Exchange, ImplicitAPI):
91
91
  'fetchLeverage': True,
92
92
  'fetchLeverages': True,
93
93
  'fetchLeverageTiers': False,
94
+ 'fetchMarginMode': True,
95
+ 'fetchMarginModes': False,
94
96
  'fetchMarketLeverageTiers': False,
95
97
  'fetchMarkets': True,
96
98
  'fetchMarkOHLCV': False,
@@ -194,6 +196,7 @@ class blofin(Exchange, ImplicitAPI):
194
196
  'account/balance': 1,
195
197
  'account/positions': 1,
196
198
  'account/leverage-info': 1,
199
+ 'account/margin-mode': 1,
197
200
  'account/batch-leverage-info': 1,
198
201
  'trade/orders-tpsl-pending': 1,
199
202
  'trade/orders-history': 1,
@@ -384,7 +387,7 @@ class blofin(Exchange, ImplicitAPI):
384
387
  strikePrice = None
385
388
  optionType = None
386
389
  tickSize = self.safe_string(market, 'tickSize')
387
- fees = self.safe_value_2(self.fees, type, 'trading', {})
390
+ fees = self.safe_dict_2(self.fees, type, 'trading', {})
388
391
  taker = self.safe_number(fees, 'taker')
389
392
  maker = self.safe_number(fees, 'maker')
390
393
  maxLeverage = self.safe_string(market, 'maxLeverage', '100')
@@ -482,7 +485,7 @@ class blofin(Exchange, ImplicitAPI):
482
485
  # }
483
486
  #
484
487
  data = self.safe_list(response, 'data', [])
485
- first = self.safe_value(data, 0, {})
488
+ first = self.safe_dict(data, 0, {})
486
489
  timestamp = self.safe_integer(first, 'ts')
487
490
  return self.parse_order_book(first, symbol, timestamp)
488
491
 
@@ -536,7 +539,7 @@ class blofin(Exchange, ImplicitAPI):
536
539
  }
537
540
  response = await self.publicGetMarketTickers(self.extend(request, params))
538
541
  data = self.safe_list(response, 'data', [])
539
- first = self.safe_value(data, 0, {})
542
+ first = self.safe_dict(data, 0, {})
540
543
  return self.parse_ticker(first, market)
541
544
 
542
545
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
@@ -961,8 +964,8 @@ class blofin(Exchange, ImplicitAPI):
961
964
  postOnly, params = self.handle_post_only(isMarketOrder, type == 'post_only', params)
962
965
  if postOnly:
963
966
  request['type'] = 'post_only'
964
- stopLoss = self.safe_value(params, 'stopLoss')
965
- takeProfit = self.safe_value(params, 'takeProfit')
967
+ stopLoss = self.safe_dict(params, 'stopLoss')
968
+ takeProfit = self.safe_dict(params, 'takeProfit')
966
969
  params = self.omit(params, ['stopLoss', 'takeProfit'])
967
970
  isStopLoss = stopLoss is not None
968
971
  isTakeProfit = takeProfit is not None
@@ -1227,7 +1230,7 @@ class blofin(Exchange, ImplicitAPI):
1227
1230
  side = self.safe_string(rawOrder, 'side')
1228
1231
  amount = self.safe_value(rawOrder, 'amount')
1229
1232
  price = self.safe_value(rawOrder, 'price')
1230
- orderParams = self.safe_value(rawOrder, 'params', {})
1233
+ orderParams = self.safe_dict(rawOrder, 'params', {})
1231
1234
  extendedParams = self.extend(orderParams, params) # the request does not accept extra params since it's a list, so we're extending each order with the common params
1232
1235
  orderRequest = self.create_order_request(marketId, type, side, amount, price, extendedParams)
1233
1236
  ordersRequests.append(orderRequest)
@@ -1261,7 +1264,7 @@ class blofin(Exchange, ImplicitAPI):
1261
1264
  request['instId'] = market['id']
1262
1265
  if limit is not None:
1263
1266
  request['limit'] = limit # default 100, max 100
1264
- isStop = self.safe_value_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1267
+ isStop = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1265
1268
  method: str = None
1266
1269
  method, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersPending')
1267
1270
  query = self.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL'])
@@ -1560,7 +1563,7 @@ class blofin(Exchange, ImplicitAPI):
1560
1563
  await self.load_markets()
1561
1564
  market = self.market(symbol)
1562
1565
  request = []
1563
- options = self.safe_value(self.options, 'cancelOrders', {})
1566
+ options = self.safe_dict(self.options, 'cancelOrders', {})
1564
1567
  defaultMethod = self.safe_string(options, 'method', 'privatePostTradeCancelBatchOrders')
1565
1568
  method = self.safe_string(params, 'method', defaultMethod)
1566
1569
  clientOrderIds = self.parse_ids(self.safe_value(params, 'clientOrderId'))
@@ -1614,7 +1617,7 @@ class blofin(Exchange, ImplicitAPI):
1614
1617
  """
1615
1618
  await self.load_markets()
1616
1619
  currency = self.currency(code)
1617
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1620
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
1618
1621
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
1619
1622
  toId = self.safe_string(accountsByType, toAccount, toAccount)
1620
1623
  request = {
@@ -1912,7 +1915,7 @@ class blofin(Exchange, ImplicitAPI):
1912
1915
  if clientOrderId is not None:
1913
1916
  request['clientOrderId'] = clientOrderId
1914
1917
  response = await self.privatePostTradeClosePosition(self.extend(request, params))
1915
- return self.safe_value(response, 'data')
1918
+ return self.safe_dict(response, 'data')
1916
1919
 
1917
1920
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1918
1921
  """
@@ -1942,7 +1945,7 @@ class blofin(Exchange, ImplicitAPI):
1942
1945
  request['limit'] = limit # default 100, max 100
1943
1946
  if since is not None:
1944
1947
  request['begin'] = since
1945
- isStop = self.safe_value_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1948
+ isStop = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1946
1949
  method: str = None
1947
1950
  method, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersHistory')
1948
1951
  query = self.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL'])
@@ -1954,6 +1957,36 @@ class blofin(Exchange, ImplicitAPI):
1954
1957
  data = self.safe_list(response, 'data', [])
1955
1958
  return self.parse_orders(data, market, since, limit)
1956
1959
 
1960
+ async def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
1961
+ """
1962
+ fetches the margin mode of a trading pair
1963
+ :see: https://docs.blofin.com/index.html#get-margin-mode
1964
+ :param str symbol: unified symbol of the market to fetch the margin mode for
1965
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1966
+ :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
1967
+ """
1968
+ await self.load_markets()
1969
+ market = self.market(symbol)
1970
+ response = await self.privateGetAccountMarginMode(params)
1971
+ #
1972
+ # {
1973
+ # "code": "0",
1974
+ # "msg": "success",
1975
+ # "data": {
1976
+ # "marginMode": "cross"
1977
+ # }
1978
+ # }
1979
+ #
1980
+ data = self.safe_dict(response, 'data', {})
1981
+ return self.parse_margin_mode(data, market)
1982
+
1983
+ def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
1984
+ return {
1985
+ 'info': marginMode,
1986
+ 'symbol': market['symbol'],
1987
+ 'marginMode': self.safe_string(marginMode, 'marginMode'),
1988
+ }
1989
+
1957
1990
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
1958
1991
  if response is None:
1959
1992
  return None # fallback to default error handler
@@ -870,6 +870,15 @@ class btcmarkets(Exchange, ImplicitAPI):
870
870
  return await self.privateDeleteOrdersId(self.extend(request, params))
871
871
 
872
872
  def calculate_fee(self, symbol, type, side, amount, price, takerOrMaker='taker', params={}):
873
+ """
874
+ calculates the presumptive fee that would be charged for an order
875
+ :param str symbol: unified market symbol
876
+ :param str type: not used by btcmarkets.calculate_fee :param string side: not used by btcmarkets.calculate_fee :param float amount: how much you want to trade, in units of the base currency on most exchanges, or number of contracts
877
+ :param float price: the price for the order to be filled at, in units of the quote currency
878
+ :param str takerOrMaker: 'taker' or 'maker'
879
+ :param dict params:
880
+ :returns dict: contains the rate, the percentage multiplied to the order amount to obtain the fee amount, and cost, the total value of the fee in units of the quote currency, for the order
881
+ """
873
882
  market = self.markets[symbol]
874
883
  currency = None
875
884
  cost = None