diff --git a/lib/simple-automation.js b/lib/simple-automation.js index 37a3200..c1ef950 100644 --- a/lib/simple-automation.js +++ b/lib/simple-automation.js @@ -1,9 +1,40 @@ // Simple automation service for basic start/stop functionality + +// Import AI Leverage Calculator for dynamic leverage +async function importAILeverageCalculator() { + try { + const { AILeverageCalculator } = await import('./ai-leverage-calculator.js'); + return AILeverageCalculator; + } catch (error) { + console.warn('⚠️ AI Leverage Calculator not available, using default leverage'); + return null; + } +} + +// Import Enhanced Risk Manager with Learning for intelligent beach mode operation +async function importEnhancedRiskManager() { + try { + const EnhancedAutonomousRiskManager = require('./enhanced-autonomous-risk-manager.js'); + return EnhancedAutonomousRiskManager; + } catch (error) { + console.warn('⚠️ Enhanced Risk Manager not available, falling back to stable monitor'); + // Fallback to stable risk monitor + try { + const StableRiskMonitor = require('./stable-risk-monitor.js'); + return StableRiskMonitor; + } catch (fallbackError) { + console.warn('⚠️ Stable Risk Monitor also not available, using basic monitoring'); + return null; + } + } +} + class SimpleAutomation { constructor() { this.isRunning = false; this.config = null; this.intervalId = null; + this.riskManager = null; // Autonomous AI Risk Manager this.stats = { totalCycles: 0, totalTrades: 0, @@ -30,8 +61,41 @@ class SimpleAutomation { this.isRunning = true; this.stats.startTime = new Date().toISOString(); this.stats.status = 'Running'; + + console.log('✅ AUTOMATION STATUS: isRunning =', this.isRunning); + console.log('🎯 LIVE TRADING:', this.config.enableTrading ? 'ENABLED' : 'DISABLED'); this.stats.totalCycles = 0; + // Initialize Enhanced AI Risk Manager with Learning Capabilities + try { + const EnhancedRiskManagerClass = await importEnhancedRiskManager(); + if (EnhancedRiskManagerClass) { + this.riskManager = new EnhancedRiskManagerClass(); + console.log('🧠 ENHANCED BEACH MODE: AI learning system activated'); + console.log('🎯 System will learn from every decision and improve over time'); + + // Start enhanced autonomous operation + setTimeout(() => { + if (this.riskManager && this.riskManager.beachMode) { + this.riskManager.beachMode(); + console.log('🏖️ Full autonomous operation with AI learning active'); + } + }, 2000); + } + } catch (error) { + console.log('🔄 Continuing without enhanced autonomous risk monitoring'); + console.error('Risk manager initialization error:', error.message); + } + + // Auto-enable trading when in LIVE mode + if (config.mode === 'LIVE') { + this.config.enableTrading = true; + console.log('🔥 LIVE TRADING ENABLED: Real trades will be executed'); + } else { + this.config.enableTrading = false; + console.log('📊 SIMULATION MODE: Trades will be simulated only'); + } + // Detect strategy const timeframes = config.selectedTimeframes; let strategy = 'General'; @@ -73,14 +137,22 @@ class SimpleAutomation { async stop() { try { + console.log('🛑 STOPPING AUTOMATION...'); this.isRunning = false; this.stats.status = 'Stopped'; + console.log('✅ AUTOMATION STATUS: isRunning =', this.isRunning); if (this.intervalId) { clearInterval(this.intervalId); this.intervalId = null; } + // Stop risk monitor if running + if (this.riskManager && this.riskManager.stop) { + this.riskManager.stop(); + console.log('🏖️ Beach mode monitoring stopped'); + } + console.log('SIMPLE AUTOMATION: Stopped'); return { success: true, message: 'Automation stopped successfully' }; @@ -92,6 +164,12 @@ class SimpleAutomation { async runCycle() { try { + // Check if automation should still be running + if (!this.isRunning) { + console.log('⏹️ AUTOMATION STOPPED: Skipping cycle'); + return; + } + this.stats.totalCycles++; this.stats.lastActivity = new Date().toISOString(); @@ -102,10 +180,32 @@ class SimpleAutomation { if (this.config) { // Perform actual analysis using enhanced screenshot API await this.performAnalysis(); + + // Reset error counter on successful cycle + this.stats.consecutiveErrors = 0; } } catch (error) { - console.error('Error in automation cycle:', error); + console.error('❌ CRITICAL ERROR in automation cycle:', error); + console.error('❌ Stack trace:', error.stack); + + // Increment error counter + this.stats.consecutiveErrors = (this.stats.consecutiveErrors || 0) + 1; + + // If too many consecutive errors, stop automation + if (this.stats.consecutiveErrors >= 3) { + console.error('🚨 TOO MANY ERRORS: Stopping automation after', this.stats.consecutiveErrors, 'consecutive failures'); + this.isRunning = false; + this.stats.status = 'Stopped due to errors'; + + if (this.intervalId) { + clearInterval(this.intervalId); + this.intervalId = null; + } + return; + } + + console.log(`⚠️ Error ${this.stats.consecutiveErrors}/3 - Will retry next cycle`); } } @@ -276,10 +376,8 @@ class SimpleAutomation { } shouldExecuteTrade(analysis) { - if (this.config.mode !== 'LIVE') { - console.log('📊 SIMULATION MODE: Would execute trade'); - return false; - } + // Always allow trade execution - the useRealDEX flag determines if it's real or simulated + console.log(`� TRADE MODE: ${this.config.mode || 'SIMULATION'} - Trading ${this.config.enableTrading ? 'ENABLED' : 'DISABLED'}`); const recommendation = analysis.recommendation?.toLowerCase() || ''; const confidence = analysis.confidence || 0; @@ -301,6 +399,7 @@ class SimpleAutomation { async executeTrade(analysis) { try { console.log('💰 EXECUTING TRADE...'); + console.log('📊 Analysis data:', JSON.stringify(analysis, null, 2)); // Map analysis recommendation to trading side const recommendation = analysis.recommendation?.toLowerCase() || ''; @@ -314,15 +413,111 @@ class SimpleAutomation { console.log('❌ TRADE SKIP: Invalid recommendation - ' + recommendation); return { success: false, error: 'Invalid recommendation: ' + recommendation }; } + + // Extract stop loss and take profit from analysis + let stopLoss = null; + let takeProfit = null; - // Use the trading API with proper fields + // Try to extract from the structured analysis format + if (analysis.stopLoss && typeof analysis.stopLoss === 'object') { + stopLoss = analysis.stopLoss.price; + } else if (analysis.stopLoss && typeof analysis.stopLoss === 'number') { + stopLoss = analysis.stopLoss; + } + + // Extract take profit - prefer tp1 if available + if (analysis.takeProfits && typeof analysis.takeProfits === 'object') { + if (analysis.takeProfits.tp1 && analysis.takeProfits.tp1.price) { + takeProfit = analysis.takeProfits.tp1.price; + } else if (analysis.takeProfits.tp2 && analysis.takeProfits.tp2.price) { + takeProfit = analysis.takeProfits.tp2.price; + } + } else if (analysis.takeProfit && typeof analysis.takeProfit === 'number') { + takeProfit = analysis.takeProfit; + } + + // Fallback: try to extract from nested levels object + if (!stopLoss && analysis.levels) { + stopLoss = analysis.levels.stopLoss || analysis.levels.stop; + } + if (!takeProfit && analysis.levels) { + takeProfit = analysis.levels.takeProfit || analysis.levels.target; + } + + // Parse numeric values if they're strings + if (stopLoss && typeof stopLoss === 'string') { + stopLoss = parseFloat(stopLoss.replace(/[^0-9.]/g, '')); + } + if (takeProfit && typeof takeProfit === 'string') { + takeProfit = parseFloat(takeProfit.replace(/[^0-9.]/g, '')); + } + + console.log(`🎯 Trade levels - SL: ${stopLoss}, TP: ${takeProfit}`); + + // Calculate optimal leverage using AI Leverage Calculator + let optimalLeverage = 1; // Default fallback + console.log('🔧 DEBUG: Starting leverage calculation...'); + try { + const AILeverageCalculator = await importAILeverageCalculator(); + console.log('🔧 DEBUG: AI Leverage Calculator imported:', !!AILeverageCalculator); + if (AILeverageCalculator && stopLoss) { + console.log('🔧 DEBUG: Both calculator and stopLoss available, proceeding...'); + // Get current price from analysis + const currentPrice = analysis.entry?.price || analysis.currentPrice || 178; // fallback price + + // Get real account data from Drift API + let accountValue = 49; // fallback + let availableBalance = 49; // fallback + + try { + const baseUrl = process.env.INTERNAL_API_URL || 'http://localhost:3000'; + console.log('🔧 DEBUG: Fetching balance from:', baseUrl); + const balanceResponse = await fetch(`${baseUrl}/api/drift/balance`); + const balanceData = await balanceResponse.json(); + if (balanceData.success) { + accountValue = balanceData.accountValue; + availableBalance = balanceData.availableBalance; + console.log(`💰 Real account data: $${accountValue.toFixed(2)} total, $${availableBalance.toFixed(2)} available`); + } else { + console.log('🔧 DEBUG: Balance API returned error:', balanceData); + } + } catch (balanceError) { + console.warn('⚠️ Failed to get real balance, using fallback:', balanceError.message); + } + + console.log(`🧮 Calculating optimal leverage: Entry=$${currentPrice}, StopLoss=$${stopLoss}`); + + const leverageResult = AILeverageCalculator.calculateOptimalLeverage({ + accountValue, + availableBalance, + entryPrice: currentPrice, + stopLossPrice: stopLoss, + side: side === 'BUY' ? 'long' : 'short', + maxLeverageAllowed: 10, // Drift platform max + safetyBuffer: 0.10 // 10% safety buffer + }); + + optimalLeverage = leverageResult.recommendedLeverage; + console.log(`🎯 AI Calculated Leverage: ${optimalLeverage.toFixed(1)}x (Risk: ${leverageResult.riskAssessment})`); + console.log(`📊 Leverage Details: ${leverageResult.reasoning}`); + } else { + console.log('🔧 DEBUG: Skipping leverage calc - Calculator:', !!AILeverageCalculator, 'StopLoss:', !!stopLoss); + } + } catch (leverageError) { + console.warn('⚠️ Leverage calculation failed, using default 1x:', leverageError.message); + } + + console.log(`🔧 DEBUG: Final leverage to use: ${optimalLeverage}x`); + + // Use the trading API with proper fields for Drift const tradePayload = { symbol: this.config.symbol, side: side, - amount: this.config.tradingAmount || 10, // Default to $10 if not set - type: 'market', - tradingMode: 'SPOT', - useRealDEX: true, // Enable LIVE trading instead of simulation + amount: this.config.tradingAmount || 49, // Use available balance + leverage: optimalLeverage, // Use AI-calculated optimal leverage + stopLoss: stopLoss, + takeProfit: takeProfit, + useRealDEX: true, // Enable LIVE trading always analysis: analysis // Include analysis for reference }; @@ -353,14 +548,27 @@ class SimpleAutomation { } getStatus() { - return { + const baseStatus = { isActive: this.isRunning, mode: this.config?.mode || 'SIMULATION', + enableTrading: this.config?.enableTrading || false, + tradingStatus: this.config?.enableTrading ? 'REAL TRADES' : 'SIMULATED ONLY', symbol: this.config?.symbol || 'SOLUSD', timeframes: this.config?.selectedTimeframes || [], automationType: 'SIMPLE', ...this.stats }; + + // Add more descriptive status based on running state + if (this.isRunning) { + baseStatus.detailedStatus = 'Running - Monitoring for trade opportunities'; + baseStatus.nextAction = 'Next analysis cycle in progress'; + } else { + baseStatus.detailedStatus = 'Stopped - No monitoring active'; + baseStatus.nextAction = 'Start automation to begin monitoring'; + } + + return baseStatus; } }