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

@@ -41,7 +41,7 @@ macdSigLen = input.int(9, "Signal", minval=1, inline="macdLens")
// Signal timing (ALWAYS applies to all signals)
groupTiming = "Signal Timing"
confirmBars = input.int(2, "Bars to confirm after flip", minval=0, maxval=3, group=groupTiming, tooltip="V8: Wait X bars after flip to confirm trend change. Filters rapid flip-flops.")
flipThreshold = input.float(0.6, "Flip threshold %", minval=0.0, maxval=2.0, step=0.1, group=groupTiming, tooltip="V8: Require price to move this % beyond line before flip. Set to 0.6% to filter small bounces while catching real reversals.")
flipThreshold = input.float(0.8, "Flip threshold %", minval=0.0, maxval=2.0, step=0.1, group=groupTiming, tooltip="V8: Require price to move this % beyond line before flip. Increased to 0.8% to filter small bounces.")
// Entry filters (optional)
groupFilters = "Entry filters"
@@ -235,10 +235,10 @@ rsiShortOk = not useRsiFilter or (rsi14 >= rsiShortMin and rsi14 <= rsiShortMax)
// V8: STICKY TREND SIGNALS - High accuracy with flip-flop protection
// Signal fires on line color changes ONLY when price breaches threshold
// Protection: 0.5% flip threshold + 0.20 ATR buffer + ADX 18+ + stickier multipliers
// Protection: 0.6% flip threshold + 0.20 ATR buffer + ADX 18+ + stickier multipliers
// Result: Clean trend signals without noise
finalLongSignal = buyReady // 🟢 Signal on red → green flip (with threshold)
finalShortSignal = sellReady // 🔴 Signal on green → red flip (with threshold)
finalLongSignal = buyReady and longOk and adxOk and longBufferOk and longPositionOk and volumeOk and rsiLongOk
finalShortSignal = sellReady and shortOk and adxOk and shortBufferOk and shortPositionOk and volumeOk and rsiShortOk
plotshape(finalLongSignal, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.circle, size=size.small)
plotshape(finalShortSignal, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.circle, size=size.small)