ccxt 4.2.93__py2.py3-none-any.whl → 4.2.95__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 (190) hide show
  1. ccxt/__init__.py +2 -2
  2. ccxt/abstract/binance.py +1 -0
  3. ccxt/abstract/binancecoinm.py +1 -0
  4. ccxt/abstract/binanceus.py +1 -0
  5. ccxt/abstract/binanceusdm.py +1 -0
  6. ccxt/abstract/bitstamp.py +6 -0
  7. ccxt/ace.py +1 -1
  8. ccxt/ascendex.py +1 -1
  9. ccxt/async_support/__init__.py +2 -2
  10. ccxt/async_support/ace.py +1 -1
  11. ccxt/async_support/ascendex.py +1 -1
  12. ccxt/async_support/base/exchange.py +7 -1
  13. ccxt/async_support/bigone.py +1 -1
  14. ccxt/async_support/binance.py +63 -5
  15. ccxt/async_support/bingx.py +1 -1
  16. ccxt/async_support/bit2c.py +1 -1
  17. ccxt/async_support/bitbank.py +1 -1
  18. ccxt/async_support/bitfinex.py +1 -1
  19. ccxt/async_support/bitfinex2.py +1 -1
  20. ccxt/async_support/bitget.py +136 -2
  21. ccxt/async_support/bithumb.py +1 -1
  22. ccxt/async_support/bitmart.py +1 -1
  23. ccxt/async_support/bitmex.py +1 -1
  24. ccxt/async_support/bitopro.py +1 -1
  25. ccxt/async_support/bitrue.py +1 -1
  26. ccxt/async_support/bitso.py +1 -1
  27. ccxt/async_support/bitstamp.py +7 -1
  28. ccxt/async_support/bitteam.py +1 -1
  29. ccxt/async_support/bitvavo.py +1 -1
  30. ccxt/async_support/blockchaincom.py +1 -1
  31. ccxt/async_support/blofin.py +1 -1
  32. ccxt/async_support/btcalpha.py +1 -1
  33. ccxt/async_support/btcbox.py +1 -1
  34. ccxt/async_support/bybit.py +2 -2
  35. ccxt/async_support/cex.py +1 -1
  36. ccxt/async_support/coinbase.py +1 -1
  37. ccxt/async_support/coinbaseinternational.py +1 -1
  38. ccxt/async_support/coinbasepro.py +1 -1
  39. ccxt/async_support/coincheck.py +1 -1
  40. ccxt/async_support/coinex.py +62 -56
  41. ccxt/async_support/coinlist.py +1 -1
  42. ccxt/async_support/coinmate.py +1 -1
  43. ccxt/async_support/coinsph.py +1 -1
  44. ccxt/async_support/cryptocom.py +1 -1
  45. ccxt/async_support/currencycom.py +1 -1
  46. ccxt/async_support/delta.py +1 -1
  47. ccxt/async_support/deribit.py +1 -1
  48. ccxt/async_support/digifinex.py +1 -1
  49. ccxt/async_support/exmo.py +1 -1
  50. ccxt/async_support/gate.py +1 -1
  51. ccxt/async_support/gemini.py +3 -2
  52. ccxt/async_support/hitbtc.py +1 -1
  53. ccxt/async_support/hollaex.py +1 -1
  54. ccxt/async_support/htx.py +117 -116
  55. ccxt/async_support/huobijp.py +1 -1
  56. ccxt/async_support/idex.py +1 -1
  57. ccxt/async_support/indodax.py +1 -1
  58. ccxt/async_support/kraken.py +1 -1
  59. ccxt/async_support/krakenfutures.py +2 -2
  60. ccxt/async_support/kucoin.py +1 -1
  61. ccxt/async_support/kucoinfutures.py +1 -1
  62. ccxt/async_support/latoken.py +1 -1
  63. ccxt/async_support/lbank.py +1 -1
  64. ccxt/async_support/mexc.py +1 -1
  65. ccxt/async_support/ndax.py +1 -1
  66. ccxt/async_support/novadax.py +1 -1
  67. ccxt/async_support/oceanex.py +1 -1
  68. ccxt/async_support/okcoin.py +1 -1
  69. ccxt/async_support/okx.py +191 -43
  70. ccxt/async_support/onetrading.py +1 -1
  71. ccxt/async_support/p2b.py +1 -1
  72. ccxt/async_support/phemex.py +1 -1
  73. ccxt/async_support/poloniex.py +1 -1
  74. ccxt/async_support/poloniexfutures.py +1 -1
  75. ccxt/async_support/probit.py +1 -1
  76. ccxt/async_support/timex.py +1 -1
  77. ccxt/async_support/tokocrypto.py +1 -1
  78. ccxt/async_support/tradeogre.py +1 -1
  79. ccxt/async_support/upbit.py +2 -2
  80. ccxt/async_support/wavesexchange.py +1 -1
  81. ccxt/async_support/whitebit.py +1 -1
  82. ccxt/async_support/woo.py +136 -2
  83. ccxt/async_support/yobit.py +1 -1
  84. ccxt/async_support/zonda.py +1 -1
  85. ccxt/base/errors.py +7 -7
  86. ccxt/base/exchange.py +18 -1
  87. ccxt/base/types.py +13 -0
  88. ccxt/bigone.py +1 -1
  89. ccxt/binance.py +63 -5
  90. ccxt/bingx.py +1 -1
  91. ccxt/bit2c.py +1 -1
  92. ccxt/bitbank.py +1 -1
  93. ccxt/bitfinex.py +1 -1
  94. ccxt/bitfinex2.py +1 -1
  95. ccxt/bitget.py +136 -2
  96. ccxt/bithumb.py +1 -1
  97. ccxt/bitmart.py +1 -1
  98. ccxt/bitmex.py +1 -1
  99. ccxt/bitopro.py +1 -1
  100. ccxt/bitrue.py +1 -1
  101. ccxt/bitso.py +1 -1
  102. ccxt/bitstamp.py +7 -1
  103. ccxt/bitteam.py +1 -1
  104. ccxt/bitvavo.py +1 -1
  105. ccxt/blockchaincom.py +1 -1
  106. ccxt/blofin.py +1 -1
  107. ccxt/btcalpha.py +1 -1
  108. ccxt/btcbox.py +1 -1
  109. ccxt/bybit.py +2 -2
  110. ccxt/cex.py +1 -1
  111. ccxt/coinbase.py +1 -1
  112. ccxt/coinbaseinternational.py +1 -1
  113. ccxt/coinbasepro.py +1 -1
  114. ccxt/coincheck.py +1 -1
  115. ccxt/coinex.py +62 -56
  116. ccxt/coinlist.py +1 -1
  117. ccxt/coinmate.py +1 -1
  118. ccxt/coinsph.py +1 -1
  119. ccxt/cryptocom.py +1 -1
  120. ccxt/currencycom.py +1 -1
  121. ccxt/delta.py +1 -1
  122. ccxt/deribit.py +1 -1
  123. ccxt/digifinex.py +1 -1
  124. ccxt/exmo.py +1 -1
  125. ccxt/gate.py +1 -1
  126. ccxt/gemini.py +3 -2
  127. ccxt/hitbtc.py +1 -1
  128. ccxt/hollaex.py +1 -1
  129. ccxt/htx.py +117 -116
  130. ccxt/huobijp.py +1 -1
  131. ccxt/idex.py +1 -1
  132. ccxt/indodax.py +1 -1
  133. ccxt/kraken.py +1 -1
  134. ccxt/krakenfutures.py +2 -2
  135. ccxt/kucoin.py +1 -1
  136. ccxt/kucoinfutures.py +1 -1
  137. ccxt/latoken.py +1 -1
  138. ccxt/lbank.py +1 -1
  139. ccxt/mexc.py +1 -1
  140. ccxt/ndax.py +1 -1
  141. ccxt/novadax.py +1 -1
  142. ccxt/oceanex.py +1 -1
  143. ccxt/okcoin.py +1 -1
  144. ccxt/okx.py +191 -43
  145. ccxt/onetrading.py +1 -1
  146. ccxt/p2b.py +1 -1
  147. ccxt/phemex.py +1 -1
  148. ccxt/poloniex.py +1 -1
  149. ccxt/poloniexfutures.py +1 -1
  150. ccxt/pro/__init__.py +1 -1
  151. ccxt/pro/ascendex.py +1 -1
  152. ccxt/pro/bitfinex2.py +1 -1
  153. ccxt/pro/bitget.py +1 -1
  154. ccxt/pro/bitmart.py +1 -1
  155. ccxt/pro/bitmex.py +1 -1
  156. ccxt/pro/bitstamp.py +1 -1
  157. ccxt/pro/bitvavo.py +1 -1
  158. ccxt/pro/blockchaincom.py +1 -1
  159. ccxt/pro/bybit.py +1 -1
  160. ccxt/pro/coinbase.py +12 -0
  161. ccxt/pro/coinbaseinternational.py +1 -1
  162. ccxt/pro/coinbasepro.py +1 -1
  163. ccxt/pro/coinex.py +1 -1
  164. ccxt/pro/cryptocom.py +1 -1
  165. ccxt/pro/gate.py +1 -1
  166. ccxt/pro/hitbtc.py +1 -1
  167. ccxt/pro/hollaex.py +1 -1
  168. ccxt/pro/htx.py +1 -1
  169. ccxt/pro/kraken.py +97 -19
  170. ccxt/pro/krakenfutures.py +105 -40
  171. ccxt/pro/kucoin.py +25 -16
  172. ccxt/pro/okcoin.py +1 -1
  173. ccxt/pro/okx.py +1 -1
  174. ccxt/pro/poloniex.py +1 -1
  175. ccxt/pro/poloniexfutures.py +1 -1
  176. ccxt/pro/whitebit.py +1 -1
  177. ccxt/probit.py +1 -1
  178. ccxt/timex.py +1 -1
  179. ccxt/tokocrypto.py +1 -1
  180. ccxt/tradeogre.py +1 -1
  181. ccxt/upbit.py +2 -2
  182. ccxt/wavesexchange.py +1 -1
  183. ccxt/whitebit.py +1 -1
  184. ccxt/woo.py +136 -2
  185. ccxt/yobit.py +1 -1
  186. ccxt/zonda.py +1 -1
  187. {ccxt-4.2.93.dist-info → ccxt-4.2.95.dist-info}/METADATA +4 -4
  188. {ccxt-4.2.93.dist-info → ccxt-4.2.95.dist-info}/RECORD +190 -190
  189. {ccxt-4.2.93.dist-info → ccxt-4.2.95.dist-info}/WHEEL +0 -0
  190. {ccxt-4.2.93.dist-info → ccxt-4.2.95.dist-info}/top_level.txt +0 -0
