ccxt 4.3.94__py2.py3-none-any.whl → 4.3.96__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 (53) hide show
  1. ccxt/__init__.py +1 -5
  2. ccxt/abstract/okx.py +2 -0
  3. ccxt/ascendex.py +8 -6
  4. ccxt/async_support/__init__.py +1 -5
  5. ccxt/async_support/ascendex.py +9 -6
  6. ccxt/async_support/base/exchange.py +1 -4
  7. ccxt/async_support/bingx.py +1 -0
  8. ccxt/async_support/bitfinex.py +4 -2
  9. ccxt/async_support/bitfinex2.py +7 -5
  10. ccxt/async_support/blofin.py +0 -1
  11. ccxt/async_support/btcturk.py +3 -3
  12. ccxt/async_support/bybit.py +7 -2
  13. ccxt/async_support/gate.py +3 -2
  14. ccxt/async_support/gemini.py +3 -2
  15. ccxt/async_support/hyperliquid.py +311 -40
  16. ccxt/async_support/independentreserve.py +5 -3
  17. ccxt/async_support/indodax.py +2 -0
  18. ccxt/async_support/kucoin.py +12 -12
  19. ccxt/async_support/mexc.py +78 -154
  20. ccxt/async_support/okx.py +2 -1
  21. ccxt/async_support/p2b.py +0 -1
  22. ccxt/async_support/tradeogre.py +0 -1
  23. ccxt/base/exchange.py +4 -8
  24. ccxt/bingx.py +1 -0
  25. ccxt/bitfinex.py +3 -2
  26. ccxt/bitfinex2.py +6 -5
  27. ccxt/blofin.py +0 -1
  28. ccxt/btcturk.py +3 -3
  29. ccxt/bybit.py +7 -2
  30. ccxt/gate.py +3 -2
  31. ccxt/gemini.py +3 -2
  32. ccxt/hyperliquid.py +311 -40
  33. ccxt/independentreserve.py +4 -3
  34. ccxt/indodax.py +2 -0
  35. ccxt/kucoin.py +2 -2
  36. ccxt/mexc.py +78 -154
  37. ccxt/okx.py +2 -1
  38. ccxt/p2b.py +0 -1
  39. ccxt/pro/__init__.py +1 -1
  40. ccxt/pro/binance.py +90 -2
  41. ccxt/pro/bybit.py +58 -4
  42. ccxt/pro/cryptocom.py +195 -0
  43. ccxt/pro/okx.py +238 -31
  44. ccxt/test/tests_async.py +3 -0
  45. ccxt/test/tests_sync.py +3 -0
  46. ccxt/tradeogre.py +0 -1
  47. {ccxt-4.3.94.dist-info → ccxt-4.3.96.dist-info}/METADATA +5 -5
  48. {ccxt-4.3.94.dist-info → ccxt-4.3.96.dist-info}/RECORD +51 -53
  49. ccxt/abstract/bitbay.py +0 -53
  50. ccxt/abstract/hitbtc3.py +0 -115
  51. {ccxt-4.3.94.dist-info → ccxt-4.3.96.dist-info}/LICENSE.txt +0 -0
  52. {ccxt-4.3.94.dist-info → ccxt-4.3.96.dist-info}/WHEEL +0 -0
  53. {ccxt-4.3.94.dist-info → ccxt-4.3.96.dist-info}/top_level.txt +0 -0
@@ -62,14 +62,15 @@ class hyperliquid(Exchange, ImplicitAPI):
62
62
  'fetchBorrowInterest': False,
63
63
  'fetchBorrowRateHistories': False,
64
64
  'fetchBorrowRateHistory': False,
65
- 'fetchCanceledOrders': False,
65
+ 'fetchCanceledAndClosedOrders': True,
66
+ 'fetchCanceledOrders': True,
66
67
  'fetchClosedOrders': True,
67
68
  'fetchCrossBorrowRate': False,
68
69
  'fetchCrossBorrowRates': False,
69
70
  'fetchCurrencies': True,
70
71
  'fetchDepositAddress': False,
71
72
  'fetchDepositAddresses': False,
72
- 'fetchDeposits': False,
73
+ 'fetchDeposits': True,
73
74
  'fetchDepositWithdrawFee': 'emulated',
