ccxt 4.4.11__py2.py3-none-any.whl → 4.4.13__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 (64) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/async_support/__init__.py +1 -1
  3. ccxt/async_support/base/exchange.py +4 -1
  4. ccxt/async_support/bigone.py +2 -0
  5. ccxt/async_support/binance.py +54 -3
  6. ccxt/async_support/bingx.py +84 -5
  7. ccxt/async_support/bitget.py +2 -0
  8. ccxt/async_support/bitmex.py +1 -0
  9. ccxt/async_support/bybit.py +4 -1
  10. ccxt/async_support/coinbaseinternational.py +2 -0
  11. ccxt/async_support/coinex.py +2 -0
  12. ccxt/async_support/delta.py +2 -0
  13. ccxt/async_support/deribit.py +2 -0
  14. ccxt/async_support/digifinex.py +2 -0
  15. ccxt/async_support/gate.py +2 -0
  16. ccxt/async_support/htx.py +8 -2
  17. ccxt/async_support/kraken.py +4 -4
  18. ccxt/async_support/krakenfutures.py +2 -0
  19. ccxt/async_support/kucoinfutures.py +2 -0
  20. ccxt/async_support/mexc.py +16 -4
  21. ccxt/async_support/okx.py +51 -20
  22. ccxt/async_support/oxfun.py +1 -0
  23. ccxt/async_support/paradex.py +1 -0
  24. ccxt/async_support/phemex.py +10 -3
  25. ccxt/async_support/poloniex.py +1 -0
  26. ccxt/base/exchange.py +7 -1
  27. ccxt/base/types.py +2 -0
  28. ccxt/bigone.py +2 -0
  29. ccxt/binance.py +54 -3
  30. ccxt/bingx.py +84 -5
  31. ccxt/bitget.py +2 -0
  32. ccxt/bitmex.py +1 -0
  33. ccxt/bybit.py +4 -1
  34. ccxt/coinbaseinternational.py +2 -0
  35. ccxt/coinex.py +2 -0
  36. ccxt/delta.py +2 -0
  37. ccxt/deribit.py +2 -0
  38. ccxt/digifinex.py +2 -0
  39. ccxt/gate.py +2 -0
  40. ccxt/htx.py +8 -2
  41. ccxt/kraken.py +4 -4
  42. ccxt/krakenfutures.py +2 -0
  43. ccxt/kucoinfutures.py +2 -0
  44. ccxt/mexc.py +16 -4
  45. ccxt/okx.py +51 -20
  46. ccxt/oxfun.py +1 -0
  47. ccxt/paradex.py +1 -0
  48. ccxt/phemex.py +10 -3
  49. ccxt/poloniex.py +1 -0
  50. ccxt/pro/__init__.py +1 -1
  51. ccxt/pro/binance.py +72 -5
  52. ccxt/pro/bitfinex.py +8 -8
  53. ccxt/pro/krakenfutures.py +2 -0
  54. ccxt/pro/phemex.py +2 -0
  55. ccxt/pro/woo.py +69 -0
  56. ccxt/test/tests_async.py +31 -3
  57. ccxt/test/tests_helpers.py +13 -36
  58. ccxt/test/tests_init.py +6 -2
  59. ccxt/test/tests_sync.py +31 -3
  60. {ccxt-4.4.11.dist-info → ccxt-4.4.13.dist-info}/METADATA +4 -5
  61. {ccxt-4.4.11.dist-info → ccxt-4.4.13.dist-info}/RECORD +64 -64
  62. {ccxt-4.4.11.dist-info → ccxt-4.4.13.dist-info}/LICENSE.txt +0 -0
  63. {ccxt-4.4.11.dist-info → ccxt-4.4.13.dist-info}/WHEEL +0 -0
  64. {ccxt-4.4.11.dist-info → ccxt-4.4.13.dist-info}/top_level.txt +0 -0
ccxt/async_support/okx.py CHANGED
@@ -121,6 +121,7 @@ class okx(Exchange, ImplicitAPI):
121
121
  'fetchMarketLeverageTiers': True,
122
122
  'fetchMarkets': True,
123
123
  'fetchMarkOHLCV': True,
124
+ 'fetchMarkPrices': True,
124
125
  'fetchMySettlementHistory': False,
125
126
  'fetchMyTrades': True,
126
127
  'fetchOHLCV': True,
@@ -1785,6 +1786,13 @@ class okx(Exchange, ImplicitAPI):
1785
1786
  return self.parse_order_book(first, symbol, timestamp)
