test: refactor hyperliquid fake markets into a fixture
This commit is contained in:
@@ -8,28 +8,118 @@ from freqtrade.exceptions import ConfigurationError
|
|||||||
from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has_re
|
from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has_re
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("margin_mode", ["isolated", "cross"])
|
@pytest.fixture
|
||||||
def test_hyperliquid_dry_run_liquidation_price(default_conf, mocker, margin_mode):
|
def markets_hip3():
|
||||||
# test if liq price calculated by dry_run_liquidation_price() is close to ccxt liq price
|
|
||||||
# testing different pairs with large/small prices, different leverages, long, short
|
|
||||||
markets = {
|
markets = {
|
||||||
"BTC/USDC:USDC": {"limits": {"leverage": {"max": 50}}, "info": {}},
|
"BTC/USDC:USDC": {
|
||||||
"ETH/USDC:USDC": {"limits": {"leverage": {"max": 50}}, "info": {}},
|
"quote": "USDC",
|
||||||
"SOL/USDC:USDC": {"limits": {"leverage": {"max": 20}}, "info": {}},
|
"base": "BTC",
|
||||||
"DOGE/USDC:USDC": {"limits": {"leverage": {"max": 20}}, "info": {}},
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 50}},
|
||||||
|
"info": {},
|
||||||
|
},
|
||||||
|
"ETH/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "ETH",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 50}},
|
||||||
|
"info": {},
|
||||||
|
},
|
||||||
|
"SOL/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "SOL",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 20}},
|
||||||
|
"info": {},
|
||||||
|
},
|
||||||
|
"DOGE/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "DOGE",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 20}},
|
||||||
|
"info": {},
|
||||||
|
},
|
||||||
"XYZ-AAPL/USDC:USDC": {
|
"XYZ-AAPL/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "XYZ-AAPL",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
"limits": {"leverage": {"max": 10}},
|
"limits": {"leverage": {"max": 10}},
|
||||||
"info": {"hip3": True, "dex": "xyz"},
|
"info": {"hip3": True, "dex": "xyz"},
|
||||||
},
|
},
|
||||||
"XYZ-TSLA/USDC:USDC": {
|
"XYZ-TSLA/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "XYZ-TSLA",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
"limits": {"leverage": {"max": 10}},
|
"limits": {"leverage": {"max": 10}},
|
||||||
"info": {"hip3": True, "dex": "xyz"},
|
"info": {"hip3": True, "dex": "xyz"},
|
||||||
},
|
},
|
||||||
"XYZ-GOOGL/USDC:USDC": {
|
"XYZ-GOOGL/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "XYZ-GOOGL",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
"limits": {"leverage": {"max": 10}},
|
"limits": {"leverage": {"max": 10}},
|
||||||
"info": {"hip3": True, "dex": "xyz"},
|
"info": {"hip3": True, "dex": "xyz"},
|
||||||
},
|
},
|
||||||
|
"XYZ-NVDA/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "XYZ-NVDA",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 10}},
|
||||||
|
"info": {"hip3": True, "dex": "xyz"},
|
||||||
|
},
|
||||||
|
"VNTL-SPACEX/USDH:USDH": {
|
||||||
|
"quote": "USDH",
|
||||||
|
"base": "VNTL-SPACEX",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 3}},
|
||||||
|
"info": {"hip3": True, "dex": "vntl"},
|
||||||
|
},
|
||||||
|
"VNTL-ANTHROPIC/USDH:USDH": {
|
||||||
|
"quote": "USDH",
|
||||||
|
"base": "VNTL-ANTHROPIC",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 3}},
|
||||||
|
"info": {"hip3": True, "dex": "vntl"},
|
||||||
|
},
|
||||||
|
"FLX-TOKEN/USDC:USDC": {
|
||||||
|
"quote": "USDC",
|
||||||
|
"base": "FLX-TOKEN",
|
||||||
|
"type": "swap",
|
||||||
|
"swap": True,
|
||||||
|
"linear": True,
|
||||||
|
"limits": {"leverage": {"max": 3}},
|
||||||
|
"info": {"hip3": True, "dex": "flx"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return markets
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("margin_mode", ["isolated", "cross"])
|
||||||
|
def test_hyperliquid_dry_run_liquidation_price(default_conf, markets_hip3, mocker, margin_mode):
|
||||||
|
# test if liq price calculated by dry_run_liquidation_price() is close to ccxt liq price
|
||||||
|
# testing different pairs with large/small prices, different leverages, long, short
|
||||||
|
|
||||||
positions = [
|
positions = [
|
||||||
{
|
{
|
||||||
"symbol": "ETH/USDC:USDC",
|
"symbol": "ETH/USDC:USDC",
|
||||||
@@ -326,7 +416,7 @@ def test_hyperliquid_dry_run_liquidation_price(default_conf, mocker, margin_mode
|
|||||||
default_conf["margin_mode"] = margin_mode
|
default_conf["margin_mode"] = margin_mode
|
||||||
default_conf["stake_currency"] = "USDC"
|
default_conf["stake_currency"] = "USDC"
|
||||||
api_mock.load_markets = get_mock_coro()
|
api_mock.load_markets = get_mock_coro()
|
||||||
api_mock.markets = markets
|
api_mock.markets = markets_hip3
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
||||||
)
|
)
|
||||||
@@ -402,17 +492,7 @@ def test_hyperliquid_get_funding_fees(default_conf, mocker):
|
|||||||
assert exchange._fetch_and_calculate_funding_fees.call_count == 1
|
assert exchange._fetch_and_calculate_funding_fees.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_get_max_leverage(default_conf, mocker):
|
def test_hyperliquid_get_max_leverage(default_conf, mocker, markets_hip3):
|
||||||
markets = {
|
|
||||||
"BTC/USDC:USDC": {"limits": {"leverage": {"max": 50}}},
|
|
||||||
"ETH/USDC:USDC": {"limits": {"leverage": {"max": 50}}},
|
|
||||||
"SOL/USDC:USDC": {"limits": {"leverage": {"max": 20}}},
|
|
||||||
"DOGE/USDC:USDC": {"limits": {"leverage": {"max": 20}}},
|
|
||||||
"XYZ-TSLA/USDC:USDC": {"limits": {"leverage": {"max": 10}}},
|
|
||||||
"XYZ-NVDA/USDC:USDC": {"limits": {"leverage": {"max": 10}}},
|
|
||||||
"VNTL-SPACEX/USDH:USDH": {"limits": {"leverage": {"max": 3}}},
|
|
||||||
"VNTL-ANTHROPIC/USDH:USDH": {"limits": {"leverage": {"max": 3}}},
|
|
||||||
}
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, exchange="hyperliquid")
|
exchange = get_patched_exchange(mocker, default_conf, exchange="hyperliquid")
|
||||||
assert exchange.get_max_leverage("BTC/USDC:USDC", 1) == 1.0
|
assert exchange.get_max_leverage("BTC/USDC:USDC", 1) == 1.0
|
||||||
|
|
||||||
@@ -424,7 +504,7 @@ def test_hyperliquid_get_max_leverage(default_conf, mocker):
|
|||||||
mocker.patch("freqtrade.exchange.hyperliquid.Hyperliquid.validate_config")
|
mocker.patch("freqtrade.exchange.hyperliquid.Hyperliquid.validate_config")
|
||||||
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, exchange="hyperliquid")
|
exchange = get_patched_exchange(mocker, default_conf, exchange="hyperliquid")
|
||||||
mocker.patch.multiple(EXMS, markets=PropertyMock(return_value=markets))
|
mocker.patch.multiple(EXMS, markets=PropertyMock(return_value=markets_hip3))
|
||||||
|
|
||||||
# Normal markets
|
# Normal markets
|
||||||
assert exchange.get_max_leverage("BTC/USDC:USDC", 1) == 50
|
assert exchange.get_max_leverage("BTC/USDC:USDC", 1) == 50
|
||||||
@@ -498,7 +578,7 @@ def test_hyperliquid__lev_prep(default_conf, mocker):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_fetch_order(default_conf_usdt, mocker):
|
def test_hyperliquid_fetch_order(default_conf_usdt, mocker, markets_hip3):
|
||||||
default_conf_usdt["dry_run"] = False
|
default_conf_usdt["dry_run"] = False
|
||||||
default_conf_usdt["trading_mode"] = "futures"
|
default_conf_usdt["trading_mode"] = "futures"
|
||||||
default_conf_usdt["margin_mode"] = "isolated"
|
default_conf_usdt["margin_mode"] = "isolated"
|
||||||
@@ -506,15 +586,6 @@ def test_hyperliquid_fetch_order(default_conf_usdt, mocker):
|
|||||||
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
|
|
||||||
# Mock markets with HIP-3 info
|
|
||||||
markets = {
|
|
||||||
"ETH/USDC:USDC": {"info": {}},
|
|
||||||
"XYZ-TSLA/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}},
|
|
||||||
"VNTL-SPACEX/USDH:USDH": {"info": {"hip3": True, "dex": "vntl"}},
|
|
||||||
}
|
|
||||||
api_mock.markets = markets
|
|
||||||
api_mock.load_markets = get_mock_coro(return_value=markets)
|
|
||||||
|
|
||||||
# Test with normal market
|
# Test with normal market
|
||||||
api_mock.fetch_order = MagicMock(
|
api_mock.fetch_order = MagicMock(
|
||||||
return_value={
|
return_value={
|
||||||
@@ -547,8 +618,9 @@ def test_hyperliquid_fetch_order(default_conf_usdt, mocker):
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
mocker.patch("freqtrade.exchange.hyperliquid.Hyperliquid.validate_config")
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
o = exchange.fetch_order("12345", "ETH/USDC:USDC")
|
o = exchange.fetch_order("12345", "ETH/USDC:USDC")
|
||||||
# Uses weighted average
|
# Uses weighted average
|
||||||
@@ -623,29 +695,23 @@ def test_hyperliquid_fetch_order(default_conf_usdt, mocker):
|
|||||||
assert gtfo_mock.call_count == 1
|
assert gtfo_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_hip3_config_validation(default_conf_usdt, mocker):
|
def test_hyperliquid_hip3_config_validation(default_conf_usdt, mocker, markets_hip3):
|
||||||
"""Test HIP-3 DEX configuration validation."""
|
"""Test HIP-3 DEX configuration validation."""
|
||||||
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
markets = {
|
|
||||||
"BTC/USDC:USDC": {"info": {}},
|
|
||||||
"XYZ-AAPL/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}},
|
|
||||||
}
|
|
||||||
api_mock.load_markets = get_mock_coro(return_value=markets)
|
|
||||||
api_mock.markets = markets
|
|
||||||
|
|
||||||
# Futures mode, no dex configured
|
# Futures mode, no dex configured
|
||||||
default_conf_copy = deepcopy(default_conf_usdt)
|
default_conf_copy = deepcopy(default_conf_usdt)
|
||||||
default_conf_copy["trading_mode"] = "futures"
|
default_conf_copy["trading_mode"] = "futures"
|
||||||
default_conf_copy["margin_mode"] = "isolated"
|
default_conf_copy["margin_mode"] = "isolated"
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_copy, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_copy, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
exchange.validate_config(default_conf_copy)
|
exchange.validate_config(default_conf_copy)
|
||||||
|
|
||||||
# Not in futures mode - no dex configured - no error
|
# Not in futures mode - no dex configured - no error
|
||||||
get_patched_exchange(
|
get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
# Not in futures mode
|
# Not in futures mode
|
||||||
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz"]
|
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz"]
|
||||||
@@ -653,14 +719,14 @@ def test_hyperliquid_hip3_config_validation(default_conf_usdt, mocker):
|
|||||||
ConfigurationError, match=r"HIP-3 DEXes are only supported in FUTURES trading mode\."
|
ConfigurationError, match=r"HIP-3 DEXes are only supported in FUTURES trading mode\."
|
||||||
):
|
):
|
||||||
get_patched_exchange(
|
get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
# Valid single DEX
|
# Valid single DEX
|
||||||
default_conf_usdt["trading_mode"] = "futures"
|
default_conf_usdt["trading_mode"] = "futures"
|
||||||
default_conf_usdt["margin_mode"] = "isolated"
|
default_conf_usdt["margin_mode"] = "isolated"
|
||||||
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz"]
|
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz"]
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
assert exchange._get_configured_hip3_dexes() == ["xyz"]
|
assert exchange._get_configured_hip3_dexes() == ["xyz"]
|
||||||
|
|
||||||
@@ -668,7 +734,7 @@ def test_hyperliquid_hip3_config_validation(default_conf_usdt, mocker):
|
|||||||
default_conf_usdt["exchange"]["hip3_dexes"] = ["invalid_dex"]
|
default_conf_usdt["exchange"]["hip3_dexes"] = ["invalid_dex"]
|
||||||
with pytest.raises(ConfigurationError, match="Invalid HIP-3 DEXes configured"):
|
with pytest.raises(ConfigurationError, match="Invalid HIP-3 DEXes configured"):
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
exchange.validate_config(default_conf_usdt)
|
exchange.validate_config(default_conf_usdt)
|
||||||
|
|
||||||
@@ -676,29 +742,23 @@ def test_hyperliquid_hip3_config_validation(default_conf_usdt, mocker):
|
|||||||
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz", "invalid_dex"]
|
default_conf_usdt["exchange"]["hip3_dexes"] = ["xyz", "invalid_dex"]
|
||||||
with pytest.raises(ConfigurationError, match="Invalid HIP-3 DEXes configured"):
|
with pytest.raises(ConfigurationError, match="Invalid HIP-3 DEXes configured"):
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
exchange.validate_config(default_conf_usdt)
|
exchange.validate_config(default_conf_usdt)
|
||||||
|
|
||||||
default_conf_usdt["margin_mode"] = "cross"
|
default_conf_usdt["margin_mode"] = "cross"
|
||||||
with pytest.raises(ConfigurationError, match="HIP-3 DEXes require 'isolated' margin mode"):
|
with pytest.raises(ConfigurationError, match="HIP-3 DEXes require 'isolated' margin mode"):
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf_usdt, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
exchange.validate_config(default_conf_usdt)
|
exchange.validate_config(default_conf_usdt)
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_get_balances_hip3(default_conf, mocker, caplog):
|
def test_hyperliquid_get_balances_hip3(default_conf, mocker, caplog, markets_hip3):
|
||||||
"""Test balance fetching from HIP-3 DEXes."""
|
"""Test balance fetching from HIP-3 DEXes."""
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
markets = {
|
|
||||||
"BTC/USDC:USDC": {"info": {}},
|
|
||||||
"XYZ-AAPL/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}},
|
|
||||||
"VNTL-SPACEX/USDH:USDH": {"info": {"hip3": True, "dex": "vntl"}},
|
|
||||||
"FLX-TOKEN/USDC:USDC": {"info": {"hip3": True, "dex": "flx"}},
|
|
||||||
}
|
|
||||||
api_mock.load_markets = get_mock_coro()
|
api_mock.load_markets = get_mock_coro()
|
||||||
api_mock.markets = markets
|
|
||||||
|
|
||||||
# Mock balance responses
|
# Mock balance responses
|
||||||
default_balance = {"USDC": {"free": 1000, "used": 0, "total": 1000}}
|
default_balance = {"USDC": {"free": 1000, "used": 0, "total": 1000}}
|
||||||
@@ -720,8 +780,9 @@ def test_hyperliquid_get_balances_hip3(default_conf, mocker, caplog):
|
|||||||
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl", "flx"]
|
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl", "flx"]
|
||||||
default_conf["trading_mode"] = "futures"
|
default_conf["trading_mode"] = "futures"
|
||||||
default_conf["margin_mode"] = "isolated"
|
default_conf["margin_mode"] = "isolated"
|
||||||
|
mocker.patch("freqtrade.exchange.hyperliquid.Hyperliquid.validate_config")
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
|
|
||||||
balances = exchange.get_balances()
|
balances = exchange.get_balances()
|
||||||
@@ -738,17 +799,9 @@ def test_hyperliquid_get_balances_hip3(default_conf, mocker, caplog):
|
|||||||
assert log_has_re("Could not fetch balance for HIP-3 DEX.*", caplog)
|
assert log_has_re("Could not fetch balance for HIP-3 DEX.*", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_fetch_positions_hip3(default_conf, mocker, caplog):
|
def test_hyperliquid_fetch_positions_hip3(default_conf, mocker, caplog, markets_hip3):
|
||||||
"""Test position fetching from HIP-3 DEXes."""
|
"""Test position fetching from HIP-3 DEXes."""
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
markets = {
|
|
||||||
"BTC/USDC:USDC": {"info": {}},
|
|
||||||
"XYZ-AAPL/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}},
|
|
||||||
"VNTL-SPACEX/USDH:USDH": {"info": {"hip3": True, "dex": "vntl"}},
|
|
||||||
"FLX-TOKEN/USDC:USDC": {"info": {"hip3": True, "dex": "flx"}},
|
|
||||||
}
|
|
||||||
api_mock.load_markets = get_mock_coro(return_value=markets)
|
|
||||||
api_mock.markets = markets
|
|
||||||
|
|
||||||
# Mock position responses
|
# Mock position responses
|
||||||
default_positions = [{"symbol": "BTC/USDC:USDC", "contracts": 0.5}]
|
default_positions = [{"symbol": "BTC/USDC:USDC", "contracts": 0.5}]
|
||||||
@@ -770,8 +823,9 @@ def test_hyperliquid_fetch_positions_hip3(default_conf, mocker, caplog):
|
|||||||
default_conf["margin_mode"] = "isolated"
|
default_conf["margin_mode"] = "isolated"
|
||||||
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl", "flx"]
|
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl", "flx"]
|
||||||
|
|
||||||
|
mocker.patch("freqtrade.exchange.hyperliquid.Hyperliquid.validate_config")
|
||||||
exchange = get_patched_exchange(
|
exchange = get_patched_exchange(
|
||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=markets_hip3
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mock super().fetch_positions() to return default positions
|
# Mock super().fetch_positions() to return default positions
|
||||||
@@ -791,21 +845,13 @@ def test_hyperliquid_fetch_positions_hip3(default_conf, mocker, caplog):
|
|||||||
assert positions_mock.call_count == 4
|
assert positions_mock.call_count == 4
|
||||||
|
|
||||||
|
|
||||||
def test_hyperliquid_market_is_tradable(default_conf, mocker):
|
def test_hyperliquid_market_is_tradable(default_conf, mocker, markets_hip3):
|
||||||
"""Test market_is_tradable filters HIP-3 markets correctly."""
|
"""Test market_is_tradable filters HIP-3 markets correctly."""
|
||||||
default_conf["trading_mode"] = "futures"
|
default_conf["trading_mode"] = "futures"
|
||||||
default_conf["margin_mode"] = "isolated"
|
default_conf["margin_mode"] = "isolated"
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
markets = {
|
api_mock.load_markets = get_mock_coro(return_value=markets_hip3)
|
||||||
"BTC/USDC:USDC": {"info": {}, "active": True},
|
api_mock.markets = markets_hip3
|
||||||
"ETH/USDC:USDC": {"info": {}, "active": True},
|
|
||||||
"XYZ-AAPL/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}, "active": True},
|
|
||||||
"XYZ-TSLA/USDC:USDC": {"info": {"hip3": True, "dex": "xyz"}, "active": True},
|
|
||||||
"VNTL-SPACEX/USDH:USDH": {"info": {"hip3": True, "dex": "vntl"}, "active": True},
|
|
||||||
"FLX-TOKEN/USDC:USDC": {"info": {"hip3": True, "dex": "flx"}, "active": True},
|
|
||||||
}
|
|
||||||
api_mock.load_markets = get_mock_coro(return_value=markets)
|
|
||||||
api_mock.markets = markets
|
|
||||||
# Mock parent call - we only want to test hyperliquid specifics here.
|
# Mock parent call - we only want to test hyperliquid specifics here.
|
||||||
mocker.patch(f"{EXMS}.market_is_tradable", return_value=True)
|
mocker.patch(f"{EXMS}.market_is_tradable", return_value=True)
|
||||||
|
|
||||||
@@ -815,12 +861,12 @@ def test_hyperliquid_market_is_tradable(default_conf, mocker):
|
|||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
||||||
)
|
)
|
||||||
|
|
||||||
assert exchange.market_is_tradable(markets["BTC/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["BTC/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["ETH/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["ETH/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["XYZ-AAPL/USDC:USDC"]) is False
|
assert exchange.market_is_tradable(markets_hip3["XYZ-AAPL/USDC:USDC"]) is False
|
||||||
assert exchange.market_is_tradable(markets["XYZ-TSLA/USDC:USDC"]) is False
|
assert exchange.market_is_tradable(markets_hip3["XYZ-TSLA/USDC:USDC"]) is False
|
||||||
assert exchange.market_is_tradable(markets["VNTL-SPACEX/USDH:USDH"]) is False
|
assert exchange.market_is_tradable(markets_hip3["VNTL-SPACEX/USDH:USDH"]) is False
|
||||||
assert exchange.market_is_tradable(markets["FLX-TOKEN/USDC:USDC"]) is False
|
assert exchange.market_is_tradable(markets_hip3["FLX-TOKEN/USDC:USDC"]) is False
|
||||||
|
|
||||||
# Test 2: Only 'xyz' configured - default + xyz markets tradable
|
# Test 2: Only 'xyz' configured - default + xyz markets tradable
|
||||||
default_conf["exchange"]["hip3_dexes"] = ["xyz"]
|
default_conf["exchange"]["hip3_dexes"] = ["xyz"]
|
||||||
@@ -828,12 +874,12 @@ def test_hyperliquid_market_is_tradable(default_conf, mocker):
|
|||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
||||||
)
|
)
|
||||||
|
|
||||||
assert exchange.market_is_tradable(markets["BTC/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["BTC/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["ETH/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["ETH/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["XYZ-AAPL/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["XYZ-AAPL/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["XYZ-TSLA/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["XYZ-TSLA/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["VNTL-SPACEX/USDH:USDH"]) is False
|
assert exchange.market_is_tradable(markets_hip3["VNTL-SPACEX/USDH:USDH"]) is False
|
||||||
assert exchange.market_is_tradable(markets["FLX-TOKEN/USDC:USDC"]) is False
|
assert exchange.market_is_tradable(markets_hip3["FLX-TOKEN/USDC:USDC"]) is False
|
||||||
|
|
||||||
# Test 3: 'xyz' and 'vntl' configured - default + xyz + vntl markets tradable
|
# Test 3: 'xyz' and 'vntl' configured - default + xyz + vntl markets tradable
|
||||||
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl"]
|
default_conf["exchange"]["hip3_dexes"] = ["xyz", "vntl"]
|
||||||
@@ -841,9 +887,9 @@ def test_hyperliquid_market_is_tradable(default_conf, mocker):
|
|||||||
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
mocker, default_conf, api_mock, exchange="hyperliquid", mock_markets=False
|
||||||
)
|
)
|
||||||
|
|
||||||
assert exchange.market_is_tradable(markets["BTC/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["BTC/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["ETH/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["ETH/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["XYZ-AAPL/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["XYZ-AAPL/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["XYZ-TSLA/USDC:USDC"]) is True
|
assert exchange.market_is_tradable(markets_hip3["XYZ-TSLA/USDC:USDC"]) is True
|
||||||
assert exchange.market_is_tradable(markets["VNTL-SPACEX/USDH:USDH"]) is True
|
assert exchange.market_is_tradable(markets_hip3["VNTL-SPACEX/USDH:USDH"]) is True
|
||||||
assert exchange.market_is_tradable(markets["FLX-TOKEN/USDC:USDC"]) is False
|
assert exchange.market_is_tradable(markets_hip3["FLX-TOKEN/USDC:USDC"]) is False
|
||||||
|
|||||||
Reference in New Issue
Block a user