ccxt/okx.py CHANGED
@@ -6,9 +6,10 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
12
13
  from ccxt.base.errors import PermissionDenied
13
14
  from ccxt.base.errors import AccountNotEnabled
14
15
  from ccxt.base.errors import AccountSuspended
@@ -20,6 +21,7 @@ from ccxt.base.errors import InvalidAddress
20
21
  from ccxt.base.errors import InvalidOrder
21
22
  from ccxt.base.errors import OrderNotFound
22
23
  from ccxt.base.errors import CancelPending
24
+ from ccxt.base.errors import ContractUnavailable
23
25
  from ccxt.base.errors import NotSupported
24
26
  from ccxt.base.errors import NetworkError
25
27
  from ccxt.base.errors import RateLimitExceeded
@@ -27,8 +29,6 @@ from ccxt.base.errors import ExchangeNotAvailable
27
29
  from ccxt.base.errors import OnMaintenance
28
30
  from ccxt.base.errors import InvalidNonce
29
31
  from ccxt.base.errors import RequestTimeout
30
- from ccxt.base.errors import AuthenticationError
31
- from ccxt.base.errors import ContractUnavailable
32
32
  from ccxt.base.decimal_to_precision import TICK_SIZE
33
33
  from ccxt.base.precise import Precise
34
34
 
