feat: Implement re-entry analytics system with fresh TradingView data
- Add market data cache service (5min expiry) for storing TradingView metrics - Create /api/trading/market-data webhook endpoint for continuous data updates - Add /api/analytics/reentry-check endpoint for validating manual trades - Update execute endpoint to auto-cache metrics from incoming signals - Enhance Telegram bot with pre-execution analytics validation - Support --force flag to override analytics blocks - Use fresh ADX/ATR/RSI data when available, fallback to historical - Apply performance modifiers: -20 for losing streaks, +10 for winning - Minimum re-entry score 55 (vs 60 for new signals) - Fail-open design: proceeds if analytics unavailable - Show data freshness and source in Telegram responses - Add comprehensive setup guide in docs/guides/REENTRY_ANALYTICS_QUICKSTART.md Phase 1 implementation for smart manual trade validation.
This commit is contained in:
@@ -15,7 +15,6 @@ import { scoreSignalQuality, SignalQualityResult } from '@/lib/trading/signal-qu
|
||||
export interface RiskCheckRequest {
|
||||
symbol: string
|
||||
direction: 'long' | 'short'
|
||||
timeframe?: string // e.g., '5', '15', '60', '1D'
|
||||
// Optional context metrics from TradingView
|
||||
atr?: number
|
||||
adx?: number
|
||||
@@ -58,7 +57,6 @@ function shouldAllowScaling(
|
||||
pricePosition: newSignal.pricePosition,
|
||||
direction: newSignal.direction,
|
||||
minScore: config.minScaleQualityScore,
|
||||
timeframe: newSignal.timeframe,
|
||||
})
|
||||
|
||||
// 2. Check quality score (higher bar than initial entry)
|
||||
@@ -148,9 +146,8 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
|
||||
const config = getMergedConfig()
|
||||
|
||||
// Check for existing positions on the same symbol
|
||||
const positionManager = await getInitializedPositionManager()
|
||||
await positionManager.reconcileTrade(body.symbol)
|
||||
const existingTrades = Array.from(positionManager.getActiveTrades().values())
|
||||
const positionManager = await getInitializedPositionManager()
|
||||
const existingTrades = Array.from(positionManager.getActiveTrades().values())
|
||||
const existingPosition = existingTrades.find(trade => trade.symbol === body.symbol)
|
||||
|
||||
if (existingPosition) {
|
||||
@@ -273,8 +270,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
|
||||
volumeRatio: body.volumeRatio || 0,
|
||||
pricePosition: body.pricePosition || 0,
|
||||
direction: body.direction,
|
||||
minScore: 60, // Hardcoded threshold
|
||||
timeframe: body.timeframe,
|
||||
minScore: 60 // Hardcoded threshold
|
||||
})
|
||||
|
||||
if (!qualityScore.passed) {
|
||||
|
||||
Reference in New Issue
Block a user