# Quant-Rust-Strategist Memory ## Architecture Overview - ~100-symbol universe across 14 sectors (expanded from original 50) - Hybrid momentum + mean-reversion via regime-adaptive dual signal in `generate_signal()` - strategy.rs: shared logic between bot.rs and backtester.rs - Backtester restricts buys to top momentum stocks (TOP_MOMENTUM_COUNT) - Signal thresholds: StrongBuy>=7.0, Buy>=4.0, Sell<=-4.0, StrongSell<=-7.0 ## Bugs Fixed (2026-02-13) ### 1. calculate_results used self.cash instead of equity curve final value - backtester.rs line ~686: `let final_value = self.cash` missed open positions - Fixed: use `self.equity_history.last().portfolio_value` ### 2. Drawdown circuit breaker cascading re-triggers - peak_portfolio_value was never reset after halt, causing immediate re-trigger - 7+ triggers in 3yr = ~140 bars (19% of backtest) sitting in cash - Fixed: reset peak to current value on halt resume ### 3. PDT blocking sells in backtester (disabled) - PDT sell-blocking removed from backtester; it measures strategy alpha not compliance - Late-day entry prevention in execute_buy remains for hourly PDT defense - would_be_day_trade was called AFTER position removal = always false (logic bug) ## PDT Implementation (2026-02-12) - Tracks day trades in rolling 5-business-day window, max 3 allowed - CRITICAL: Stop-loss exits must NEVER be blocked by PDT (risk mgmt > compliance) - Late-day entry prevention: On hourly, block buys after 19:00 UTC (~last 2 hours) - PDT blocking DISABLED in backtester (kept in bot.rs for live trading) ## Current Parameters (config.rs, updated 2026-02-13) - ATR Stop: 3.0x | Trail: 2.0x distance, 2.0x activation - Risk: 1.2%/trade, max 25% position, 5% cash reserve, 5% max loss - Max 7 positions, 2/sector | Drawdown halt: 15% (10 bars) | Time exit: 40 - Cooldown: 5 bars | Ramp-up: 15 bars | Slippage: 10bps - Buy threshold: 4.0 (lowered from 4.5) | Momentum pool: top 20 (widened from 10) - Daily: momentum=63, ema_trend=50 | Hourly: momentum=63, ema_trend=200 - ADX: range<20, trend>25, strong>40 ## Hourly Timeframe: DO NOT CHANGE FROM BASELINE - Hourly IndicatorParams: momentum=63, ema_trend=200 (long lookbacks filter IEX noise) - Shorter periods (momentum=21, ema_trend=50): CATASTROPHIC -8% loss ## Failed Experiments (avoid repeating) 1. Tighter ATR stop (<3.0x): too many stop-outs on hourly 2. Lower buy threshold (3.5): too many weak entries (but 4.0 is fine) 3. Blocking stop-loss exits for PDT: traps capital in losers, dangerous 4. Lower volume threshold (0.7): bad trades on IEX. Keep 0.8 5. Shorter hourly lookbacks: catastrophic losses 6. Drawdown halt 12% with non-resetting peak: cascading re-triggers in multi-year tests ## IEX Data Stochasticity - Backtests have significant run-to-run variation from IEX data timing - Do NOT panic about minor performance swings between runs - Always run 2-3 times and compare ranges before concluding a change helped/hurt ## Build Notes - `cargo build --release` compiles clean (only dead_code warnings for types.rs fields) - No tests exist