ccxt 4.4.9__py2.py3-none-any.whl → 4.4.11__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 (85) hide show
  1. ccxt/__init__.py +1 -1
  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/oceanex.py +5 -0
  7. ccxt/ascendex.py +5 -4
  8. ccxt/async_support/__init__.py +1 -1
  9. ccxt/async_support/ascendex.py +5 -4
  10. ccxt/async_support/base/exchange.py +1 -1
  11. ccxt/async_support/binance.py +9 -11
  12. ccxt/async_support/bingx.py +20 -21
  13. ccxt/async_support/bitfinex2.py +7 -16
  14. ccxt/async_support/bitget.py +9 -8
  15. ccxt/async_support/bitmart.py +4 -3
  16. ccxt/async_support/bitmex.py +7 -6
  17. ccxt/async_support/blofin.py +7 -16
  18. ccxt/async_support/bybit.py +18 -16
  19. ccxt/async_support/coinex.py +19 -5
  20. ccxt/async_support/delta.py +6 -5
  21. ccxt/async_support/deribit.py +4 -3
  22. ccxt/async_support/digifinex.py +18 -4
  23. ccxt/async_support/gate.py +32 -13
  24. ccxt/async_support/hashkey.py +6 -6
  25. ccxt/async_support/hitbtc.py +6 -5
  26. ccxt/async_support/htx.py +29 -6
  27. ccxt/async_support/hyperliquid.py +6 -1
  28. ccxt/async_support/kraken.py +35 -13
  29. ccxt/async_support/krakenfutures.py +6 -5
  30. ccxt/async_support/kucoinfutures.py +13 -2
  31. ccxt/async_support/mexc.py +14 -7
  32. ccxt/async_support/oceanex.py +80 -4
  33. ccxt/async_support/okx.py +19 -3
  34. ccxt/async_support/oxfun.py +7 -7
  35. ccxt/async_support/phemex.py +4 -3
  36. ccxt/async_support/poloniexfutures.py +13 -2
  37. ccxt/async_support/vertex.py +6 -5
  38. ccxt/async_support/whitebit.py +14 -13
  39. ccxt/async_support/woo.py +42 -21
  40. ccxt/async_support/woofipro.py +19 -6
  41. ccxt/async_support/xt.py +5 -3
  42. ccxt/base/exchange.py +1 -1
  43. ccxt/base/types.py +1 -0
  44. ccxt/binance.py +9 -11
  45. ccxt/bingx.py +20 -21
  46. ccxt/bitfinex2.py +7 -16
  47. ccxt/bitget.py +9 -8
  48. ccxt/bitmart.py +4 -3
  49. ccxt/bitmex.py +7 -6
  50. ccxt/blofin.py +7 -16
  51. ccxt/bybit.py +18 -16
  52. ccxt/coinex.py +19 -5
  53. ccxt/delta.py +6 -5
  54. ccxt/deribit.py +4 -3
  55. ccxt/digifinex.py +18 -4
  56. ccxt/gate.py +32 -13
  57. ccxt/hashkey.py +6 -6
  58. ccxt/hitbtc.py +6 -5
  59. ccxt/htx.py +29 -6
  60. ccxt/hyperliquid.py +6 -1
  61. ccxt/kraken.py +35 -13
  62. ccxt/krakenfutures.py +6 -5
  63. ccxt/kucoinfutures.py +13 -2
  64. ccxt/mexc.py +14 -7
  65. ccxt/oceanex.py +80 -4
  66. ccxt/okx.py +19 -3
  67. ccxt/oxfun.py +7 -7
  68. ccxt/phemex.py +4 -3
  69. ccxt/poloniexfutures.py +13 -2
  70. ccxt/pro/__init__.py +1 -1
  71. ccxt/pro/deribit.py +114 -2
  72. ccxt/pro/exmo.py +29 -2
  73. ccxt/pro/gate.py +1 -1
  74. ccxt/pro/okx.py +1 -1
  75. ccxt/vertex.py +6 -5
  76. ccxt/whitebit.py +14 -13
  77. ccxt/woo.py +42 -21
  78. ccxt/woofipro.py +19 -6
  79. ccxt/xt.py +5 -3
  80. ccxt-4.4.11.dist-info/METADATA +636 -0
  81. {ccxt-4.4.9.dist-info → ccxt-4.4.11.dist-info}/RECORD +84 -84
  82. ccxt-4.4.9.dist-info/METADATA +0 -636
  83. {ccxt-4.4.9.dist-info → ccxt-4.4.11.dist-info}/LICENSE.txt +0 -0
  84. {ccxt-4.4.9.dist-info → ccxt-4.4.11.dist-info}/WHEEL +0 -0
  85. {ccxt-4.4.9.dist-info → ccxt-4.4.11.dist-info}/top_level.txt +0 -0
