#!/usr/bin/env node /** * 24/7 Server-Side Automation with AI Learning * Runs continuously in Docker container without browser dependency */ const fs = require('fs').promises; const path = require('path'); class Server24x7Automation { constructor() { this.isRunning = false; this.config = { mode: 'SIMULATION', // Safe paper trading symbol: 'SOLUSD', timeframe: '60', // 1 hour intervalMinutes: 60, // Run every 60 minutes autoExecuteThreshold: 60, // Execute trades with β‰₯60% confidence maxDailyTrades: 10, tradingAmount: 100, learningEnabled: true }; this.stats = { startTime: null, totalCycles: 0, totalTrades: 0, successfulTrades: 0, lastAnalysis: null, lastTrade: null }; this.intervalId = null; } async log(message) { const timestamp = new Date().toISOString(); const logEntry = `[${timestamp}] ${message}`; console.log(logEntry); // Also save to log file try { await fs.appendFile('/tmp/24x7-automation.log', logEntry + '\n'); } catch (error) { // Ignore file errors } } async start() { if (this.isRunning) { await this.log('⚠️ Automation already running'); return { success: false, message: 'Already running' }; } await this.log('πŸš€ Starting 24/7 Server Automation...'); await this.log(`πŸ“Š Config: ${this.config.symbol} ${this.config.timeframe}m, every ${this.config.intervalMinutes} minutes`); await this.log(`🎯 Auto-execute threshold: β‰₯${this.config.autoExecuteThreshold}% confidence`); this.isRunning = true; this.stats.startTime = new Date(); // Run first cycle immediately await this.runAnalysisCycle(); // Schedule recurring cycles this.intervalId = setInterval(async () => { try { await this.runAnalysisCycle(); } catch (error) { await this.log(`❌ Cycle error: ${error.message}`); } }, this.config.intervalMinutes * 60 * 1000); await this.log('βœ… 24/7 Automation started successfully'); return { success: true, message: '24/7 automation started' }; } async stop() { if (!this.isRunning) { await this.log('⚠️ Automation not running'); return { success: false, message: 'Not running' }; } this.isRunning = false; if (this.intervalId) { clearInterval(this.intervalId); this.intervalId = null; } await this.log('πŸ›‘ 24/7 Automation stopped'); return { success: true, message: 'Automation stopped' }; } async runAnalysisCycle() { this.stats.totalCycles++; await this.log(`πŸ”„ Starting analysis cycle #${this.stats.totalCycles}`); try { // 1. Get AI analysis const analysis = await this.getAIAnalysis(); if (!analysis) { await this.log('❌ Failed to get AI analysis'); return; } this.stats.lastAnalysis = new Date(); await this.log(`πŸ“Š Analysis: ${analysis.recommendation} (${analysis.confidence}% confidence)`); // 2. Check if we should auto-execute if (analysis.confidence >= this.config.autoExecuteThreshold) { await this.log(`🎯 Confidence ${analysis.confidence}% β‰₯ threshold ${this.config.autoExecuteThreshold}% - executing trade`); const tradeResult = await this.executeAutoTrade(analysis); if (tradeResult.success) { this.stats.totalTrades++; this.stats.lastTrade = new Date(); await this.log(`βœ… Auto-trade executed: ${tradeResult.message}`); } else { await this.log(`❌ Auto-trade failed: ${tradeResult.message}`); } } else { await this.log(`⏸️ Confidence ${analysis.confidence}% < threshold ${this.config.autoExecuteThreshold}% - no trade`); } } catch (error) { await this.log(`❌ Analysis cycle error: ${error.message}`); } } async getAIAnalysis() { try { // Call the same API that the browser version uses const response = await fetch(`http://localhost:9001/api/ai-analysis/latest?symbol=${this.config.symbol}&timeframe=${this.config.timeframe}`); if (!response.ok) { throw new Error(`API responded with ${response.status}`); } const data = await response.json(); if (data.success && data.data && data.data.analysis) { return { recommendation: data.data.analysis.recommendation, confidence: data.data.analysis.confidence, reasoning: data.data.analysis.reasoning, entry: data.data.analysis.entry, stopLoss: data.data.analysis.stopLoss, takeProfit: data.data.analysis.takeProfit }; } return null; } catch (error) { await this.log(`❌ AI Analysis API error: ${error.message}`); return null; } } async executeAutoTrade(analysis) { try { // Create paper trade using the same API const tradeData = { symbol: this.config.symbol, side: analysis.recommendation, // BUY or SELL amount: this.config.tradingAmount, entry: analysis.entry, stopLoss: analysis.stopLoss, takeProfit: analysis.takeProfit, confidence: analysis.confidence, reasoning: analysis.reasoning, source: '24x7_automation' }; const response = await fetch('http://localhost:9001/api/safe-paper-trading/create-trade', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(tradeData) }); if (!response.ok) { throw new Error(`Trade API responded with ${response.status}`); } const result = await response.json(); if (result.success) { this.stats.successfulTrades++; return { success: true, message: `Paper trade created: ${result.trade.id}` }; } else { return { success: false, message: result.message || 'Trade creation failed' }; } } catch (error) { return { success: false, message: error.message }; } } getStatus() { const uptime = this.stats.startTime ? Math.floor((Date.now() - this.stats.startTime.getTime()) / 1000) : 0; const successRate = this.stats.totalTrades > 0 ? Math.round((this.stats.successfulTrades / this.stats.totalTrades) * 100) : 0; return { isRunning: this.isRunning, config: this.config, stats: { ...this.stats, uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`, successRate: `${successRate}%`, nextCycle: this.intervalId ? new Date(Date.now() + (this.config.intervalMinutes * 60 * 1000)) : null } }; } } // Create singleton instance const automation24x7 = new Server24x7Automation(); // Export for API use if (typeof module !== 'undefined') { module.exports = { automation24x7 }; } // CLI interface if (require.main === module) { const command = process.argv[2]; switch (command) { case 'start': automation24x7.start().then(result => { console.log(result); if (!result.success) process.exit(1); }); break; case 'stop': automation24x7.stop().then(result => { console.log(result); process.exit(0); }); break; case 'status': console.log(JSON.stringify(automation24x7.getStatus(), null, 2)); break; default: console.log(` πŸ€– 24/7 Server Automation Usage: node start-24-7-automation.js start # Start automation node start-24-7-automation.js stop # Stop automation node start-24-7-automation.js status # Check status Features: βœ… Runs without browser dependency βœ… Safe paper trading mode βœ… AI analysis every 60 minutes βœ… Auto-execute trades β‰₯60% confidence βœ… Integrates with existing learning system βœ… Logs all activity `); } }