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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user