ccxt/async_support/htx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.htx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -203,7 +203,7 @@ class htx(Exchange, ImplicitAPI):
203
203
  },
204
204
  'www': 'https://www.huobi.com',
205
205
  'referral': {
206
- 'url': 'https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223',
206
+ 'url': 'https://www.htx.com.vc/invite/en-us/1h?invite_code=6rmm2223',
207
207
  'discount': 0.15,
208
208
  },
209
209
  'doc': [
@@ -1237,6 +1237,7 @@ class htx(Exchange, ImplicitAPI):
1237
1237
  # https://github.com/ccxt/ccxt/issues/6081
1238
1238
  # https://github.com/ccxt/ccxt/issues/3365
1239
1239
  # https://github.com/ccxt/ccxt/issues/2873
1240
+ 'NGL': 'GFNGL',
1240
1241
  'GET': 'THEMIS', # conflict with GET(Guaranteed Entrance Token, GET Protocol)
1241
1242
  'GTC': 'GAMECOM', # conflict with Gitcoin and Gastrocoin
1242
1243
  'HIT': 'HITCHAIN',
@@ -1248,6 +1249,7 @@ class htx(Exchange, ImplicitAPI):
1248
1249
  'SBTC': 'SUPERBITCOIN',
1249
1250
  'SOUL': 'SOULSAVER',
1250
1251
  'BIFI': 'BITCOINFILE', # conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706
1252
+ 'FUD': 'FTX Users\' Debt',
1251
1253
  },
1252
1254
  })
1253
1255
 
@@ -6383,7 +6385,7 @@ class htx(Exchange, ImplicitAPI):
6383
6385
  sorted = self.sort_by(rates, 'timestamp')
6384
6386
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
6385
6387
 
6386
- def parse_funding_rate(self, contract, market: Market = None):
6388
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
6387
6389
  #
6388
6390
  # {
6389
6391
  # "status": "ok",
@@ -6402,6 +6404,9 @@ class htx(Exchange, ImplicitAPI):
6402
6404
  nextFundingRate = self.safe_number(contract, 'estimated_rate')
6403
6405
  fundingTimestamp = self.safe_integer(contract, 'funding_time')
6404
6406
  nextFundingTimestamp = self.safe_integer(contract, 'next_funding_time')
6407
+ fundingTimeString = self.safe_string(contract, 'funding_time')
6408
+ nextFundingTimeString = self.safe_string(contract, 'next_funding_time')
6409
+ millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
6405
6410
  marketId = self.safe_string(contract, 'contract_code')
6406
6411
  symbol = self.safe_symbol(marketId, market)
6407
6412
  return {
@@ -6422,9 +6427,20 @@ class htx(Exchange, ImplicitAPI):
6422
6427
  'previousFundingRate': None,
6423
6428
  'previousFundingTimestamp': None,
6424
6429
  'previousFundingDatetime': None,
6430
+ 'interval': self.parse_funding_interval(millisecondsInterval),
6425
6431
  }
6426
6432
 
6427
- async def fetch_funding_rate(self, symbol: str, params={}):
6433
+ def parse_funding_interval(self, interval):
6434
+ intervals: dict = {
6435
+ '3600000': '1h',
6436
+ '14400000': '4h',
6437
+ '28800000': '8h',
6438
+ '57600000': '16h',
6439
+ '86400000': '24h',
6440
+ }
6441
+ return self.safe_string(intervals, interval, interval)
6442
+
6443
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
6428
6444
  """
6429
6445
  fetch the current funding rate
6430
6446
  :param str symbol: unified market symbol
@@ -6461,12 +6477,12 @@ class htx(Exchange, ImplicitAPI):
6461
6477
  result = self.safe_value(response, 'data', {})
6462
6478
  return self.parse_funding_rate(result, market)
6463
6479
 
6464
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
6480
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6465
6481
  """
6466
6482
  fetch the funding rate for multiple markets
6467
6483
  :param str[]|None symbols: list of unified market symbols
6468
6484
  :param dict [params]: extra parameters specific to the exchange API endpoint
6469
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
6485
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
6470
6486
  """
6471
6487
  await self.load_markets()
6472
6488
  symbols = self.market_symbols(symbols)
@@ -6840,6 +6856,10 @@ class htx(Exchange, ImplicitAPI):
6840
6856
  async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
6841
6857
  """
