// Enhanced automation with integrated AI learning system // Dynamic import for ES6 modules async function importSimpleAutomation() { try { const module = await import('./simple-automation.js'); // Extract the class from the singleton instance return module.simpleAutomation.constructor; } catch (error) { console.warn('⚠️ Could not import SimpleAutomation, using fallback'); // Fallback - create a basic class structure return class BasicAutomation { constructor() { this.isRunning = false; this.config = null; this.stats = { totalCycles: 0, totalTrades: 0 }; } async start(config) { return { success: false, message: 'Base automation not available' }; } async stop() { return { success: true, message: 'Stopped' }; } getStatus() { return { isRunning: this.isRunning, stats: this.stats }; } }; } } // Import learning system async function importSimplifiedStopLossLearner() { try { const { SimplifiedStopLossLearner } = await import('./simplified-stop-loss-learner-fixed.js'); return SimplifiedStopLossLearner; } catch (error) { console.warn('⚠️ SimplifiedStopLossLearner not available, continuing without learning'); return null; } } class AutomationWithLearning { constructor() { this.baseAutomation = null; this.learner = null; this.activeTrades = new Map(); // Track active trades for outcome assessment this.learningDecisions = new Map(); // Track decisions for learning this.learningEnabled = false; this.isRunning = false; this.config = null; this.stats = { totalCycles: 0, totalTrades: 0 }; } async initializeBaseAutomation() { if (!this.baseAutomation) { const SimpleAutomationClass = await importSimpleAutomation(); this.baseAutomation = new SimpleAutomationClass(); } return this.baseAutomation; } async initializeLearningSystem() { try { const SimplifiedStopLossLearnerClass = await importSimplifiedStopLossLearner(); if (SimplifiedStopLossLearnerClass) { this.learner = new SimplifiedStopLossLearnerClass(); console.log('✅ AI Learning System initialized successfully'); // Generate initial learning report if (typeof this.learner.generateLearningReport === 'function') { const report = await this.learner.generateLearningReport(); console.log('📊 Current Learning Status:', report.summary); } return true; } } catch (error) { console.warn('⚠️ Could not initialize learning system:', error.message); } return false; } async start(config) { try { // Initialize base automation await this.initializeBaseAutomation(); // Initialize learning system await this.initializeLearningSystem(); // Use base automation if available, otherwise implement basic functionality let result; if (this.baseAutomation && typeof this.baseAutomation.start === 'function') { result = await this.baseAutomation.start(config); } else { // Basic start functionality this.isRunning = true; this.config = config; result = { success: true, message: 'Basic automation started' }; } if (result.success && this.learner) { console.log('🧠 AI LEARNING SYSTEM: Activated and ready to learn from trades'); console.log('📊 The system will now record decisions and improve over time'); this.learningEnabled = true; } return result; } catch (error) { console.error('❌ Error starting automation with learning:', error); return { success: false, message: error.message }; } } async stop() { try { let result; if (this.baseAutomation && typeof this.baseAutomation.stop === 'function') { result = await this.baseAutomation.stop(); } else { this.isRunning = false; result = { success: true, message: 'Basic automation stopped' }; } this.learningEnabled = false; return result; } catch (error) { console.error('❌ Error stopping automation:', error); return { success: false, message: error.message }; } } getStatus() { let baseStatus; if (this.baseAutomation && typeof this.baseAutomation.getStatus === 'function') { baseStatus = this.baseAutomation.getStatus(); } else { baseStatus = { isRunning: this.isRunning, config: this.config, stats: this.stats }; } return { ...baseStatus, learningSystem: { enabled: this.learningEnabled, hasLearner: !!this.learner, activeDecisions: this.activeTrades.size, trackedTrades: Array.from(this.activeTrades.keys()) } }; } async getLearningStatus() { if (!this.learningEnabled || !this.learner) { return { enabled: false, message: 'Learning system not available' }; } try { let report = null; // Try to get comprehensive learning report if (typeof this.learner.generateLearningReport === 'function') { report = await this.learner.generateLearningReport(); } else if (typeof this.learner.getLearningStatus === 'function') { report = await this.learner.getLearningStatus(); } return { enabled: true, learningActive: this.learningEnabled, activeDecisions: this.activeTrades.size, report: report || { summary: { message: 'Learning system active but no data available yet' } } }; } catch (error) { console.error('❌ Error getting learning status:', error); return { enabled: true, learningActive: this.learningEnabled, error: error.message }; } } async executeTrade(analysis) { try { console.log('🧠 LEARNING-ENHANCED TRADE EXECUTION'); // Record decision before execution for learning let decisionId = null; if (this.learningEnabled && this.learner) { decisionId = await this.recordTradingDecision(analysis); } // Enhance analysis with learning-based adjustments const enhancedAnalysis = await this.enhanceAnalysisWithLearning(analysis); // Execute the trade using enhanced analysis let tradeResult; if (this.baseAutomation && typeof this.baseAutomation.executeTrade === 'function') { tradeResult = await this.baseAutomation.executeTrade(enhancedAnalysis); } else { // Basic trade execution simulation tradeResult = { success: true, message: 'Trade simulated (learning system active)', simulation: true }; } // Track trade for outcome assessment if (tradeResult.success && decisionId) { this.trackTradeForLearning(decisionId, tradeResult, enhancedAnalysis); } return tradeResult; } catch (error) { console.error('❌ Error in learning-enhanced trade execution:', error); return { success: false, error: error.message }; } } async recordTradingDecision(analysis) { if (!this.learner || typeof this.learner.recordDecision !== 'function') { return null; } try { const decisionData = { symbol: this.config?.symbol || 'SOLUSD', recommendation: analysis.recommendation, confidence: analysis.confidence, stopLoss: this.extractStopLoss(analysis), takeProfit: this.extractTakeProfit(analysis), entryPrice: analysis.entry?.price || analysis.currentPrice, marketConditions: { timeframe: this.config?.selectedTimeframes || ['1h'], analysis: analysis.reasoning || analysis.summary }, timestamp: new Date().toISOString() }; const decisionId = await this.learner.recordDecision(decisionData); console.log(`📝 LEARNING: Recorded decision ${decisionId}`); return decisionId; } catch (error) { console.error('❌ Error recording decision:', error); return null; } } async enhanceAnalysisWithLearning(analysis) { if (!this.learningEnabled || !this.learner) { console.log('📊 Using original analysis (learning not available)'); return analysis; } try { // Get learning-based recommendations if available if (typeof this.learner.getSmartRecommendation === 'function') { const currentPrice = analysis.entry?.price || analysis.currentPrice || 178; const originalStopLoss = this.extractStopLoss(analysis); if (originalStopLoss) { const distanceFromSL = Math.abs(currentPrice - originalStopLoss); const learningRecommendation = await this.learner.getSmartRecommendation({ symbol: this.config?.symbol || 'SOLUSD', distanceFromSL, marketConditions: { recommendation: analysis.recommendation, confidence: analysis.confidence, timeframe: this.config?.selectedTimeframes || ['1h'] } }); if (learningRecommendation && learningRecommendation.confidence > 70) { console.log(`🧠 LEARNING ENHANCEMENT: ${learningRecommendation.action} (${learningRecommendation.confidence}% confidence)`); console.log(`💡 Reasoning: ${learningRecommendation.reasoning}`); // Apply learning-based adjustments if (learningRecommendation.action === 'TIGHTEN_STOP_LOSS') { analysis = this.adjustStopLoss(analysis, learningRecommendation.suggestedValue); } else if (learningRecommendation.action === 'ADJUST_TAKE_PROFIT') { analysis = this.adjustTakeProfit(analysis, learningRecommendation.suggestedValue); } // Add learning metadata to analysis analysis.learningEnhanced = true; analysis.learningConfidence = learningRecommendation.confidence; analysis.learningReasoning = learningRecommendation.reasoning; } } } return analysis; } catch (error) { console.error('❌ Error enhancing analysis with learning:', error); return analysis; // Return original analysis if learning fails } } adjustStopLoss(analysis, newStopLoss) { if (newStopLoss) { if (analysis.stopLoss && typeof analysis.stopLoss === 'object') { analysis.stopLoss.price = newStopLoss; } else { analysis.stopLoss = newStopLoss; } console.log(`🔧 LEARNING ADJUSTMENT: Stop-loss adjusted to $${newStopLoss}`); } return analysis; } adjustTakeProfit(analysis, newTakeProfit) { if (newTakeProfit) { if (analysis.takeProfits && analysis.takeProfits.tp1) { analysis.takeProfits.tp1.price = newTakeProfit; } else if (analysis.takeProfit) { analysis.takeProfit = newTakeProfit; } else { analysis.takeProfit = newTakeProfit; } console.log(`🎯 LEARNING ADJUSTMENT: Take-profit adjusted to $${newTakeProfit}`); } return analysis; } trackTradeForLearning(decisionId, tradeResult, analysis) { if (!decisionId) return; this.activeTrades.set(decisionId, { tradeResult, analysis, timestamp: new Date().toISOString(), symbol: this.config?.symbol || 'SOLUSD' }); console.log(`📊 LEARNING: Tracking trade ${decisionId} for outcome assessment`); // Set up outcome assessment check (will check position status later) setTimeout(() => { this.assessTradeOutcome(decisionId); }, 300000); // Check after 5 minutes } async assessTradeOutcome(decisionId) { if (!this.learningEnabled || !this.learner || !this.activeTrades.has(decisionId)) { return; } try { const tradeInfo = this.activeTrades.get(decisionId); // Check current position status via API const baseUrl = process.env.INTERNAL_API_URL || 'http://localhost:3000'; const response = await fetch(`${baseUrl}/api/automation/position-monitor`); const positionData = await response.json(); let outcome = null; let actualPnL = 0; if (positionData.success) { // Determine outcome based on position status if (!positionData.monitor.hasPosition) { // Position closed - check if it was profitable outcome = 'POSITION_CLOSED'; // Try to get actual P&L from position history try { const historyResponse = await fetch(`${baseUrl}/api/drift/position-history`); const historyData = await historyResponse.json(); if (historyData.success && historyData.trades.length > 0) { // Find the most recent trade const recentTrade = historyData.trades[0]; actualPnL = recentTrade.pnl; outcome = actualPnL > 0 ? 'WIN' : 'LOSS'; } } catch (historyError) { console.warn('⚠️ Could not fetch trade history for outcome assessment'); } } else { // Position still open - check if it's profitable const currentPnL = positionData.monitor.position?.unrealizedPnl || 0; actualPnL = currentPnL; outcome = currentPnL > 0 ? 'CURRENTLY_PROFITABLE' : 'CURRENTLY_LOSING'; } } // Record outcome for learning if (outcome && typeof this.learner.assessDecisionOutcome === 'function') { const outcomeData = { decisionId, outcome, actualPnL, timestamp: new Date().toISOString(), positionInfo: positionData.monitor }; await this.learner.assessDecisionOutcome(outcomeData); console.log(`🧠 LEARNING: Assessed outcome for decision ${decisionId}: ${outcome} (P&L: $${actualPnL.toFixed(2)})`); // Clean up tracked trade this.activeTrades.delete(decisionId); } } catch (error) { console.error('❌ Error assessing trade outcome:', error); } } extractStopLoss(analysis) { if (analysis.stopLoss && typeof analysis.stopLoss === 'object') { return analysis.stopLoss.price; } else if (analysis.stopLoss && typeof analysis.stopLoss === 'number') { return analysis.stopLoss; } else if (analysis.levels?.stopLoss) { return analysis.levels.stopLoss; } return null; } extractTakeProfit(analysis) { if (analysis.takeProfits && analysis.takeProfits.tp1?.price) { return analysis.takeProfits.tp1.price; } else if (analysis.takeProfit && typeof analysis.takeProfit === 'number') { return analysis.takeProfit; } else if (analysis.levels?.takeProfit) { return analysis.levels.takeProfit; } return null; } } module.exports = AutomationWithLearning;