Risk Limits Reference
Risk limits are configured in config/risk_limits.yaml. These settings control the four layers of risk management that protect your capital.
File Location
config/risk_limits.yaml
Restart the backend after making changes:
./scripts/restart-backend.sh
Settings
autonomy_mode
Controls system autonomy level. See Autonomy Modes.
autonomy_mode: PAPER_ONLY # PAPER_ONLY | MANUAL_APPROVAL | BOUNDED_AUTONOMOUS | FULL_AUTONOMOUS
Options:
PAPER_ONLY: Simulated trades only, no real moneyMANUAL_APPROVAL: System generates signals, you approve each tradeBOUNDED_AUTONOMOUS: System executes within strict limitsFULL_AUTONOMOUS: System operates with full discretion
Default: PAPER_ONLY
position_limits
Layer 1 risk controls for individual positions.
position_limits:
max_position_pct: 5.0 # Max 5% of portfolio per position
max_sector_pct: 25.0 # Max 25% per sector
stop_loss_pct: 2.0 # 2% stop-loss per position
min_price: 5.0 # No penny stocks (< $5)
no_leverage: true # No margin/leverage
Settings:
-
max_position_pct (default:
5.0): Maximum percentage of portfolio value in a single position. A $10,000 portfolio can hold max $500 in any one stock. -
max_sector_pct (default:
25.0): Maximum percentage of portfolio value in a single sector. Prevents sector concentration risk. -
stop_loss_pct (default:
2.0): Automatic stop-loss percentage per position. If a position drops 2% from entry price, it’s automatically sold. -
min_price (default:
5.0): Minimum stock price in dollars. Stocks below this price are filtered out (no penny stocks). -
no_leverage (default:
true): Disables margin and leverage. Set tofalseto enable margin trading (not recommended).
portfolio_limits
Layer 2 risk controls for overall portfolio health.
portfolio_limits:
max_drawdown_pct: 10.0 # Halt trading if drawdown exceeds 10%
max_daily_loss_pct: 3.0 # Max 3% daily loss
max_positions: 20 # Max 20 concurrent positions
max_daily_trades: 50 # Max 50 trades per day
min_cash_reserve_pct: 10.0 # Keep 10% in cash
Settings:
-
max_drawdown_pct (default:
10.0): Maximum drawdown from peak equity. If your account drops 10% from its highest value, all trading halts until you manually restart. -
max_daily_loss_pct (default:
3.0): Maximum loss in a single trading day. If you lose 3% of portfolio value in one day, trading halts until the next day. -
max_positions (default:
20): Maximum number of concurrent open positions. Limits complexity and ensures diversification. -
max_daily_trades (default:
50): Maximum number of trades per day. Prevents runaway trading and excessive transaction costs. -
min_cash_reserve_pct (default:
10.0): Minimum percentage of portfolio kept in cash. Ensures liquidity for opportunities and withdrawals.
pdt_guard
Layer 1 component: Pattern Day Trading rule enforcement.
pdt_guard:
enabled: true
max_day_trades: 3 # Max 3 day trades per 5 business days (FINRA PDT rule)
rolling_window_days: 5 # Rolling 5 business day window
account_threshold: 25000.0 # PDT rule applies under $25K
Settings:
-
enabled (default:
true): Enable/disable PDT guard. ⚠️ Do not disable unless you have a PDT-exempt account (≥$25K equity) or are in PAPER_ONLY mode. -
max_day_trades (default:
3): Maximum day trades per rolling window (FINRA regulation). -
rolling_window_days (default:
5): Rolling window in business days (FINRA regulation). -
account_threshold (default:
25000.0): Account equity threshold in dollars. Accounts below this are subject to PDT restrictions.
circuit_breakers
Layer 3 risk controls for abnormal market or system conditions.
circuit_breakers:
vix_threshold: 35.0 # Halt trading if VIX > 35
stale_data_seconds: 300 # Alert if data older than 5 minutes
reconciliation_interval_seconds: 300 # Check positions every 5 minutes
max_reconciliation_drift_pct: 1.0 # Alert if positions drift > 1%
dead_man_switch_hours: 48 # Require operator heartbeat every 48 hours
Settings:
-
vix_threshold (default:
35.0): VIX level that triggers trading halt. VIX >35 indicates extreme market volatility (panic/crash conditions). -
stale_data_seconds (default:
300): Maximum age of price data in seconds. If data is older than 5 minutes, trading pauses (detects feed interruptions). -
reconciliation_interval_seconds (default:
300): How often to reconcile positions with broker (every 5 minutes). -
max_reconciliation_drift_pct (default:
1.0): Maximum allowed drift between system’s position records and broker’s actual positions. Alerts if drift exceeds 1%. -
dead_man_switch_hours (default:
48): Maximum time without operator check-in. If no human oversight for 48 hours, trading halts automatically.
kill_switch
Layer 4: Emergency manual override settings.
kill_switch:
http_enabled: true
telegram_enabled: false
cooldown_minutes: 60 # After kill switch, wait 60 min before restart
Settings:
-
http_enabled (default:
true): Enable HTTP API endpoint for kill switch (POST /api/risk/kill-switch). -
telegram_enabled (default:
false): Enable Telegram bot commands for kill switch (requires Telegram bot setup). -
cooldown_minutes (default:
60): Cooldown period after kill switch activation. After activating kill switch, you must wait 60 minutes before resuming trading (prevents panic flip-flopping).
Environment Variable Overrides
Risk limits can be overridden using environment variables:
# Change autonomy mode
export SA_RISK__AUTONOMY_MODE=MANUAL_APPROVAL
# Adjust position limits
export SA_RISK__POSITION_LIMITS__MAX_POSITION_PCT=3.0
# Adjust PDT threshold
export SA_RISK__PDT_GUARD__ACCOUNT_THRESHOLD=30000.0
Format: SA_RISK__<section>__<key>=value
Conservative Defaults
The default limits are intentionally conservative:
- Small positions: 5% max per position (20 positions needed for full diversification)
- Tight stops: 2% stop-loss per position (limits downside)
- Low daily loss: 3% max daily loss (prevents spiral losses)
- Moderate drawdown: 10% max drawdown (protects against prolonged losing streaks)
Recommended: Start with defaults, then gradually relax limits after gaining confidence in the system.
Risk Limit Violations
When a limit is breached:
- Order rejected: New orders that would violate limits are blocked
- Dashboard alert: Risk page shows warning with violated limit
- Log entry: Violation logged to
logs/backend.log - Notification: Alert sent via configured channels (Slack/Telegram)
Some violations halt trading entirely (max drawdown, max daily loss, circuit breakers). Others just block specific orders (position size, PDT).
Monitoring
The Risk page displays:
- Current vs. max values for all limits
- Warning indicators when approaching limits (e.g., 80% of max drawdown)
- Circuit breaker status (active/inactive)
- PDT counter (X/3 day trades used)
- Recent risk events log
Related Topics
- Risk Management — Explanation of the 4 layers
- PDT Rule — Pattern Day Trading details
- Autonomy Modes — How autonomy affects risk controls
- Kill Switch — Emergency halt procedure
- Application Settings — Other configuration options