74
75
  'fetchDepositWithdrawFees': False,
75
76
  'fetchFundingHistory': False,
@@ -79,7 +80,7 @@ class hyperliquid(Exchange, ImplicitAPI):
79
80
  'fetchIndexOHLCV': False,
80
81
  'fetchIsolatedBorrowRate': False,
81
82
  'fetchIsolatedBorrowRates': False,
82
- 'fetchLedger': False,
83
+ 'fetchLedger': True,
83
84
  'fetchLeverage': False,
84
85
  'fetchLeverageTiers': False,
85
86
  'fetchLiquidations': False,
@@ -95,7 +96,7 @@ class hyperliquid(Exchange, ImplicitAPI):
95
96
  'fetchOpenOrders': True,
96
97
  'fetchOrder': True,
97
98
  'fetchOrderBook': True,
98
- 'fetchOrders': False,
99
+ 'fetchOrders': True,
99
100
  'fetchOrderTrades': False,
100
101
  'fetchPosition': True,
101
102
  'fetchPositionMode': False,
@@ -111,7 +112,7 @@ class hyperliquid(Exchange, ImplicitAPI):
111
112
  'fetchTransfer': False,
112
113
  'fetchTransfers': False,
113
114
  'fetchWithdrawal': False,
114
- 'fetchWithdrawals': False,
115
+ 'fetchWithdrawals': True,
115
116
  'reduceMargin': True,
116
117
  'repayCrossMargin': False,
117
118
  'repayIsolatedMargin': False,
@@ -815,6 +816,7 @@ class hyperliquid(Exchange, ImplicitAPI):
815
816
  await self.load_markets()
816
817
  market = self.market(symbol)
817
818
  until = self.safe_integer(params, 'until', self.milliseconds())
819
+ useTail = (since is None)
818
820
  if since is None:
819
821
  since = 0
820
822
  params = self.omit(params, ['until'])
@@ -844,7 +846,7 @@ class hyperliquid(Exchange, ImplicitAPI):
844
846
  # }
845
847
  # ]
846
848
  #
847
- return self.parse_ohlcvs(response, market, timeframe, since, limit)
849
+ return self.parse_ohlcvs(response, market, timeframe, since, limit, useTail)
848
850
 
849
851
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
850
852
  #
@@ -1645,7 +1647,14 @@ class hyperliquid(Exchange, ImplicitAPI):
1645
1647
  # }
1646
1648
  # ]
1647
1649
  #
1648
- return self.parse_orders(response, market, since, limit)
1650
+ orderWithStatus = []
1651
+ for i in range(0, len(response)):
1652
+ order = response[i]
1653
+ extendOrder = {}
1654
+ if self.safe_string(order, 'status') is None:
1655
+ extendOrder['ccxtStatus'] = 'open'
1656
+ orderWithStatus.append(self.extend(order, extendOrder))
1657
+ return self.parse_orders(orderWithStatus, market, since, limit)
1649
1658
 
1650
1659
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1651
1660
  """
@@ -1657,8 +1666,53 @@ class hyperliquid(Exchange, ImplicitAPI):
1657
1666
  :param str [params.user]: user address, will default to self.walletAddress if not provided
1658
1667
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1659
1668
  """