6842
6858
  set the level of leverage for a market
6859
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-switch-leverage
6860
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-switch-leverage
6861
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#switch-leverage
6862
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#switch-leverage # Coin-m futures
6843
6863
  :param float leverage: the rate of leverage
6844
6864
  :param str symbol: unified market symbol
6845
6865
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -8097,6 +8117,9 @@ class htx(Exchange, ImplicitAPI):
8097
8117
  async def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
8098
8118
  """
8099
8119
  Fetches historical settlement records
8120
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#query-historical-settlement-records-of-the-platform-interface
8121
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-historical-settlement-records-of-the-platform-interface
8122
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-historical-settlement-records-of-the-platform-interface
8100
8123
  :param str symbol: unified symbol of the market to fetch the settlement history for
8101
8124
  :param int [since]: timestamp in ms, value range = current time - 90 days,default = current time - 90 days
8102
8125
  :param int [limit]: page items, default 20, shall not exceed 50
@@ -1927,6 +1927,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1927
1927
  # "crossed": True,
1928
1928
  # "dir": "Close Long",
1929
1929
  # "fee": "0.050062",
1930
+ # "feeToken": "USDC",
1930
1931
  # "hash": "0x09d77c96791e98b5775a04092584ab010d009445119c71e4005c0d634ea322bc",
1931
1932
  # "liquidationMarkPx": null,
1932
1933
  # "oid": 3929354691,
@@ -1985,7 +1986,11 @@ class hyperliquid(Exchange, ImplicitAPI):
1985
1986
  'price': price,
1986
1987
  'amount': amount,
1987
1988
  'cost': None,
1988
- 'fee': {'cost': fee, 'currency': 'USDC'},
1989
+ 'fee': {
1990
+ 'cost': fee,
1991
+ 'currency': self.safe_string(trade, 'feeToken'),
1992
+ 'rate': None,
1993
+ },
1989
1994
  }, market)
1990
1995
 
1991
1996
  async def fetch_position(self, symbol: str, params={}):
@@ -66,6 +66,7 @@ class kraken(Exchange, ImplicitAPI):
66
66
  'createStopMarketOrder': True,
67
67
  'createStopOrder': True,
68
68
  'createTrailingAmountOrder': True,
69
+ 'createTrailingPercentOrder': True,
69
70
  'editOrder': True,
70
71
  'fetchBalance': True,
71
72
  'fetchBorrowInterest': False,
@@ -456,7 +457,9 @@ class kraken(Exchange, ImplicitAPI):
456
457
  'EGeneral:Internal error': ExchangeNotAvailable,
457
458
  'EGeneral:Temporary lockout': DDoSProtection,
458
459
  'EGeneral:Permission denied': PermissionDenied,
460
+ 'EGeneral:Invalid arguments:price': InvalidOrder,
459
461
  'EOrder:Unknown order': InvalidOrder,
462
+ 'EOrder:Invalid price:Invalid price argument': InvalidOrder,
460
463
  'EOrder:Order minimum not met': InvalidOrder,
461
464
  'EGeneral:Invalid arguments': BadRequest,
462
465
  'ESession:Invalid session': AuthenticationError,
@@ -1397,8 +1400,8 @@ class kraken(Exchange, ImplicitAPI):
1397
1400
 
1398
1401
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1399
1402
  """
1400
- :see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
1401
1403
  create a trade order
1404
+ :see: https://docs.kraken.com/api/docs/rest-api/add-order
1402
1405
  :param str symbol: unified symbol of the market to create an order in
1403
1406
  :param str type: 'market' or 'limit'
1404
1407
  :param str side: 'buy' or 'sell'
@@ -1410,7 +1413,9 @@ class kraken(Exchange, ImplicitAPI):
1410
1413
  :param float [params.stopLossPrice]: *margin only* the price that a stop loss order is triggered at
1411
1414
  :param float [params.takeProfitPrice]: *margin only* the price that a take profit order is triggered at
1412
1415
  :param str [params.trailingAmount]: *margin only* the quote amount to trail away from the current market price
1416
+ :param str [params.trailingPercent]: *margin only* the percent to trail away from the current market price
1413
1417
  :param str [params.trailingLimitAmount]: *margin only* the quote amount away from the trailingAmount
1418
+ :param str [params.trailingLimitPercent]: *margin only* the percent away from the trailingAmount
1414
1419
  :param str [params.offset]: *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
