Phase 5 — Risk Framework
Layers (as implemented)
| Layer | Component | Production |
|---|---|---|
| Pre-trade signal | RiskManager.check_signal |
Yes |
| Pre-trade order | ComplianceGateway.check_order + portfolio_state |
Yes (fixed #82) |
| Portfolio drawdown | DrawdownManager |
Yes — soft 8%, hard 15%, per-day cool-off |
| Kill switch | KillTier WARN→THROTTLE→NO_NEW→FLATTEN |
Yes |
| Dead man's switch | DeadManSwitch 300s |
Yes (same process — see gap) |
| Factor / VaR display | API risk panel | Wired #74 — gates sizing: no |
| EVT / stress | qgtm_risk/evt.py, stress.py |
Dashboard-only |
Limits (defaults, qgtm_core/constants.py + RiskLimits)
| Limit | Value |
|---|---|
| Max drawdown | 15% |
| Daily circuit | 3% |
| Weekly circuit | 5% |
| Single name | 15% |
| Sector | 40% |
| Gross leverage target | 2.0x (raised #52) |
| Intraday capital fraction | 50% of equity |
| Intraday rebalance notional cap | Per INTRADAY_STRATEGY_REBALANCE_MAX_NOTIONAL_PCT |
Drawdown manager (critical fix on main)
- Per-day cool-off/re-entry (
_last_step_date) — fixes 2.5-minute cool-off bug. - Peak reset on re-entry complete (
1f0964b8) — fixes permanent zero exposure after recovery. - Verify on droplet: if pinned at
9d9fa79d, peak-reset may be missing.
Quarantine as risk control
QUARANTINED_STRATEGIES frozenset — daemon skips in rebalance. Authoritative kill list until OOS rehab.
Attestation
Daily risk attestation via:
See scripts/risk_report.py for JSON + exit code on breach.
Gaps vs institutional standard
| Gap | Priority |
|---|---|
| EVT not in sizing path | P1 |
| Options greeks / margin | P1 if trading options |
| Independent DMS process | P1 |
| Live vs paper limit parity | P0 before live gate |
| Stress tests automated pre-open | P2 |