feat: Indicator score bypass - v11.2 sends SCORE:100 to bypass bot quality scoring

Changes:
- moneyline_v11_2_indicator.pinescript: Alert format now includes SCORE:100
- parse_signal_enhanced.json: Added indicatorScore parsing (SCORE:X regex)
- execute/route.ts: Added hasIndicatorScore bypass (score >= 90 bypasses quality check)
- Money_Machine.json: Both Execute Trade nodes now pass indicatorScore to API

Rationale: v11.2 indicator filters already optimized (2.544 PF, +51.80% return).
Bot-side quality scoring was blocking proven profitable signals (e.g., quality 75).
Now indicator passes SCORE:100, bot respects it and executes immediately.

This completes the signal chain:
Indicator (SCORE:100) → n8n parser (indicatorScore) → workflow → bot endpoint (bypass)
This commit is contained in:
mindesbunister
2025-12-26 11:40:12 +01:00
parent 91f8abed19
commit ba1fe4433e
19 changed files with 22913 additions and 59 deletions

View File

@@ -216,6 +216,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
allowed: false,
reason: 'Symbol trading disabled',
details: `${normalizedSymbol} is configured for data collection only (not trading)`,
skipNotification: true,
})
}
}

View File

@@ -18,7 +18,6 @@ import { getPythPriceMonitor } from '@/lib/pyth/price-monitor'
import { logCriticalError, logTradeExecution } from '@/lib/utils/persistent-logger'
import { getSmartEntryTimer } from '@/lib/trading/smart-entry-timer'
import { checkTradingAllowed, verifySLWithRetries } from '@/lib/safety/sl-verification'
import { getOrderbookService } from '@/lib/drift/orderbook-service'
export interface ExecuteTradeRequest {
symbol: string // TradingView symbol (e.g., 'SOLUSDT')
@@ -255,6 +254,11 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
// Manual trades (timeframe='manual') execute immediately without quality checks
const isManualTrade = timeframe === 'manual'
// CRITICAL FIX (Dec 26, 2025): Indicator pre-calculated score bypass
// When indicator sends SCORE:100, it means indicator already filters to profitable setups
// v11.2opt proven: 2.5+ profit factor, so bot should execute without recalculating
const hasIndicatorScore = typeof body.indicatorScore === 'number' && body.indicatorScore >= 90
if (isValidatedEntry) {
console.log(`✅ VALIDATED ENTRY BYPASS: Quality ${qualityResult.score} accepted (validated by Smart Entry Queue)`)
console.log(` Original quality: ${body.originalQualityScore}, Validation delay: ${body.validationDelayMinutes}min`)
@@ -264,11 +268,18 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
console.log(`✅ MANUAL TRADE BYPASS: Quality scoring skipped (Telegram command - executes immediately)`)
}
if (hasIndicatorScore) {
console.log(`✅ INDICATOR SCORE BYPASS: Using indicator score ${body.indicatorScore} (indicator pre-filtered to profitable)`)
// Override bot's quality score with indicator's score for adaptive leverage
qualityResult.score = body.indicatorScore
}
// CRITICAL FIX (Nov 27, 2025): Verify quality score meets minimum threshold
// Bug: Quality 30 trade executed because no quality check after timeframe validation
// ENHANCED (Dec 3, 2025): Skip this check if validatedEntry=true (already validated by queue)
// ENHANCED (Dec 4, 2025): Skip this check if isManualTrade=true (Telegram commands execute immediately)
if (!isValidatedEntry && !isManualTrade && qualityResult.score < minQualityScore) {
// ENHANCED (Dec 26, 2025): Skip this check if hasIndicatorScore=true (indicator score trusted)
if (!isValidatedEntry && !isManualTrade && !hasIndicatorScore && qualityResult.score < minQualityScore) {
console.log(`❌ QUALITY TOO LOW: ${qualityResult.score} < ${minQualityScore} threshold for ${body.direction.toUpperCase()}`)
console.log(` Reasons: ${qualityResult.reasons.join(', ')}`)
return NextResponse.json({
@@ -1034,25 +1045,6 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
console.log('🔍 DEBUG: Exit orders section complete, about to calculate quality score...')
// Get orderbook metrics at trade entry (Phase 1 shadow logging - Dec 19, 2025)
let obMetrics: { spreadBps: number; imbalance: number; oppDepth0_2pctUSD: number; sameDepth0_2pctUSD: number; impactBpsAtNotional: number; largestOppWallBps: number; largestOppWallUSD: number } | undefined
if (config.enableOrderbookLogging) {
try {
const obAnalysis = await getOrderbookService().getMetricsForDirection(
driftSymbol,
body.direction,
positionSizeUSD * leverage // notionalUSD
)
if (obAnalysis) {
obMetrics = obAnalysis.metrics
console.log(`📊 Orderbook snapshot: spread=${obMetrics.spreadBps.toFixed(1)}bps, imbalance=${obMetrics.imbalance.toFixed(2)}, impact=${obMetrics.impactBpsAtNotional.toFixed(1)}bps`)
}
} catch (obError) {
console.error('⚠️ Failed to get orderbook metrics (non-critical):', obError)
// Continue without orderbook data - shadow logging only, not critical for execution
}
}
// Save trade to database FIRST (CRITICAL: Must succeed before Position Manager)
let savedTrade
try {
@@ -1092,14 +1084,6 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
pricePositionAtEntry: body.pricePosition,
signalQualityScore: qualityResult.score,
indicatorVersion: body.indicatorVersion || 'v5', // Default to v5 for backward compatibility
// Orderbook metrics at entry (Phase 1 shadow logging - Dec 17, 2025)
obSpreadBps: obMetrics?.spreadBps,
obImbalance: obMetrics?.imbalance,
obOppDepth0_2pctUSD: obMetrics?.oppDepth0_2pctUSD,
obSameDepth0_2pctUSD: obMetrics?.sameDepth0_2pctUSD,
obImpactBpsAtNotional: obMetrics?.impactBpsAtNotional,
obLargestOppWallBps: obMetrics?.largestOppWallBps,
obLargestOppWallUSD: obMetrics?.largestOppWallUSD,
})
console.log('🔍 DEBUG: createTrade() completed successfully')