1415
1420
  :param str [params.trigger]: *margin only* the activation price type, 'last' or 'index', default is 'last'
1416
1421
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -1717,8 +1722,11 @@ class kraken(Exchange, ImplicitAPI):
1717
1722
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
1718
1723
  isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder or isTakeProfitTriggerOrder
1719
1724
  trailingAmount = self.safe_string(params, 'trailingAmount')
1725
+ trailingPercent = self.safe_string(params, 'trailingPercent')
1720
1726
  trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
1727
+ trailingLimitPercent = self.safe_string(params, 'trailingLimitPercent')
1721
1728
  isTrailingAmountOrder = trailingAmount is not None
1729
+ isTrailingPercentOrder = trailingPercent is not None
1722
1730
  isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
1723
1731
  isMarketOrder = type == 'market'
1724
1732
  cost = self.safe_string(params, 'cost')
@@ -1750,19 +1758,30 @@ class kraken(Exchange, ImplicitAPI):
1750
1758
  request['ordertype'] = 'take-profit'
1751
1759
  if isLimitOrder:
1752
1760
  request['price2'] = self.price_to_precision(symbol, price)
1753
- elif isTrailingAmountOrder:
1761
+ elif isTrailingAmountOrder or isTrailingPercentOrder:
1762
+ trailingPercentString = None
1763
+ if isTrailingPercentOrder:
1764
+ trailingPercentString = trailingPercent if (trailingPercent.endswith('%')) else '+' + (self.number_to_string(trailingPercent) + '%')
1765
+ trailingAmountString = '+' + trailingAmount if (trailingAmount is not None) else None # must use + for self
1766
+ offset = self.safe_string(params, 'offset', '-') # can use + or - for self
1767
+ trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount) if (trailingLimitAmount is not None) else None
1754
1768
  trailingActivationPriceType = self.safe_string(params, 'trigger', 'last')
1755
- trailingAmountString = '+' + trailingAmount
1756
1769
  request['trigger'] = trailingActivationPriceType
1757
- if isLimitOrder or (trailingLimitAmount is not None):
1758
- offset = self.safe_string(params, 'offset', '-')
1759
- trailingLimitAmountString = offset + self.number_to_string(trailingLimitAmount)
1760
- request['price'] = trailingAmountString
1761
- request['price2'] = trailingLimitAmountString
1770
+ if isLimitOrder or (trailingLimitAmount is not None) or (trailingLimitPercent is not None):
1762
1771
  request['ordertype'] = 'trailing-stop-limit'
1772
+ if trailingLimitPercent is not None:
1773
+ trailingLimitPercentString = trailingLimitPercent if (trailingLimitPercent.endswith('%')) else (self.number_to_string(trailingLimitPercent) + '%')
1774
+ request['price'] = trailingPercentString
1775
+ request['price2'] = trailingLimitPercentString
1776
+ elif trailingLimitAmount is not None:
1777
+ request['price'] = trailingAmountString
1778
+ request['price2'] = trailingLimitAmountString
1763
1779
  else:
1764
- request['price'] = trailingAmountString
1765
1780
  request['ordertype'] = 'trailing-stop'
1781
+ if trailingPercent is not None:
1782
+ request['price'] = trailingPercentString
1783
+ else:
1784
+ request['price'] = trailingAmountString
1766
1785
  if reduceOnly:
1767
1786
  if method == 'createOrderWs':
1768
1787
  request['reduce_only'] = True # ws request can't have stringified bool
@@ -1789,7 +1808,7 @@ class kraken(Exchange, ImplicitAPI):
1789
1808
  request['oflags'] = extendedPostFlags
1790
1809
  if (flags is not None) and not ('oflags' in request):
1791
1810
  request['oflags'] = flags
1792
- params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
1811
+ params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingPercent', 'trailingLimitAmount', 'trailingLimitPercent', 'offset'])
1793
1812
  return [request, params]
1794
1813
 
1795
1814
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
@@ -2916,11 +2935,15 @@ class kraken(Exchange, ImplicitAPI):
2916
2935
  # urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2917
2936
  url += '?' + self.urlencode_nested(params)
2918
2937
  elif api == 'private':
2938
+ price = self.safe_string(params, 'price')
2939
+ isTriggerPercent = False
2940
+ if price is not None:
2941
+ isTriggerPercent = True if (price.endswith('%')) else False
2919
2942
  isCancelOrderBatch = (path == 'CancelOrderBatch')
2920
2943
  self.check_required_credentials()
