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/async_support/okx.py CHANGED
@@ -7,9 +7,10 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- 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
10
+ 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
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 AccountNotEnabled
15
16
  from ccxt.base.errors import AccountSuspended
@@ -21,6 +22,7 @@ from ccxt.base.errors import InvalidAddress
21
22
  from ccxt.base.errors import InvalidOrder
22
23
  from ccxt.base.errors import OrderNotFound
23
24
  from ccxt.base.errors import CancelPending
25
+ from ccxt.base.errors import ContractUnavailable
24
26
  from ccxt.base.errors import NotSupported
25
27
  from ccxt.base.errors import NetworkError
26
28
  from ccxt.base.errors import RateLimitExceeded
@@ -28,8 +30,6 @@ from ccxt.base.errors import ExchangeNotAvailable
28
30
  from ccxt.base.errors import OnMaintenance
29
31
  from ccxt.base.errors import InvalidNonce
30
32
  from ccxt.base.errors import RequestTimeout
31
- from ccxt.base.errors import AuthenticationError
32
- from ccxt.base.errors import ContractUnavailable
33
33
  from ccxt.base.decimal_to_precision import TICK_SIZE
34
34
  from ccxt.base.precise import Precise
35
35
 
@@ -83,6 +83,8 @@ class okx(Exchange, ImplicitAPI):
83
83
  'fetchCanceledOrders': True,
84
84
  'fetchClosedOrder': None,
85
85
  'fetchClosedOrders': True,
86
+ 'fetchConvertCurrencies': True,
87
+ 'fetchConvertQuote': True,
86
88
  'fetchCrossBorrowRate': True,
87
89
  'fetchCrossBorrowRates': True,
88
90
  'fetchCurrencies': True,
@@ -1137,7 +1139,7 @@ class okx(Exchange, ImplicitAPI):
1137
1139
  return super(okx, self).handle_market_type_and_params(methodName, market, params)
1138
1140
 
1139
1141
  def convert_to_instrument_type(self, type):
1140
- exchangeTypes = self.safe_value(self.options, 'exchangeType', {})
1142
+ exchangeTypes = self.safe_dict(self.options, 'exchangeType', {})
1141
1143
  return self.safe_string(exchangeTypes, type, type)
1142
1144
 
1143
1145
  def create_expired_option_market(self, symbol: str):
@@ -2771,7 +2773,7 @@ class okx(Exchange, ImplicitAPI):
2771
2773
  side = self.safe_string(rawOrder, 'side')
2772
2774
  amount = self.safe_value(rawOrder, 'amount')
2773
2775
  price = self.safe_value(rawOrder, 'price')
2774
- orderParams = self.safe_value(rawOrder, 'params', {})
2776
+ orderParams = self.safe_dict(rawOrder, 'params', {})
2775
2777
  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
2776
2778
  orderRequest = self.create_order_request(marketId, type, side, amount, price, extendedParams)
2777
2779
  ordersRequests.append(orderRequest)
@@ -2933,8 +2935,8 @@ class okx(Exchange, ImplicitAPI):
2933
2935
  # "msg": ""
2934
2936
  # }
2935
2937
  #
2936
- data = self.safe_value(response, 'data', [])
2937
- first = self.safe_value(data, 0)
2938
+ data = self.safe_list(response, 'data', [])
2939
+ first = self.safe_dict(data, 0, {})
2938
2940
  order = self.parse_order(first, market)
2939
2941
  order['type'] = type
2940
2942
  order['side'] = side
@@ -4039,7 +4041,7 @@ class okx(Exchange, ImplicitAPI):
4039
4041
  paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
4040
4042
  if paginate:
4041
4043
  return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
4042
- options = self.safe_value(self.options, 'fetchLedger', {})
4044
+ options = self.safe_dict(self.options, 'fetchLedger', {})
4043
4045
  method = self.safe_string(options, 'method')
4044
4046
  method = self.safe_string(params, 'method', method)
4045
4047
  params = self.omit(params, 'method')
@@ -4354,7 +4356,7 @@ class okx(Exchange, ImplicitAPI):
4354
4356
  # ]
