Files
trading_bot_v3/lib/enhanced-risk-manager.ts
mindesbunister 416f72181e feat: enhance paper trading with comprehensive AI analysis and learning insights
New Features:
- 📊 Detailed Market Analysis Panel (similar to pro trading interface)
  * Market sentiment, recommendation, resistance/support levels
  * Detailed trading setup with entry/exit points
  * Risk management with R:R ratios and confirmation triggers
  * Technical indicators (RSI, OBV, VWAP) analysis

- 🧠 AI Learning Insights Panel
  * Real-time learning status and success rates
  * Winner/Loser trade outcome tracking
  * AI reflection messages explaining what was learned
  * Current thresholds and pattern recognition data

- 🔮 AI Database Integration
  * Shows what AI learned from previous trades
  * Current confidence thresholds and risk parameters
  * Pattern recognition for symbol/timeframe combinations
  * Next trade adjustments based on learning

- 🎓 Intelligent Learning from Outcomes
  * Automatic trade outcome analysis (winner/loser)
  * AI generates learning insights from each trade result
  * Confidence adjustment based on trade performance
  * Pattern reinforcement or correction based on results

- Beautiful gradient panels with color-coded sections
- Clear winner/loser indicators with visual feedback
- Expandable detailed analysis view
- Real-time learning progress tracking

- Completely isolated paper trading (no real money risk)
- Real market data integration for authentic learning
- Safe practice environment with professional analysis tools

This provides a complete AI learning trading simulation where users can:
1. Get real market analysis with detailed reasoning
2. Execute safe paper trades with zero risk
3. See immediate feedback on trade outcomes
4. Learn from AI reflections and insights
5. Understand how AI adapts and improves over time
2025-08-02 17:56:02 +02:00

306 lines
10 KiB
TypeScript