2921
2944
  nonce = str(self.nonce())
2922
2945
  # urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2923
- if isCancelOrderBatch:
2946
+ if isCancelOrderBatch or isTriggerPercent:
2924
2947
  body = self.json(self.extend({'nonce': nonce}, params))
2925
2948
  else:
2926
2949
  body = self.urlencode_nested(self.extend({'nonce': nonce}, params))
@@ -2933,9 +2956,8 @@ class kraken(Exchange, ImplicitAPI):
2933
2956
  headers = {
2934
2957
  'API-Key': self.apiKey,
2935
2958
  'API-Sign': signature,
2936
- # 'Content-Type': 'application/x-www-form-urlencoded',
2937
2959
  }
2938
- if isCancelOrderBatch:
2960
+ if isCancelOrderBatch or isTriggerPercent:
2939
2961
  headers['Content-Type'] = 'application/json'
2940
2962
  else:
2941
2963
  headers['Content-Type'] = 'application/x-www-form-urlencoded'
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.krakenfutures import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TransferEntry
9
+ from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -2030,10 +2030,10 @@ class krakenfutures(Exchange, ImplicitAPI):
2030
2030
  result[code] = account
2031
2031
  return self.safe_balance(result)
2032
2032
 
2033
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
2033
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
2034
2034
  """
2035
+ fetch the current funding rates for multiple markets
2035
2036
  :see: https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-tickers
2036
- fetch the current funding rates
2037
2037
  :param str[] symbols: unified market symbols
2038
2038
  :param dict [params]: extra parameters specific to the exchange API endpoint
2039
2039
  :returns Order[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -2041,7 +2041,7 @@ class krakenfutures(Exchange, ImplicitAPI):
2041
2041
  await self.load_markets()
2042
2042
  marketIds = self.market_ids(symbols)
2043
2043
  response = await self.publicGetTickers(params)
2044
- tickers = self.safe_value(response, 'tickers')
2044
+ tickers = self.safe_list(response, 'tickers', [])
2045
2045
  fundingRates = []
2046
2046
  for i in range(0, len(tickers)):
2047
2047
  entry = tickers[i]
@@ -2054,7 +2054,7 @@ class krakenfutures(Exchange, ImplicitAPI):
2054
2054
  fundingRates.append(parsed)
2055
2055
  return self.index_by(fundingRates, 'symbol')
2056
2056
 
2057
- def parse_funding_rate(self, ticker, market: Market = None):
2057
+ def parse_funding_rate(self, ticker, market: Market = None) -> FundingRate:
2058
2058
  #
2059
2059
  # {"ask": 26.283,
2060
2060
  # "askSize": 4.6,
@@ -2108,6 +2108,7 @@ class krakenfutures(Exchange, ImplicitAPI):
2108
2108
  'previousFundingRate': None,
2109
2109
  'previousFundingTimestamp': None,
2110
2110
  'previousFundingDatetime': None,
2111
+ 'interval': None,
2111
2112
  }
2112
2113
 
2113
2114
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.kucoin import kucoin
7
7
  from ccxt.abstract.kucoinfutures import ImplicitAPI
8
- from ccxt.base.types import Balances, Currency, Int, Leverage, LeverageTier, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
8
+ from ccxt.base.types import Balances, Currency, Int, Leverage, LeverageTier, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
9
9
  from typing import List
10
10
  from ccxt.base.errors import AuthenticationError
11
11
  from ccxt.base.errors import PermissionDenied
@@ -2046,7 +2046,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
2046
2046
  'trades': None,
2047
2047
  }, market)
2048
2048
 
2049
- async def fetch_funding_rate(self, symbol: str, params={}):
2049
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
2050
2050
  """
2051
2051
  fetch the current funding rate
2052
2052
  :see: https://www.kucoin.com/docs/rest/futures-trading/funding-fees/get-current-funding-rate
@@ -2093,8 +2093,19 @@ class kucoinfutures(kucoin, ImplicitAPI):
2093
2093
  'previousFundingRate': None,
2094
2094
  'previousFundingTimestamp': None,
2095
2095
  'previousFundingDatetime': None,
2096
+ 'interval': self.parse_funding_interval(self.safe_string(data, 'granularity')),
2096
2097
  }
2097
2098
 
2099
+ def parse_funding_interval(self, interval):
2100
+ intervals: dict = {
2101
+ '3600000': '1h',
2102
+ '14400000': '4h',
2103
+ '28800000': '8h',
2104
+ '57600000': '16h',
2105
+ '86400000': '24h',
2106
+ }
2107
+ return self.safe_string(intervals, interval, interval)
2108
+
2098
2109
  def parse_balance(self, response) -> Balances:
