remove: V10 momentum system - backtest proved it adds no value

- Removed v10 TradingView indicator (moneyline_v10_momentum_dots.pinescript)
- Removed v10 penalty system from signal-quality.ts (-30/-25 point penalties)
- Removed backtest result files (sweep_*.csv)
- Updated copilot-instructions.md to remove v10 references
- Simplified direction-specific quality thresholds (LONG 90+, SHORT 80+)

Rationale:
- 1,944 parameter combinations tested in backtest
- All top results IDENTICAL (568 trades, $498 P&L, 61.09% WR)
- Momentum parameters had ZERO impact on trade selection
- Profit factor 1.027 too low (barely profitable after fees)
- Max drawdown -$1,270 vs +$498 profit = terrible risk-reward
- v10 penalties were blocking good trades (bug: applied to wrong positions)

Keeping v9 as production system - simpler, proven, effective.
This commit is contained in:
mindesbunister
2025-11-28 22:35:32 +01:00
parent 4fb6a45fab
commit 5f7702469e
5869 changed files with 1116282 additions and 116 deletions

View File

@@ -19,6 +19,8 @@ export interface RiskCheckRequest {
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)
signalPrice?: number // TradingView-provided price snapshot
indicatorVersion?: string // Pine Script version tag (v8/v9/v10)
// Optional context metrics from TradingView
atr?: number
adx?: number
@@ -183,6 +185,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
}
const body: RiskCheckRequest = await request.json()
const fallbackPrice = body.currentPrice ?? body.signalPrice
console.log('🔍 Risk check for:', body)
@@ -287,23 +290,28 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
// Save blocked signal if we have metrics
if (hasContextMetrics) {
const currentPrice = await getCurrentPrice(body.symbol, body.currentPrice)
const currentPrice = await getCurrentPrice(body.symbol, fallbackPrice)
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: 0, // Not calculated yet
minScoreRequired: config.minSignalQualityScore,
blockReason: 'HOURLY_TRADE_LIMIT',
blockDetails: `${tradesInLastHour} trades in last hour (max: ${config.maxTradesPerHour})`,
})
if (currentPrice > 0) {
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: 0, // Not calculated yet
minScoreRequired: config.minSignalQualityScore,
blockReason: 'HOURLY_TRADE_LIMIT',
blockDetails: `${tradesInLastHour} trades in last hour (max: ${config.maxTradesPerHour})`,
indicatorVersion: body.indicatorVersion || 'v5',
})
} else {
console.warn('⚠️ Skipping blocked signal save: price unavailable (hourly limit)')
}
}
return NextResponse.json({
@@ -332,23 +340,28 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
// Save blocked signal if we have metrics
if (hasContextMetrics) {
const currentPrice = await getCurrentPrice(body.symbol, body.currentPrice)
const currentPrice = await getCurrentPrice(body.symbol, fallbackPrice)
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: 0, // Not calculated yet
minScoreRequired: config.minSignalQualityScore,
blockReason: 'COOLDOWN_PERIOD',
blockDetails: `Wait ${remainingMinutes} more min (cooldown: ${config.minTimeBetweenTrades} min)`,
})
if (currentPrice > 0) {
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: 0, // Not calculated yet
minScoreRequired: config.minSignalQualityScore,
blockReason: 'COOLDOWN_PERIOD',
blockDetails: `Wait ${remainingMinutes} more min (cooldown: ${config.minTimeBetweenTrades} min)`,
indicatorVersion: body.indicatorVersion || 'v5',
})
} else {
console.warn('⚠️ Skipping blocked signal save: price unavailable (cooldown)')
}
}
return NextResponse.json({
@@ -364,7 +377,7 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
// Get current price from Pyth for flip-flop price context check
const priceMonitor = getPythPriceMonitor()
const latestPrice = priceMonitor.getCachedPrice(body.symbol)
const currentPrice = latestPrice?.price || body.currentPrice
const currentPrice = latestPrice?.price || fallbackPrice || 0
// Use direction-specific quality threshold (Nov 23, 2025)
const minQualityScore = getMinQualityScoreForDirection(body.direction, config)
@@ -392,26 +405,31 @@ export async function POST(request: NextRequest): Promise<NextResponse<RiskCheck
})
// Get current price for the blocked signal record
const currentPrice = await getCurrentPrice(body.symbol, body.currentPrice)
const currentPrice = await getCurrentPrice(body.symbol, fallbackPrice)
// Save blocked signal to database for future analysis
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: qualityScore.score,
signalQualityVersion: 'v4', // Update this when scoring logic changes
scoreBreakdown: { reasons: qualityScore.reasons },
minScoreRequired: minQualityScore, // Use direction-specific threshold
blockReason: 'QUALITY_SCORE_TOO_LOW',
blockDetails: `Score: ${qualityScore.score}/${config.minSignalQualityScore} - ${qualityScore.reasons.join(', ')}`,
})
if (currentPrice > 0) {
await createBlockedSignal({
symbol: body.symbol,
direction: body.direction,
timeframe: body.timeframe,
signalPrice: currentPrice,
atr: body.atr,
adx: body.adx,
rsi: body.rsi,
volumeRatio: body.volumeRatio,
pricePosition: body.pricePosition,
signalQualityScore: qualityScore.score,
signalQualityVersion: 'v4', // Update this when scoring logic changes
scoreBreakdown: { reasons: qualityScore.reasons },
minScoreRequired: minQualityScore, // Use direction-specific threshold
blockReason: 'QUALITY_SCORE_TOO_LOW',
blockDetails: `Score: ${qualityScore.score}/${minQualityScore} - ${qualityScore.reasons.join(', ')}`,
indicatorVersion: body.indicatorVersion || 'v5',
})
} else {
console.warn('⚠️ Skipping blocked signal save: price unavailable (quality block)')
}
return NextResponse.json({
allowed: false,