4355
4357
  # }
4356
4358
  #
4357
- data = self.safe_value(response, 'data', [])
4359
+ data = self.safe_list(response, 'data', [])
4358
4360
  filtered = self.filter_by(data, 'selected', True)
4359
4361
  parsed = self.parse_deposit_addresses(filtered, [currency['code']], False)
4360
4362
  return self.index_by(parsed, 'network')
@@ -4417,7 +4419,7 @@ class okx(Exchange, ImplicitAPI):
4417
4419
  }
4418
4420
  network = self.safe_string(params, 'network') # self line allows the user to specify either ERC20 or ETH
4419
4421
  if network is not None:
4420
- networks = self.safe_value(self.options, 'networks', {})
4422
+ networks = self.safe_dict(self.options, 'networks', {})
4421
4423
  network = self.safe_string(networks, network.upper(), network) # handle ETH>ERC20 alias
4422
4424
  request['chain'] = currency['id'] + '-' + network
4423
4425
  params = self.omit(params, 'network')
@@ -4425,7 +4427,7 @@ class okx(Exchange, ImplicitAPI):
4425
4427
  if fee is None:
4426
4428
  currencies = await self.fetch_currencies()
4427
4429
  self.currencies = self.deep_extend(self.currencies, currencies)
4428
- targetNetwork = self.safe_value(currency['networks'], self.network_id_to_code(network), {})
4430
+ targetNetwork = self.safe_dict(currency['networks'], self.network_id_to_code(network), {})
4429
4431
  fee = self.safe_string(targetNetwork, 'fee')
4430
4432
  if fee is None:
4431
4433
  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.')
@@ -4445,7 +4447,7 @@ class okx(Exchange, ImplicitAPI):
4445
4447
  # ]
4446
4448
  # }
4447
4449
  #
4448
- data = self.safe_value(response, 'data', [])
4450
+ data = self.safe_list(response, 'data', [])
4449
4451
  transaction = self.safe_dict(data, 0)
4450
4452
  return self.parse_transaction(transaction, currency)
4451
4453
 
@@ -4652,7 +4654,7 @@ class okx(Exchange, ImplicitAPI):
4652
4654
  # "msg": ''
4653
4655
  # }
4654
4656
  #
4655
- data = self.safe_value(response, 'data')
4657
+ data = self.safe_list(response, 'data', [])
4656
4658
  withdrawal = self.safe_dict(data, 0, {})
4657
4659
  return self.parse_transaction(withdrawal)
4658
4660
 
@@ -4924,8 +4926,8 @@ class okx(Exchange, ImplicitAPI):
4924
4926
  # ]
4925
4927
  # }
4926
4928
  #
4927
- data = self.safe_value(response, 'data', [])
4928
- position = self.safe_value(data, 0)
4929
+ data = self.safe_list(response, 'data', [])
4930
+ position = self.safe_dict(data, 0)
4929
4931
  if position is None:
4930
4932
  return None
4931
4933
  return self.parse_position(position, market)
@@ -4955,7 +4957,7 @@ class okx(Exchange, ImplicitAPI):
4955
4957
  marketIdsLength = len(marketIds)
4956
4958
  if marketIdsLength > 0:
4957
4959
  request['instId'] = ','.join(marketIds)
4958
- fetchPositionsOptions = self.safe_value(self.options, 'fetchPositions', {})
4960
+ fetchPositionsOptions = self.safe_dict(self.options, 'fetchPositions', {})
4959
4961
  method = self.safe_string(fetchPositionsOptions, 'method', 'privateGetAccountPositions')
4960
4962
  response = None
4961
4963
  if method == 'privateGetAccountPositionsHistory':
@@ -5008,7 +5010,7 @@ class okx(Exchange, ImplicitAPI):
5008
5010
  # ]
5009
5011
  # }
5010
5012
  #
5011
- positions = self.safe_value(response, 'data', [])
5013
+ positions = self.safe_list(response, 'data', [])
5012
5014
  result = []
5013
5015
  for i in range(0, len(positions)):
