← all research
REJECTED

"Phase 6 — Risk & sizing (Alpaca crypto)"

2026-08-15

Status: DONE (2026-08-15) · Suite: 294 passed, 2 skipped (+13 tests in tests/test_alpaca_risk.py)

What was built

data/alpaca/risk.py — vol-targeted sizing + wall-clock trading guardrails for the long/flat bar system.

Sizing (no leverage, spot only)

risk_budget = equity * risk_per_trade            (config 2%)
qty         = risk_budget / ATR                  (coin units)
notional    = min(qty * price, equity * max_position_pct)   (cap: 10%)

Guardrails (RiskManager, state machine)

GateBehavior
daily loss limit (max_drawdown_daily, 5%)halts until the next UTC day
total drawdown (max_drawdown_total, 15%)halts until equity recovers above peak × (1-thresh); computed from running peak, not sticky
consecutive-loss cooldown (cooldown_after_loss, 4)after N losses in a row, skip N trades (a win serves one)
max daily trades (max_daily_trades, 12)halts for the day
no equityhard halt

Tests

13 offline tests: exact notional math (cap binding, 1-ATR cost = risk budget when uncapped), min-notional skip, degenerate inputs → 0, non-negative qty, long-only realized PnL, daily gate + UTC day roll, cooldown arming/serving, computed (recoverable) drawdown halt, max-daily-trades, peak tracking, config defaults, halt_reason helper.

Integration

Phase 7's paper executor consumes RiskManager + size() per signal before ordering: gate → size → market/limit order. The Phase-8 monitor reports the halt reasons; the same guards apply to live trading.