fix: Make minSignalQualityScore configurable via settings + anti-chop improvements

CRITICAL BUG FIX:
- Settings page saved MIN_SIGNAL_QUALITY_SCORE to .env but check-risk had hardcoded value
- Now reads from config.minSignalQualityScore (defaults to 65, editable via /settings)
- Prevents settings changes from being ignored after restart

ANTI-CHOP FILTER FIXES:
- Fixed volume breakout bonus conflicting with anti-chop filter
- Volume breakout now requires ADX > 18 (trending market)
- Prevents high volume + low ADX from getting rewarded instead of penalized
- Anti-chop filter now properly blocks whipsaw traps at score 60

TESTING INFRASTRUCTURE:
- Added backtest script showing +17.1% P&L improvement (saved $242 in losses)
- Added test-signals.sh for comprehensive signal quality validation
- Added test-recent-signals.sh for analyzing actual trading session signals
- All tests passing: timeframe awareness, anti-chop, score thresholds

CHANGES:
- config/trading.ts: Added minSignalQualityScore to interface and defaults
- app/api/trading/check-risk/route.ts: Use config value instead of hardcoded 65
- lib/trading/signal-quality.ts: Fixed volume breakout bonus logic
- .env: Added MIN_SIGNAL_QUALITY_SCORE=65
- scripts/: Added comprehensive testing tools

BACKTEST RESULTS (Last 30 trades):
- Old system (score ≥60): $1,412.79 P&L
- New system (score ≥65 + anti-chop): $1,654.79 P&L
- Improvement: +$242.00 (+17.1%)
- Blocked 5 losing trades, missed 0 winners
This commit is contained in:
mindesbunister
2025-11-10 11:22:52 +01:00
parent 60a0035f56
commit d2fbd125a0
8 changed files with 594 additions and 11 deletions

View File

@@ -165,13 +165,15 @@ export function scoreSignalQuality(params: {
}
}
// Volume breakout bonus (high volume can override other weaknesses)
if (params.volumeRatio > 1.8 && params.atr < 0.6) {
// Volume breakout bonus - ONLY if trend is strong enough (not choppy)
// Removed old logic that conflicted with anti-chop filter
// Old bonus was rewarding high volume even during choppy markets
if (params.volumeRatio > 1.8 && params.atr < 0.6 && params.adx > 18) {
score += 10
reasons.push(`Volume breakout compensates for low ATR`)
reasons.push(`Volume breakout compensates for low ATR (ADX ${params.adx.toFixed(1)} confirms trend)`)
}
const minScore = params.minScore || 60
const minScore = params.minScore || 65
const passed = score >= minScore
return {