5014
5016
  result.append(self.parse_position(positions[i]))
@@ -5196,7 +5198,7 @@ class okx(Exchange, ImplicitAPI):
5196
5198
  """
5197
5199
  await self.load_markets()
5198
5200
  currency = self.currency(code)
5199
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
5201
+ accountsByType = self.safe_dict(self.options, 'accountsByType', {})
5200
5202
  fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
5201
5203
  toId = self.safe_string(accountsByType, toAccount, toAccount)
5202
5204
  request = {
@@ -5236,7 +5238,7 @@ class okx(Exchange, ImplicitAPI):
5236
5238
  # ]
5237
5239
  # }
5238
5240
  #
5239
- data = self.safe_value(response, 'data', [])
5241
+ data = self.safe_list(response, 'data', [])
5240
5242
  rawTransfer = self.safe_dict(data, 0, {})
5241
5243
  return self.parse_transfer(rawTransfer, currency)
5242
5244
 
@@ -5299,7 +5301,7 @@ class okx(Exchange, ImplicitAPI):
5299
5301
  amount = self.safe_number(transfer, 'amt')
5300
5302
  fromAccountId = self.safe_string(transfer, 'from')
5301
5303
  toAccountId = self.safe_string(transfer, 'to')
5302
- accountsById = self.safe_value(self.options, 'accountsById', {})
5304
+ accountsById = self.safe_dict(self.options, 'accountsById', {})
5303
5305
  timestamp = self.safe_integer(transfer, 'ts')
5304
5306
  balanceChange = self.safe_string(transfer, 'sz')
5305
5307
  if balanceChange is not None:
@@ -5349,7 +5351,7 @@ class okx(Exchange, ImplicitAPI):
5349
5351
  # "msg": ""
5350
5352
  # }
5351
5353
  #
5352
- data = self.safe_value(response, 'data', [])
5354
+ data = self.safe_list(response, 'data', [])
5353
5355
  transfer = self.safe_dict(data, 0)
5354
5356
  return self.parse_transfer(transfer)
5355
5357
 
@@ -5534,8 +5536,8 @@ class okx(Exchange, ImplicitAPI):
5534
5536
  # "msg": ""
5535
5537
  # }
5536
5538
  #
5537
- data = self.safe_value(response, 'data', [])
5538
- entry = self.safe_value(data, 0, {})
5539
+ data = self.safe_list(response, 'data', [])
5540
+ entry = self.safe_dict(data, 0, {})
5539
5541
  return self.parse_funding_rate(entry, market)
5540
5542
 
5541
5543
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -5667,7 +5669,7 @@ class okx(Exchange, ImplicitAPI):
5667
5669
  # "type": "8"
5668
5670
  # }
5669
5671
  #
5670
- data = self.safe_value(response, 'data', [])
5672
+ data = self.safe_list(response, 'data', [])
5671
5673
  result = []
5672
5674
  for i in range(0, len(data)):
5673
5675
  entry = data[i]
@@ -5838,7 +5840,7 @@ class okx(Exchange, ImplicitAPI):
5838
5840
  # ],
5839
5841
  # }
5840
5842
  #
5841
- data = self.safe_value(response, 'data', [])
5843
+ data = self.safe_list(response, 'data', [])
5842
5844
  rates = []
5843
5845
  for i in range(0, len(data)):
5844
5846
  rates.append(self.parse_borrow_rate(data[i]))
@@ -5871,8 +5873,8 @@ class okx(Exchange, ImplicitAPI):
5871
5873
  # "msg": ""
5872
5874
  # }
5873
5875
  #
5874
- data = self.safe_value(response, 'data')
5875
- rate = self.safe_value(data, 0)
5876
+ data = self.safe_list(response, 'data', [])
5877
+ rate = self.safe_dict(data, 0, {})
5876
5878
  return self.parse_borrow_rate(rate)
5877
5879
 
5878
5880
  def parse_borrow_rate(self, info, currency: Currency = None):
@@ -5967,7 +5969,7 @@ class okx(Exchange, ImplicitAPI):
5967
5969
  # "msg": ""
5968
5970
  # }
5969
5971
  #
5970
- data = self.safe_value(response, 'data')
5972
+ data = self.safe_list(response, 'data', [])
5971
5973
  return self.parse_borrow_rate_histories(data, codes, since, limit)
5972
5974
 
5973
5975
  async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
@@ -6007,7 +6009,7 @@ class okx(Exchange, ImplicitAPI):
6007
6009
  # "msg": ""
6008
6010
  # }
6009
6011
  #
6010
- data = self.safe_value(response, 'data')
6012
+ data = self.safe_list(response, 'data', [])
6011
6013
  return self.parse_borrow_rate_history(data, code, since, limit)
6012
6014
 
6013
6015
  async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
@@ -6187,7 +6189,7 @@ class okx(Exchange, ImplicitAPI):
6187
6189
  # ]
6188
6190
  # }
6189
6191
  #
6190
- data = self.safe_value(response, 'data')
6192
+ data = self.safe_list(response, 'data', [])
6191
6193
  return self.parse_market_leverage_tiers(data, market)
6192
6194
 
6193
6195
  def parse_market_leverage_tiers(self, info, market: Market = None):
@@ -6280,7 +6282,7 @@ class okx(Exchange, ImplicitAPI):
6280
6282
  # "msg": ""
6281
6283
  # }
6282
6284
  #
6283
- data = self.safe_value(response, 'data')
6285
+ data = self.safe_list(response, 'data', [])
6284
6286
  interest = self.parse_borrow_interests(data)
6285
6287
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6286
6288
 
@@ -6333,8 +6335,8 @@ class okx(Exchange, ImplicitAPI):
6333
6335
  # "msg": ""
6334
6336
  # }
6335
6337
  #
6336
- data = self.safe_value(response, 'data', [])
6337
- loan = self.safe_value(data, 0)
6338
+ data = self.safe_list(response, 'data', [])
6339
+ loan = self.safe_dict(data, 0, {})
6338
6340
  return self.parse_margin_loan(loan, currency)
6339
6341
 
6340
6342
  async def repay_cross_margin(self, code: str, amount, params={}):
@@ -6375,8 +6377,8 @@ class okx(Exchange, ImplicitAPI):
6375
6377
  # "msg": ""
6376
6378
  # }
6377
6379
  #
6378
- data = self.safe_value(response, 'data', [])
6379
- loan = self.safe_value(data, 0)
6380
+ data = self.safe_list(response, 'data', [])
6381
+ loan = self.safe_dict(data, 0, {})
6380
6382
  return self.parse_margin_loan(loan, currency)
6381
6383
 
6382
6384
  def parse_margin_loan(self, info, currency: Currency = None):
@@ -6453,8 +6455,8 @@ class okx(Exchange, ImplicitAPI):
6453
6455
  :param int [params.until]: The time in ms of the latest record to retrieve unix timestamp
6454
6456
  :returns: An array of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
6455
6457
  """