1786
1787
 
1787
1788
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1789
+ #
1790
+ # {
1791
+ # "instType":"SWAP",
1792
+ # "instId":"BTC-USDT-SWAP",
1793
+ # "markPx":"200",
1794
+ # "ts":"1597026383085"
1795
+ # }
1788
1796
  #
1789
1797
  # {
1790
1798
  # "instType": "SPOT",
@@ -1836,6 +1844,7 @@ class okx(Exchange, ImplicitAPI):
1836
1844
  'average': None,
1837
1845
  'baseVolume': baseVolume,
1838
1846
  'quoteVolume': quoteVolume,
1847
+ 'markPrice': self.safe_string(ticker, 'markPx'),
1839
1848
  'info': ticker,
1840
1849
  }, market)
1841
1850
 
@@ -1936,6 +1945,33 @@ class okx(Exchange, ImplicitAPI):
1936
1945
  tickers = self.safe_list(response, 'data', [])
1937
1946
  return self.parse_tickers(tickers, symbols)
1938
1947
 
1948
+ async def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
1949
+ """
1950
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1951
+ :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
1952
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1953
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1954
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1955
+ """
1956
+ await self.load_markets()
1957
+ symbols = self.market_symbols(symbols)
1958
+ market = self.get_market_from_symbols(symbols)
1959
+ marketType = None
1960
+ marketType, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
1961
+ request: dict = {
1962
+ 'instType': self.convert_to_instrument_type(marketType),
1963
+ }
1964
+ if marketType == 'option':
1965
+ defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
1966
+ currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
1967
+ if currencyId is None:
1968
+ raise ArgumentsRequired(self.id + ' fetchTickers() requires an underlying uly or marketId parameter for options markets')
1969
+ else:
1970
+ request['uly'] = currencyId
1971
+ response = await self.publicGetPublicMarkPrice(self.extend(request, params))
1972
+ tickers = self.safe_list(response, 'data', [])
1973
+ return self.parse_tickers(tickers, symbols)
1974
+
1939
1975
  def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1940
1976
  #
1941
1977
  # public fetchTrades
@@ -2795,7 +2831,7 @@ class okx(Exchange, ImplicitAPI):
2795
2831
  :param str [params.positionSide]: if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
2796
2832
  :param str [params.trailingPercent]: the percent to trail away from the current market price
2797
2833
  :param str [params.tpOrdKind]: 'condition' or 'limit', the default is 'condition'
2798
- :param str [params.hedged]: True/false, to automatically set exchange-specific params needed when trading in hedge mode
2834
+ :param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode
2799
2835
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2800
2836
  """
2801
2837
  await self.load_markets()
@@ -4528,32 +4564,27 @@ class okx(Exchange, ImplicitAPI):
4528
4564
  :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
4529
4565
  :param str code: unified currency code
4530
4566
  :param dict [params]: extra parameters specific to the exchange API endpoint
4567
+ :param str [params.network]: the network name for the deposit address
4531
4568
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
4532
4569
  """
4570
+ await self.load_markets()
4533
4571
  rawNetwork = self.safe_string_upper(params, 'network')
4534
- networks = self.safe_value(self.options, 'networks', {})
4535
- network = self.safe_string(networks, rawNetwork, rawNetwork)
4536
4572
  params = self.omit(params, 'network')
4573
+ code = self.safe_currency_code(code)
4574
+ network = self.network_id_to_code(rawNetwork, code)
4537
4575
  response = await self.fetch_deposit_addresses_by_network(code, params)
4538
- result = None
4539
- if network is None:
4540
- result = self.safe_value(response, code)
4576
+ if network is not None:
4577
+ result = self.safe_dict(response, network)
4541
4578
  if result is None:
4542
- alias = self.safe_string(networks, code, code)
4543
- result = self.safe_value(response, alias)
4544
- if result is None:
4545
- defaultNetwork = self.safe_string(self.options, 'defaultNetwork', 'ERC20')
4546
- result = self.safe_value(response, defaultNetwork)
4547
- if result is None:
4548
- values = list(response.values())
4549
- result = self.safe_value(values, 0)
4550
- if result is None:
4551
- raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find deposit address for ' + code)
4579
+ raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
4552
4580
  return result
