feat: add price movement context to flip-flop detection

Improved flip-flop penalty logic to distinguish between:
- Chop (bad): <2% price move from opposite signal → -25 penalty
- Reversal (good): ≥2% price move from opposite signal → allowed

Changes:
- lib/database/trades.ts: getRecentSignals() now returns oppositeDirectionPrice
- lib/trading/signal-quality.ts: Added currentPrice parameter, price movement check
- app/api/trading/check-risk/route.ts: Added currentPrice to RiskCheckRequest interface
- app/api/trading/execute/route.ts: Pass openResult.fillPrice as currentPrice
- app/api/analytics/reentry-check/route.ts: Pass currentPrice from metrics

Example scenarios:
- ETH $170 SHORT → $153 LONG (10% move) = reversal allowed 
- ETH $154.50 SHORT → $154.30 LONG (0.13% move) = chop blocked ⚠️

Deployed: 09:18 CET Nov 14, 2025
Container: trading-bot-v4
This commit is contained in:
mindesbunister
2025-11-14 07:46:28 +01:00
parent cf0de17aee
commit 77a9437d26
5 changed files with 46 additions and 6 deletions

View File

@@ -147,6 +147,7 @@ export async function POST(request: NextRequest) {
pricePosition: metrics.pricePosition,
direction: direction as 'long' | 'short',
symbol: symbol,
currentPrice: metrics.currentPrice,
skipFrequencyCheck: true, // Re-entry check already considers recent trades
})

View File

@@ -16,6 +16,7 @@ export interface RiskCheckRequest {
symbol: string
direction: 'long' | 'short'
timeframe?: string // e.g., "5" for 5min, "60" for 1H, "D" for daily
currentPrice?: number // Current market price (for flip-flop context)
// Optional context metrics from TradingView
atr?: number
adx?: number
@@ -58,6 +59,7 @@ async function shouldAllowScaling(
pricePosition: newSignal.pricePosition,
direction: newSignal.direction,
symbol: newSignal.symbol,
currentPrice: newSignal.currentPrice,
minScore: config.minScaleQualityScore,
})
@@ -318,6 +320,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
pricePosition: body.pricePosition || 0,
direction: body.direction,
symbol: body.symbol,
currentPrice: body.currentPrice,
timeframe: body.timeframe, // Pass timeframe for context-aware scoring
minScore: config.minSignalQualityScore // Use config value
})

View File

@@ -365,6 +365,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
pricePosition: body.pricePosition || 0,
direction: body.direction,
symbol: driftSymbol,
currentPrice: openResult.fillPrice,
timeframe: body.timeframe,
})
@@ -596,6 +597,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<ExecuteTr
pricePosition: body.pricePosition || 0,
direction: body.direction,
symbol: driftSymbol,
currentPrice: openResult.fillPrice,
timeframe: body.timeframe,
})