Make symbol risk guard configurable

This commit is contained in:
Codex
2026-06-27 17:28:52 +03:00
parent 7d84bf38cc
commit 57d9514eec
8 changed files with 76 additions and 8 deletions
+1
View File
@@ -67,6 +67,7 @@ def make_settings():
kelly_max_fraction=0.20,
risk_per_trade_percent=0.01,
risk_guard_enabled=True,
risk_symbol_guard_enabled=True,
risk_recent_trade_window=20,
risk_max_consecutive_losses=4,
risk_min_recent_profit_factor=0.85,
+41 -1
View File
@@ -34,7 +34,12 @@ def test_risk_guard_reduces_size_after_consecutive_losses(make_settings, tmp_pat
def test_risk_guard_blocks_only_bad_symbol(make_settings, tmp_path) -> None:
settings = make_settings(tmp_path, risk_max_consecutive_losses=3, symbols=["BTCUSDT", "ETHUSDT"])
settings = make_settings(
tmp_path,
risk_symbol_guard_enabled=True,
risk_max_consecutive_losses=3,
symbols=["BTCUSDT", "ETHUSDT"],
)
storage = Storage(settings.database_path)
now = utc_now()
for _ in range(3):
@@ -76,6 +81,41 @@ def test_risk_guard_blocks_only_bad_symbol(make_settings, tmp_path) -> None:
assert symbol_rows["ETHUSDT"]["block_new_entries"] is False
def test_risk_guard_can_disable_symbol_blocks(make_settings, tmp_path) -> None:
settings = make_settings(
tmp_path,
risk_symbol_guard_enabled=False,
risk_max_consecutive_losses=3,
symbols=["BTCUSDT", "ETHUSDT"],
)
storage = Storage(settings.database_path)
now = utc_now()
for _ in range(3):
storage.insert_trade(
Trade(
id=None,
symbol="BTCUSDT",
side="SELL",
qty=1.0,
entry_price=100.0,
exit_price=99.0,
net_pnl=-1.0,
opened_at=now,
closed_at=now,
entry_diagnostics={"forecast": {"probability_up": 0.64, "model": "torch_gru"}},
)
)
guard = risk_guard_snapshot(settings, storage.closed_trades(), storage.latest_equity())
assert guard["symbol_guard_enabled"] is False
assert guard["blocked_symbols"] == []
symbol_rows = {row["symbol"]: row for row in guard["symbols"]}
assert symbol_rows["BTCUSDT"]["consecutive_losses"] == 3
assert symbol_rows["BTCUSDT"]["block_new_entries"] is False
assert symbol_rows["BTCUSDT"]["reasons"] == []
def test_risk_guard_ignores_trades_outside_active_universe(make_settings, tmp_path) -> None:
settings = make_settings(tmp_path, risk_max_consecutive_losses=2, symbols=["BTCUSDT", "ETHUSDT"])
storage = Storage(settings.database_path)
+15
View File
@@ -52,6 +52,21 @@ def test_fast_trading_env_sets_effective_intervals(tmp_path, monkeypatch) -> Non
assert settings.max_entries_per_minute == 4
def test_symbol_risk_guard_can_be_disabled(tmp_path, monkeypatch) -> None:
monkeypatch.delenv("RISK_SYMBOL_GUARD_ENABLED", raising=False)
monkeypatch.setenv("TRADING_MODE", "paper")
env_file = tmp_path / ".env"
env_file.write_text(
"TRADING_MODE=paper\nRISK_SYMBOL_GUARD_ENABLED=false\n",
encoding="utf-8",
)
settings = load_settings(env_file)
assert settings.risk_guard_enabled is True
assert settings.risk_symbol_guard_enabled is False
def test_llm_advisor_is_disabled_by_default(tmp_path, monkeypatch) -> None:
monkeypatch.delenv("LLM_ADVISOR_ENABLED", raising=False)
monkeypatch.setenv("TRADING_MODE", "paper")