Add ADX > 18 requirement for extreme price positions
- Shorts/longs at < 15% range require ADX > 18 AND volume > 1.2x - OR RSI < 35 for shorts, RSI > 60 for longs - Increased penalty from -10 to -15 when conditions not met - Changed threshold from < 5% to < 15% to catch more edge cases Test results: - Big loser (01:35): ADX 16.1, price 9.3% → Score 60 (was 90) → BLOCKED - Today's signal (10:05): ADX 17.3, price 0.9% → Score 55 (was 85) → BLOCKED Rationale: False breakdowns in choppy ranges (ADX < 18) cause losses. Tradeoff: May block some profitable breakdowns, but prevents chop losses.
This commit is contained in:
@@ -173,24 +173,35 @@ export function scoreSignalQuality(params: {
|
||||
score -= 15
|
||||
reasons.push(`Price near top of range (${params.pricePosition.toFixed(0)}%) - risky long`)
|
||||
}
|
||||
} else if (params.direction === 'short' && params.pricePosition < 5) {
|
||||
// High volume breakdown at range bottom can be good
|
||||
// Also allow if RSI is bearish (< 40) - breakdowns continue lower
|
||||
if (params.volumeRatio > 1.2 || (params.rsi > 0 && params.rsi < 40)) {
|
||||
} else if (params.direction === 'short' && params.pricePosition < 15) {
|
||||
// Shorts near range bottom (< 15%) require strong confirmation
|
||||
// Require STRONG trend (ADX > 18) to avoid false breakdowns in choppy ranges
|
||||
// OR very bearish RSI (< 35) indicating strong momentum continuation
|
||||
const hasStrongTrend = params.adx > 18
|
||||
const isVeryBearish = params.rsi > 0 && params.rsi < 35
|
||||
const hasGoodVolume = params.volumeRatio > 1.2
|
||||
|
||||
if ((hasGoodVolume && hasStrongTrend) || isVeryBearish) {
|
||||
score += 5
|
||||
reasons.push(`Valid breakdown at range bottom (${params.pricePosition.toFixed(0)}%, vol ${params.volumeRatio.toFixed(2)}x, RSI ${params.rsi.toFixed(1)})`)
|
||||
reasons.push(`Valid breakdown at range bottom (${params.pricePosition.toFixed(0)}%, vol ${params.volumeRatio.toFixed(2)}x, ADX ${params.adx.toFixed(1)}, RSI ${params.rsi.toFixed(1)})`)
|
||||
} else {
|
||||
score -= 10
|
||||
reasons.push(`Price near bottom of range (${params.pricePosition.toFixed(0)}%) - reduced penalty for short`)
|
||||
score -= 15
|
||||
reasons.push(`Price near bottom (${params.pricePosition.toFixed(0)}%) - need ADX > 18 or RSI < 35 for breakdown`)
|
||||
}
|
||||
} else if (params.direction === 'long' && params.pricePosition < 5) {
|
||||
// Longs at bottom with good volume = potential reversal
|
||||
if (params.volumeRatio > 1.2 || (params.rsi > 0 && params.rsi > 60)) {
|
||||
} else if (params.direction === 'long' && params.pricePosition < 15) {
|
||||
// Longs near range bottom (< 15%) require strong reversal confirmation
|
||||
// Require STRONG trend (ADX > 18) to avoid catching falling knives
|
||||
// OR very bullish RSI (> 60) after bounce showing momentum shift
|
||||
const hasStrongTrend = params.adx > 18
|
||||
const isVeryBullish = params.rsi > 0 && params.rsi > 60
|
||||
const hasGoodVolume = params.volumeRatio > 1.2
|
||||
|
||||
if ((hasGoodVolume && hasStrongTrend) || isVeryBullish) {
|
||||
score += 5
|
||||
reasons.push(`Potential reversal at bottom (${params.pricePosition.toFixed(0)}%, vol ${params.volumeRatio.toFixed(2)}x, RSI ${params.rsi.toFixed(1)})`)
|
||||
reasons.push(`Potential reversal at bottom (${params.pricePosition.toFixed(0)}%, vol ${params.volumeRatio.toFixed(2)}x, ADX ${params.adx.toFixed(1)}, RSI ${params.rsi.toFixed(1)})`)
|
||||
} else {
|
||||
score -= 10
|
||||
reasons.push(`Price near bottom (${params.pricePosition.toFixed(0)}%) - reduced penalty for reversal long`)
|
||||
score -= 15
|
||||
reasons.push(`Price near bottom (${params.pricePosition.toFixed(0)}%) - need ADX > 18 or RSI > 60 for reversal`)
|
||||
}
|
||||
} else {
|
||||
score += 5
|
||||
|
||||
Reference in New Issue
Block a user