6456
- options = self.safe_value(self.options, 'fetchOpenInterestHistory', {})
6457
- timeframes = self.safe_value(options, 'timeframes', {})
6458
+ options = self.safe_dict(self.options, 'fetchOpenInterestHistory', {})
6459
+ timeframes = self.safe_dict(options, 'timeframes', {})
6458
6460
  timeframe = self.safe_string(timeframes, timeframe, timeframe)
6459
6461
  if timeframe != '5m' and timeframe != '1H' and timeframe != '1D':
6460
6462
  raise BadRequest(self.id + ' fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe')
@@ -6719,7 +6721,7 @@ class okx(Exchange, ImplicitAPI):
6719
6721
  # "msg": ""
6720
6722
  # }
6721
6723
  #
6722
- data = self.safe_value(response, 'data', [])
6724
+ data = self.safe_list(response, 'data', [])
6723
6725
  settlements = self.parse_settlements(data, market)
6724
6726
  sorted = self.sort_by(settlements, 'timestamp')
6725
6727
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
@@ -6758,7 +6760,7 @@ class okx(Exchange, ImplicitAPI):
6758
6760
  for i in range(0, len(settlements)):
6759
6761
  entry = settlements[i]
6760
6762
  timestamp = self.safe_integer(entry, 'ts')
