it be better

This commit is contained in:
zastian-dev
2026-02-13 13:12:22 +00:00
parent 80a8e7c346
commit 1ef03999b7
6 changed files with 250 additions and 223 deletions

View File

@@ -4,26 +4,36 @@
- ~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 10 momentum stocks (TOP_MOMENTUM_COUNT=10)
- Signal thresholds: StrongBuy>=7.0, Buy>=4.5, Sell<=-4.0, StrongSell<=-7.0
- 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)
- Prevents entries needing same-day stop-loss exits
- Reduced hourly trades 100->86, improved PF 1.24->1.59
- "PDT performance degradation" was mostly IEX data stochasticity, not actual PDT blocking
- PDT blocking DISABLED in backtester (kept in bot.rs for live trading)
## Backtest Results (3-month, 2026-02-12, post-PDT-fix)
### Hourly: +12.00%, Sharpe 0.12, PF 1.59, 52% WR, 86 trades, MaxDD -9.36%
### Daily: +11.68%, Sharpe 2.65, PF 3.07, 61% WR, 18 trades, MaxDD -5.36%
## Current Parameters (config.rs)
## 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: 12% (20 bars) | Time exit: 40
- 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
@@ -33,10 +43,11 @@
## 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. Keep 4.5
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
@@ -44,5 +55,5 @@
- 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)
- `cargo build --release` compiles clean (only dead_code warnings for types.rs fields)
- No tests exist