4553
- result = self.safe_value(response, network)
4554
- if result is None:
4555
- raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
4556
- return result
4581
+ codeNetwork = self.network_id_to_code(code, code)
4582
+ if codeNetwork in response:
4583
+ return response[codeNetwork]
4584
+ # if the network is not specified, return the first address
4585
+ keys = list(response.keys())
4586
+ first = self.safe_string(keys, 0)
4587
+ return self.safe_dict(response, first)
4557
4588
 
4558
4589
  async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
4559
4590
  """
@@ -859,6 +859,7 @@ class oxfun(Exchange, ImplicitAPI):
859
859
  'average': None,
860
860
  'baseVolume': self.safe_string(ticker, 'currencyVolume24h'),
861
861
  'quoteVolume': None, # the exchange returns cost in OX
862
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
862
863
  'info': ticker,
863
864
  }, market)
864
865
 
@@ -652,6 +652,7 @@ class paradex(Exchange, ImplicitAPI):
652
652
  'average': None,
653
653
  'baseVolume': None,
654
654
  'quoteVolume': self.safe_string(ticker, 'volume_24h'),
655
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
655
656
  'info': ticker,
656
657
  }, market)
657
658
 
@@ -2402,6 +2402,8 @@ class phemex(Exchange, ImplicitAPI):
2402
2402
  :param float [params.takeProfit.triggerPrice]: take profit trigger price
2403
2403
  :param dict [params.stopLoss]: *swap only* *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
2404
2404
  :param float [params.stopLoss.triggerPrice]: stop loss trigger price
2405
+ :param str [params.posSide]: *swap only* "Merged" for one way mode, "Long" for buy side of hedged mode, "Short" for sell side of hedged mode
2406
+ :param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
2405
2407
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2406
2408
  """
2407
2409
  await self.load_markets()
@@ -2486,13 +2488,18 @@ class phemex(Exchange, ImplicitAPI):
2486
2488
  amountString = self.number_to_string(amount)
2487
2489
  request['baseQtyEv'] = self.to_ev(amountString, market)
2488
2490
  elif market['swap']:
2491
+ hedged = self.safe_bool(params, 'hedged', False)
2492
+ params = self.omit(params, 'hedged')
2489
2493
  posSide = self.safe_string_lower(params, 'posSide')
2490
2494
  if posSide is None:
2491
- posSide = 'Merged'
2495
+ if hedged:
2496
+ if reduceOnly:
2497
+ side = 'sell' if (side == 'buy') else 'buy'
2498
+ posSide = 'Long' if (side == 'buy') else 'Short'
2499
+ else:
2500
+ posSide = 'Merged'
2492
2501
  posSide = self.capitalize(posSide)
2493
2502
  request['posSide'] = posSide
2494
- if reduceOnly is not None:
2495
- request['reduceOnly'] = reduceOnly
2496
2503
  if market['settle'] == 'USDT':
2497
2504
  request['orderQtyRq'] = amount
2498
2505
  else:
@@ -633,6 +633,7 @@ class poloniex(Exchange, ImplicitAPI):
633
633
  'average': None,
634
634
  'baseVolume': self.safe_string(ticker, 'quantity'),
635
635
  'quoteVolume': self.safe_string(ticker, 'amount'),
636
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
636
637
  'info': ticker,
637
638
  }, market)
638
639
 
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.11'
7
+ __version__ = '4.4.13'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -1952,6 +1952,7 @@ class Exchange(object):
1952
1952
  'fetchTicker': True,
1953
1953
  'fetchTickerWs': None,
1954
1954
  'fetchTickers': None,
1955
+ 'fetchMarkPrices': None,
1955
1956
  'fetchTickersWs': None,
1956
1957
  'fetchTime': None,
1957
1958
  'fetchTrades': True,
@@ -3478,6 +3479,8 @@ class Exchange(object):
3478
3479
  'baseVolume': self.parse_number(baseVolume),
3479
3480
  'quoteVolume': self.parse_number(quoteVolume),
3480
3481
  'previousClose': self.safe_number(ticker, 'previousClose'),
3482
+ 'indexPrice': self.safe_number(ticker, 'indexPrice'),
3483
+ 'markPrice': self.safe_number(ticker, 'markPrice'),
3481
3484
  })
3482
3485
 
3483
3486
  def fetch_borrow_rate(self, code: str, amount, params={}):
@@ -4508,6 +4511,9 @@ class Exchange(object):
4508
4511
  def fetch_tickers(self, symbols: Strings = None, params={}):
4509
4512
  raise NotSupported(self.id + ' fetchTickers() is not supported yet')
4510
4513
 
