feat(v9): Complete MA gap backend integration

Integrated MA gap analysis into signal quality evaluation pipeline:

BACKEND SCORING (lib/trading/signal-quality.ts):
- Added maGap?: number parameter to scoreSignalQuality interface
- Implemented convergence/divergence scoring logic:
  * LONG: +15pts tight bullish (0-2%), +12pts converging (-2-0%), +8pts early momentum (-5--2%)
  * SHORT: +15pts tight bearish (-2-0%), +12pts converging (0-2%), +8pts early momentum (2-5%)
  * Penalties: -5pts for misaligned MA structure (>5% wrong direction)

N8N PARSER (workflows/trading/parse_signal_enhanced.json):
- Added MAGAP:([-\d.]+) regex pattern for negative number support
- Extracts maGap from TradingView v9 alert messages
- Returns maGap in parsed output (backward compatible with v8)
- Updated comment to show v9 format

API ENDPOINTS:
- app/api/trading/check-risk/route.ts: Pass maGap to scoreSignalQuality (2 calls)
- app/api/trading/execute/route.ts: Pass maGap to scoreSignalQuality (2 calls)

FULL PIPELINE NOW COMPLETE:
1. TradingView v9 → Generates signal with MAGAP field
2. n8n webhook → Extracts maGap from alert message
3. Backend scoring → Evaluates MA gap convergence (+8 to +15 pts)
4. Quality threshold → Borderline signals (75-85) can reach 91+
5. Execute decision → Only signals scoring ≥91 are executed

MOTIVATION:
Helps borderline quality signals reach execution threshold without overriding
safety rules. Addresses Nov 25 missed opportunity where good signal had MA
convergence but borderline quality score.

TESTING REQUIRED:
- Verify n8n parses MAGAP correctly from v9 alerts
- Confirm backend receives maGap parameter
- Validate MA gap scoring applied to quality calculation
- Monitor first 10-20 v9 signals for scoring accuracy
This commit is contained in:
mindesbunister
2025-11-26 10:50:25 +01:00
parent 1b6131be5f
commit ff92e7b78c
11 changed files with 1858 additions and 5 deletions

View File

@@ -55,6 +55,7 @@ export async function scoreSignalQuality(params: {
timeframe?: string // "5" = 5min, "15" = 15min, "60" = 1H, "D" = daily
minScore?: number // Configurable minimum score threshold
skipFrequencyCheck?: boolean // For testing or when frequency check not needed
maGap?: number // V9: MA gap percentage (MA50-MA200)/MA200*100
}): Promise<SignalQualityResult> {
let score = 50 // Base score
const reasons: string[] = []
@@ -274,6 +275,57 @@ export async function scoreSignalQuality(params: {
}
}
// V9: MA Gap Analysis (Nov 26, 2025)
// MA convergence/divergence indicates momentum building or fading
// Helps catch early trend signals when MAs align with direction
if (params.maGap !== undefined && params.maGap !== null) {
if (params.direction === 'long') {
if (params.maGap >= 0 && params.maGap < 2.0) {
// Tight bullish convergence (MA50 above MA200, close together)
score += 15
reasons.push(`✅ Tight bullish MA convergence (${params.maGap.toFixed(2)}% gap) (+15 pts)`)
} else if (params.maGap < 0 && params.maGap > -2.0) {
// MAs converging from below (MA50 approaching MA200)
score += 12
reasons.push(`✅ MAs converging bullish (${params.maGap.toFixed(2)}% gap) (+12 pts)`)
} else if (params.maGap < -2.0 && params.maGap > -5.0) {
// Early momentum building
score += 8
reasons.push(`✅ Early bullish momentum (${params.maGap.toFixed(2)}% gap) (+8 pts)`)
} else if (params.maGap >= 2.0) {
// Wide gap = momentum already extended
score += 5
reasons.push(`⚠️ Extended bullish gap (${params.maGap.toFixed(2)}%) (+5 pts)`)
} else if (params.maGap <= -5.0) {
// Very bearish MA structure for long
score -= 5
reasons.push(`⚠️ Bearish MA structure for long (${params.maGap.toFixed(2)}%) (-5 pts)`)
}
} else if (params.direction === 'short') {
if (params.maGap <= 0 && params.maGap > -2.0) {
// Tight bearish convergence (MA50 below MA200, close together)
score += 15
reasons.push(`✅ Tight bearish MA convergence (${params.maGap.toFixed(2)}% gap) (+15 pts)`)
} else if (params.maGap > 0 && params.maGap < 2.0) {
// MAs converging from above (MA50 approaching MA200)
score += 12
reasons.push(`✅ MAs converging bearish (${params.maGap.toFixed(2)}% gap) (+12 pts)`)
} else if (params.maGap > 2.0 && params.maGap < 5.0) {
// Early momentum building
score += 8
reasons.push(`✅ Early bearish momentum (${params.maGap.toFixed(2)}% gap) (+8 pts)`)
} else if (params.maGap <= -2.0) {
// Wide gap = momentum already extended
score += 5
reasons.push(`⚠️ Extended bearish gap (${params.maGap.toFixed(2)}%) (+5 pts)`)
} else if (params.maGap >= 5.0) {
// Very bullish MA structure for short
score -= 5
reasons.push(`⚠️ Bullish MA structure for short (${params.maGap.toFixed(2)}%) (-5 pts)`)
}
}
}
// Direction-specific threshold support (Nov 23, 2025)
// Use provided minScore, or fall back to 60 if not specified
const minScore = params.minScore || 60