feat: Direction-specific quality thresholds (long=90, short=95)

- DATA-DRIVEN: 227 trades analysis showed longs 71.4% WR vs shorts 28.6% WR at quality 90-94
- LONG threshold: 90 (captures profitable 90-94 signals: +4.77 total, +.40 avg)
- SHORT threshold: 95 (blocks toxic 90-94 signals: -53.76 total, -9.11 avg)
- Historical validation: Quality 90+ longs +00.62 vs shorts -77.90

Modified files:
- config/trading.ts: Added minSignalQualityScoreLong/Short fields + getMinQualityScoreForDirection()
- lib/trading/signal-quality.ts: Accept direction-specific minScore parameter
- app/api/trading/check-risk/route.ts: Use direction-specific thresholds
- .env: Added MIN_SIGNAL_QUALITY_SCORE_LONG=90 and _SHORT=95

Fallback logic: direction-specific → global → 60 default
Backward compatible with existing code
This commit is contained in:
mindesbunister
2025-11-23 15:01:56 +01:00
parent 625566224a
commit 01aaa0932a
5 changed files with 111 additions and 9 deletions

View File

@@ -58,8 +58,10 @@ export interface TradingConfig {
trailingStopMaxPercent: number // Maximum trailing distance in percent
trailingStopActivation: number // Activate when runner profits exceed this %
// Signal Quality
minSignalQualityScore: number // Minimum quality score for initial entry (0-100)
// Signal Quality (Direction-specific thresholds - Nov 23, 2025)
minSignalQualityScore: number // Global fallback (0-100)
minSignalQualityScoreLong?: number // Override for LONG signals (0-100)
minSignalQualityScoreShort?: number // Override for SHORT signals (0-100)
// Position Scaling (add to winning positions)
enablePositionScaling: boolean // Allow scaling into existing positions
@@ -156,8 +158,12 @@ export const DEFAULT_TRADING_CONFIG: TradingConfig = {
trailingStopMaxPercent: 0.9, // Cap trailing distance at 0.9%
trailingStopActivation: 0.5, // Activate trailing when runner is +0.5% in profit
// Signal Quality
minSignalQualityScore: 91, // Raised to 91 on Nov 21, 2025 after trade #7 (ADX 19.0 weak trend, quality 90, -$387 loss) - v8 averaging 93.6 with 57.1% WR
// Signal Quality (Direction-specific thresholds - Nov 23, 2025 DATA-DRIVEN UPDATE)
minSignalQualityScore: 91, // Global fallback (unchanged)
minSignalQualityScoreLong: 90, // LONGS: 71.4% WR at quality 90-94 (+$44.77 on 7 trades, +$6.40 avg)
minSignalQualityScoreShort: 95, // SHORTS: Keep strict (quality 90-94 = 28.6% WR, -$553.76 on 7 trades)
// Historical validation: Quality 90+ longs = 50% WR +$600.62 (38 trades), shorts = 47.4% WR -$177.90
// v8 data: 3 longs 100% WR +$565, 7 shorts 42.9% WR -$311
// Position Scaling (conservative defaults)
enablePositionScaling: false, // Disabled by default - enable after testing
@@ -552,6 +558,12 @@ export function getConfigFromEnv(): Partial<TradingConfig> {
minSignalQualityScore: process.env.MIN_SIGNAL_QUALITY_SCORE
? parseInt(process.env.MIN_SIGNAL_QUALITY_SCORE)
: undefined,
minSignalQualityScoreLong: process.env.MIN_SIGNAL_QUALITY_SCORE_LONG
? parseInt(process.env.MIN_SIGNAL_QUALITY_SCORE_LONG)
: undefined,
minSignalQualityScoreShort: process.env.MIN_SIGNAL_QUALITY_SCORE_SHORT
? parseInt(process.env.MIN_SIGNAL_QUALITY_SCORE_SHORT)
: undefined,
enablePositionScaling: process.env.ENABLE_POSITION_SCALING
? process.env.ENABLE_POSITION_SCALING === 'true'
: undefined,
@@ -587,6 +599,20 @@ export function getConfigFromEnv(): Partial<TradingConfig> {
return config
}
// Get minimum quality score for a specific direction (Nov 23, 2025)
export function getMinQualityScoreForDirection(
direction: 'long' | 'short',
config: TradingConfig
): number {
if (direction === 'long' && config.minSignalQualityScoreLong !== undefined) {
return config.minSignalQualityScoreLong
}
if (direction === 'short' && config.minSignalQualityScoreShort !== undefined) {
return config.minSignalQualityScoreShort
}
return config.minSignalQualityScore
}
// Merge configurations
export function getMergedConfig(
overrides?: Partial<TradingConfig>