4514
+ def fetch_mark_prices(self, symbols: Strings = None, params={}):
4515
+ raise NotSupported(self.id + ' fetchMarkPrices() is not supported yet')
4516
+
4511
4517
  def fetch_tickers_ws(self, symbols: Strings = None, params={}):
4512
4518
  raise NotSupported(self.id + ' fetchTickers() is not supported yet')
4513
4519
 
ccxt/base/types.py CHANGED
@@ -272,6 +272,8 @@ class Ticker(TypedDict):
272
272
  average: Num
273
273
  quoteVolume: Num
274
274
  baseVolume: Num
275
+ markPrice: Num
276
+ indexPrice: Num
275
277
 
276
278
 
277
279
  Tickers = Dict[str, Ticker]
ccxt/bigone.py CHANGED
@@ -723,6 +723,8 @@ class bigone(Exchange, ImplicitAPI):
723
723
  'average': None,
724
724
  'baseVolume': self.safe_string_2(ticker, 'volume', 'volume24h'),
725
725
  'quoteVolume': self.safe_string(ticker, 'volume24hInUsd'),
726
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
727
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
726
728
  'info': ticker,
727
729
  }, market)
728
730
 
ccxt/binance.py CHANGED
@@ -132,6 +132,7 @@ class binance(Exchange, ImplicitAPI):
132
132
  'fetchMarketLeverageTiers': 'emulated',
133
133
  'fetchMarkets': True,
134
134
  'fetchMarkOHLCV': True,
135
+ 'fetchMarkPrices': True,
135
136
  'fetchMyLiquidations': True,
136
137
  'fetchMySettlementHistory': True,
137
138
  'fetchMyTrades': True,
@@ -1216,6 +1217,9 @@ class binance(Exchange, ImplicitAPI):
1216
1217
  },
1217
1218
  'option': {},
1218
1219
  },
1220
+ 'currencies': {
1221
+ 'BNFCR': self.safe_currency_structure({'id': 'BNFCR', 'code': 'BNFCR', 'precision': self.parse_number('0.001')}),
1222
+ },
1219
1223
  'commonCurrencies': {
1220
1224
  'BCC': 'BCC', # kept for backward-compatibility https://github.com/ccxt/ccxt/issues/4848
1221
1225
  'YOYO': 'YOYOW',
@@ -3714,6 +3718,18 @@ class binance(Exchange, ImplicitAPI):
3714
3718
  return orderbook
3715
3719
 
3716
3720
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
3721
+ # markPrices
3722
+ #
3723
+ # {
3724
+ # "symbol": "BTCUSDT",
3725
+ # "markPrice": "11793.63104562", # mark price
3726
+ # "indexPrice": "11781.80495970", # index price
3727
+ # "estimatedSettlePrice": "11781.16138815", # Estimated Settle Price, only useful in the last hour before the settlement starts.
3728
+ # "lastFundingRate": "0.00038246", # This is the lastest estimated funding rate
3729
+ # "nextFundingTime": 1597392000000,
3730
+ # "interestRate": "0.00010000",
3731
+ # "time": 1597370495002
3732
+ # }
3717
3733
  #
3718
3734
  # {
3719
3735
  # "symbol": "ETHBTC",
@@ -3817,7 +3833,7 @@ class binance(Exchange, ImplicitAPI):
3817
3833
  # "time":"1673899278514"
3818
3834
  # }
3819
3835
  #
3820
- timestamp = self.safe_integer(ticker, 'closeTime')
3836
+ timestamp = self.safe_integer_2(ticker, 'closeTime', 'time')
3821
3837
  marketType = None
3822
3838
  if ('time' in ticker):
3823
3839
  marketType = 'contract'
@@ -3857,6 +3873,8 @@ class binance(Exchange, ImplicitAPI):
3857
3873
  'average': None,
3858
3874
  'baseVolume': baseVolume,
3859
3875
  'quoteVolume': quoteVolume,
3876
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
3877
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
3860
3878
  'info': ticker,
3861
3879
  }, market)
3862
3880
 
@@ -4087,6 +4105,31 @@ class binance(Exchange, ImplicitAPI):
4087
4105
  raise NotSupported(self.id + ' fetchTickers() does not support ' + type + ' markets yet')
4088
4106
  return self.parse_tickers(response, symbols)
4089
4107
 
