Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/quant_strategy_plugins/market_regime_control_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ def build_market_regime_control_signal(
final_route = ROUTE_BLOCKED
suggested_action = ACTION_BLOCKED
route_source = COMPONENT_BENCHMARK_GUARD
# The generic guard owns a hard fail-closed data contract. Keep this
# output shadow-only, but expose zero scalars and a defense requirement
# so a separately approved strategy consumer cannot accidentally treat
# absent/stale benchmark data as permission to retain risk.
risk_budget_scalar = 0.0
leverage_scalar = 0.0
risk_asset_scalar = 0.0
crisis_defense_required = True
blocked_actions = ("increase_leverage", "increase_risk", "taco_rebound_veto", "panic_reversal_veto")
reason_codes.extend(
f"benchmark_guard:{code}"
for code in _reason_codes(benchmark_guard) or ("blocked",)
Expand Down
27 changes: 27 additions & 0 deletions tests/test_benchmark_drawdown_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,30 @@ def test_unified_market_regime_requires_an_explicit_policy_to_mount_the_guard()
assert payload["position_control"]["risk_asset_scalar"] == 0.5
with pytest.raises(ValueError, match="explicit frozen policy"):
_build_market_regime_control_payload(_prices([100.0] * 30), {"benchmark_drawdown_guard_enabled": True})


def test_unified_market_regime_preserves_fail_closed_scalars_when_guard_data_is_unavailable() -> None:
config = {
"crisis_enabled": False,
"macro_enabled": False,
"taco_enabled": False,
"panic_reversal_enabled": False,
"benchmark_drawdown_guard_enabled": True,
"benchmark_guard_benchmark_symbol": "QQQ",
"benchmark_guard_drawdown_lookback_sessions": 20,
"benchmark_guard_soft_drawdown_threshold": -0.05,
"benchmark_guard_hard_drawdown_threshold": -0.10,
"benchmark_guard_soft_risk_asset_scalar": 0.50,
"benchmark_guard_hard_risk_asset_scalar": 0.0,
"benchmark_guard_max_price_age_days": 3,
"as_of": "2026-02-12",
}

payload = _build_market_regime_control_payload(pd.DataFrame(), config)

assert payload["canonical_route"] == ROUTE_BLOCKED
assert payload["position_control"]["risk_budget_scalar"] == 0.0
assert payload["position_control"]["leverage_scalar"] == 0.0
assert payload["position_control"]["risk_asset_scalar"] == 0.0
assert payload["position_control"]["crisis_defense_required"] is True
assert payload["execution_controls"]["broker_order_allowed"] is False