/**
* Enhanced Risk Management System
*
* Addresses the core issues that caused 47% account loss:
* 1. Proper position sizing based on account balance and risk tolerance
* 2. Dynamic stop losses based on market volatility (ATR)
* 3. Timeframe-appropriate risk management
* 4. Anti-overtrading mechanisms
* 5. Emergency stop loss protection
*/
// import { getDB } from './db'
export interface RiskAssessment {
accountBalance: number
currentRisk: number // Percentage of account at risk
maxPositionSize: number // Maximum $ amount for next trade
recommendedSize: number // Recommended $ amount for next trade
stopLossDistance: number // Distance to stop loss in $
riskRewardRatio: number
leverageRecommendation: number
timeframeRisk: 'LOW' | 'MEDIUM' | 'HIGH' | 'EXTREME'
coolingOffRequired: boolean
riskWarnings: string[]
}
export interface TradeRiskParameters {
symbol: string
direction: 'LONG' | 'SHORT'
entryPrice: number
stopLoss: number
takeProfit: number
timeframe: string
currentBalance: number
recentLosses: number // Recent consecutive losses
}
export class EnhancedRiskManager {
private readonly MAX_RISK_PER_TRADE = 1.0 // 1% max risk per trade
private readonly MAX_TOTAL_RISK = 5.0 // 5% max total account risk
private readonly COOLING_OFF_HOURS = 24 // Hours to wait after 2 consecutive losses
private readonly MAX_CONSECUTIVE_LOSSES = 2
// ATR multipliers for different timeframes
private readonly ATR_MULTIPLIERS: Record<string, number> = {
'5': 1.0, // 5m: Tight stops
'15': 1.5, // 15m: Moderate stops
'30': 2.0, // 30m: Wider stops
'60': 2.5, // 1h: Standard stops
'240': 3.0, // 4h: Wide stops
'D': 4.0 // Daily: Very wide stops
}
// Risk level based on timeframe
private readonly TIMEFRAME_RISK: Record<string, string> = {
'5': 'EXTREME',
'15': 'HIGH',
'30': 'HIGH',
'60': 'MEDIUM',
'240': 'LOW',
'D': 'LOW'
}
async assessTradeRisk(params: TradeRiskParameters): Promise<RiskAssessment> {
const {
symbol,
direction,
entryPrice,
stopLoss,
takeProfit,
timeframe,
currentBalance,
recentLosses
} = params
console.log('🛡️ Enhanced Risk Assessment Starting...')
console.log(`💰 Account Balance: $${currentBalance}`)
console.log(`📊 Trade: ${direction} ${symbol} @ $${entryPrice}`)
console.log(`🛑 Stop Loss: $${stopLoss}`)
console.log(`🎯 Take Profit: $${takeProfit}`)
console.log(`⏰ Timeframe: ${timeframe}`)
console.log(`📉 Recent Losses: ${recentLosses}`)
const warnings: string[] = []
// Calculate stop loss distance
const stopLossDistance = Math.abs(entryPrice - stopLoss)
const stopLossPercentage = (stopLossDistance / entryPrice) * 100
// Calculate risk/reward ratio
const takeProfitDistance = Math.abs(takeProfit - entryPrice)
const riskRewardRatio = takeProfitDistance / stopLossDistance
console.log(`📏 Stop Loss Distance: $${stopLossDistance.toFixed(2)} (${stopLossPercentage.toFixed(2)}%)`)
console.log(`📈 Risk/Reward Ratio: 1:${riskRewardRatio.toFixed(2)}`)
// Check if cooling off period is required
const coolingOffRequired = recentLosses >= this.MAX_CONSECUTIVE_LOSSES
if (coolingOffRequired) {
warnings.push(`🚨 COOLING OFF: ${recentLosses} consecutive losses detected. Wait ${this.COOLING_OFF_HOURS}h before next trade.`)
}
// Get timeframe risk level
const timeframeRisk = this.TIMEFRAME_RISK[timeframe] || 'HIGH'
// Adjust max risk based on timeframe and recent performance
let adjustedMaxRisk = this.MAX_RISK_PER_TRADE
if (timeframeRisk === 'EXTREME') {
adjustedMaxRisk = 0.5 // 0.5% for very short timeframes
warnings.push('⚠️ EXTREME RISK: Very short timeframe detected. Risk reduced to 0.5%')
} else if (timeframeRisk === 'HIGH') {
adjustedMaxRisk = 0.75 // 0.75% for high risk timeframes
warnings.push('⚠️ HIGH RISK: Short timeframe detected. Risk reduced to 0.75%')
}
// Further reduce risk after losses
if (recentLosses >= 1) {
adjustedMaxRisk *= 0.5 // Halve risk after any recent loss
warnings.push(`📉 Risk halved due to ${recentLosses} recent loss(es)`)
}
// Calculate position sizes
const riskAmount = currentBalance * (adjustedMaxRisk / 100)
const maxPositionSize = currentBalance * 0.1 // Never more than 10% of account
const recommendedSize = Math.min(riskAmount / (stopLossPercentage / 100), maxPositionSize)
console.log(`💵 Risk Amount: $${riskAmount.toFixed(2)} (${adjustedMaxRisk}% of balance)`)
console.log(`📦 Max Position Size: $${maxPositionSize.toFixed(2)}`)
console.log(`✅ Recommended Size: $${recommendedSize.toFixed(2)}`)
// Risk/Reward validation
if (riskRewardRatio < 1.5) {
warnings.push(`⚠️ POOR R:R: Risk/Reward ${riskRewardRatio.toFixed(2)} is below minimum 1.5`)
}
// Stop loss distance validation
if (stopLossPercentage > 5) {
warnings.push(`⚠️ WIDE STOP: ${stopLossPercentage.toFixed(2)}% stop loss is very wide`)
}
// Calculate current account risk
const currentRisk = await this.calculateCurrentAccountRisk(currentBalance)
if (currentRisk > this.MAX_TOTAL_RISK) {
warnings.push(`🚨 MAX RISK: Current account risk ${currentRisk.toFixed(1)}% exceeds maximum ${this.MAX_TOTAL_RISK}%`)
}
// Leverage recommendation based on timeframe and risk
let leverageRecommendation = 1
if (timeframeRisk === 'LOW' && riskRewardRatio >= 2) {
leverageRecommendation = 2
} else if (timeframeRisk === 'MEDIUM' && riskRewardRatio >= 2.5) {
leverageRecommendation = 1.5
}
const assessment: RiskAssessment = {
accountBalance: currentBalance,
currentRisk,
maxPositionSize,
recommendedSize,
stopLossDistance,
riskRewardRatio,
leverageRecommendation,
timeframeRisk: timeframeRisk as any,
coolingOffRequired,
riskWarnings: warnings
}
console.log('🛡️ Risk Assessment Complete:')
console.log(` Current Risk: ${currentRisk.toFixed(1)}%`)
console.log(` Recommended Size: $${recommendedSize.toFixed(2)}`)
console.log(` R:R Ratio: 1:${riskRewardRatio.toFixed(2)}`)
console.log(` Timeframe Risk: ${timeframeRisk}`)
console.log(` Warnings: ${warnings.length}`)
return assessment
}
async calculateCurrentAccountRisk(currentBalance: number): Promise<number> {
try {
// For now, return 0 as a safe default
// TODO: Implement database integration when available
console.log('📊 Current Account Risk: Database not available, returning 0%')
return 0
} catch (error) {
console.error('❌ Error calculating account risk:', error)
return 0
}
}
async getRecentLossCount(): Promise<number> {
try {
// For now, return 0 as a safe default
// TODO: Implement database integration when available
console.log('📉 Recent consecutive losses: Database not available, returning 0')
return 0
} catch (error) {
console.error('❌ Error getting recent loss count:', error)
return 0
}
}
calculateDynamicStopLoss(
entryPrice: number,
direction: 'LONG' | 'SHORT',
timeframe: string,
atr?: number
): number {
// Use ATR if available, otherwise use percentage-based stop
const atrMultiplier = this.ATR_MULTIPLIERS[timeframe] || 2.0
let stopDistance: number
if (atr && atr > 0) {
stopDistance = atr * atrMultiplier
console.log(`📏 ATR-based stop: ${atr} * ${atrMultiplier} = ${stopDistance}`)
} else {
// Fallback to percentage-based stops
const percentageStop = timeframe === '5' ? 0.5 :
timeframe === '15' ? 1.0 :
timeframe === '60' ? 1.5 : 2.0
stopDistance = entryPrice * (percentageStop / 100)
console.log(`📏 Percentage-based stop: ${percentageStop}% = ${stopDistance}`)
}
const stopLoss = direction === 'LONG'
? entryPrice - stopDistance
: entryPrice + stopDistance
console.log(`🛑 Dynamic Stop Loss: $${stopLoss.toFixed(2)} (${direction})`)
return parseFloat(stopLoss.toFixed(2))
}
async shouldAllowTrade(params: TradeRiskParameters): Promise<{
allowed: boolean
reason: string
riskAssessment: RiskAssessment
}> {
const riskAssessment = await this.assessTradeRisk(params)
// Check cooling off period
if (riskAssessment.coolingOffRequired) {
return {
allowed: false,
reason: 'Cooling off period required after consecutive losses',
riskAssessment
}
}
// Check if account risk is too high
if (riskAssessment.currentRisk > this.MAX_TOTAL_RISK) {
return {
allowed: false,
reason: `Total account risk ${riskAssessment.currentRisk.toFixed(1)}% exceeds maximum ${this.MAX_TOTAL_RISK}%`,
riskAssessment
}
}
// Check risk/reward ratio
if (riskAssessment.riskRewardRatio < 1.5) {
return {
allowed: false,
reason: `Risk/Reward ratio ${riskAssessment.riskRewardRatio.toFixed(2)} is below minimum 1.5`,
riskAssessment
}
}
// Check if recommended size is too small
if (riskAssessment.recommendedSize < 10) {
return {
allowed: false,
reason: 'Recommended position size too small - market conditions may be unsuitable',
riskAssessment
}
}
return {
allowed: true,
reason: 'Trade approved by risk management',
riskAssessment
}
}
async recordTradeDecision(
decision: 'APPROVED' | 'REJECTED',
reason: string,
riskAssessment: RiskAssessment
): Promise<void> {
try {
// For now, just log the decision
// TODO: Implement database integration when available
console.log(`📝 Risk decision recorded: ${decision} - ${reason}`)
console.log(` Account Balance: $${riskAssessment.accountBalance}`)
console.log(` Current Risk: ${riskAssessment.currentRisk}%`)
console.log(` Recommended Size: $${riskAssessment.recommendedSize}`)
console.log(` R:R Ratio: 1:${riskAssessment.riskRewardRatio}`)
} catch (error) {
console.error('❌ Error recording risk decision:', error)
}
}
}
export const enhancedRiskManager = new EnhancedRiskManager()