4108
+ def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
4109
+ """
4110
+ fetches mark prices for multiple markets
4111
+ :see: https://binance-docs.github.io/apidocs/futures/en/#mark-price
4112
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
4113
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4114
+ :param str [params.subType]: "linear" or "inverse"
4115
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
4116
+ """
4117
+ self.load_markets()
4118
+ symbols = self.market_symbols(symbols, None, True, True, True)
4119
+ market = self.get_market_from_symbols(symbols)
4120
+ type = None
4121
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
4122
+ subType = None
4123
+ subType, params = self.handle_sub_type_and_params('fetchTickers', market, params, 'linear')
4124
+ response = None
4125
+ if self.is_linear(type, subType):
4126
+ response = self.fapiPublicGetPremiumIndex(params)
4127
+ elif self.is_inverse(type, subType):
4128
+ response = self.dapiPublicGetPremiumIndex(params)
4129
+ else:
4130
+ raise NotSupported(self.id + ' fetchMarkPrices() does not support ' + type + ' markets yet')
4131
+ return self.parse_tickers(response, symbols)
4132
+
4090
4133
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
4091
4134
  # when api method = publicGetKlines or fapiPublicGetKlines or dapiPublicGetKlines
4092
4135
  # [
@@ -5595,6 +5638,8 @@ class binance(Exchange, ImplicitAPI):
5595
5638
  :param float [params.takeProfitPrice]: the price that a take profit order is triggered at
5596
5639
  :param boolean [params.portfolioMargin]: set to True if you would like to create an order in a portfolio margin account
5597
5640
  :param str [params.stopLossOrTakeProfit]: 'stopLoss' or 'takeProfit', required for spot trailing orders