1669
+ await self.load_markets()
1670
+ orders = await self.fetch_orders(symbol, None, None, params) # don't filter here because we don't want to catch open orders
1671
+ closedOrders = self.filter_by_array(orders, 'status', ['closed'], False)
1672
+ return self.filter_by_symbol_since_limit(closedOrders, symbol, since, limit)
1673
+
1674
+ async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1675
+ """
1676
+ fetch all canceled orders
1677
+ :param str symbol: unified market symbol
1678
+ :param int [since]: the earliest time in ms to fetch open orders for
1679
+ :param int [limit]: the maximum number of open orders structures to retrieve
1680
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1681
+ :param str [params.user]: user address, will default to self.walletAddress if not provided
1682
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1683
+ """
1684
+ await self.load_markets()
1685
+ orders = await self.fetch_orders(symbol, None, None, params) # don't filter here because we don't want to catch open orders
1686
+ closedOrders = self.filter_by_array(orders, 'status', ['canceled'], False)
1687
+ return self.filter_by_symbol_since_limit(closedOrders, symbol, since, limit)
1688
+
1689
+ async def fetch_canceled_and_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1690
+ """
1691
+ fetch all closed and canceled orders
1692
+ :param str symbol: unified market symbol
1693
+ :param int [since]: the earliest time in ms to fetch open orders for
1694
+ :param int [limit]: the maximum number of open orders structures to retrieve
1695
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1696
+ :param str [params.user]: user address, will default to self.walletAddress if not provided
1697
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1698
+ """
1699
+ await self.load_markets()
1700
+ orders = await self.fetch_orders(symbol, None, None, params) # don't filter here because we don't want to catch open orders
1701
+ closedOrders = self.filter_by_array(orders, 'status', ['canceled', 'closed', 'rejected'], False)
1702
+ return self.filter_by_symbol_since_limit(closedOrders, symbol, since, limit)
1703
+
1704
+ async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1705
+ """
1706
+ fetch all orders
1707
+ :param str symbol: unified market symbol
1708
+ :param int [since]: the earliest time in ms to fetch open orders for
1709
+ :param int [limit]: the maximum number of open orders structures to retrieve
1710
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1711
+ :param str [params.user]: user address, will default to self.walletAddress if not provided
1712
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1713
+ """
1660
1714
  userAddress = None
1661
- userAddress, params = self.handle_public_address('fetchClosedOrders', params)
1715
+ userAddress, params = self.handle_public_address('fetchOrders', params)
1662
1716
  await self.load_markets()
1663
1717
  market = self.safe_market(symbol)