2099
2110
  result: dict = {
2100
2111
  'info': response,
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.mexc import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, IndexType, Int, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, IndexType, Int, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFees, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -3616,23 +3616,29 @@ class mexc(Exchange, ImplicitAPI):
3616
3616
  :param int [since]: the earliest time in ms to fetch trades for
3617
3617
  :param int [limit]: the maximum number of trades structures to retrieve
3618
3618
  :param dict [params]: extra parameters specific to the exchange API endpoint
3619
+ :param int [params.until]: the latest time in ms to fetch trades for
3619
3620
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
3620
3621
  """
3621
3622
  if symbol is None:
3622
3623
  raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
3623
3624
  await self.load_markets()
3624
3625
  market = self.market(symbol)
3625
- marketType, query = self.handle_market_type_and_params('fetchMyTrades', market, params)
3626
+ marketType: Str = None
3627
+ marketType, params = self.handle_market_type_and_params('fetchMyTrades', market, params)
3626
3628
  request: dict = {
3627
3629
  'symbol': market['id'],
3628
3630
  }
3629
3631
  trades = None
3630
3632
  if marketType == 'spot':
3631
3633
  if since is not None:
3632
- request['start_time'] = since
3634
+ request['startTime'] = since
3633
3635
  if limit is not None:
3634
3636
  request['limit'] = limit
3635
- trades = await self.spotPrivateGetMyTrades(self.extend(request, query))
3637
+ until = self.safe_integer(params, 'until')
3638
+ if until is not None:
3639
+ params = self.omit(params, 'until')
3640
+ request['endTime'] = until
3641
+ trades = await self.spotPrivateGetMyTrades(self.extend(request, params))
3636
3642
  #
3637
3643
  # spot
3638
3644
  #
@@ -3662,7 +3668,7 @@ class mexc(Exchange, ImplicitAPI):
3662
3668
  request['end_time'] = self.sum(since, self.options['maxTimeTillEnd'])
3663
3669
  if limit is not None:
3664
3670
  request['page_size'] = limit
3665
- response = await self.contractPrivateGetOrderListOrderDeals(self.extend(request, query))
3671
+ response = await self.contractPrivateGetOrderListOrderDeals(self.extend(request, params))
3666
3672
  #
3667
3673
  # {
3668
3674
  # "success": True,
@@ -3905,7 +3911,7 @@ class mexc(Exchange, ImplicitAPI):
3905
3911
  })
3906
3912
  return result
3907
3913
 
3908
- def parse_funding_rate(self, contract, market: Market = None):
3914
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
3909
3915
  #
3910
3916
  # {
3911
3917
  # "symbol": "BTC_USDT",
@@ -3941,9 +3947,10 @@ class mexc(Exchange, ImplicitAPI):
3941
3947
  'previousFundingRate': None,
3942
3948
  'previousFundingTimestamp': None,
3943
3949
  'previousFundingDatetime': None,
3950
+ 'interval': None,
3944
3951
  }
3945
3952
 
3946
- async def fetch_funding_rate(self, symbol: str, params={}):
3953
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
3947
3954
  """
3948
3955
  fetch the current funding rate
3949
3956
  :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-funding-rate
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.oceanex import ImplicitAPI
8
- from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
8
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
@@ -54,9 +54,9 @@ class oceanex(Exchange, ImplicitAPI):
54
54
  'fetchClosedOrders': True,
55
55
  'fetchCrossBorrowRate': False,
56
56
  'fetchCrossBorrowRates': False,
57
- 'fetchDepositAddress': False,
58
- 'fetchDepositAddresses': False,
59
- 'fetchDepositAddressesByNetwork': False,
57
+ 'fetchDepositAddress': 'emulated',
58
+ 'fetchDepositAddresses': None,
59
+ 'fetchDepositAddressesByNetwork': True,
60
60
  'fetchIsolatedBorrowRate': False,
61
61
  'fetchIsolatedBorrowRates': False,
62
62
  'fetchMarkets': True,
@@ -117,6 +117,11 @@ class oceanex(Exchange, ImplicitAPI):
117
117
  'order/delete',
118
118
  'order/delete/multi',
119
119
  'orders/clear',
120
+ '/withdraws/special/new',
121
+ '/deposit_address',
122
+ '/deposit_addresses',
123
+ '/deposit_history',
124
+ '/withdraw_history',
120
125
  ],