5641
+ :param str [params.positionSide]: *swap and portfolio margin only* "BOTH" for one-way mode, "LONG" for buy side of hedged mode, "SHORT" for sell side of hedged mode
5642
+ :param bool [params.hedged]: *swap and portfolio margin only* True for hedged mode, False for one way mode, default is False
5598
5643
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
5599
5644
  """
5600
5645
  self.load_markets()
@@ -5680,9 +5725,9 @@ class binance(Exchange, ImplicitAPI):
5680
5725
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'createOrder', 'papi', 'portfolioMargin', False)
5681
5726
  marginMode = None
5682
5727
  marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
5728
+ reduceOnly = self.safe_bool(params, 'reduceOnly', False)
5683
5729
  if (marketType == 'margin') or (marginMode is not None) or market['option']:
5684
5730
  # for swap and future reduceOnly is a string that cant be sent with close position set to True or in hedge mode
5685
- reduceOnly = self.safe_bool(params, 'reduceOnly', False)
5686
5731
  params = self.omit(params, 'reduceOnly')
5687
5732
  if market['option']:
5688
5733
  request['reduceOnly'] = reduceOnly
@@ -5883,7 +5928,13 @@ class binance(Exchange, ImplicitAPI):
5883
5928
  # remove timeInForce from params because PO is only used by self.is_post_only and it's not a valid value for Binance
5884
5929
  if self.safe_string(params, 'timeInForce') == 'PO':
5885
5930
  params = self.omit(params, 'timeInForce')
5886
- requestParams = self.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent', 'quoteOrderQty', 'cost', 'test'])
5931
+ hedged = self.safe_bool(params, 'hedged', False)
5932
+ if not market['spot'] and not market['option'] and hedged:
5933
+ if reduceOnly:
5934
+ params = self.omit(params, 'reduceOnly')
5935
+ side = 'sell' if (side == 'buy') else 'buy'
5936
+ request['positionSide'] = 'LONG' if (side == 'buy') else 'SHORT'
5937
+ requestParams = self.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent', 'quoteOrderQty', 'cost', 'test', 'hedged'])
5887
5938
  return self.extend(request, requestParams)
5888
5939
 
5889
5940
  def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
ccxt/bingx.py CHANGED
@@ -80,6 +80,7 @@ class bingx(Exchange, ImplicitAPI):
80
80
  'fetchMarginMode': True,
81
81
  'fetchMarkets': True,
82
82
  'fetchMarkOHLCV': True,
83
+ 'fetchMarkPrices': True,
83
84
  'fetchMyLiquidations': True,
84
85
  'fetchOHLCV': True,
85
86
  'fetchOpenInterest': True,
@@ -590,8 +591,8 @@ class bingx(Exchange, ImplicitAPI):
590
591
  networkList = self.safe_list(entry, 'networkList')
591
592
  networks: dict = {}
592
593
  fee = None
593
- depositEnabled = None
594
- withdrawEnabled = None
594
+ depositEnabled = False
595
+ withdrawEnabled = False
595
596
  defaultLimits: dict = {}
596
597
  for j in range(0, len(networkList)):
597
598
  rawNetwork = networkList[j]
@@ -602,7 +603,7 @@ class bingx(Exchange, ImplicitAPI):
602
603
  if networkDepositEnabled:
603
604
  depositEnabled = True
604
605
  networkWithdrawEnabled = self.safe_bool(rawNetwork, 'withdrawEnable')
605
- if networkDepositEnabled:
606
+ if networkWithdrawEnabled:
606
607
  withdrawEnabled = True
607
608
  limits: dict = {
608
609
  'withdraw': {
@@ -1654,7 +1655,70 @@ class bingx(Exchange, ImplicitAPI):
1654
1655
  tickers = self.safe_list(response, 'data')
1655
1656
  return self.parse_tickers(tickers, symbols)
1656
1657
 
1658
+ def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
1659
+ """
1660
+ fetches mark prices for multiple markets
1661
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/market-api.html#Mark%20Price%20and%20Funding%20Rate
1662
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1663
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1664
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1665
+ """
1666
+ self.load_markets()
1667
+ market = None
1668
+ if symbols is not None:
1669
+ symbols = self.market_symbols(symbols)
1670
+ firstSymbol = self.safe_string(symbols, 0)
1671
+ if firstSymbol is not None:
1672
+ market = self.market(firstSymbol)
1673
+ subType = None
1674
+ subType, params = self.handle_sub_type_and_params('fetchMarkPrices', market, params, 'linear')
1675
+ response = None
1676
+ if subType == 'inverse':
1677
+ response = self.cswapV1PublicGetMarketPremiumIndex(params)
1678
+ else:
1679
+ response = self.swapV2PublicGetQuotePremiumIndex(params)
1680
+ #
1681
+ # spot and swap
1682
+ #
1683
+ # {
1684
+ # "code": 0,
1685
+ # "msg": "",
1686
+ # "timestamp": 1720647285296,
1687
+ # "data": [
1688
+ # {
1689
+ # "symbol": "SOL-USD",
1690
+ # "priceChange": "-2.418",
1691
+ # "priceChangePercent": "-1.6900%",
1692
+ # "lastPrice": "140.574",
1693
+ # "lastQty": "1",
1694
+ # "highPrice": "146.190",
1695
+ # "lowPrice": "138.586",
1696
+ # "volume": "1464648.00",
1697
+ # "quoteVolume": "102928.12",
1698
+ # "openPrice": "142.994",
1699
+ # "closeTime": "1720647284976",
1700
+ # "bidPrice": "140.573",
1701
+ # "bidQty": "372",
1702
+ # "askPrice": "140.577",
1703
+ # "askQty": "58"
1704
+ # },
1705
+ # ...
1706
+ # ]
1707
+ # }
1708
+ #
1709
+ tickers = self.safe_list(response, 'data')
1710
+ return self.parse_tickers(tickers, symbols)
1711
+
1657
1712
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1713
+ #
1714
+ # mark price
1715
+ # {
1716
+ # "symbol": "string",
1717
+ # "lastFundingRate": "string",
1718
+ # "markPrice": "string",
1719
+ # "indexPrice": "string",
1720
+ # "nextFundingTime": "int64"
1721
+ # }
1658
1722
  #
1659
1723
  # spot
1660
1724
  # {
@@ -1740,6 +1804,8 @@ class bingx(Exchange, ImplicitAPI):
1740
1804
  'average': None,
1741
1805
  'baseVolume': baseVolume,
1742
1806
  'quoteVolume': quoteVolume,
1807
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
1808
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
1743
1809
  'info': ticker,
1744
1810
  }, market)
1745
1811
 
@@ -2457,6 +2523,7 @@ class bingx(Exchange, ImplicitAPI):
2457
2523
  :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
2458
2524
  :param float [params.stopLoss.triggerPrice]: stop loss trigger price
2459
2525
  :param boolean [params.test]: *swap only* whether to use the test endpoint or not, default is False
2526
+ :param str [params.positionSide]: *contracts only* "BOTH" for one way mode, "LONG" for buy side of hedged mode, "SHORT" for sell side of hedged mode
2460
2527
  :param boolean [params.hedged]: *swap only* whether the order is in hedged mode or one way mode
2461
2528
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2462
2529
  """