1664
1718
  request: dict = {
@@ -1829,20 +1883,20 @@ class hyperliquid(Exchange, ImplicitAPI):
1829
1883
  coin = self.safe_string(entry, 'coin')
1830
1884
  marketId = None
1831
1885
  if coin is not None:
1832
- if coin.find('/') > -1:
1833
- marketId = coin
1834
- else:
1835
- marketId = coin + '/USDC:USDC'
1886
+ marketId = self.coin_to_market_id(coin)
1836
1887
  if self.safe_string(entry, 'id') is None:
1837
1888
  market = self.safe_market(marketId, None)
1838
1889
  else:
1839
1890
  market = self.safe_market(marketId, market)
1840
1891
  symbol = market['symbol']
1841
1892
  timestamp = self.safe_integer_2(order, 'timestamp', 'statusTimestamp')
1842
- status = self.safe_string(order, 'status')
1893
+ status = self.safe_string_2(order, 'status', 'ccxtStatus')
1894
+ order = self.omit(order, ['ccxtStatus'])
1843
1895
  side = self.safe_string(entry, 'side')
1844
1896
  if side is not None:
1845
1897
  side = 'sell' if (side == 'A') else 'buy'
1898
+ totalAmount = self.safe_string_2(entry, 'origSz', 'totalSz')
1899
+ remaining = self.safe_string(entry, 'sz')
1846
1900
  return self.safe_order({
1847
1901
  'info': order,
1848
1902
  'id': self.safe_string(entry, 'oid'),
@@ -1857,13 +1911,13 @@ class hyperliquid(Exchange, ImplicitAPI):
1857
1911
  'postOnly': None,
1858
1912
  'reduceOnly': self.safe_bool(entry, 'reduceOnly'),
1859
1913
  'side': side,
1860
- 'price': self.safe_number(entry, 'limitPx'),
1914
+ 'price': self.safe_string(entry, 'limitPx'),
1861
1915
  'triggerPrice': self.safe_number(entry, 'triggerPx') if self.safe_bool(entry, 'isTrigger') else None,
1862
- 'amount': self.safe_number_2(entry, 'sz', 'totalSz'),
1916
+ 'amount': totalAmount,
1863
1917
  'cost': None,
1864
- 'average': self.safe_number(entry, 'avgPx'),
1865
- 'filled': None,
1866
- 'remaining': None,
1918
+ 'average': self.safe_string(entry, 'avgPx'),
1919
+ 'filled': Precise.string_sub(totalAmount, remaining),
1920
+ 'remaining': remaining,
1867
1921
  'status': self.parse_order_status(status),
1868
1922
  'fee': None,
1869
1923
  'trades': None,
@@ -1957,7 +2011,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1957
2011
  price = self.safe_string(trade, 'px')
1958
2012
  amount = self.safe_string(trade, 'sz')
1959
2013
  coin = self.safe_string(trade, 'coin')
1960
- marketId = coin + '/USDC:USDC'
2014
+ marketId = self.coin_to_market_id(coin)
1961
2015
  market = self.safe_market(marketId, None)
1962
2016
  symbol = market['symbol']
1963
2017
  id = self.safe_string(trade, 'tid')
@@ -2091,7 +2145,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2091
2145
  #
2092
2146
  entry = self.safe_dict(position, 'position', {})
2093
2147
  coin = self.safe_string(entry, 'coin')
2094
- marketId = coin + '/USDC:USDC'
2148
+ marketId = self.coin_to_market_id(coin)
2095
2149
  market = self.safe_market(marketId, None)
2096
2150
  symbol = market['symbol']
2097
2151
  leverage = self.safe_dict(entry, 'leverage', {})
@@ -2377,11 +2431,13 @@ class hyperliquid(Exchange, ImplicitAPI):
2377
2431
  """
2378
2432
  make a withdrawal(only support USDC)
2379
2433
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request
2434
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault
2380
2435
  :param str code: unified currency code
2381
2436
  :param float amount: the amount to withdraw
2382
2437
  :param str address: the address to withdraw to
2383
2438
  :param str tag:
2384
2439
  :param dict [params]: extra parameters specific to the exchange API endpoint
2440
+ :param str [params.vaultAddress]: vault address withdraw from
2385
2441
  :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2386
2442
  """
2387
2443
  self.check_required_credentials()
@@ -2391,24 +2447,38 @@ class hyperliquid(Exchange, ImplicitAPI):
2391
2447
  code = code.upper()
2392
2448
  if code != 'USDC':
2393
2449
  raise NotSupported(self.id + 'withdraw() only support USDC')
2394
- isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
2450
+ vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2451
+ params = self.omit(params, 'vaultAddress')
2395
2452
  nonce = self.milliseconds()
2396
- payload: dict = {
2397
- 'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
2398
- 'destination': address,
2399
- 'amount': str(amount),
2400
- 'time': nonce,
2401
- }
2402
- sig = self.build_withdraw_sig(payload)
2403
- request: dict = {
2404
- 'action': {
2453
+ action: dict = {}
2454
+ sig = None
2455
+ if vaultAddress is not None:
2456
+ action = {
2457
+ 'type': 'vaultTransfer',
2458
+ 'vaultAddress': '0x' + vaultAddress,
2459
+ 'isDeposit': False,
2460
+ 'usd': amount,
2461
+ }
2462
+ sig = self.sign_l1_action(action, nonce)
2463
+ else:
2464
+ isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
2465
+ payload: dict = {
2466
+ 'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
2467
+ 'destination': address,
2468
+ 'amount': str(amount),
2469
+ 'time': nonce,
2470
+ }
2471
+ sig = self.build_withdraw_sig(payload)
2472
+ action = {
2405
2473
  'hyperliquidChain': payload['hyperliquidChain'],
2406
2474
  'signatureChainId': '0x66eee', # check self out
2407
2475
  'destination': address,
2408
2476
  'amount': str(amount),
2409
2477
  'time': nonce,
2410
2478
  'type': 'withdraw3',
2411
- },
2479
+ }
2480
+ request: dict = {
2481
+ 'action': action,
2412
2482
  'nonce': nonce,
2413
2483
  'signature': sig,
2414
2484
  }
@@ -2419,27 +2489,51 @@ class hyperliquid(Exchange, ImplicitAPI):
2419
2489
  #
2420
2490
  # {status: 'ok', response: {type: 'default'}}
2421
2491
  #
2492
+ # fetchDeposits / fetchWithdrawals
2493
+ # {
2494
+ # "time":1724762307531,
2495
+ # "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781",
2496
+ # "delta":{
2497
+ # "type":"accountClassTransfer",
2498
+ # "usdc":"50.0",
2499
+ # "toPerp":false
2500
+ # }
2501
+ # }
2502
+ #
2503
+ timestamp = self.safe_integer(transaction, 'time')
2504
+ delta = self.safe_dict(transaction, 'delta', {})
2505
+ fee = None
2506
+ feeCost = self.safe_integer(delta, 'fee')
2507
+ if feeCost is not None:
2508
+ fee = {
2509
+ 'currency': 'USDC',
2510
+ 'cost': feeCost,
2511
+ }
2512
+ internal = None
2513
+ type = self.safe_string(delta, 'type')
2514
+ if type is not None:
2515
+ internal = (type == 'internalTransfer')
2422
2516
  return {
2423
2517
  'info': transaction,
2424
2518
  'id': None,
2425
- 'txid': None,
2426
- 'timestamp': None,
2427
- 'datetime': None,
2519
+ 'txid': self.safe_string(transaction, 'hash'),
2520
+ 'timestamp': timestamp,
2521
+ 'datetime': self.iso8601(timestamp),
2428
2522
  'network': None,
2429
2523
  'address': None,
2430
- 'addressTo': None,
2431
- 'addressFrom': None,
2524
+ 'addressTo': self.safe_string(delta, 'destination'),
2525
+ 'addressFrom': self.safe_string(delta, 'user'),
2432
2526
  'tag': None,
2433
2527
  'tagTo': None,
2434
2528
  'tagFrom': None,
2435
2529
  'type': None,
2436
- 'amount': None,
2530
+ 'amount': self.safe_integer(delta, 'usdc'),
2437
2531
  'currency': None,
2438
2532
  'status': self.safe_string(transaction, 'status'),
2439
2533
  'updated': None,
2440
2534
  'comment': None,
2441
- 'internal': None,
2442
- 'fee': None,
2535
+ 'internal': internal,
2536
+ 'fee': fee,
2443
2537
  }
2444
2538
 
2445
2539
  async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
@@ -2546,6 +2640,183 @@ class hyperliquid(Exchange, ImplicitAPI):
2546
2640
  'tierBased': None,
2547
2641
  }
2548
2642
 
2643
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2644
+ """
2645
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
2646
+ :param str code: unified currency code
2647
+ :param int [since]: timestamp in ms of the earliest ledger entry
2648
+ :param int [limit]: max number of ledger entrys to return
2649
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2650
+ :param int [params.until]: timestamp in ms of the latest ledger entry
2651
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2652
+ """
2653
+ await self.load_markets()
2654
+ userAddress = None
2655
+ userAddress, params = self.handle_public_address('fetchLedger', params)
2656
+ request: dict = {
2657
+ 'type': 'userNonFundingLedgerUpdates',
2658
+ 'user': userAddress,
2659
+ }
2660
+ if since is not None:
2661
+ request['startTime'] = since
2662
+ until = self.safe_integer(params, 'until')
2663
+ if until is not None:
2664
+ request['endTime'] = until
2665
+ params = self.omit(params, ['until'])
2666
+ response = await self.publicPostInfo(self.extend(request, params))
2667
+ #
2668
+ # [
2669
+ # {
2670
+ # "time":1724762307531,
2671
+ # "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781",
2672
+ # "delta":{
2673
+ # "type":"accountClassTransfer",
2674
+ # "usdc":"50.0",
2675
+ # "toPerp":false
2676
+ # }
2677
+ # }
2678
+ # ]
2679
+ #
2680
+ return self.parse_ledger(response, None, since, limit)
2681
+
2682
+ def parse_ledger_entry(self, item: dict, currency: Currency = None):
2683
+ #
2684
+ # {
2685
+ # "time":1724762307531,
2686
+ # "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781",
2687
+ # "delta":{
2688
+ # "type":"accountClassTransfer",
2689
+ # "usdc":"50.0",
2690
+ # "toPerp":false
2691
+ # }
2692
+ # }
2693
+ #
2694
+ timestamp = self.safe_integer(item, 'time')
2695
+ delta = self.safe_dict(item, 'delta', {})
2696
+ fee = None
2697
+ feeCost = self.safe_integer(delta, 'fee')
2698
+ if feeCost is not None:
2699
+ fee = {
2700
+ 'currency': 'USDC',
2701
+ 'cost': feeCost,
2702
+ }
2703
+ type = self.safe_string(delta, 'type')
2704
+ amount = self.safe_string(delta, 'usdc')
2705
+ return {
2706
+ 'id': self.safe_string(item, 'hash'),
2707
+ 'direction': None,
2708
+ 'account': None,
2709
+ 'referenceAccount': self.safe_string(delta, 'user'),
2710
+ 'referenceId': self.safe_string(item, 'hash'),
2711
+ 'type': self.parse_ledger_entry_type(type),
2712
+ 'currency': None,
2713
+ 'amount': self.parse_number(amount),
2714
+ 'timestamp': timestamp,
2715
+ 'datetime': self.iso8601(timestamp),
2716
+ 'before': None,
2717
+ 'after': None,
2718
+ 'status': None,
2719
+ 'fee': fee,
2720
+ 'info': item,
2721
+ }
2722
+
2723
+ def parse_ledger_entry_type(self, type):
2724
+ ledgerType: dict = {
2725
+ 'internalTransfer': 'transfer',
2726
+ 'accountClassTransfer': 'transfer',
2727
+ }
2728
+ return self.safe_string(ledgerType, type, type)
2729
+
2730
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2731
+ """
2732
+ fetch all deposits made to an account
2733
+ :param str code: unified currency code
2734
+ :param int [since]: the earliest time in ms to fetch deposits for
2735
+ :param int [limit]: the maximum number of deposits structures to retrieve
2736
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2737
+ :param int [params.until]: the latest time in ms to fetch withdrawals for
2738
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2739
+ """
2740
+ await self.load_markets()
2741
+ userAddress = None
2742
+ userAddress, params = self.handle_public_address('fetchDepositsWithdrawals', params)
2743
+ request: dict = {
2744
+ 'type': 'userNonFundingLedgerUpdates',
2745
+ 'user': userAddress,
2746
+ }
2747
+ if since is not None:
2748
+ request['startTime'] = since
2749
+ until = self.safe_integer(params, 'until')
2750
+ if until is not None:
2751
+ request['endTime'] = until
2752
+ params = self.omit(params, ['until'])
2753
+ response = await self.publicPostInfo(self.extend(request, params))
2754
+ #
2755
+ # [
2756
+ # {
2757
+ # "time":1724762307531,
2758
+ # "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781",
2759
+ # "delta":{
2760
+ # "type":"accountClassTransfer",
2761
+ # "usdc":"50.0",
2762
+ # "toPerp":false
2763
+ # }
2764
+ # }
2765
+ # ]
2766
+ #
2767
+ records = self.extract_type_from_delta(response)
2768
+ deposits = self.filter_by_array(records, 'type', ['deposit'], False)
2769
+ return self.parse_transactions(deposits, None, since, limit)
2770
+
2771
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2772
+ """
2773
+ fetch all withdrawals made from an account
2774
+ :param str code: unified currency code
2775
+ :param int [since]: the earliest time in ms to fetch withdrawals for
2776
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
2777
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2778
+ :param int [params.until]: the latest time in ms to fetch withdrawals for
2779
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2780
+ """
2781
+ await self.load_markets()
2782
+ userAddress = None
2783
+ userAddress, params = self.handle_public_address('fetchDepositsWithdrawals', params)
2784
+ request: dict = {
2785
+ 'type': 'userNonFundingLedgerUpdates',
2786
+ 'user': userAddress,
2787
+ }
2788
+ if since is not None:
2789
+ request['startTime'] = since
2790
+ until = self.safe_integer(params, 'until')
2791
+ if until is not None:
2792
+ request['endTime'] = until
2793
+ params = self.omit(params, ['until'])
2794
+ response = await self.publicPostInfo(self.extend(request, params))
2795
+ #
2796
+ # [
2797
+ # {
2798
+ # "time":1724762307531,
2799
+ # "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781",
2800
+ # "delta":{
2801
+ # "type":"accountClassTransfer",
2802
+ # "usdc":"50.0",
2803
+ # "toPerp":false
2804
+ # }
2805
+ # }
2806
+ # ]
2807
+ #
2808
+ records = self.extract_type_from_delta(response)
2809
+ withdrawals = self.filter_by_array(records, 'type', ['withdraw'], False)
2810
+ return self.parse_transactions(withdrawals, None, since, limit)
2811
+
2812
+ def extract_type_from_delta(self, data=[]):
2813
+ records = []
2814
+ for i in range(0, len(data)):
2815
+ record = data[i]
2816
+ record['type'] = record['delta']['type']
2817
+ records.append(record)
2818
+ return records
2819
+
2549
2820
  def format_vault_address(self, address: Str = None):
2550
2821
  if address is None:
2551
2822
  return None
@@ -2565,7 +2836,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2565
2836
  raise ArgumentsRequired(self.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set')
2566
2837
 
2567
2838
  def coin_to_market_id(self, coin: Str):
2568
- if coin.find('/') > -1:
2839
+ if coin.find('/') > -1 or coin.find('@') > -1:
2569
2840
  return coin # spot
2570
2841
  return coin + '/USDC:USDC'
2571
2842
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.independentreserve import ImplicitAPI
8
+ import asyncio
8
9
  import hashlib
9
10
  from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, TradingFees, Transaction
10
11
  from typing import List
@@ -154,11 +155,12 @@ class independentreserve(Exchange, ImplicitAPI):
154
155
  :param dict [params]: extra parameters specific to the exchange API endpoint
155
156
  :returns dict[]: an array of objects representing market data
156
157
  """
157
- baseCurrencies = await self.publicGetGetValidPrimaryCurrencyCodes(params)
158
+ baseCurrenciesPromise = self.publicGetGetValidPrimaryCurrencyCodes(params)
158
159
  # ['Xbt', 'Eth', 'Usdt', ...]
159
- quoteCurrencies = await self.publicGetGetValidSecondaryCurrencyCodes(params)
160
+ quoteCurrenciesPromise = self.publicGetGetValidSecondaryCurrencyCodes(params)
160
161
  # ['Aud', 'Usd', 'Nzd', 'Sgd']
161
- limits = await self.publicGetGetOrderMinimumVolumes(params)
162
+ limitsPromise = self.publicGetGetOrderMinimumVolumes(params)
163
+ baseCurrencies, quoteCurrencies, limits = await asyncio.gather(*[baseCurrenciesPromise, quoteCurrenciesPromise, limitsPromise])
162
164
  #
163
165
  # {
164
166
  # "Xbt": 0.0001,
@@ -831,6 +831,8 @@ class indodax(Exchange, ImplicitAPI):
831
831
  elif type == 'limit':
832
832
  priceIsRequired = True
833
833
  quantityIsRequired = True
834
+ if side == 'buy':
835
+ request[market['quoteId']] = self.parse_to_numeric(Precise.string_mul(self.number_to_string(amount), self.number_to_string(price)))
834
836
  if priceIsRequired:
835
837
  if price is None:
836
838
  raise InvalidOrder(self.id + ' createOrder() requires a price argument for a ' + type + ' order')
@@ -645,6 +645,7 @@ class kucoin(Exchange, ImplicitAPI):
645
645
  'KALT': 'ALT', # ALTLAYER
646
646
  },
647
647
  'options': {
648
+ 'hf': False,
648
649
  'version': 'v1',
649
650
  'symbolSeparator': '-',
650
651
  'fetchMyTradesMethod': 'private_get_fills',
@@ -1228,9 +1229,8 @@ class kucoin(Exchange, ImplicitAPI):
1228
1229
  status: Int = self.safe_integer(data, 'status')
1229
1230
  self.options['hfMigrated'] = (status == 2)
1230
1231
 
1231
- async def handle_hf_and_params(self, params={}):
1232
- await self.load_migration_status()
1233
- migrated: Bool = self.safe_bool(self.options, 'hfMigrated')
1232
+ def handle_hf_and_params(self, params={}):
1233
+ migrated: Bool = self.safe_bool_2(self.options, 'hfMigrated', 'hf', False)
1234
1234
  loadedHf: Bool = None
1235
1235
  if migrated is not None:
1236
1236
  if migrated:
@@ -2068,7 +2068,7 @@ class kucoin(Exchange, ImplicitAPI):
2068
2068
  testOrder = self.safe_bool(params, 'test', False)
2069
2069
  params = self.omit(params, 'test')
2070
2070
  hf = None
2071
- hf, params = await self.handle_hf_and_params(params)
2071
+ hf, params = self.handle_hf_and_params(params)
2072
2072
  useSync = False
2073
2073
  useSync, params = self.handle_option_and_params(params, 'createOrder', 'sync', False)
2074
2074
  triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
@@ -2184,7 +2184,7 @@ class kucoin(Exchange, ImplicitAPI):
2184
2184
  'orderList': ordersRequests,
2185
2185
  }
2186
2186
  hf = None
2187
- hf, params = await self.handle_hf_and_params(params)
2187
+ hf, params = self.handle_hf_and_params(params)
2188
2188
  useSync = False
2189
2189
  useSync, params = self.handle_option_and_params(params, 'createOrders', 'sync', False)
2190
2190
  response = None
@@ -2356,7 +2356,7 @@ class kucoin(Exchange, ImplicitAPI):
2356
2356
  clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
2357
2357
  stop = self.safe_bool_2(params, 'stop', 'trigger', False)
2358
2358
  hf = None
2359
- hf, params = await self.handle_hf_and_params(params)
2359
+ hf, params = self.handle_hf_and_params(params)
2360
2360
  useSync = False
2361
2361
  useSync, params = self.handle_option_and_params(params, 'cancelOrder', 'sync', False)
2362
2362
  if hf or useSync:
@@ -2464,7 +2464,7 @@ class kucoin(Exchange, ImplicitAPI):
2464
2464
  request: dict = {}
2465
2465
  stop = self.safe_bool(params, 'stop', False)
2466
2466
  hf = None
2467
- hf, params = await self.handle_hf_and_params(params)
2467
+ hf, params = self.handle_hf_and_params(params)
2468
2468
  params = self.omit(params, 'stop')
2469
2469
  marginMode, query = self.handle_margin_mode_and_params('cancelAllOrders', params)
2470
2470
  if symbol is not None:
@@ -2513,7 +2513,7 @@ class kucoin(Exchange, ImplicitAPI):
2513
2513
  until = self.safe_integer(params, 'until')
2514
2514
  stop = self.safe_bool_2(params, 'stop', 'trigger', False)
2515
2515
  hf = None
2516
- hf, params = await self.handle_hf_and_params(params)
2516
+ hf, params = self.handle_hf_and_params(params)
2517
2517
  if hf and (symbol is None):
2518
2518
  raise ArgumentsRequired(self.id + ' fetchOrdersByStatus() requires a symbol parameter for hf orders')
2519
2519
  params = self.omit(params, ['stop', 'trigger', 'till', 'until'])
@@ -2675,7 +2675,7 @@ class kucoin(Exchange, ImplicitAPI):
2675
2675
  clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
2676
2676
  stop = self.safe_bool_2(params, 'stop', 'trigger', False)
2677
2677
  hf = None
2678
- hf, params = await self.handle_hf_and_params(params)
2678
+ hf, params = self.handle_hf_and_params(params)
2679
2679
  market = None
2680
2680
  if symbol is not None:
2681
2681
  market = self.market(symbol)
@@ -2926,7 +2926,7 @@ class kucoin(Exchange, ImplicitAPI):
2926
2926
  return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
2927
2927
  request: dict = {}
2928
2928
  hf = None
2929
- hf, params = await self.handle_hf_and_params(params)
2929
+ hf, params = self.handle_hf_and_params(params)
2930
2930
  if hf and symbol is None:
2931
2931
  raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol parameter for hf orders')
2932
2932
  market = None
@@ -3601,7 +3601,7 @@ class kucoin(Exchange, ImplicitAPI):
3601
3601
  type = self.safe_string(accountsByType, requestedType, requestedType)
3602
3602
  params = self.omit(params, 'type')
3603
3603
  hf = None
3604
- hf, params = await self.handle_hf_and_params(params)
3604
+ hf, params = self.handle_hf_and_params(params)
3605
3605
  if hf:
3606
3606
  type = 'trade_hf'
3607
3607
  marginMode, query = self.handle_margin_mode_and_params('fetchBalance', params)
@@ -4030,7 +4030,7 @@ class kucoin(Exchange, ImplicitAPI):
4030
4030
  paginate = False
4031
4031
  paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
4032
4032
  hf = None
4033
- hf, params = await self.handle_hf_and_params(params)
4033
+ hf, params = self.handle_hf_and_params(params)
4034
4034
  if paginate:
4035
4035
  return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
4036
4036
  request: dict = {