Make symbol risk guard configurable
This commit is contained in:
@@ -112,6 +112,9 @@ def risk_guard_snapshot(
|
||||
"enabled": False,
|
||||
"block_new_entries": False,
|
||||
"position_size_multiplier": 1.0,
|
||||
"symbol_guard_enabled": settings.risk_symbol_guard_enabled,
|
||||
"blocked_symbols": [],
|
||||
"symbols": [],
|
||||
"reasons": [],
|
||||
}
|
||||
active_trades = _active_universe_trades(settings, closed_trades)
|
||||
@@ -145,6 +148,7 @@ def risk_guard_snapshot(
|
||||
"reasons": all_reasons,
|
||||
"global_reasons": reasons,
|
||||
"degraded_reasons": degraded_reasons,
|
||||
"symbol_guard_enabled": settings.risk_symbol_guard_enabled,
|
||||
"blocked_symbols": blocked_symbols,
|
||||
"symbols": symbol_stats,
|
||||
"consecutive_losses": consecutive_losses,
|
||||
@@ -202,6 +206,7 @@ def _active_universe_trades(settings: Settings, trades: list[dict[str, Any]]) ->
|
||||
def _symbol_guard_stats(settings: Settings, trades: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
expectancy_min_samples = max(6, min(settings.risk_recent_trade_window, 10))
|
||||
loss_streak_min_samples = max(3, settings.risk_max_consecutive_losses)
|
||||
symbol_guard_enabled = settings.risk_symbol_guard_enabled
|
||||
rows: list[dict[str, Any]] = []
|
||||
for symbol in settings.symbols:
|
||||
symbol_trades = [trade for trade in trades if str(trade.get("symbol", "")).upper() == symbol.upper()]
|
||||
@@ -209,17 +214,19 @@ def _symbol_guard_stats(settings: Settings, trades: list[dict[str, Any]]) -> lis
|
||||
stats = _trade_stats(recent)
|
||||
losses = _consecutive_losses(recent)
|
||||
reasons: list[str] = []
|
||||
if stats["trades"] >= expectancy_min_samples:
|
||||
if stats["profit_factor"] < settings.risk_min_recent_profit_factor and stats["avg_net_percent"] <= 0:
|
||||
reasons.append("symbol_expectancy_negative")
|
||||
if stats["trades"] >= loss_streak_min_samples:
|
||||
if losses >= settings.risk_max_consecutive_losses:
|
||||
reasons.append("symbol_consecutive_losses")
|
||||
if symbol_guard_enabled:
|
||||
if stats["trades"] >= expectancy_min_samples:
|
||||
if stats["profit_factor"] < settings.risk_min_recent_profit_factor and stats["avg_net_percent"] <= 0:
|
||||
reasons.append("symbol_expectancy_negative")
|
||||
if stats["trades"] >= loss_streak_min_samples:
|
||||
if losses >= settings.risk_max_consecutive_losses:
|
||||
reasons.append("symbol_consecutive_losses")
|
||||
rows.append(
|
||||
{
|
||||
"symbol": symbol.upper(),
|
||||
"block_new_entries": bool(reasons),
|
||||
"block_new_entries": bool(reasons) if symbol_guard_enabled else False,
|
||||
"reasons": reasons,
|
||||
"symbol_guard_enabled": symbol_guard_enabled,
|
||||
"consecutive_losses": losses,
|
||||
**stats,
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ class Settings:
|
||||
kelly_max_fraction: float
|
||||
risk_per_trade_percent: float
|
||||
risk_guard_enabled: bool
|
||||
risk_symbol_guard_enabled: bool
|
||||
risk_recent_trade_window: int
|
||||
risk_max_consecutive_losses: int
|
||||
risk_min_recent_profit_factor: float
|
||||
@@ -265,6 +266,7 @@ def load_settings(env_file: str | Path | None = None) -> Settings:
|
||||
kelly_max_fraction=_float_env("KELLY_MAX_FRACTION", 0.20),
|
||||
risk_per_trade_percent=_float_env("RISK_PER_TRADE_PERCENT", 0.01),
|
||||
risk_guard_enabled=_bool_env("RISK_GUARD_ENABLED", True),
|
||||
risk_symbol_guard_enabled=_bool_env("RISK_SYMBOL_GUARD_ENABLED", True),
|
||||
risk_recent_trade_window=_int_env("RISK_RECENT_TRADE_WINDOW", 20),
|
||||
risk_max_consecutive_losses=_int_env("RISK_MAX_CONSECUTIVE_LOSSES", 4),
|
||||
risk_min_recent_profit_factor=_float_env("RISK_MIN_RECENT_PROFIT_FACTOR", 0.85),
|
||||
|
||||
@@ -290,6 +290,7 @@ def _safe_config(settings: Settings) -> dict[str, Any]:
|
||||
"kelly_max_fraction": settings.kelly_max_fraction,
|
||||
"risk_per_trade_percent": settings.risk_per_trade_percent,
|
||||
"risk_guard_enabled": settings.risk_guard_enabled,
|
||||
"risk_symbol_guard_enabled": settings.risk_symbol_guard_enabled,
|
||||
"risk_recent_trade_window": settings.risk_recent_trade_window,
|
||||
"risk_max_consecutive_losses": settings.risk_max_consecutive_losses,
|
||||
"risk_min_recent_profit_factor": settings.risk_min_recent_profit_factor,
|
||||
|
||||
Reference in New Issue
Block a user