/** * Enhanced Autonomous AI Risk Management System with Complete R/R Learning * * This system learns from BOTH stop losses AND take profits to optimize * risk/reward setups and make smarter position management decisions. */ const SimplifiedStopLossLearner = require('./simplified-stop-loss-learner'); const SimplifiedRiskRewardLearner = require('./simplified-risk-reward-learner'); const HttpUtil = require('./http-util'); const { exec } = require('child_process'); const util = require('util'); const execAsync = util.promisify(exec); class EnhancedAutonomousRiskManager { constructor() { this.isActive = false; this.learner = new SimplifiedStopLossLearner(); this.rrLearner = new SimplifiedRiskRewardLearner(); // NEW: Complete R/R learning this.emergencyThreshold = 1.0; // Will be updated by learning system this.riskThreshold = 2.0; this.mediumRiskThreshold = 5.0; this.pendingDecisions = new Map(); // Track decisions awaiting outcomes this.activeSetups = new Map(); // Track R/R setups for outcome learning this.lastAnalysis = null; this.baseApiUrl = this.detectApiUrl(); // Docker-aware API URL this.lastScreenshotAnalysis = null; // Track when we last analyzed screenshots this.screenshotAnalysisThreshold = 3.5; // Only analyze screenshots when < 3.5% from SL (demo: was 3.0) this.screenshotAnalysisInterval = 2 * 60 * 1000; // Don't analyze more than once every 2 minutes (demo: was 5) } /** * Detect the correct API URL based on environment * Returns localhost for host environment, gateway IP for Docker */ detectApiUrl() { try { // Check if running inside Docker container const fs = require('fs'); if (fs.existsSync('/.dockerenv')) { // Get the default gateway IP from /proc/net/route try { const routeData = fs.readFileSync('/proc/net/route', 'utf8'); const lines = routeData.split('\n'); for (const line of lines) { const parts = line.trim().split(/\s+/); // Look for default route (destination 00000000) if (parts[1] === '00000000' && parts[2] && parts[2] !== '00000000') { // Convert hex gateway to IP const gatewayHex = parts[2]; const ip = [ parseInt(gatewayHex.substr(6, 2), 16), parseInt(gatewayHex.substr(4, 2), 16), parseInt(gatewayHex.substr(2, 2), 16), parseInt(gatewayHex.substr(0, 2), 16) ].join('.'); return `http://${ip}:9001`; } } // Fallback to known gateway IP return 'http://192.168.160.1:9001'; } catch (routeError) { // Fallback to the known gateway IP for this Docker setup return 'http://192.168.160.1:9001'; } } // Check hostname (Docker containers often have specific hostnames) const os = require('os'); const hostname = os.hostname(); if (hostname && hostname.length === 12 && /^[a-f0-9]+$/.test(hostname)) { // Same gateway detection for hostname-based detection try { const routeData = fs.readFileSync('/proc/net/route', 'utf8'); const lines = routeData.split('\n'); for (const line of lines) { const parts = line.trim().split(/\s+/); if (parts[1] === '00000000' && parts[2] && parts[2] !== '00000000') { const gatewayHex = parts[2]; const ip = [ parseInt(gatewayHex.substr(6, 2), 16), parseInt(gatewayHex.substr(4, 2), 16), parseInt(gatewayHex.substr(2, 2), 16), parseInt(gatewayHex.substr(0, 2), 16) ].join('.'); return `http://${ip}:9001`; } } return 'http://192.168.160.1:9001'; } catch (routeError) { return 'http://192.168.160.1:9001'; } } // Default to localhost for host environment return 'http://localhost:9001'; } catch (error) { // Fallback to localhost if detection fails return 'http://localhost:9001'; } } /** * Determine if we should trigger screenshot analysis based on risk level */ shouldTriggerScreenshotAnalysis(distancePercent) { // Only trigger when approaching critical levels if (distancePercent > this.screenshotAnalysisThreshold) { return false; } // Don't analyze too frequently if (this.lastScreenshotAnalysis) { const timeSinceLastAnalysis = Date.now() - this.lastScreenshotAnalysis.getTime(); if (timeSinceLastAnalysis < this.screenshotAnalysisInterval) { return false; } } return true; } /** * Request screenshot analysis from the main trading system */ async requestScreenshotAnalysis(symbol) { try { this.lastScreenshotAnalysis = new Date(); await this.log(`📸 Requesting chart analysis for ${symbol} - risk level requires visual confirmation`); // Use the enhanced screenshot API with analysis const response = await HttpUtil.post(`${this.baseApiUrl}/api/enhanced-screenshot`, { symbol: symbol, timeframes: ['1h'], // Focus on primary timeframe for speed layouts: ['ai'], // Only AI layout for faster analysis analyze: true, reason: 'RISK_MANAGEMENT_ANALYSIS' }); if (response.success && response.analysis) { await this.log(`✅ Chart analysis complete: ${response.analysis.recommendation} (${response.analysis.confidence}% confidence)`); return { recommendation: response.analysis.recommendation, confidence: response.analysis.confidence, marketSentiment: response.analysis.marketSentiment, keyLevels: response.analysis.keyLevels, reasoning: response.analysis.reasoning, supportNearby: this.detectNearbySupport(response.analysis, symbol), resistanceNearby: this.detectNearbyResistance(response.analysis, symbol), technicalStrength: this.assessTechnicalStrength(response.analysis), timestamp: new Date() }; } return null; } catch (error) { await this.log(`❌ Error in screenshot analysis: ${error.message}`); return null; } } /** * Detect if there's strong support near current price */ detectNearbySupport(analysis, symbol) { if (!analysis.keyLevels?.support) return false; // Get current price from last position data const currentPrice = this.lastAnalysis?.monitor?.position?.currentPrice || 0; if (!currentPrice) return false; // Check if any support level is within 2% of current price return analysis.keyLevels.support.some(supportLevel => { const distance = Math.abs(currentPrice - supportLevel) / currentPrice; return distance < 0.02; // Within 2% }); } /** * Detect if there's resistance near current price */ detectNearbyResistance(analysis, symbol) { if (!analysis.keyLevels?.resistance) return false; const currentPrice = this.lastAnalysis?.monitor?.position?.currentPrice || 0; if (!currentPrice) return false; return analysis.keyLevels.resistance.some(resistanceLevel => { const distance = Math.abs(currentPrice - resistanceLevel) / currentPrice; return distance < 0.02; // Within 2% }); } /** * Assess overall technical strength from chart analysis */ assessTechnicalStrength(analysis) { let strength = 'NEUTRAL'; if (analysis.confidence > 80 && analysis.marketSentiment === 'BULLISH') { strength = 'STRONG_BULLISH'; } else if (analysis.confidence > 80 && analysis.marketSentiment === 'BEARISH') { strength = 'STRONG_BEARISH'; } else if (analysis.confidence > 60) { strength = `MODERATE_${analysis.marketSentiment}`; } return strength; } async log(message) { const timestamp = new Date().toISOString(); console.log(`[${timestamp}] 🤖 Enhanced Risk AI: ${message}`); } /** * Main analysis function that integrates learning-based decision making */ async analyzePosition(monitor) { try { if (!monitor || !monitor.hasPosition) { return { action: 'NO_ACTION', reasoning: 'No position to analyze', confidence: 1.0 }; } const { position, stopLossProximity } = monitor; const distance = parseFloat(stopLossProximity.distancePercent); // Update thresholds based on learning await this.updateThresholdsFromLearning(); // SMART SCREENSHOT ANALYSIS TRIGGER // Only analyze screenshots when approaching critical levels let chartAnalysis = null; if (this.shouldTriggerScreenshotAnalysis(distance)) { await this.log(`📸 Triggering screenshot analysis - distance: ${distance}%`); chartAnalysis = await this.requestScreenshotAnalysis(position.symbol); } // Get AI recommendation based on learned patterns const smartRecommendation = await this.learner.getSmartRecommendation({ distanceFromSL: distance, symbol: position.symbol, marketConditions: { price: position.entryPrice, // Current price context unrealizedPnl: position.unrealizedPnl, side: position.side }, chartAnalysis: chartAnalysis // Include visual analysis if available }); let decision; // Enhanced decision logic using learning if (distance < this.emergencyThreshold) { decision = await this.handleEmergencyRisk(monitor, smartRecommendation); } else if (distance < this.riskThreshold) { decision = await this.handleHighRisk(monitor, smartRecommendation); } else if (distance < this.mediumRiskThreshold) { decision = await this.handleMediumRisk(monitor, smartRecommendation); } else { decision = await this.handleSafePosition(monitor, smartRecommendation); } // Record this decision for learning const decisionId = await this.recordDecisionForLearning(monitor, decision, smartRecommendation); decision.decisionId = decisionId; this.lastAnalysis = { monitor, decision, timestamp: new Date() }; return decision; } catch (error) { await this.log(`❌ Error in position analysis: ${error.message}`); return { action: 'ERROR', reasoning: `Analysis error: ${error.message}`, confidence: 0.1 }; } } async handleEmergencyRisk(monitor, smartRecommendation) { const { position, stopLossProximity } = monitor; const distance = parseFloat(stopLossProximity.distancePercent); await this.log(`🚨 EMERGENCY: Position ${distance}% from stop loss!`); // Use learning-based recommendation if highly confident if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.8) { await this.log(`🧠 Using learned strategy: ${smartRecommendation.suggestedAction} (${(smartRecommendation.confidence * 100).toFixed(1)}% confidence)`); return { action: smartRecommendation.suggestedAction, reasoning: `AI Learning: ${smartRecommendation.reasoning}`, confidence: smartRecommendation.confidence, urgency: 'CRITICAL', learningEnhanced: true, supportingData: smartRecommendation.supportingData }; } // Fallback to rule-based emergency logic return { action: 'EMERGENCY_EXIT', reasoning: 'Price critically close to stop loss. Autonomous exit to preserve capital.', confidence: 0.9, urgency: 'CRITICAL', parameters: { exitPercentage: 100, maxSlippage: 0.5 } }; } async handleHighRisk(monitor, smartRecommendation) { const { position, stopLossProximity } = monitor; const distance = parseFloat(stopLossProximity.distancePercent); await this.log(`âš ī¸ HIGH RISK: Position ${distance}% from stop loss`); // Check if we have recent chart analysis data const chartAnalysis = smartRecommendation.chartAnalysis; // Use chart analysis to make smarter decisions if (chartAnalysis) { await this.log(`📊 Using chart analysis: ${chartAnalysis.technicalStrength} sentiment, ${chartAnalysis.confidence}% confidence`); // If there's strong support nearby and bullish sentiment, consider holding if (chartAnalysis.supportNearby && chartAnalysis.technicalStrength.includes('BULLISH') && chartAnalysis.confidence > 70 && position.side === 'long') { await this.log(`đŸ›Ąī¸ Strong support detected near ${position.currentPrice} - holding position with tighter stop`); return { action: 'TIGHTEN_STOP_LOSS', reasoning: `Chart shows strong support nearby (${chartAnalysis.reasoning}). Tightening stop instead of exiting.`, confidence: chartAnalysis.confidence / 100, urgency: 'HIGH', chartEnhanced: true, parameters: { newStopLossDistance: distance * 0.8 // Tighten by 20% } }; } // If chart shows weakness, exit more aggressively if (chartAnalysis.technicalStrength.includes('BEARISH') && chartAnalysis.confidence > 60) { await this.log(`📉 Chart shows weakness - executing defensive exit`); return { action: 'PARTIAL_EXIT', reasoning: `Chart analysis shows bearish signals (${chartAnalysis.reasoning}). Reducing exposure.`, confidence: chartAnalysis.confidence / 100, urgency: 'HIGH', chartEnhanced: true, parameters: { exitPercentage: 70, // More aggressive exit keepStopLoss: true } }; } } // Check learning recommendation if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.7) { return { action: smartRecommendation.suggestedAction, reasoning: `AI Learning: ${smartRecommendation.reasoning}`, confidence: smartRecommendation.confidence, urgency: 'HIGH', learningEnhanced: true }; } // Enhanced market analysis for high-risk situations const marketAnalysis = await this.analyzeMarketConditions(position.symbol); if (marketAnalysis.trend === 'BULLISH' && position.side === 'LONG') { return { action: 'TIGHTEN_STOP_LOSS', reasoning: 'Market still favorable. Tightening stop loss for better risk management.', confidence: 0.7, urgency: 'HIGH', parameters: { newStopLossDistance: distance * 0.7 // Tighten by 30% } }; } else { return { action: 'PARTIAL_EXIT', reasoning: 'Market conditions uncertain. Reducing position size to manage risk.', confidence: 0.75, urgency: 'HIGH', parameters: { exitPercentage: 50, keepStopLoss: true } }; } } async handleMediumRisk(monitor, smartRecommendation) { const { position, stopLossProximity } = monitor; const distance = parseFloat(stopLossProximity.distancePercent); await this.log(`🟡 MEDIUM RISK: Position ${distance}% from stop loss`); // Learning-based decision for medium risk if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.6) { return { action: smartRecommendation.suggestedAction, reasoning: `AI Learning: ${smartRecommendation.reasoning}`, confidence: smartRecommendation.confidence, urgency: 'MEDIUM', learningEnhanced: true }; } // Default medium risk response return { action: 'ENHANCED_MONITORING', reasoning: 'Increased monitoring frequency. Preparing contingency plans.', confidence: 0.6, urgency: 'MEDIUM', parameters: { monitoringInterval: 30, // seconds alertThreshold: this.riskThreshold } }; } async handleSafePosition(monitor, smartRecommendation) { const { position } = monitor; // Even in safe positions, check for optimization opportunities if (smartRecommendation.learningBased && smartRecommendation.confidence > 0.8) { if (smartRecommendation.suggestedAction === 'SCALE_POSITION') { return { action: 'SCALE_POSITION', reasoning: `AI Learning: ${smartRecommendation.reasoning}`, confidence: smartRecommendation.confidence, urgency: 'LOW', learningEnhanced: true }; } } return { action: 'MONITOR', reasoning: 'Position is safe. Continuing standard monitoring.', confidence: 0.8, urgency: 'LOW' }; } /** * Record a new risk/reward setup when trade is placed */ async recordTradeSetup(tradeData) { try { const { tradeId, symbol, entryPrice, stopLoss, takeProfit, leverage, side, aiReasoning } = tradeData; const setupId = await this.rrLearner.recordRiskRewardSetup({ tradeId, symbol, entryPrice, stopLoss, takeProfit, leverage: leverage || 1.0, side, aiReasoning: aiReasoning || 'Autonomous AI setup', aiConfidence: 0.8, expectedOutcome: 'REACH_TAKE_PROFIT' }); if (setupId) { this.activeSetups.set(tradeId, { setupId, tradeData, timestamp: new Date() }); await this.log(`📊 Recorded R/R setup ${setupId} for trade ${tradeId}: SL=${stopLoss} TP=${takeProfit}`); } return setupId; } catch (error) { await this.log(`❌ Error recording trade setup: ${error.message}`); return null; } } /** * Record trade outcome when position closes */ async recordTradeOutcome(tradeId, outcomeData) { try { const setup = this.activeSetups.get(tradeId); if (!setup) { await this.log(`âš ī¸ No setup found for trade ${tradeId}`); return; } const { exitPrice, exitReason, actualPnL } = outcomeData; const timeToExit = Math.floor((Date.now() - setup.timestamp.getTime()) / 60000); // minutes const outcome = await this.rrLearner.recordTradeOutcome({ setupId: setup.setupId, exitPrice, exitReason, // 'STOP_LOSS', 'TAKE_PROFIT', 'MANUAL_EXIT', 'LIQUIDATION' actualPnL, timeToExit, setupData: setup.tradeData }); if (outcome) { await this.log(`✅ Recorded outcome for trade ${tradeId}: ${exitReason} - Quality: ${outcome.quality}`); // Learn from this outcome if (outcome.suggestedImprovements.length > 0) { await this.log(`💡 Improvement suggestions: ${outcome.suggestedImprovements.join(', ')}`); } } // Remove from active setups this.activeSetups.delete(tradeId); return outcome; } catch (error) { await this.log(`❌ Error recording trade outcome: ${error.message}`); return null; } } /** * Get smart risk/reward recommendation for new trade */ async getSmartRiskRewardSetup(requestData) { try { const recommendation = await this.rrLearner.getSmartRiskRewardRecommendation(requestData); await this.log(`đŸŽ¯ Smart R/R recommendation: SL=${recommendation.stopLossDistance?.toFixed(2)}% RR=1:${recommendation.riskRewardRatio.toFixed(2)} (${(recommendation.confidence * 100).toFixed(1)}% confidence)`); return recommendation; } catch (error) { await this.log(`❌ Error getting R/R recommendation: ${error.message}`); return { stopLossDistance: 2.5, riskRewardRatio: 2.0, confidence: 0.3, reasoning: 'Error in recommendation system', learningBased: false }; } } async recordDecisionForLearning(monitor, decision, smartRecommendation) { try { const { position, stopLossProximity } = monitor; const distance = parseFloat(stopLossProximity.distancePercent); const decisionData = { tradeId: position.id || `position_${Date.now()}`, symbol: position.symbol, decision: decision.action, distanceFromSL: distance, reasoning: decision.reasoning, currentPrice: position.entryPrice, confidenceScore: decision.confidence, expectedOutcome: this.predictOutcome(decision.action, distance), marketConditions: await this.getCurrentMarketConditions(position.symbol), learningRecommendation: smartRecommendation }; const decisionId = await this.learner.recordDecision(decisionData); // Store decision for outcome tracking this.pendingDecisions.set(decisionId, { ...decisionData, timestamp: new Date(), monitor: monitor }); await this.log(`📝 Recorded decision ${decisionId} for learning: ${decision.action}`); return decisionId; } catch (error) { await this.log(`❌ Error recording decision for learning: ${error.message}`); return null; } } /** * Assess outcomes of previous decisions and R/R setups */ async assessDecisionOutcomes() { try { // Assess stop loss decisions for (const [decisionId, decisionData] of this.pendingDecisions.entries()) { const timeSinceDecision = Date.now() - decisionData.timestamp.getTime(); // Assess after sufficient time has passed (5 minutes minimum) if (timeSinceDecision > 5 * 60 * 1000) { const outcome = await this.determineDecisionOutcome(decisionData); if (outcome) { await this.learner.assessDecisionOutcome({ decisionId, actualOutcome: outcome.result, timeToOutcome: Math.floor(timeSinceDecision / 60000), // minutes pnlImpact: outcome.pnlImpact, additionalContext: outcome.context }); // Remove from pending decisions this.pendingDecisions.delete(decisionId); await this.log(`✅ Assessed SL decision ${decisionId}: ${outcome.result}`); } } } // Check for closed positions and assess R/R setups await this.assessRiskRewardSetups(); } catch (error) { await this.log(`❌ Error assessing decision outcomes: ${error.message}`); } } /** * Check for closed positions and assess risk/reward setup outcomes */ async assessRiskRewardSetups() { try { for (const [tradeId, setup] of this.activeSetups.entries()) { const timeSinceSetup = Date.now() - setup.timestamp.getTime(); // Check if position is still active after reasonable time if (timeSinceSetup > 10 * 60 * 1000) { // 10 minutes minimum const positionStatus = await this.checkPositionStatus(setup.tradeData.symbol); if (!positionStatus || !positionStatus.hasPosition) { // Position closed - try to determine outcome const outcome = await this.determineTradeOutcome(setup); if (outcome) { await this.recordTradeOutcome(tradeId, outcome); } else { // If we can't determine outcome, record as manual exit await this.recordTradeOutcome(tradeId, { exitPrice: setup.tradeData.entryPrice, // Assume breakeven exitReason: 'MANUAL_EXIT', actualPnL: 0 }); } } } } } catch (error) { await this.log(`❌ Error assessing R/R setups: ${error.message}`); } } /** * Determine trade outcome from position monitoring */ async determineTradeOutcome(setup) { try { // This is a simplified version - in real implementation, you'd check // trade history, position changes, and execution logs const currentStatus = await this.getCurrentPositionStatus(setup.tradeData.symbol); if (!currentStatus) { // Position no longer exists - need to determine how it closed // For demo purposes, simulate random outcomes const outcomes = ['STOP_LOSS', 'TAKE_PROFIT', 'MANUAL_EXIT']; const randomOutcome = outcomes[Math.floor(Math.random() * outcomes.length)]; let exitPrice = setup.tradeData.entryPrice; let actualPnL = 0; switch (randomOutcome) { case 'STOP_LOSS': exitPrice = setup.tradeData.stopLoss; actualPnL = -Math.abs(setup.tradeData.entryPrice - setup.tradeData.stopLoss); break; case 'TAKE_PROFIT': exitPrice = setup.tradeData.takeProfit; actualPnL = Math.abs(setup.tradeData.takeProfit - setup.tradeData.entryPrice); break; case 'MANUAL_EXIT': exitPrice = setup.tradeData.entryPrice + (Math.random() - 0.5) * 10; // Random exit actualPnL = exitPrice - setup.tradeData.entryPrice; break; } return { exitPrice, exitReason: randomOutcome, actualPnL }; } return null; // Position still active } catch (error) { await this.log(`❌ Error determining trade outcome: ${error.message}`); return null; } } async checkPositionStatus(symbol) { // Check if position is still active try { const data = await HttpUtil.get(`${this.baseApiUrl}/api/automation/position-monitor`); if (data.success && data.monitor?.hasPosition && data.monitor.position?.symbol === symbol) { return data.monitor; } return null; } catch (error) { return null; } } async determineDecisionOutcome(decisionData) { try { // Get current position status const currentStatus = await this.getCurrentPositionStatus(decisionData.symbol); if (!currentStatus) { return { result: 'POSITION_CLOSED', pnlImpact: 0, context: { reason: 'Position no longer exists' } }; } // Compare current situation with when decision was made const originalDistance = decisionData.distanceFromSL; const currentDistance = currentStatus.distanceFromSL; const pnlChange = currentStatus.unrealizedPnl - (decisionData.monitor.position?.unrealizedPnl || 0); // Determine if decision was beneficial if (decisionData.decision === 'EMERGENCY_EXIT' && currentDistance < 0.5) { return { result: 'AVOIDED_MAJOR_LOSS', pnlImpact: Math.abs(pnlChange), // Positive impact context: { originalDistance, currentDistance } }; } if (decisionData.decision === 'TIGHTEN_STOP_LOSS' && pnlChange > 0) { return { result: 'IMPROVED_PROFIT', pnlImpact: pnlChange, context: { originalDistance, currentDistance } }; } if (decisionData.decision === 'HOLD' && currentDistance > originalDistance) { return { result: 'CORRECT_HOLD', pnlImpact: pnlChange, context: { distanceImproved: currentDistance - originalDistance } }; } // Default assessment return { result: pnlChange >= 0 ? 'NEUTRAL_POSITIVE' : 'NEUTRAL_NEGATIVE', pnlImpact: pnlChange, context: { originalDistance, currentDistance } }; } catch (error) { await this.log(`❌ Error determining decision outcome: ${error.message}`); return null; } } async getCurrentPositionStatus(symbol) { try { const data = await HttpUtil.get(`${this.baseApiUrl}/api/automation/position-monitor`); if (data.success && data.monitor?.hasPosition) { return { distanceFromSL: parseFloat(data.monitor.stopLossProximity?.distancePercent || 0), unrealizedPnl: data.monitor.position?.unrealizedPnl || 0 }; } return null; } catch (error) { return null; } } async updateThresholdsFromLearning() { try { // Get learned optimal thresholds const patterns = await this.learner.analyzeDecisionPatterns(); if (patterns?.distanceOptimization) { const optimization = patterns.distanceOptimization; if (optimization.emergencyRange?.optimalThreshold) { this.emergencyThreshold = optimization.emergencyRange.optimalThreshold; } if (optimization.highRiskRange?.optimalThreshold) { this.riskThreshold = optimization.highRiskRange.optimalThreshold; } if (optimization.mediumRiskRange?.optimalThreshold) { this.mediumRiskThreshold = optimization.mediumRiskRange.optimalThreshold; } await this.log(`🔄 Updated thresholds from learning: Emergency=${this.emergencyThreshold.toFixed(2)}%, Risk=${this.riskThreshold.toFixed(2)}%, Medium=${this.mediumRiskThreshold.toFixed(2)}%`); } } catch (error) { await this.log(`❌ Error updating thresholds from learning: ${error.message}`); } } predictOutcome(action, distance) { // Predict what we expect to happen based on the action const predictions = { 'EMERGENCY_EXIT': 'AVOID_MAJOR_LOSS', 'PARTIAL_EXIT': 'REDUCE_RISK', 'TIGHTEN_STOP_LOSS': 'BETTER_RISK_REWARD', 'SCALE_POSITION': 'INCREASED_PROFIT', 'HOLD': 'MAINTAIN_POSITION', 'ENHANCED_MONITORING': 'EARLY_WARNING' }; return predictions[action] || 'UNKNOWN_OUTCOME'; } async analyzeMarketConditions(symbol) { // Enhanced market analysis for better decision making try { const data = await HttpUtil.get(`${this.baseApiUrl}/api/automation/position-monitor`); if (data.success && data.monitor?.position) { const pnl = data.monitor.position.unrealizedPnl; const trend = pnl > 0 ? 'BULLISH' : pnl < -1 ? 'BEARISH' : 'SIDEWAYS'; return { trend, strength: Math.abs(pnl), timeOfDay: new Date().getHours(), volatility: Math.random() * 0.1 // Mock volatility }; } } catch (error) { // Fallback analysis } return { trend: 'UNKNOWN', strength: 0, timeOfDay: new Date().getHours(), volatility: 0.05 }; } async getCurrentMarketConditions(symbol) { const conditions = await this.analyzeMarketConditions(symbol); return { ...conditions, dayOfWeek: new Date().getDay(), timestamp: new Date().toISOString() }; } /** * Enhanced Beach Mode with learning integration */ async beachMode() { await this.log('đŸ–ī¸ ENHANCED BEACH MODE: Autonomous operation with AI learning'); this.isActive = true; // Main monitoring loop const monitoringLoop = async () => { if (!this.isActive) return; try { // Check current positions const data = await HttpUtil.get(`${this.baseApiUrl}/api/automation/position-monitor`); if (data.success) { const decision = await this.analyzePosition(data.monitor); await this.executeDecision(decision); } // Assess outcomes of previous decisions await this.assessDecisionOutcomes(); } catch (error) { await this.log(`Error in beach mode: ${error.message}`); } // Schedule next check if (this.isActive) { setTimeout(monitoringLoop, 60000); // Check every minute } }; // Start monitoring monitoringLoop(); // Generate learning reports periodically setInterval(async () => { if (this.isActive) { // const report = await this.learner.generateLearningReport(); // TEMPORARILY DISABLED if (report) { await this.log(`📊 Learning Update: ${report.summary.totalDecisions} decisions, ${(report.summary.systemConfidence * 100).toFixed(1)}% confidence`); } } }, 15 * 60 * 1000); // Every 15 minutes } async executeDecision(decision) { await this.log(`đŸŽ¯ Executing decision: ${decision.action} - ${decision.reasoning} (Confidence: ${(decision.confidence * 100).toFixed(1)}%)`); // Add learning enhancement indicators if (decision.learningEnhanced) { await this.log(`🧠 Decision enhanced by AI learning system`); } // Implementation would depend on your trading API switch (decision.action) { case 'EMERGENCY_EXIT': await this.log('🚨 Implementing emergency exit protocol'); break; case 'PARTIAL_EXIT': await this.log('📉 Executing partial position closure'); break; case 'TIGHTEN_STOP_LOSS': await this.log('đŸŽ¯ Adjusting stop loss parameters'); break; case 'SCALE_POSITION': await this.log('📈 Scaling position size'); break; case 'ENHANCED_MONITORING': await this.log('đŸ‘ī¸ Activating enhanced monitoring'); break; default: await this.log(`â„šī¸ Monitoring: ${decision.reasoning}`); } } stop() { this.isActive = false; this.log('🛑 Enhanced autonomous risk management stopped'); } /** * Get comprehensive learning system status including R/R insights */ async getLearningStatus() { try { // const slReport = await this.learner.generateLearningReport(); // TEMPORARILY DISABLED const rrPatterns = await this.rrLearner.updateRiskRewardLearning(); return { isLearning: true, stopLossLearning: { totalDecisions: this.pendingDecisions.size + (slReport?.summary?.totalDecisions || 0), systemConfidence: slReport?.summary?.systemConfidence || 0.3, pendingAssessments: this.pendingDecisions.size, insights: slReport?.insights }, riskRewardLearning: { activeSetups: this.activeSetups.size, totalSetups: rrPatterns?.stopLossPatterns?.length || 0, stopLossPatterns: rrPatterns?.stopLossPatterns || [], takeProfitPatterns: rrPatterns?.takeProfitPatterns || [], optimalRatios: rrPatterns?.optimalRatios || [], learningQuality: this.assessRRLearningQuality(rrPatterns) }, currentThresholds: { emergency: this.emergencyThreshold, risk: this.riskThreshold, mediumRisk: this.mediumRiskThreshold }, lastAnalysis: this.lastAnalysis, systemMaturity: this.calculateSystemMaturity(slReport, rrPatterns), beachModeReady: this.isSystemReadyForBeachMode(slReport, rrPatterns) }; } catch (error) { return { isLearning: false, error: error.message, stopLossLearning: { totalDecisions: 0, systemConfidence: 0.1 }, riskRewardLearning: { activeSetups: 0, totalSetups: 0 } }; } } assessRRLearningQuality(rrPatterns) { if (!rrPatterns) return 'INSUFFICIENT_DATA'; const totalPatterns = (rrPatterns.stopLossPatterns?.length || 0) + (rrPatterns.takeProfitPatterns?.length || 0); if (totalPatterns >= 10) return 'HIGH_QUALITY'; if (totalPatterns >= 5) return 'MEDIUM_QUALITY'; if (totalPatterns >= 2) return 'LOW_QUALITY'; return 'INSUFFICIENT_DATA'; } calculateSystemMaturity(slReport, rrPatterns) { const slDecisions = slReport?.summary?.totalDecisions || 0; const rrSetups = rrPatterns?.optimalRatios?.length || 0; const totalLearningPoints = slDecisions + (rrSetups * 2); // R/R setups worth 2x if (totalLearningPoints >= 100) return 'EXPERT'; if (totalLearningPoints >= 50) return 'ADVANCED'; if (totalLearningPoints >= 20) return 'INTERMEDIATE'; if (totalLearningPoints >= 10) return 'NOVICE'; return 'BEGINNER'; } isSystemReadyForBeachMode(slReport, rrPatterns) { const slConfidence = slReport?.summary?.systemConfidence || 0; const rrQuality = this.assessRRLearningQuality(rrPatterns); return slConfidence > 0.6 && ['HIGH_QUALITY', 'MEDIUM_QUALITY'].includes(rrQuality); } } // Export for use in other modules module.exports = EnhancedAutonomousRiskManager; // Direct execution for testing if (require.main === module) { const riskManager = new EnhancedAutonomousRiskManager(); console.log('🤖 Enhanced Autonomous Risk Manager with AI Learning'); console.log('🧠 Now learning from every decision to become smarter!'); console.log('đŸ–ī¸ Perfect for beach mode - gets better while you relax!'); riskManager.beachMode(); process.on('SIGINT', () => { riskManager.stop(); process.exit(0); }); }