@@ -4183,13 +4250,25 @@ class bingx(Exchange, ImplicitAPI):
4183
4250
  currencyId = self.safe_string(depositAddress, 'coin')
4184
4251
  currency = self.safe_currency(currencyId, currency)
4185
4252
  code = currency['code']
4186
- network = self.safe_string(depositAddress, 'network')
4253
+ # the exchange API returns deposit addresses without the leading '0x' prefix
4254
+ # however, the exchange API does require the 0x prefix to withdraw
4255
+ # so we append the prefix before returning the address to the user
4256
+ # that is only if the underlying contract address has the 0x prefix
4257
+ networkCode = self.safe_string(depositAddress, 'network')
4258
+ if networkCode is not None:
4259
+ if networkCode in currency['networks']:
4260
+ network = currency['networks'][networkCode]
4261
+ contractAddress = self.safe_string(network['info'], 'contractAddress')
4262
+ if contractAddress is not None:
4263
+ if contractAddress[0] == '0' and contractAddress[1] == 'x':
4264
+ if address[0] != '0' or address[1] != 'x':
4265
+ address = '0x' + address
4187
4266
  self.check_address(address)
4188
4267
  return {
4189
4268
  'currency': code,
4190
4269
  'address': address,
4191
4270
  'tag': tag,
4192
- 'network': network,
4271
+ 'network': networkCode,
4193
4272
  'info': depositAddress,
4194
4273
  }
4195
4274
 
ccxt/bitget.py CHANGED
@@ -2569,6 +2569,7 @@ class bitget(Exchange, ImplicitAPI):
2569
2569
  'average': None,
2570
2570
  'baseVolume': self.safe_string(ticker, 'baseVolume'),
2571
2571
  'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
2572
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
2572
2573
  'info': ticker,
2573
2574
  }, market)
2574
2575
 
@@ -3947,6 +3948,7 @@ class bitget(Exchange, ImplicitAPI):
3947
3948
  :param str [params.trailingTriggerPrice]: *swap and future only* the price to trigger a trailing stop order, default uses the price argument
3948
3949
  :param str [params.triggerType]: *swap and future only* 'fill_price', 'mark_price' or 'index_price'
3949
3950
  :param boolean [params.oneWayMode]: *swap and future only* required to set self to True in one_way_mode and you can leave self in hedge_mode, can adjust the mode using the setPositionMode() method
3951
+ :param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode, default is False
3950
3952
  :param bool [params.reduceOnly]: True or False whether the order is reduce-only