@@ -82,6 +82,8 @@ class okx(Exchange, ImplicitAPI):
82
82
  'fetchCanceledOrders': True,
83
83
  'fetchClosedOrder': None,
84
84
  'fetchClosedOrders': True,
85
+ 'fetchConvertCurrencies': True,
86
+ 'fetchConvertQuote': True,
85
87
  'fetchCrossBorrowRate': True,
86
88
  'fetchCrossBorrowRates': True,
87
89
  'fetchCurrencies': True,
@@ -1136,7 +1138,7 @@ class okx(Exchange, ImplicitAPI):
1136
1138
  return super(okx, self).handle_market_type_and_params(methodName, market, params)
1137
1139
 
1138
1140
  def convert_to_instrument_type(self, type):
1139
- exchangeTypes = self.safe_value(self.options, 'exchangeType', {})
1141
+ exchangeTypes = self.safe_dict(self.options, 'exchangeType', {})
1140
1142
  return self.safe_string(exchangeTypes, type, type)
1141
1143
 
1142
1144
  def create_expired_option_market(self, symbol: str):
@@ -2770,7 +2772,7 @@ class okx(Exchange, ImplicitAPI):
2770
2772
  side = self.safe_string(rawOrder, 'side')
2771
2773
  amount = self.safe_value(rawOrder, 'amount')
2772
2774
  price = self.safe_value(rawOrder, 'price')
2773
- orderParams = self.safe_value(rawOrder, 'params', {})
2775
+ orderParams = self.safe_dict(rawOrder, 'params', {})
2774
2776
  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
2775
2777
  orderRequest = self.create_order_request(marketId, type, side, amount, price, extendedParams)
2776
2778
  ordersRequests.append(orderRequest)
@@ -2932,8 +2934,8 @@ class okx(Exchange, ImplicitAPI):
2932
2934
  # "msg": ""
2933
2935
  # }
2934
2936
  #
2935
- data = self.safe_value(response, 'data', [])
2936
- first = self.safe_value(data, 0)
2937
+ data = self.safe_list(response, 'data', [])
2938
+ first = self.safe_dict(data, 0, {})
2937
2939
  order = self.parse_order(first, market)
2938
2940
  order['type'] = type
2939
2941
  order['side'] = side
@@ -4038,7 +4040,7 @@ class okx(Exchange, ImplicitAPI):
4038
4040
  paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
4039
4041
  if paginate:
4040
4042
  return self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
4041
- options = self.safe_value(self.options, 'fetchLedger', {})
4043
+ options = self.safe_dict(self.options, 'fetchLedger', {})
4042
4044
  method = self.safe_string(options, 'method')
4043
4045
  method = self.safe_string(params, 'method', method)
4044
4046
  params = self.omit(params, 'method')
@@ -4353,7 +4355,7 @@ class okx(Exchange, ImplicitAPI):
4353
4355
  # ]
4354
4356
  # }
4355
4357
  #
4356
- data = self.safe_value(response, 'data', [])
4358
+ data = self.safe_list(response, 'data', [])
4357
4359
  filtered = self.filter_by(data, 'selected', True)
4358
4360
  parsed = self.parse_deposit_addresses(filtered, [currency['code']], False)
4359
4361
  return self.index_by(parsed, 'network')
@@ -4416,7 +4418,7 @@ class okx(Exchange, ImplicitAPI):
4416
4418
  }
4417
4419
  network = self.safe_string(params, 'network') # self line allows the user to specify either ERC20 or ETH
4418
4420
  if network is not None:
4419
- networks = self.safe_value(self.options, 'networks', {})
4421
+ networks = self.safe_dict(self.options, 'networks', {})
4420
4422
  network = self.safe_string(networks, network.upper(), network) # handle ETH>ERC20 alias
