feat: Direction-specific adaptive leverage for SHORTs (Q80+, RSI 33+)

- Quality 80-89 + RSI 33+ → 10x leverage (conservative tier)
- Quality 90+ + RSI 33+ → 15x leverage (full confidence tier)
- RSI < 33 penalty: -25 points (drops below Q80 threshold)
- Data-driven: 14 SHORT analysis showed 100% WR at Q80+ RSI33+ (2/2 wins)
- All disasters had RSI < 33 (4 trades, -$665.70 total)
- Modified: config/trading.ts, lib/trading/signal-quality.ts, execute endpoint
- Updated: MIN_SIGNAL_QUALITY_SCORE_SHORT=80 (down from 95)
- Expected impact: +$40.58 vs current system (+216% improvement)
This commit is contained in:
mindesbunister
2025-11-25 12:26:21 +01:00
parent fa3c76c878
commit 439c5a1ee8
4 changed files with 54 additions and 7 deletions

View File

@@ -322,13 +322,15 @@ export function calculateActualPositionSize(
/**
* Get actual position size for symbol with percentage support
* Now supports adaptive leverage based on quality score (Nov 24, 2025)
* ENHANCED Nov 25, 2025: Direction-specific leverage for SHORTs
* This is the main function to use when opening positions
*/
export async function getActualPositionSizeForSymbol(
symbol: string,
baseConfig: TradingConfig,
freeCollateral: number,
qualityScore?: number // NEW: Optional quality score for adaptive leverage
qualityScore?: number, // Optional quality score for adaptive leverage
direction?: 'long' | 'short' // NEW: Direction for SHORT-specific leverage tiers
): Promise<{ size: number; leverage: number; enabled: boolean; usePercentage: boolean }> {
let symbolSettings: { size: number; leverage: number; enabled: boolean }
let usePercentage = false
@@ -367,10 +369,21 @@ export async function getActualPositionSizeForSymbol(
)
// NEW (Nov 24, 2025): Apply adaptive leverage based on quality score
// ENHANCED (Nov 25, 2025): Direction-specific thresholds
let finalLeverage = symbolSettings.leverage
if (qualityScore !== undefined && baseConfig.useAdaptiveLeverage) {
finalLeverage = getLeverageForQualityScore(qualityScore, baseConfig)
console.log(`📊 Adaptive leverage: Quality ${qualityScore}${finalLeverage}x leverage (threshold: ${baseConfig.qualityLeverageThreshold})`)
finalLeverage = getLeverageForQualityScore(qualityScore, baseConfig, direction)
// Log SHORT-specific leverage decisions
if (direction === 'short') {
if (qualityScore >= 90) {
console.log(`📊 Adaptive leverage (SHORT): Quality ${qualityScore}${finalLeverage}x leverage (Tier 1: Q90+)`)
} else if (qualityScore >= 80) {
console.log(`📊 Adaptive leverage (SHORT): Quality ${qualityScore}${finalLeverage}x leverage (Tier 2: Q80-89)`)
}
} else {
console.log(`📊 Adaptive leverage: Quality ${qualityScore}${finalLeverage}x leverage (threshold: ${baseConfig.qualityLeverageThreshold})`)
}
}
return {
@@ -652,16 +665,37 @@ export function getMinQualityScoreForDirection(
// Get leverage based on signal quality score (Nov 24, 2025)
// Data-driven: v8 quality 95+ = 100% WR (4/4 wins), quality 90-94 more volatile
// Get leverage based on signal quality score (Nov 24, 2025)
// ENHANCED Nov 25, 2025: Direction-specific thresholds for adaptive leverage
// Data-driven:
// LONGs: Quality 95+ = 100% WR (4/4 wins), quality 90-94 more volatile → 90/95 split
// SHORTs: Quality 80+/RSI 33+ = 100% WR (2/2 wins), quality 90+ safer → 80/90 split
export function getLeverageForQualityScore(
qualityScore: number,
config: TradingConfig
config: TradingConfig,
direction?: 'long' | 'short'
): number {
// If adaptive leverage disabled, use fixed leverage
if (!config.useAdaptiveLeverage) {
return config.leverage
}
// High quality signals get maximum leverage
// Direction-specific quality thresholds for leverage
// SHORTs are riskier, use lower threshold (80 vs 90) but still tier by quality
if (direction === 'short') {
// Quality 90+ SHORTs → Full leverage (when combined with RSI 33+)
if (qualityScore >= 90) {
return config.highQualityLeverage
}
// Quality 80-89 SHORTs → Reduced leverage (more conservative)
if (qualityScore >= 80) {
return config.lowQualityLeverage
}
// Below 80 shouldn't execute (filtered out), but return minimum if it does
return config.lowQualityLeverage
}
// LONGs use original threshold (95+ for high leverage)
if (qualityScore >= config.qualityLeverageThreshold) {
return config.highQualityLeverage
}