feat: support hyperliquid unified account
This commit is contained in:
@@ -5,11 +5,20 @@ from copy import deepcopy
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import ccxt
|
||||
|
||||
from freqtrade.constants import BuySell
|
||||
from freqtrade.enums import MarginMode, TradingMode
|
||||
from freqtrade.enums.runmode import NON_UTIL_MODES
|
||||
from freqtrade.exceptions import ConfigurationError, ExchangeError, OperationalException
|
||||
from freqtrade.exceptions import (
|
||||
ConfigurationError,
|
||||
DDosProtection,
|
||||
ExchangeError,
|
||||
OperationalException,
|
||||
TemporaryError,
|
||||
)
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.exchange.common import retrier
|
||||
from freqtrade.exchange.exchange_types import CcxtBalances, CcxtOrder, CcxtPosition, FtHas
|
||||
from freqtrade.util.datetime_helpers import dt_from_ts
|
||||
|
||||
@@ -22,6 +31,8 @@ class Hyperliquid(Exchange):
|
||||
Contains adjustments needed for Freqtrade to work with this exchange.
|
||||
"""
|
||||
|
||||
unified_account = False
|
||||
|
||||
_ft_has: FtHas = {
|
||||
"ohlcv_has_history": False,
|
||||
"l2_limit_range": [20],
|
||||
@@ -58,6 +69,36 @@ class Hyperliquid(Exchange):
|
||||
config.update(super()._ccxt_config)
|
||||
return config
|
||||
|
||||
@retrier
|
||||
def additional_exchange_init(self) -> None:
|
||||
"""
|
||||
Additional exchange initialization logic.
|
||||
.api will be available at this point.
|
||||
Query User account Account Type to determine unified account status
|
||||
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#query-a-users-abstraction-state
|
||||
"""
|
||||
|
||||
try:
|
||||
if self.trading_mode == TradingMode.FUTURES and not self._config["dry_run"]:
|
||||
# Determine account status
|
||||
# Unified accounts must use the spot endpoint for balances
|
||||
request = {
|
||||
"type": "userAbstraction",
|
||||
"user": self._api.walletAddress,
|
||||
}
|
||||
response = self._api.publicPostInfo(request)
|
||||
self.unified_account = response in ('"unifiedAccount"', '"portfolioMargin"')
|
||||
|
||||
except ccxt.DDoSProtection as e:
|
||||
raise DDosProtection(e) from e
|
||||
except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
|
||||
raise TemporaryError(
|
||||
f"Error in additional_exchange_init due to {e.__class__.__name__}. Message: {e}"
|
||||
) from e
|
||||
|
||||
except ccxt.BaseError as e:
|
||||
raise OperationalException(e) from e
|
||||
|
||||
def _get_configured_hip3_dexes(self) -> list[str]:
|
||||
"""Get list of configured HIP-3 DEXes."""
|
||||
return self._config.get("exchange", {}).get("hip3_dexes", [])
|
||||
@@ -122,7 +163,10 @@ class Hyperliquid(Exchange):
|
||||
This override is not absolutely necessary and is only there for correct used / total values
|
||||
which are however not used by Freqtrade in futures mode at the moment.
|
||||
"""
|
||||
balances = super().get_balances()
|
||||
params = params or {}
|
||||
if self.unified_account:
|
||||
params["type"] = "spot"
|
||||
balances = super().get_balances(params)
|
||||
dexes = self._get_configured_hip3_dexes()
|
||||
for dex in dexes:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user