4421
4423
  request['chain'] = currency['id'] + '-' + network
4422
4424
  params = self.omit(params, 'network')
@@ -4424,7 +4426,7 @@ class okx(Exchange, ImplicitAPI):
4424
4426
  if fee is None:
4425
4427
  currencies = self.fetch_currencies()
4426
4428
  self.currencies = self.deep_extend(self.currencies, currencies)
4427
- targetNetwork = self.safe_value(currency['networks'], self.network_id_to_code(network), {})
4429
+ targetNetwork = self.safe_dict(currency['networks'], self.network_id_to_code(network), {})
4428
4430
  fee = self.safe_string(targetNetwork, 'fee')
4429
4431
  if fee is None:
4430
4432
  raise ArgumentsRequired(self.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.')
@@ -4444,7 +4446,7 @@ class okx(Exchange, ImplicitAPI):
4444
4446
  # ]
4445
4447
  # }
4446
4448
  #
4447
- data = self.safe_value(response, 'data', [])
4449
+ data = self.safe_list(response, 'data', [])
4448
4450
  transaction = self.safe_dict(data, 0)
4449
4451
  return self.parse_transaction(transaction, currency)
4450
4452
 
@@ -4651,7 +4653,7 @@ class okx(Exchange, ImplicitAPI):
4651
4653
  # "msg": ''
4652
4654
  # }
4653
4655
  #
4654
- data = self.safe_value(response, 'data')
4656
+ data = self.safe_list(response, 'data', [])
4655
4657
  withdrawal = self.safe_dict(data, 0, {})
4656
4658
  return self.parse_transaction(withdrawal)
4657
4659
 
@@ -4923,8 +4925,8 @@ class okx(Exchange, ImplicitAPI):
4923
4925
  # ]
4924
4926
  # }
4925
4927
  #
4926
- data = self.safe_value(response, 'data', [])
4927
- position = self.safe_value(data, 0)
4928
+ data = self.safe_list(response, 'data', [])
4929
+ position = self.safe_dict(data, 0)
4928
4930
  if position is None:
4929
4931
  return None
4930
4932
  return self.parse_position(position, market)
@@ -4954,7 +4956,7 @@ class okx(Exchange, ImplicitAPI):
4954
4956
  marketIdsLength = len(marketIds)
4955
4957
  if marketIdsLength > 0:
4956
4958
  request['instId'] = ','.join(marketIds)
4957
- fetchPositionsOptions = self.safe_value(self.options, 'fetchPositions', {})
4959
+ fetchPositionsOptions = self.safe_dict(self.options, 'fetchPositions', {})
4958
4960
  method = self.safe_string(fetchPositionsOptions, 'method', 'privateGetAccountPositions')
4959
4961
  response = None
4960
4962
  if method == 'privateGetAccountPositionsHistory':
@@ -5007,7 +5009,7 @@ class okx(Exchange, ImplicitAPI):
5007
5009
  # ]
5008
5010
  # }
5009
5011
  #
5010
- positions = self.safe_value(response, 'data', [])
5012
+ positions = self.safe_list(response, 'data', [])
5011
5013
  result = []
5012
5014
  for i in range(0, len(positions)):
5013
5015
  result.append(self.parse_position(positions[i]))
@@ -5195,7 +5197,7 @@ class okx(Exchange, ImplicitAPI):
5195
5197
  """
5196
5198
  self.load_markets()
5197
5199
  currency = self.currency(code)
5198
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
5200
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
5199
5201
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
5200
5202
  toId = self.safe_string(accountsByType, toAccount, toAccount)
5201
5203
  request = {
@@ -5235,7 +5237,7 @@ class okx(Exchange, ImplicitAPI):
5235
5237
  # ]
5236
5238
  # }
5237
5239
  #
5238
- data = self.safe_value(response, 'data', [])
5240
+ data = self.safe_list(response, 'data', [])
5239
5241
  rawTransfer = self.safe_dict(data, 0, {})
5240
5242
  return self.parse_transfer(rawTransfer, currency)
5241
5243
 
@@ -5298,7 +5300,7 @@ class okx(Exchange, ImplicitAPI):
5298
5300
  amount = self.safe_number(transfer, 'amt')
5299
5301
  fromAccountId = self.safe_string(transfer, 'from')
5300
5302
  toAccountId = self.safe_string(transfer, 'to')
5301
- accountsById = self.safe_value(self.options, 'accountsById', {})
5303
+ accountsById = self.safe_dict(self.options, 'accountsById', {})
5302
5304
  timestamp = self.safe_integer(transfer, 'ts')
5303
5305
  balanceChange = self.safe_string(transfer, 'sz')
5304
5306
  if balanceChange is not None:
@@ -5348,7 +5350,7 @@ class okx(Exchange, ImplicitAPI):
5348
5350
  # "msg": ""
5349
5351
  # }
5350
5352
  #
5351
- data = self.safe_value(response, 'data', [])
5353
+ data = self.safe_list(response, 'data', [])
5352
5354
  transfer = self.safe_dict(data, 0)
5353
5355
  return self.parse_transfer(transfer)
5354
5356
 
@@ -5533,8 +5535,8 @@ class okx(Exchange, ImplicitAPI):
5533
5535
  # "msg": ""
5534
5536
  # }
5535
5537
  #
5536
- data = self.safe_value(response, 'data', [])
5537
- entry = self.safe_value(data, 0, {})
5538
+ data = self.safe_list(response, 'data', [])
5539
+ entry = self.safe_dict(data, 0, {})
5538
5540
  return self.parse_funding_rate(entry, market)
5539
5541
 
5540
5542
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -5666,7 +5668,7 @@ class okx(Exchange, ImplicitAPI):
5666
5668
  # "type": "8"
5667
5669
  # }
5668
5670
  #
5669
- data = self.safe_value(response, 'data', [])
5671
+ data = self.safe_list(response, 'data', [])
5670
5672
  result = []
5671
5673
  for i in range(0, len(data)):
5672
5674
  entry = data[i]
@@ -5837,7 +5839,7 @@ class okx(Exchange, ImplicitAPI):
5837
5839
  # ],
5838
5840
  # }
5839
5841
  #
5840
- data = self.safe_value(response, 'data', [])
5842
+ data = self.safe_list(response, 'data', [])
5841
5843
  rates = []
5842
5844
  for i in range(0, len(data)):
5843
5845
  rates.append(self.parse_borrow_rate(data[i]))
@@ -5870,8 +5872,8 @@ class okx(Exchange, ImplicitAPI):
5870
5872
  # "msg": ""
5871
5873
  # }
5872
5874
  #
5873
- data = self.safe_value(response, 'data')
5874
- rate = self.safe_value(data, 0)
5875
+ data = self.safe_list(response, 'data', [])
5876
+ rate = self.safe_dict(data, 0, {})
5875
5877
  return self.parse_borrow_rate(rate)
5876
5878
 
5877
5879
  def parse_borrow_rate(self, info, currency: Currency = None):
@@ -5966,7 +5968,7 @@ class okx(Exchange, ImplicitAPI):
5966
5968
  # "msg": ""
5967
5969
  # }
5968
5970
  #
5969
- data = self.safe_value(response, 'data')
5971
+ data = self.safe_list(response, 'data', [])
5970
5972
  return self.parse_borrow_rate_histories(data, codes, since, limit)
5971
5973
 
5972
5974
  def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
@@ -6006,7 +6008,7 @@ class okx(Exchange, ImplicitAPI):
6006
6008
  # "msg": ""
6007
6009
  # }
6008
6010
  #
6009
- data = self.safe_value(response, 'data')
6011
+ data = self.safe_list(response, 'data', [])
6010
6012
  return self.parse_borrow_rate_history(data, code, since, limit)
6011
6013
 
6012
6014
  def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
@@ -6186,7 +6188,7 @@ class okx(Exchange, ImplicitAPI):
6186
6188
  # ]
6187
6189
  # }
6188
6190
  #
6189
- data = self.safe_value(response, 'data')
6191
+ data = self.safe_list(response, 'data', [])
6190
6192
  return self.parse_market_leverage_tiers(data, market)
6191
6193
 
6192
6194
  def parse_market_leverage_tiers(self, info, market: Market = None):
@@ -6279,7 +6281,7 @@ class okx(Exchange, ImplicitAPI):
6279
6281
  # "msg": ""
6280
6282
  # }
6281
6283
  #
6282
- data = self.safe_value(response, 'data')
6284
+ data = self.safe_list(response, 'data', [])
6283
6285
  interest = self.parse_borrow_interests(data)
6284
6286
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6285
6287
 
@@ -6332,8 +6334,8 @@ class okx(Exchange, ImplicitAPI):
6332
6334
  # "msg": ""
6333
6335
  # }
6334
6336
  #
6335
- data = self.safe_value(response, 'data', [])
6336
- loan = self.safe_value(data, 0)
6337
+ data = self.safe_list(response, 'data', [])
6338
+ loan = self.safe_dict(data, 0, {})
6337
6339
  return self.parse_margin_loan(loan, currency)
6338
6340
 
6339
6341
  def repay_cross_margin(self, code: str, amount, params={}):
@@ -6374,8 +6376,8 @@ class okx(Exchange, ImplicitAPI):
6374
6376
  # "msg": ""
6375
6377
  # }
6376
6378
  #
6377
- data = self.safe_value(response, 'data', [])
6378
- loan = self.safe_value(data, 0)
6379
+ data = self.safe_list(response, 'data', [])
6380
+ loan = self.safe_dict(data, 0, {})
6379
6381
  return self.parse_margin_loan(loan, currency)
6380
6382
 
6381
6383
  def parse_margin_loan(self, info, currency: Currency = None):
@@ -6452,8 +6454,8 @@ class okx(Exchange, ImplicitAPI):
6452
6454
  :param int [params.until]: The time in ms of the latest record to retrieve unix timestamp
6453
6455
  :returns: An array of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
6454
6456
  """
6455
- options = self.safe_value(self.options, 'fetchOpenInterestHistory', {})
6456
- timeframes = self.safe_value(options, 'timeframes', {})
6457
+ options = self.safe_dict(self.options, 'fetchOpenInterestHistory', {})
6458
+ timeframes = self.safe_dict(options, 'timeframes', {})
6457
6459
  timeframe = self.safe_string(timeframes, timeframe, timeframe)
6458
6460
  if timeframe != '5m' and timeframe != '1H' and timeframe != '1D':
6459
6461
  raise BadRequest(self.id + ' fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe')
@@ -6718,7 +6720,7 @@ class okx(Exchange, ImplicitAPI):
6718
6720
  # "msg": ""
6719
6721
  # }
6720
6722
  #
6721
- data = self.safe_value(response, 'data', [])
6723
+ data = self.safe_list(response, 'data', [])
6722
6724
  settlements = self.parse_settlements(data, market)
6723
6725
  sorted = self.sort_by(settlements, 'timestamp')
6724
6726
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
@@ -6757,7 +6759,7 @@ class okx(Exchange, ImplicitAPI):
6757
6759
  for i in range(0, len(settlements)):
6758
6760
  entry = settlements[i]
6759
6761
  timestamp = self.safe_integer(entry, 'ts')
6760
- details = self.safe_value(entry, 'details', [])
6762
+ details = self.safe_list(entry, 'details', [])
6761
6763
  for j in range(0, len(details)):
6762
6764
  settlement = self.parse_settlement(details[j], market)
6763
6765
  result.append(self.extend(settlement, {
@@ -6797,7 +6799,7 @@ class okx(Exchange, ImplicitAPI):
6797
6799
  # "msg": ""
6798
6800
  # }
6799
6801
  #
6800
- underlyings = self.safe_value(response, 'data', [])
6802
+ underlyings = self.safe_list(response, 'data', [])
6801
6803
  return underlyings[0]
6802
6804
 
6803
6805
  def fetch_greeks(self, symbol: str, params={}) -> Greeks:
@@ -6847,7 +6849,7 @@ class okx(Exchange, ImplicitAPI):
6847
6849
  # "msg": ""
6848
6850
  # }
6849
6851
  #
6850
- data = self.safe_value(response, 'data', [])
6852
+ data = self.safe_list(response, 'data', [])
6851
6853
  for i in range(0, len(data)):
6852
6854
  entry = data[i]
6853
6855
  entryMarketId = self.safe_string(entry, 'instId')
@@ -6960,7 +6962,7 @@ class okx(Exchange, ImplicitAPI):
6960
6962
  # "outTime": "1701877077102579"
6961
6963
  # }
6962
6964
  #
6963
- data = self.safe_value(response, 'data')
6965
+ data = self.safe_list(response, 'data', [])
6964
6966
  order = self.safe_dict(data, 0)
6965
6967
  return self.parse_order(order, market)
6966
6968
 
@@ -7097,6 +7099,152 @@ class okx(Exchange, ImplicitAPI):
7097
7099
  'quoteVolume': None,
7098
7100
  }
7099
7101
 
7102
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7103
+ """
7104
+ fetch a quote for converting from one currency to another
7105
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
7106
+ :param str fromCode: the currency that you want to sell and convert from
7107
+ :param str toCode: the currency that you want to buy and convert into
7108
+ :param float [amount]: how much you want to trade in units of the from currency
7109
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7110
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
7111
+ """
7112
+ self.load_markets()
7113
+ request = {
7114
+ 'baseCcy': fromCode.upper(),
7115
+ 'quoteCcy': toCode.upper(),
7116
+ 'rfqSzCcy': fromCode.upper(),
7117
+ 'rfqSz': self.number_to_string(amount),
7118
+ 'side': 'sell',
7119
+ }
7120
+ response = self.privatePostAssetConvertEstimateQuote(self.extend(request, params))
7121
+ #
7122
+ # {
7123
+ # "code": "0",
7124
+ # "data": [
7125
+ # {
7126
+ # "baseCcy": "ETH",
7127
+ # "baseSz": "0.01023052",
7128
+ # "clQReqId": "",
7129
+ # "cnvtPx": "2932.40104429",
7130
+ # "origRfqSz": "30",
7131
+ # "quoteCcy": "USDT",
7132
+ # "quoteId": "quoterETH-USDT16461885104612381",
7133
+ # "quoteSz": "30",
7134
+ # "quoteTime": "1646188510461",
7135
+ # "rfqSz": "30",
7136
+ # "rfqSzCcy": "USDT",
7137
+ # "side": "buy",
7138
+ # "ttlMs": "10000"
7139
+ # }
7140
+ # ],
7141
+ # "msg": ""
7142
+ # }
7143
+ #
7144
+ data = self.safe_list(response, 'data', [])
7145
+ result = self.safe_dict(data, 0, {})
7146
+ fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
7147
+ fromCurrency = self.currency(fromCurrencyId)
7148
+ toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
7149
+ toCurrency = self.currency(toCurrencyId)
7150
+ return self.parse_conversion(result, fromCurrency, toCurrency)
7151
+
7152
+ def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
7153
+ #
7154
+ # fetchConvertQuote
7155
+ #
7156
+ # {
7157
+ # "baseCcy": "ETH",
7158
+ # "baseSz": "0.01023052",
7159
+ # "clQReqId": "",
7160
+ # "cnvtPx": "2932.40104429",
7161
+ # "origRfqSz": "30",
7162
+ # "quoteCcy": "USDT",
7163
+ # "quoteId": "quoterETH-USDT16461885104612381",
7164
+ # "quoteSz": "30",
7165
+ # "quoteTime": "1646188510461",
7166
+ # "rfqSz": "30",
7167
+ # "rfqSzCcy": "USDT",
7168
+ # "side": "buy",
7169
+ # "ttlMs": "10000"
7170
+ # }
7171
+ #
7172
+ timestamp = self.safe_integer(conversion, 'quoteTime')
7173
+ fromCoin = self.safe_string(conversion, 'baseCcy')
7174
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
7175
+ to = self.safe_string(conversion, 'quoteCcy')
7176
+ toCode = self.safe_currency_code(to, toCurrency)
7177
+ return {
7178
+ 'info': conversion,
7179
+ 'timestamp': timestamp,
7180
+ 'datetime': self.iso8601(timestamp),
7181
+ 'id': self.safe_string(conversion, 'clQReqId'),
7182
+ 'fromCurrency': fromCode,
7183
+ 'fromAmount': self.safe_number(conversion, 'baseSz'),
7184
+ 'toCurrency': toCode,
7185
+ 'toAmount': self.safe_number(conversion, 'quoteSz'),
7186
+ 'price': self.safe_number(conversion, 'cnvtPx'),
7187
+ 'fee': None,
7188
+ }
7189
+
7190
+ def fetch_convert_currencies(self, params={}) -> Currencies:
7191
+ """
7192
+ fetches all available currencies that can be converted
7193
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
7194
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7195
+ :returns dict: an associative dictionary of currencies
7196
+ """
7197
+ self.load_markets()
7198
+ response = self.privateGetAssetConvertCurrencies(params)
7199
+ #
7200
+ # {
7201
+ # "code": "0",
7202
+ # "data": [
7203
+ # {
7204
+ # "ccy": "BTC",
7205
+ # "max": "",
7206
+ # "min": ""
7207
+ # },
7208
+ # ],
7209
+ # "msg": ""
7210
+ # }
7211
+ #
7212
+ result = {}
7213
+ data = self.safe_list(response, 'data', [])
7214
+ for i in range(0, len(data)):
7215
+ entry = data[i]
7216
+ id = self.safe_string(entry, 'ccy')
7217
+ code = self.safe_currency_code(id)
7218
+ result[code] = {
7219
+ 'info': entry,
7220
+ 'id': id,
7221
+ 'code': code,
7222
+ 'networks': None,
7223
+ 'type': None,
7224
+ 'name': None,
7225
+ 'active': None,
7226
+ 'deposit': None,
7227
+ 'withdraw': None,
7228
+ 'fee': None,
7229
+ 'precision': None,
7230
+ 'limits': {
7231
+ 'amount': {
7232
+ 'min': self.safe_number(entry, 'min'),
7233
+ 'max': self.safe_number(entry, 'max'),
7234
+ },
7235
+ 'withdraw': {
7236
+ 'min': None,
7237
+ 'max': None,
7238
+ },
7239
+ 'deposit': {
7240
+ 'min': None,
7241
+ 'max': None,
7242
+ },
7243
+ },
7244
+ 'created': None,
7245
+ }
7246
+ return result
7247
+
7100
7248
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
7101
7249
  if not response:
7102
7250
  return None # fallback to default error handler
@@ -7123,7 +7271,7 @@ class okx(Exchange, ImplicitAPI):
7123
7271
  code = self.safe_string(response, 'code')
7124
7272
  if (code != '0') and (code != '2'): # 2 means that bulk operation partially succeeded
7125
7273
  feedback = self.id + ' ' + body
7126
- data = self.safe_value(response, 'data', [])
7274
+ data = self.safe_list(response, 'data', [])
7127
7275
  for i in range(0, len(data)):
7128
7276
  error = data[i]
7129
7277
  errorCode = self.safe_string(error, 'sCode')
ccxt/onetrading.py CHANGED
@@ -8,6 +8,7 @@ from ccxt.abstract.onetrading import ImplicitAPI
8
8
  from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
+ from ccxt.base.errors import AuthenticationError
11
12
  from ccxt.base.errors import PermissionDenied
12
13
  from ccxt.base.errors import ArgumentsRequired
13
14
  from ccxt.base.errors import BadRequest
@@ -17,7 +18,6 @@ from ccxt.base.errors import InvalidOrder
17
18
  from ccxt.base.errors import OrderNotFound
18
19
  from ccxt.base.errors import DDoSProtection
19
20
  from ccxt.base.errors import ExchangeNotAvailable
20
- from ccxt.base.errors import AuthenticationError
21
21
  from ccxt.base.decimal_to_precision import TICK_SIZE
22
22
  from ccxt.base.precise import Precise
23
23
 
ccxt/p2b.py CHANGED
@@ -8,11 +8,11 @@ from ccxt.abstract.p2b import ImplicitAPI
8
8
  import hashlib
9
9
  from ccxt.base.types import Int, Market, Num, Order, OrderSide, OrderType, Str, Strings, Ticker, Tickers
10
10
  from typing import List
11
+ from ccxt.base.errors import AuthenticationError
11
12
  from ccxt.base.errors import ArgumentsRequired
12
13
  from ccxt.base.errors import BadRequest
13
14
  from ccxt.base.errors import InsufficientFunds
14
15
  from ccxt.base.errors import ExchangeNotAvailable
15
- from ccxt.base.errors import AuthenticationError
16
16
  from ccxt.base.decimal_to_precision import TICK_SIZE
17
17
 
18
18
 
ccxt/phemex.py CHANGED
@@ -10,6 +10,7 @@ import numbers
10
10
  from ccxt.base.types import Balances, Currencies, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
13
14
  from ccxt.base.errors import PermissionDenied
14
15
  from ccxt.base.errors import AccountSuspended
15
16
  from ccxt.base.errors import ArgumentsRequired
@@ -23,7 +24,6 @@ from ccxt.base.errors import DuplicateOrderId
23
24
  from ccxt.base.errors import NotSupported
24
25
  from ccxt.base.errors import DDoSProtection
25
26
  from ccxt.base.errors import RateLimitExceeded
26
- from ccxt.base.errors import AuthenticationError
27
27
  from ccxt.base.decimal_to_precision import TICK_SIZE
28
28
  from ccxt.base.precise import Precise
29
29
 
ccxt/poloniex.py CHANGED
@@ -9,6 +9,7 @@ import hashlib
9
9
  from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
12
13
  from ccxt.base.errors import PermissionDenied
13
14
  from ccxt.base.errors import AccountSuspended
14
15
  from ccxt.base.errors import ArgumentsRequired
@@ -21,7 +22,6 @@ from ccxt.base.errors import NotSupported
21
22
  from ccxt.base.errors import ExchangeNotAvailable
22
23
  from ccxt.base.errors import OnMaintenance
23
24
  from ccxt.base.errors import RequestTimeout
24
- from ccxt.base.errors import AuthenticationError
25
25
  from ccxt.base.decimal_to_precision import TICK_SIZE
26
26
  from ccxt.base.precise import Precise
27
27
 
ccxt/poloniexfutures.py CHANGED
@@ -8,6 +8,7 @@ from ccxt.abstract.poloniexfutures import ImplicitAPI
8
8
  import hashlib
9
9
  from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
10
10
  from typing import List
11
+ from ccxt.base.errors import AuthenticationError
11
12
  from ccxt.base.errors import AccountSuspended
12
13
  from ccxt.base.errors import ArgumentsRequired
13
14
  from ccxt.base.errors import BadRequest
@@ -17,7 +18,6 @@ from ccxt.base.errors import NotSupported
17
18
  from ccxt.base.errors import RateLimitExceeded
18
19
  from ccxt.base.errors import ExchangeNotAvailable
19
20
  from ccxt.base.errors import InvalidNonce
20
- from ccxt.base.errors import AuthenticationError
21
21
  from ccxt.base.decimal_to_precision import TICK_SIZE
22
22
  from ccxt.base.precise import Precise
23
23
 
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.93'
7
+ __version__ = '4.2.95'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/ascendex.py CHANGED
@@ -9,8 +9,8 @@ import hashlib
9
9
  from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
- from ccxt.base.errors import NetworkError
13
12
  from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import NetworkError
14
14
 
15
15
 
16
16
  class ascendex(ccxt.async_support.ascendex):
ccxt/pro/bitfinex2.py CHANGED
@@ -10,8 +10,8 @@ from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import InvalidNonce
14
13
  from ccxt.base.errors import AuthenticationError
14
+ from ccxt.base.errors import InvalidNonce
15
15
  from ccxt.base.precise import Precise
16
16
 
17
17
 
ccxt/pro/bitget.py CHANGED
@@ -10,12 +10,12 @@ from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Stri
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
13
14
  from ccxt.base.errors import ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
15
16
  from ccxt.base.errors import NotSupported
16
17
  from ccxt.base.errors import RateLimitExceeded
17
18
  from ccxt.base.errors import InvalidNonce
18
- from ccxt.base.errors import AuthenticationError
19
19
  from ccxt.base.precise import Precise
20
20
 
21
21
 
ccxt/pro/bitmart.py CHANGED
@@ -11,9 +11,9 @@ from ccxt.base.types import Balances, Int, Market, Order, OrderBook, Position, S
11
11
  from ccxt.async_support.base.ws.client import Client
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
+ from ccxt.base.errors import AuthenticationError
14
15
  from ccxt.base.errors import ArgumentsRequired
15
16
  from ccxt.base.errors import NotSupported
16
- from ccxt.base.errors import AuthenticationError
17
17
 
18
18
 
19
19
  class bitmart(ccxt.async_support.bitmart):
ccxt/pro/bitmex.py CHANGED
@@ -10,8 +10,8 @@ from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Stri
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import RateLimitExceeded
14
13
  from ccxt.base.errors import AuthenticationError
14
+ from ccxt.base.errors import RateLimitExceeded
15
15
 
16
16
 
17
17
  class bitmex(ccxt.async_support.bitmex):
ccxt/pro/bitstamp.py CHANGED
@@ -8,8 +8,8 @@ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
8
8
  from ccxt.base.types import Int, Order, OrderBook, Str, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
- from ccxt.base.errors import ArgumentsRequired
12
11
  from ccxt.base.errors import AuthenticationError
12
+ from ccxt.base.errors import ArgumentsRequired
13
13
 
14
14
 
15
15
  class bitstamp(ccxt.async_support.bitstamp):
ccxt/pro/bitvavo.py CHANGED
@@ -10,8 +10,8 @@ from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, Ord
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import ArgumentsRequired
14
13
  from ccxt.base.errors import AuthenticationError
14
+ from ccxt.base.errors import ArgumentsRequired
15
15
 
16
16
 
17
17
  class bitvavo(ccxt.async_support.bitvavo):