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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user