3951
3953
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3952
3954
  """
ccxt/bitmex.py CHANGED
@@ -1370,6 +1370,7 @@ class bitmex(Exchange, ImplicitAPI):
1370
1370
  'average': None,
1371
1371
  'baseVolume': self.safe_string(ticker, 'homeNotional24h'),
1372
1372
  'quoteVolume': self.safe_string(ticker, 'foreignNotional24h'),
1373
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
1373
1374
  'info': ticker,
1374
1375
  }, market)
1375
1376
 
ccxt/bybit.py CHANGED
@@ -2053,6 +2053,8 @@ class bybit(Exchange, ImplicitAPI):
2053
2053
  'average': None,
2054
2054
  'baseVolume': baseVolume,
2055
2055
  'quoteVolume': quoteVolume,
2056
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
2057
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
2056
2058
  'info': ticker,
2057
2059
  }, market)
2058
2060
 
@@ -3430,7 +3432,8 @@ class bybit(Exchange, ImplicitAPI):
3430
3432
  :param str [params.timeInForce]: "GTC", "IOC", "FOK"
3431
3433
  :param bool [params.postOnly]: True or False whether the order is post-only
3432
3434
  :param bool [params.reduceOnly]: True or False whether the order is reduce-only
3433
- :param str [params.positionIdx]: *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
3435
+ :param str [params.positionIdx]: *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
3436
+ :param bool [params.hedged]: *contracts only* True for hedged mode, False for one way mode, default is False
3434
3437
  :param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
3435
3438
  :param str [params.tpslMode]: *contract only* 'full' or 'partial'
3436
3439
  :param str [params.mmp]: *option only* market maker protection
@@ -1426,6 +1426,8 @@ class coinbaseinternational(Exchange, ImplicitAPI):
1426
1426
  'baseVolume': None,
1427
1427
  'quoteVolume': None,
1428
1428
  'previousClose': None,
1429
+ 'markPrice': self.safe_number(ticker, 'mark_price'),
1430
+ 'indexPrice': self.safe_number(ticker, 'index_price'),
1429
1431
  })
1430
1432
 
1431
1433
  def fetch_balance(self, params={}) -> Balances:
ccxt/coinex.py CHANGED
@@ -921,6 +921,8 @@ class coinex(Exchange, ImplicitAPI):
921
921
  'average': None,
922
922
  'baseVolume': self.safe_string(ticker, 'volume'),
923
923
  'quoteVolume': None,
924
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
925
+ 'indexPrice': self.safe_string(ticker, 'index_price'),
924
926
  'info': ticker,
925
927
  }, market)
926
928
 
ccxt/delta.py CHANGED
@@ -946,6 +946,8 @@ class delta(Exchange, ImplicitAPI):
946
946
  'average': None,
947
947
  'baseVolume': self.safe_number(ticker, 'volume'),
948
948
  'quoteVolume': self.safe_number(ticker, 'turnover'),
949
+ 'markPrice': self.safe_number(ticker, 'mark_price'),
950
+ 'indexPrice': self.safe_number(ticker, 'spot_price'),
949
951
  'info': ticker,
950
952
  }, market)
951
953
 
ccxt/deribit.py CHANGED
@@ -1133,6 +1133,8 @@ class deribit(Exchange, ImplicitAPI):
1133
1133
  'average': None,
1134
1134
  'baseVolume': None,
1135
1135
  'quoteVolume': self.safe_string(stats, 'volume'),
1136
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
1137
+ 'indexPrice': self.safe_string(ticker, 'index_price'),
1136
1138
  'info': ticker,
1137
1139
  }, market)
1138
1140
 
ccxt/digifinex.py CHANGED
@@ -1163,6 +1163,8 @@ class digifinex(Exchange, ImplicitAPI):
1163
1163
  'average': None,
1164
1164
  'baseVolume': self.safe_string_2(ticker, 'vol', 'volume_24h'),
1165
1165
  'quoteVolume': self.safe_string(ticker, 'base_vol'),
1166
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
1167
+ 'indexPrice': indexPrice,
1166
1168
  'info': ticker,
1167
1169
  }, market)
1168
1170
 
ccxt/gate.py CHANGED
@@ -2514,6 +2514,8 @@ class gate(Exchange, ImplicitAPI):
2514
2514
  'average': None,
2515
2515
  'baseVolume': baseVolume,
2516
2516
  'quoteVolume': quoteVolume,
2517
+ 'markPrice': self.safe_string(ticker, 'mark_price'),
2518
+ 'indexPrice': self.safe_string(ticker, 'index_price'),
2517
2519
  'info': ticker,
2518
2520
  }, market)
2519
2521
 
ccxt/htx.py CHANGED
@@ -3481,6 +3481,12 @@ class htx(Exchange, ImplicitAPI):
3481
3481
  def fetch_order(self, id: str, symbol: Str = None, params={}):
3482
3482
  """
3483
3483
  fetches information on an order made by the user
3484
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order-based-on-client-order-id
3485
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-order-detail-of-an-order
3486
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-get-information-of-an-order
3487
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-get-information-of-order
3488
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-information-of-an-order
3489
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-information-of-an-order
3484
3490
  :param str symbol: unified symbol of the market the order was made in
3485
3491
  :param dict [params]: extra parameters specific to the exchange API endpoint
3486
3492
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -4081,7 +4087,7 @@ class htx(Exchange, ImplicitAPI):
4081
4087
  self.load_accounts()
4082
4088
  for i in range(0, len(self.accounts)):
4083
4089
  account = self.accounts[i]
4084
- if account['type'] == 'spot':
4090
+ if self.safe_string(account, 'type') == 'spot':
4085
4091
  accountId = self.safe_string(account, 'id')
4086
4092
  if accountId is not None:
4087
4093
  break
@@ -4736,7 +4742,7 @@ class htx(Exchange, ImplicitAPI):
4736
4742
  cost = self.safe_string(order, 'amount')
4737
4743
  else:
4738
4744
  amount = self.safe_string_2(order, 'volume', 'amount')
4739
- cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo
4745
+ cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
4740
4746
  filled = self.safe_string_n(order, ['filled-amount', 'field-amount', 'trade_volume']) # typo in their API, filled amount
4741
4747
  price = self.safe_string_2(order, 'price', 'order_price')
4742
4748
  feeCost = self.safe_string_2(order, 'filled-fees', 'field-fees') # typo in their API, filled feeSide