121
126
  },
122
127
  },
@@ -858,6 +863,77 @@ class oceanex(Exchange, ImplicitAPI):
858
863
  data = self.safe_list(response, 'data')
859
864
  return self.parse_orders(data)
860
865
 
866
+ async def fetch_deposit_addresses_by_network(self, code: str, params={}):
867
+ """
868
+ fetch the deposit addresses for a currency associated with self account
869
+ :see: https://api.oceanex.pro/doc/v1/#deposit-addresses-post
870
+ :param str code: unified currency code
871
+ :param dict [params]: extra parameters specific to the exchange API endpoint
872
+ :returns dict: a dictionary `address structures <https://docs.ccxt.com/#/?id=address-structure>`, indexed by the network
873
+ """
874
+ await self.load_markets()
875
+ currency = self.currency(code)
876
+ request: dict = {
877
+ 'currency': currency['id'],
878
+ }
879
+ response = await self.privatePostDepositAddresses(self.extend(request, params))
880
+ #
881
+ # {
882
+ # code: '0',
883
+ # message: 'Operation successful',
884
+ # data: {
885
+ # data: {
886
+ # currency_id: 'usdt',
887
+ # display_name: 'USDT',
888
+ # num_of_resources: '3',
889
+ # resources: [
890
+ # {
891
+ # chain_name: 'TRC20',
892
+ # currency_id: 'usdt',
893
+ # address: 'TPcS7VgKMFmpRrWY82GbJzDeMnemWxEbpg',
894
+ # memo: '',
895
+ # deposit_status: 'enabled'
896
+ # },
897
+ # ...
898
+ # ]
899
+ # }
900
+ # }
901
+ # }
902
+ #
903
+ data = self.safe_dict(response, 'data', {})
904
+ data2 = self.safe_dict(data, 'data', {})
905
+ resources = self.safe_list(data2, 'resources', [])
906
+ result = {}
907
+ for i in range(0, len(resources)):
908
+ resource = resources[i]
909
+ enabled = self.safe_string(resource, 'deposit_status')
910
+ if enabled == 'enabled':
911
+ parsedAddress = self.parse_deposit_address(resource, currency)
912
+ result[parsedAddress['currency']] = parsedAddress
913
+ return result
914
+
915
+ def parse_deposit_address(self, depositAddress, currency: Currency = None):
916
+ #
917
+ # {
918
+ # chain_name: 'TRC20',
919
+ # currency_id: 'usdt',
920
+ # address: 'TPcS7VgKMFmpRrWY82GbJzDeMnemWxEbpg',
921
+ # memo: '',
922
+ # deposit_status: 'enabled'
923
+ # }
924
+ #
925
+ address = self.safe_string(depositAddress, 'address')
926
+ self.check_address(address)
927
+ currencyId = self.safe_string(depositAddress, 'currency_id')
928
+ networkId = self.safe_string(depositAddress, 'chain_name')
929
+ return {
930
+ 'info': depositAddress,
931
+ 'currency': self.safe_currency_code(currencyId, currency),
932
+ 'address': address,
933
+ 'tag': self.safe_string(depositAddress, 'memo'),
934
+ 'network': self.network_id_to_code(networkId),
935
+ }
936
+
861
937
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
862
938
  url = self.urls['api']['rest'] + '/' + self.version + '/' + self.implode_params(path, params)
863
939
  query = self.omit(params, self.extract_params(path))
ccxt/async_support/okx.py CHANGED
@@ -7,7 +7,7 @@ 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, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, Greeks, Int, LedgerEntry, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, Greeks, Int, LedgerEntry, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from typing import Any
13
13
  from ccxt.base.errors import ExchangeError
@@ -18,6 +18,7 @@ from ccxt.base.errors import AccountSuspended
18
18
  from ccxt.base.errors import ArgumentsRequired
19
19
  from ccxt.base.errors import BadRequest
20
20
  from ccxt.base.errors import BadSymbol
21
+ from ccxt.base.errors import ManualInteractionNeeded
21
22
  from ccxt.base.errors import InsufficientFunds
22
23
  from ccxt.base.errors import InvalidAddress
23
24
  from ccxt.base.errors import InvalidOrder
@@ -600,6 +601,7 @@ class okx(Exchange, ImplicitAPI):
600
601
  # General Class
601
602
  '1': ExchangeError, # Operation failed
602
603
  '2': ExchangeError, # Bulk operation partially succeeded