6761
- details = self.safe_value(entry, 'details', [])
6763
+ details = self.safe_list(entry, 'details', [])
6762
6764
  for j in range(0, len(details)):
6763
6765
  settlement = self.parse_settlement(details[j], market)
6764
6766
  result.append(self.extend(settlement, {
@@ -6798,7 +6800,7 @@ class okx(Exchange, ImplicitAPI):
6798
6800
  # "msg": ""
6799
6801
  # }
6800
6802
  #
6801
- underlyings = self.safe_value(response, 'data', [])
6803
+ underlyings = self.safe_list(response, 'data', [])
6802
6804
  return underlyings[0]
6803
6805
 
6804
6806
  async def fetch_greeks(self, symbol: str, params={}) -> Greeks:
@@ -6848,7 +6850,7 @@ class okx(Exchange, ImplicitAPI):
6848
6850
  # "msg": ""
6849
6851
  # }
6850
6852
  #
6851
- data = self.safe_value(response, 'data', [])
6853
+ data = self.safe_list(response, 'data', [])
6852
6854
  for i in range(0, len(data)):
6853
6855
  entry = data[i]
6854
6856
  entryMarketId = self.safe_string(entry, 'instId')
@@ -6961,7 +6963,7 @@ class okx(Exchange, ImplicitAPI):
6961
6963
  # "outTime": "1701877077102579"
6962
6964
  # }
6963
6965
  #
6964
- data = self.safe_value(response, 'data')
6966
+ data = self.safe_list(response, 'data', [])
6965
6967
  order = self.safe_dict(data, 0)
6966
6968
  return self.parse_order(order, market)
6967
6969
 
@@ -7098,6 +7100,152 @@ class okx(Exchange, ImplicitAPI):
7098
7100
  'quoteVolume': None,
7099
7101
  }
7100
7102
 
7103
+ async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7104
+ """
7105
+ fetch a quote for converting from one currency to another
7106
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
7107
+ :param str fromCode: the currency that you want to sell and convert from
7108
+ :param str toCode: the currency that you want to buy and convert into
7109
+ :param float [amount]: how much you want to trade in units of the from currency
7110
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7111
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
7112
+ """
7113
+ await self.load_markets()
7114
+ request = {
7115
+ 'baseCcy': fromCode.upper(),
7116
+ 'quoteCcy': toCode.upper(),
7117
+ 'rfqSzCcy': fromCode.upper(),
7118
+ 'rfqSz': self.number_to_string(amount),
7119
+ 'side': 'sell',
7120
+ }
7121
+ response = await self.privatePostAssetConvertEstimateQuote(self.extend(request, params))
7122
+ #
7123
+ # {
7124
+ # "code": "0",
7125
+ # "data": [
7126
+ # {
7127
+ # "baseCcy": "ETH",
7128
+ # "baseSz": "0.01023052",
7129
+ # "clQReqId": "",
7130
+ # "cnvtPx": "2932.40104429",
7131
+ # "origRfqSz": "30",
7132
+ # "quoteCcy": "USDT",
7133
+ # "quoteId": "quoterETH-USDT16461885104612381",
7134
+ # "quoteSz": "30",
7135
+ # "quoteTime": "1646188510461",
7136
+ # "rfqSz": "30",
7137
+ # "rfqSzCcy": "USDT",
7138
+ # "side": "buy",
7139
+ # "ttlMs": "10000"
7140
+ # }
7141
+ # ],
7142
+ # "msg": ""
7143
+ # }
7144
+ #
7145
+ data = self.safe_list(response, 'data', [])
7146
+ result = self.safe_dict(data, 0, {})
7147
+ fromCurrencyId = self.safe_string(result, 'baseCcy', fromCode)
7148
+ fromCurrency = self.currency(fromCurrencyId)
7149
+ toCurrencyId = self.safe_string(result, 'quoteCcy', toCode)
7150
+ toCurrency = self.currency(toCurrencyId)
7151
+ return self.parse_conversion(result, fromCurrency, toCurrency)
7152
+
7153
+ def parse_conversion(self, conversion, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
7154
+ #
7155
+ # fetchConvertQuote
7156
+ #
7157
+ # {
7158
+ # "baseCcy": "ETH",
7159
+ # "baseSz": "0.01023052",
7160
+ # "clQReqId": "",
7161
+ # "cnvtPx": "2932.40104429",
7162
+ # "origRfqSz": "30",
7163
+ # "quoteCcy": "USDT",
7164
+ # "quoteId": "quoterETH-USDT16461885104612381",
7165
+ # "quoteSz": "30",
7166
+ # "quoteTime": "1646188510461",
7167
+ # "rfqSz": "30",
7168
+ # "rfqSzCcy": "USDT",
7169
+ # "side": "buy",
7170
+ # "ttlMs": "10000"
7171
+ # }
7172
+ #
7173
+ timestamp = self.safe_integer(conversion, 'quoteTime')
7174
+ fromCoin = self.safe_string(conversion, 'baseCcy')
7175
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
7176
+ to = self.safe_string(conversion, 'quoteCcy')
7177
+ toCode = self.safe_currency_code(to, toCurrency)
7178
+ return {
7179
+ 'info': conversion,
7180
+ 'timestamp': timestamp,
7181
+ 'datetime': self.iso8601(timestamp),
7182
+ 'id': self.safe_string(conversion, 'clQReqId'),
7183
+ 'fromCurrency': fromCode,
7184
+ 'fromAmount': self.safe_number(conversion, 'baseSz'),
7185
+ 'toCurrency': toCode,
7186
+ 'toAmount': self.safe_number(conversion, 'quoteSz'),
7187
+ 'price': self.safe_number(conversion, 'cnvtPx'),
7188
+ 'fee': None,
7189
+ }
7190
+
7191
+ async def fetch_convert_currencies(self, params={}) -> Currencies:
7192
+ """
7193
+ fetches all available currencies that can be converted
7194
+ :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
7195
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7196
+ :returns dict: an associative dictionary of currencies
7197
+ """
7198
+ await self.load_markets()
7199
+ response = await self.privateGetAssetConvertCurrencies(params)
7200
+ #
7201
+ # {
7202
+ # "code": "0",
7203
+ # "data": [
7204
+ # {
7205
+ # "ccy": "BTC",
7206
+ # "max": "",
7207
+ # "min": ""
7208
+ # },
7209
+ # ],
7210
+ # "msg": ""
7211
+ # }
7212
+ #
7213
+ result = {}
7214
+ data = self.safe_list(response, 'data', [])
7215
+ for i in range(0, len(data)):
7216
+ entry = data[i]
7217
+ id = self.safe_string(entry, 'ccy')
7218
+ code = self.safe_currency_code(id)
7219
+ result[code] = {
7220
+ 'info': entry,
7221
+ 'id': id,
7222
+ 'code': code,
7223
+ 'networks': None,
7224
+ 'type': None,
7225
+ 'name': None,
7226
+ 'active': None,
7227
+ 'deposit': None,
7228
+ 'withdraw': None,
7229
+ 'fee': None,
7230
+ 'precision': None,
7231
+ 'limits': {
7232
+ 'amount': {
7233
+ 'min': self.safe_number(entry, 'min'),
7234
+ 'max': self.safe_number(entry, 'max'),
7235
+ },
7236
+ 'withdraw': {
7237
+ 'min': None,
7238
+ 'max': None,
7239
+ },
7240
+ 'deposit': {
7241
+ 'min': None,
7242
+ 'max': None,
7243
+ },
7244
+ },
7245
+ 'created': None,
7246
+ }
7247
+ return result
7248
+
7101
7249
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
7102
7250
  if not response:
7103
7251
  return None # fallback to default error handler
@@ -7124,7 +7272,7 @@ class okx(Exchange, ImplicitAPI):
7124
7272
  code = self.safe_string(response, 'code')
7125
7273
  if (code != '0') and (code != '2'): # 2 means that bulk operation partially succeeded
7126
7274
  feedback = self.id + ' ' + body
7127
- data = self.safe_value(response, 'data', [])
7275
+ data = self.safe_list(response, 'data', [])
7128
7276
  for i in range(0, len(data)):
7129
7277
  error = data[i]
7130
7278
  errorCode = self.safe_string(error, 'sCode')
@@ -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/async_support/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
 
@@ -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
 
@@ -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
 
@@ -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
 
@@ -9,6 +9,7 @@ import math
9
9
  from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
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 ArgumentsRequired
13
14
  from ccxt.base.errors import BadRequest
14
15
  from ccxt.base.errors import BadSymbol
@@ -19,7 +20,6 @@ from ccxt.base.errors import InvalidOrder
19
20
  from ccxt.base.errors import DDoSProtection
20
21
  from ccxt.base.errors import RateLimitExceeded
21
22
  from ccxt.base.errors import ExchangeNotAvailable
22
- from ccxt.base.errors import AuthenticationError
23
23
  from ccxt.base.decimal_to_precision import TRUNCATE
24
24
  from ccxt.base.decimal_to_precision import TICK_SIZE
25
25
  from ccxt.base.precise import Precise
@@ -8,6 +8,7 @@ from ccxt.abstract.timex import ImplicitAPI
8
8
  from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, 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 OrderNotFound
17
18
  from ccxt.base.errors import NotSupported
18
19
  from ccxt.base.errors import RateLimitExceeded
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
 
@@ -10,6 +10,7 @@ import json
10
10
  from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
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
@@ -29,7 +30,6 @@ from ccxt.base.errors import ExchangeNotAvailable
29
30
  from ccxt.base.errors import OnMaintenance
30
31
  from ccxt.base.errors import InvalidNonce
31
32
  from ccxt.base.errors import RequestTimeout
32
- from ccxt.base.errors import AuthenticationError
33
33
  from ccxt.base.decimal_to_precision import TRUNCATE
34
34
  from ccxt.base.decimal_to_precision import DECIMAL_PLACES
35
35
  from ccxt.base.precise import Precise
@@ -8,9 +8,9 @@ from ccxt.abstract.tradeogre import ImplicitAPI
8
8
  from ccxt.base.types import IndexType, Int, Market, Num, Order, OrderSide, OrderType, Str, Ticker
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 BadRequest
12
13
  from ccxt.base.errors import InsufficientFunds
13
- from ccxt.base.errors import AuthenticationError
14
14
  from ccxt.base.decimal_to_precision import TICK_SIZE
15
15
 
16
16
 
@@ -8,14 +8,14 @@ from ccxt.abstract.upbit import ImplicitAPI
8
8
  from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, 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
14
15
  from ccxt.base.errors import InsufficientFunds
16
+ from ccxt.base.errors import AddressPending
15
17
  from ccxt.base.errors import InvalidOrder
16
18
  from ccxt.base.errors import OrderNotFound
17
- from ccxt.base.errors import AuthenticationError
18
- from ccxt.base.errors import AddressPending
19
19
  from ccxt.base.decimal_to_precision import TICK_SIZE
20
20
  from ccxt.base.precise import Precise
21
21
 
@@ -11,6 +11,7 @@ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBo
11
11
  from typing import List
12
12
  from typing import Any
13
13
  from ccxt.base.errors import ExchangeError
14
+ from ccxt.base.errors import AuthenticationError
14
15
  from ccxt.base.errors import AccountSuspended
15
16
  from ccxt.base.errors import ArgumentsRequired
16
17
  from ccxt.base.errors import BadRequest
@@ -20,7 +21,6 @@ from ccxt.base.errors import InvalidOrder
20
21
  from ccxt.base.errors import OrderNotFound
21
22
  from ccxt.base.errors import DuplicateOrderId
22
23
  from ccxt.base.errors import ExchangeNotAvailable
23
- from ccxt.base.errors import AuthenticationError
24
24
  from ccxt.base.decimal_to_precision import DECIMAL_PLACES
25
25
  from ccxt.base.precise import Precise
26
26