feat: implement AI-driven dynamic leverage calculator
- Under k: Use 100% of available balance for maximum growth - Over k: Use 50% balance for controlled risk management - AI calculates optimal leverage maintaining safe liquidation distance - Liquidation price stays safely below stop loss (10% buffer) New Features: - AILeverageCalculator class with sophisticated risk assessment - Dynamic position sizing based on account value and market conditions - Liquidation price calculation and safety validation - Risk assessment levels (LOW/MEDIUM/HIGH) with reasoning - Support for both long and short positions with AI leverage - Enhanced automation-service-simple.ts with AI leverage - Position sizing now returns leverage + risk metrics - Trade execution uses AI-calculated leverage values - Database storage includes AI leverage metadata - Comprehensive logging for leverage decisions - Safety buffer prevents liquidation near stop loss - Maximum leverage limited by platform constraints (20x) - Account-based strategy (aggressive <k, conservative >k) - Real-time balance and position validation This enables maximum profit potential while maintaining strict risk controls.
This commit is contained in:
251
lib/ai-leverage-calculator.ts
Normal file
251
lib/ai-leverage-calculator.ts
Normal file
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* AI-Driven Dynamic Leverage Calculator
|
||||
*
|
||||
* Calculates optimal leverage to maximize profits while maintaining safe liquidation distance
|
||||
* Strategy: Use maximum leverage possible without liquidation price being too close to stop loss
|
||||
*/
|
||||
|
||||
interface LeverageCalculationParams {
|
||||
accountValue: number
|
||||
availableBalance: number
|
||||
entryPrice: number
|
||||
stopLossPrice: number
|
||||
side: 'long' | 'short'
|
||||
maxLeverageAllowed: number // Platform maximum (e.g., 20x for Drift)
|
||||
safetyBuffer: number // Distance between liquidation and SL (default: 10%)
|
||||
}
|
||||
|
||||
interface LeverageResult {
|
||||
recommendedLeverage: number
|
||||
positionSize: number
|
||||
liquidationPrice: number
|
||||
marginRequired: number
|
||||
maxPossibleLeverage: number
|
||||
riskAssessment: 'LOW' | 'MEDIUM' | 'HIGH'
|
||||
reasoning: string
|
||||
}
|
||||
|
||||
export class AILeverageCalculator {
|
||||
|
||||
/**
|
||||
* Calculate optimal leverage for maximum profit with safe liquidation distance
|
||||
*/
|
||||
static calculateOptimalLeverage(params: LeverageCalculationParams): LeverageResult {
|
||||
const {
|
||||
accountValue,
|
||||
availableBalance,
|
||||
entryPrice,
|
||||
stopLossPrice,
|
||||
side,
|
||||
maxLeverageAllowed,
|
||||
safetyBuffer = 0.10 // 10% safety buffer by default
|
||||
} = params
|
||||
|
||||
console.log('🧮 AI Leverage Calculation:', {
|
||||
accountValue: accountValue.toFixed(2),
|
||||
availableBalance: availableBalance.toFixed(2),
|
||||
entryPrice,
|
||||
stopLossPrice,
|
||||
side,
|
||||
maxLeverageAllowed
|
||||
})
|
||||
|
||||
// Strategy 1: Under $1k - Use 100% of available balance
|
||||
const useFullBalance = accountValue < 1000
|
||||
const baseAmount = useFullBalance ? availableBalance : availableBalance * 0.5 // 50% for accounts over $1k
|
||||
|
||||
console.log(`💰 Balance Strategy: ${useFullBalance ? 'AGGRESSIVE (100%)' : 'CONSERVATIVE (50%)'} - Using $${baseAmount.toFixed(2)}`)
|
||||
|
||||
// Calculate stop loss distance as percentage
|
||||
const stopLossDistance = Math.abs(entryPrice - stopLossPrice) / entryPrice
|
||||
console.log(`📊 Stop Loss Distance: ${(stopLossDistance * 100).toFixed(2)}%`)
|
||||
|
||||
// Calculate maximum safe leverage based on liquidation distance
|
||||
const maxSafeLeverage = this.calculateMaxSafeLeverage(
|
||||
entryPrice,
|
||||
stopLossPrice,
|
||||
side,
|
||||
safetyBuffer
|
||||
)
|
||||
|
||||
// Determine final leverage (limited by platform max and safety calculations)
|
||||
const finalLeverage = Math.min(maxSafeLeverage, maxLeverageAllowed)
|
||||
|
||||
// Calculate position size and margin
|
||||
const positionSize = baseAmount * finalLeverage
|
||||
const marginRequired = positionSize / finalLeverage
|
||||
|
||||
// Calculate liquidation price for verification
|
||||
const liquidationPrice = this.calculateLiquidationPrice(
|
||||
entryPrice,
|
||||
finalLeverage,
|
||||
side,
|
||||
marginRequired,
|
||||
positionSize
|
||||
)
|
||||
|
||||
// Risk assessment
|
||||
const riskAssessment = this.assessRisk(finalLeverage, stopLossDistance, useFullBalance)
|
||||
|
||||
// Generate AI reasoning
|
||||
const reasoning = this.generateLeverageReasoning(
|
||||
finalLeverage,
|
||||
maxSafeLeverage,
|
||||
maxLeverageAllowed,
|
||||
liquidationPrice,
|
||||
stopLossPrice,
|
||||
useFullBalance,
|
||||
side
|
||||
)
|
||||
|
||||
const result: LeverageResult = {
|
||||
recommendedLeverage: finalLeverage,
|
||||
positionSize,
|
||||
liquidationPrice,
|
||||
marginRequired,
|
||||
maxPossibleLeverage: maxSafeLeverage,
|
||||
riskAssessment,
|
||||
reasoning
|
||||
}
|
||||
|
||||
console.log('🎯 AI Leverage Result:', {
|
||||
recommendedLeverage: `${finalLeverage.toFixed(1)}x`,
|
||||
positionSize: `$${positionSize.toFixed(2)}`,
|
||||
liquidationPrice: `$${liquidationPrice.toFixed(4)}`,
|
||||
riskAssessment,
|
||||
reasoning
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate maximum safe leverage where liquidation price maintains safety buffer from stop loss
|
||||
*/
|
||||
private static calculateMaxSafeLeverage(
|
||||
entryPrice: number,
|
||||
stopLossPrice: number,
|
||||
side: 'long' | 'short',
|
||||
safetyBuffer: number
|
||||
): number {
|
||||
|
||||
// Calculate where liquidation should be (beyond stop loss + safety buffer)
|
||||
let maxLiquidationPrice: number
|
||||
|
||||
if (side === 'long') {
|
||||
// For longs: liquidation should be below stop loss
|
||||
maxLiquidationPrice = stopLossPrice * (1 - safetyBuffer)
|
||||
} else {
|
||||
// For shorts: liquidation should be above stop loss
|
||||
maxLiquidationPrice = stopLossPrice * (1 + safetyBuffer)
|
||||
}
|
||||
|
||||
console.log(`🛡️ Max Safe Liquidation Price: $${maxLiquidationPrice.toFixed(4)} (${side} position)`)
|
||||
|
||||
// Calculate max leverage that keeps liquidation at safe distance
|
||||
// Simplified liquidation formula: For longs: liq = entry * (1 - 1/leverage)
|
||||
let maxLeverage: number
|
||||
|
||||
if (side === 'long') {
|
||||
// entry * (1 - 1/leverage) = maxLiquidationPrice
|
||||
// 1 - 1/leverage = maxLiquidationPrice / entry
|
||||
// 1/leverage = 1 - maxLiquidationPrice / entry
|
||||
// leverage = 1 / (1 - maxLiquidationPrice / entry)
|
||||
maxLeverage = 1 / (1 - maxLiquidationPrice / entryPrice)
|
||||
} else {
|
||||
// For shorts: liq = entry * (1 + 1/leverage)
|
||||
// entry * (1 + 1/leverage) = maxLiquidationPrice
|
||||
// 1 + 1/leverage = maxLiquidationPrice / entry
|
||||
// 1/leverage = maxLiquidationPrice / entry - 1
|
||||
// leverage = 1 / (maxLiquidationPrice / entry - 1)
|
||||
maxLeverage = 1 / (maxLiquidationPrice / entryPrice - 1)
|
||||
}
|
||||
|
||||
// Ensure reasonable bounds
|
||||
maxLeverage = Math.max(1, Math.min(maxLeverage, 50)) // Between 1x and 50x
|
||||
|
||||
console.log(`⚖️ Max Safe Leverage: ${maxLeverage.toFixed(2)}x`)
|
||||
|
||||
return maxLeverage
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate liquidation price for given position parameters
|
||||
*/
|
||||
private static calculateLiquidationPrice(
|
||||
entryPrice: number,
|
||||
leverage: number,
|
||||
side: 'long' | 'short',
|
||||
marginRequired: number,
|
||||
positionSize: number
|
||||
): number {
|
||||
|
||||
// Simplified liquidation calculation
|
||||
// In reality, this would need to account for fees, funding, etc.
|
||||
|
||||
if (side === 'long') {
|
||||
// Long liquidation: entry * (1 - 1/leverage)
|
||||
return entryPrice * (1 - 1/leverage)
|
||||
} else {
|
||||
// Short liquidation: entry * (1 + 1/leverage)
|
||||
return entryPrice * (1 + 1/leverage)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess risk level based on leverage and position parameters
|
||||
*/
|
||||
private static assessRisk(
|
||||
leverage: number,
|
||||
stopLossDistance: number,
|
||||
useFullBalance: boolean
|
||||
): 'LOW' | 'MEDIUM' | 'HIGH' {
|
||||
|
||||
if (leverage <= 2 && stopLossDistance >= 0.05) return 'LOW'
|
||||
if (leverage <= 5 && stopLossDistance >= 0.03) return 'MEDIUM'
|
||||
if (leverage <= 10 && stopLossDistance >= 0.02) return 'MEDIUM'
|
||||
|
||||
return 'HIGH'
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate AI reasoning for leverage decision
|
||||
*/
|
||||
private static generateLeverageReasoning(
|
||||
finalLeverage: number,
|
||||
maxSafeLeverage: number,
|
||||
maxPlatformLeverage: number,
|
||||
liquidationPrice: number,
|
||||
stopLossPrice: number,
|
||||
useFullBalance: boolean,
|
||||
side: 'long' | 'short'
|
||||
): string {
|
||||
|
||||
const reasons = []
|
||||
|
||||
// Balance strategy reasoning
|
||||
if (useFullBalance) {
|
||||
reasons.push("Account <$1k: Using 100% available balance for maximum growth")
|
||||
} else {
|
||||
reasons.push("Account >$1k: Using 50% balance for controlled risk")
|
||||
}
|
||||
|
||||
// Leverage limitation reasoning
|
||||
if (finalLeverage === maxSafeLeverage) {
|
||||
reasons.push(`Max safe leverage ${finalLeverage.toFixed(1)}x maintains liquidation safely beyond stop loss`)
|
||||
} else if (finalLeverage === maxPlatformLeverage) {
|
||||
reasons.push(`Platform limit ${maxPlatformLeverage}x reached (could use ${maxSafeLeverage.toFixed(1)}x safely)`)
|
||||
}
|
||||
|
||||
// Liquidation safety reasoning
|
||||
const liquidationBuffer = side === 'long'
|
||||
? (stopLossPrice - liquidationPrice) / stopLossPrice * 100
|
||||
: (liquidationPrice - stopLossPrice) / stopLossPrice * 100
|
||||
|
||||
reasons.push(`Liquidation $${liquidationPrice.toFixed(4)} is ${liquidationBuffer.toFixed(1)}% beyond stop loss`)
|
||||
|
||||
return reasons.join('. ')
|
||||
}
|
||||
}
|
||||
|
||||
export default AILeverageCalculator
|
||||
Reference in New Issue
Block a user