604
+ '4088': ManualInteractionNeeded, # {"code":"4088","data":[],"msg":"You can’t trade or deposit until you’ve verified your identity again. Head to Identity Verification to complete it."}
603
605
  '50000': BadRequest, # Body can not be empty
604
606
  '50001': OnMaintenance, # Matching engine upgrading. Please try again later
605
607
  '50002': BadRequest, # Json data format error
@@ -5623,7 +5625,7 @@ class okx(Exchange, ImplicitAPI):
5623
5625
  headers['OK-ACCESS-SIGN'] = signature
5624
5626
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
5625
5627
 
5626
- def parse_funding_rate(self, contract, market: Market = None):
5628
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
5627
5629
  #
5628
5630
  # {
5629
5631
  # "fundingRate": "0.00027815",
@@ -5657,6 +5659,9 @@ class okx(Exchange, ImplicitAPI):
5657
5659
  symbol = self.safe_symbol(marketId, market)
5658
5660
  nextFundingRate = self.safe_number(contract, 'nextFundingRate')
5659
5661
  fundingTime = self.safe_integer(contract, 'fundingTime')
5662
+ fundingTimeString = self.safe_string(contract, 'fundingTime')
5663
+ nextFundingTimeString = self.safe_string(contract, 'nextFundingRate')
5664
+ millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
5660
5665
  # https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee
5661
5666
  # > The current interest is 0.
5662
5667
  return {
@@ -5677,9 +5682,20 @@ class okx(Exchange, ImplicitAPI):
5677
5682
  'previousFundingRate': None,
5678
5683
  'previousFundingTimestamp': None,
5679
5684
  'previousFundingDatetime': None,
5685
+ 'interval': self.parse_funding_interval(millisecondsInterval),
5680
5686
  }
5681
5687
 
5682
- async def fetch_funding_rate(self, symbol: str, params={}):
5688
+ def parse_funding_interval(self, interval):
5689
+ intervals: dict = {
5690
+ '3600000': '1h',
5691
+ '14400000': '4h',
5692
+ '28800000': '8h',
5693
+ '57600000': '16h',
5694
+ '86400000': '24h',
5695
+ }
5696
+ return self.safe_string(intervals, interval, interval)
5697
+
5698
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
5683
5699
  """
5684
5700
  fetch the current funding rate
5685
5701
  :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.oxfun import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -84,7 +84,7 @@ class oxfun(Exchange, ImplicitAPI):
84
84
  'fetchDepositWithdrawFee': False,
85
85
  'fetchDepositWithdrawFees': False,
86
86
  'fetchFundingHistory': True,
87
- 'fetchFundingRate': False,
87
+ 'fetchFundingRate': 'emulated',
88
88
  'fetchFundingRateHistory': True,
89
89
  'fetchFundingRates': True,
90
90
  'fetchIndexOHLCV': False,
@@ -988,10 +988,10 @@ class oxfun(Exchange, ImplicitAPI):
988
988
  timestamp = self.safe_integer(data, 'lastUpdatedAt')
989
989
  return self.parse_order_book(data, market['symbol'], timestamp)
990
990
 
991
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
991
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
992
992
  """
993
+ fetch the current funding rates for multiple markets
993
994
  :see: https://docs.ox.fun/?json#get-v3-funding-estimates
994
- fetch the current funding rates
995
995
  :param str[] symbols: unified market symbols
996
996
  :param dict [params]: extra parameters specific to the exchange API endpoint
997
997
  :returns Order[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -1021,14 +1021,13 @@ class oxfun(Exchange, ImplicitAPI):
1021
1021
  result = self.parse_funding_rates(data)
1022
1022
  return self.filter_by_array(result, 'symbol', symbols)
1023
1023
 
1024
- def parse_funding_rate(self, fundingRate, market: Market = None):
1024
+ def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
1025
1025
  #
1026
1026
  # {
1027
1027
  # "marketCode": "OX-USD-SWAP-LIN",
1028
1028
  # "fundingAt": "1715515200000",
1029
1029
  # "estFundingRate": "0.000200000"
1030
- # },
1031
- #
1030
+ # }
1032
1031
  #
1033
1032
  symbol = self.safe_string(fundingRate, 'marketCode')
1034
1033
  market = self.market(symbol)
@@ -1051,6 +1050,7 @@ class oxfun(Exchange, ImplicitAPI):
1051
1050
  'previousFundingRate': None,
1052
1051
  'previousFundingTimestamp': None,
1053
1052
  'previousFundingDatetime': None,
1053
+ 'interval': None,
1054
1054
  }
1055
1055
 
1056
1056
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):