diff --git a/app/api/automation-24x7/route.js b/app/api/automation-24x7/route.js
new file mode 100644
index 0000000..460c207
--- /dev/null
+++ b/app/api/automation-24x7/route.js
@@ -0,0 +1,76 @@
+import { NextResponse } from 'next/server'
+
+// Import the 24/7 automation service
+let automation24x7
+try {
+ const automationModule = require('../../../../start-24-7-automation.js')
+ automation24x7 = automationModule.automation24x7
+} catch (error) {
+ console.error('β Could not load 24/7 automation service:', error.message)
+}
+
+export async function POST(request) {
+ try {
+ if (!automation24x7) {
+ return NextResponse.json({
+ success: false,
+ message: '24/7 automation service not available'
+ }, { status: 500 })
+ }
+
+ const { action, config } = await request.json()
+
+ if (action === 'start') {
+ // Update config if provided
+ if (config) {
+ Object.assign(automation24x7.config, config)
+ }
+
+ const result = await automation24x7.start()
+ return NextResponse.json(result)
+
+ } else if (action === 'stop') {
+ const result = await automation24x7.stop()
+ return NextResponse.json(result)
+
+ } else {
+ return NextResponse.json({
+ success: false,
+ message: 'Invalid action. Use "start" or "stop"'
+ }, { status: 400 })
+ }
+
+ } catch (error) {
+ console.error('β 24/7 automation control error:', error)
+ return NextResponse.json({
+ success: false,
+ message: 'Failed to control automation',
+ error: error.message
+ }, { status: 500 })
+ }
+}
+
+export async function GET(request) {
+ try {
+ if (!automation24x7) {
+ return NextResponse.json({
+ success: false,
+ message: '24/7 automation service not available'
+ }, { status: 500 })
+ }
+
+ const status = automation24x7.getStatus()
+ return NextResponse.json({
+ success: true,
+ automation: status
+ })
+
+ } catch (error) {
+ console.error('β 24/7 automation status error:', error)
+ return NextResponse.json({
+ success: false,
+ message: 'Failed to get automation status',
+ error: error.message
+ }, { status: 500 })
+ }
+}
diff --git a/app/api/safe-paper-trading/create-trade/route.js b/app/api/safe-paper-trading/create-trade/route.js
new file mode 100644
index 0000000..f03b819
--- /dev/null
+++ b/app/api/safe-paper-trading/create-trade/route.js
@@ -0,0 +1,111 @@
+import { NextResponse } from 'next/server'
+
+// Simple in-memory storage for paper trades (in production, use database)
+let paperTrades = []
+let tradeIdCounter = 1
+
+export async function POST(request) {
+ try {
+ const tradeData = await request.json()
+
+ // Validate required fields
+ const required = ['symbol', 'side', 'amount', 'entry', 'confidence']
+ for (const field of required) {
+ if (!tradeData[field]) {
+ return NextResponse.json({
+ success: false,
+ message: `Missing required field: ${field}`
+ }, { status: 400 })
+ }
+ }
+
+ // Create paper trade
+ const trade = {
+ id: `PAPER_${Date.now()}_${tradeIdCounter++}`,
+ symbol: tradeData.symbol,
+ side: tradeData.side,
+ amount: tradeData.amount,
+ entry: tradeData.entry,
+ stopLoss: tradeData.stopLoss,
+ takeProfit: tradeData.takeProfit,
+ confidence: tradeData.confidence,
+ reasoning: tradeData.reasoning,
+ source: tradeData.source || 'manual',
+ status: 'OPEN',
+ createdAt: new Date().toISOString(),
+ pnl: 0,
+ fees: 0
+ }
+
+ // Store trade
+ paperTrades.push(trade)
+
+ console.log(`π Paper trade created: ${trade.id} - ${trade.side} ${trade.symbol} at $${trade.entry} (${trade.confidence}% confidence)`)
+
+ // Log to AI learning system if available
+ try {
+ const learningData = {
+ id: `decision_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
+ symbol: trade.symbol,
+ timeframe: '60',
+ side: trade.side,
+ confidence: trade.confidence,
+ entry: trade.entry,
+ stopLoss: trade.stopLoss,
+ takeProfit: trade.takeProfit,
+ reasoning: trade.reasoning,
+ source: 'paper_trade_automation',
+ createdAt: new Date().toISOString()
+ }
+
+ // Store in learning system (try to call learning API)
+ fetch('http://localhost:9001/api/ai-learning/record-decision', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(learningData)
+ }).catch(error => {
+ console.log('β οΈ Could not log to learning system:', error.message)
+ })
+
+ } catch (error) {
+ console.log('β οΈ Learning system integration error:', error.message)
+ }
+
+ return NextResponse.json({
+ success: true,
+ message: 'Paper trade created successfully',
+ trade: trade
+ })
+
+ } catch (error) {
+ console.error('β Create paper trade error:', error)
+ return NextResponse.json({
+ success: false,
+ message: 'Failed to create paper trade',
+ error: error.message
+ }, { status: 500 })
+ }
+}
+
+export async function GET(request) {
+ try {
+ // Return all paper trades
+ return NextResponse.json({
+ success: true,
+ trades: paperTrades,
+ summary: {
+ total: paperTrades.length,
+ open: paperTrades.filter(t => t.status === 'OPEN').length,
+ closed: paperTrades.filter(t => t.status === 'CLOSED').length,
+ totalPnL: paperTrades.reduce((sum, t) => sum + (t.pnl || 0), 0)
+ }
+ })
+ } catch (error) {
+ console.error('β Get paper trades error:', error)
+ return NextResponse.json({
+ success: false,
+ message: 'Failed to get paper trades',
+ error: error.message
+ }, { status: 500 })
+ }
+}
diff --git a/app/safe-paper-trading/page.js b/app/safe-paper-trading/page.js
index 700600e..c983b6c 100644
--- a/app/safe-paper-trading/page.js
+++ b/app/safe-paper-trading/page.js
@@ -147,18 +147,42 @@ export default function SafePaperTradingPage() {
if (savedContinuousLearning === 'true') {
console.log('π Restoring continuous learning state...')
setContinuousLearning(true)
+ // Force restart continuous learning immediately
setTimeout(() => {
console.log('π Starting continuous learning from restored state')
startContinuousLearning()
- }, 2000)
+ }, 1000) // Reduced delay
+ } else {
+ console.log('π‘ No continuous learning state found - user needs to start manually')
}
} catch (error) {
console.error('β οΈ Error checking continuous learning state:', error)
}
}
- // Check state after a short delay to ensure everything is loaded
- setTimeout(checkContinuousLearningState, 1000)
+ // Force enable learning for testing - DEBUG FUNCTION
+ const forceEnableLearning = () => {
+ console.log('π§ FORCE ENABLING CONTINUOUS LEARNING...')
+ localStorage.setItem('safePaperTrading_continuousLearning', 'true')
+ setContinuousLearning(true)
+ setTimeout(() => {
+ console.log('π Force starting continuous learning')
+ startContinuousLearning()
+ }, 500)
+ console.log('β
Continuous learning forcefully enabled')
+ }
+
+ // Check state immediately
+ checkContinuousLearningState()
+
+ // Expose force enable function to browser console for debugging
+ if (typeof window !== 'undefined') {
+ window.forceEnableLearning = forceEnableLearning
+ console.log('π§ Debug function exposed: window.forceEnableLearning()')
+ }
+
+ // Also check after a short delay to ensure everything is loaded
+ setTimeout(checkContinuousLearningState, 2000)
}, [])
// Persist analysis data whenever it changes
@@ -810,51 +834,6 @@ export default function SafePaperTradingPage() {
- {/* AI LEARNING SETUP NOTICE */}
- {!continuousLearning || !autoExecuteTrades ? (
-
-
π€ Enable AI Learning from Virtual Trading
-
- Current Issue: AI is analyzing but not learning from outcomes because virtual trading is not enabled.
-
-
-
-
Step 1: Enable Continuous Learning
-
- {continuousLearning ? 'β
Enabled' : 'β Click "π Start Learning" button below'}
-
-
-
-
Step 2: Enable Auto-Execute
-
- {autoExecuteTrades ? 'β
Enabled' : continuousLearning ? 'β Enable "Auto-Execute Trades" below' : 'βΈοΈ Waiting for Step 1'}
-
-
-
-
- Result: AI will automatically execute virtual trades β track outcomes β learn patterns β improve over time
-
-
- ) : (
-
-
β
AI Learning System Active
-
-
- π Continuous Learning: ON
-
-
- π€ Auto-Execute: ON
-
-
- π Virtual Trading: Active
-
-
-
- π§ AI will automatically execute virtual trades based on analysis and learn from outcomes to improve performance
-
-
- )}
-
{/* Header with Balance */}
@@ -995,49 +974,32 @@ export default function SafePaperTradingPage() {
- {/* Auto-Execute Toggle - Show always, but disabled until continuous learning is active */}
-
-
-
-
Auto-Execute Trades
-
- {continuousLearning
- ? "Automatically execute paper trades based on AI recommendations (β₯60% confidence)"
- : "β οΈ Enable Continuous Learning first to activate auto-execute virtual trading"
- }
-
+ {/* Auto-Execute Toggle - Only show when continuous learning is active */}
+ {continuousLearning && (
+
+
+
+ Auto-Execute Trades
+ Automatically execute paper trades based on AI recommendations (β₯60% confidence)
+
+
setAutoExecuteTrades(!autoExecuteTrades)}
+ className={`ml-4 px-4 py-2 rounded-lg font-medium transition-all duration-200 ${
+ autoExecuteTrades
+ ? 'bg-green-600 hover:bg-green-700 text-white'
+ : 'bg-gray-600 hover:bg-gray-700 text-white'
+ }`}
+ >
+ {autoExecuteTrades ? 'π€ ON' : 'π Manual'}
+
-
{
- if (!continuousLearning) {
- alert('Please enable Continuous Learning first to activate auto-execute virtual trading!')
- return
- }
- setAutoExecuteTrades(!autoExecuteTrades)
- }}
- disabled={!continuousLearning}
- className={`ml-4 px-4 py-2 rounded-lg font-medium transition-all duration-200 ${
- !continuousLearning
- ? 'bg-gray-500 text-gray-400 cursor-not-allowed opacity-50'
- : autoExecuteTrades
- ? 'bg-green-600 hover:bg-green-700 text-white'
- : 'bg-gray-600 hover:bg-gray-700 text-white'
- }`}
- >
- {!continuousLearning ? 'π Locked' : autoExecuteTrades ? 'π€ ON' : 'π Manual'}
-
+ {autoExecuteTrades && (
+
+ β‘ Paper trades will be executed automatically when AI recommends BUY/SELL with β₯60% confidence
+
+ )}
- {autoExecuteTrades && continuousLearning && (
-
- β‘ Paper trades will be executed automatically when AI recommends BUY/SELL with β₯60% confidence
-
- )}
- {!continuousLearning && (
-
- π‘ For AI Learning: Enable "Continuous Learning" + "Auto-Execute" so the AI can learn from virtual trade outcomes
-
- )}
-
+ )}
diff --git a/automation-daemon.js b/automation-daemon.js
new file mode 100644
index 0000000..c8fdea3
--- /dev/null
+++ b/automation-daemon.js
@@ -0,0 +1,271 @@
+#!/usr/bin/env node
+
+/**
+ * Simple 24/7 Background Automation Daemon
+ * Runs as a background process in Docker container
+ */
+
+const { spawn } = require('child_process');
+const fs = require('fs').promises;
+const path = require('path');
+
+class BackgroundAutomation {
+ constructor() {
+ this.logFile = '/tmp/automation-24x7.log';
+ this.pidFile = '/tmp/automation-24x7.pid';
+ this.config = {
+ symbol: 'SOLUSD',
+ timeframe: '60',
+ intervalMinutes: 60,
+ autoExecuteThreshold: 60
+ };
+ }
+
+ async log(message) {
+ const timestamp = new Date().toISOString();
+ const logEntry = `[${timestamp}] ${message}\n`;
+ console.log(logEntry.trim());
+
+ try {
+ await fs.appendFile(this.logFile, logEntry);
+ } catch (error) {
+ // Ignore file errors
+ }
+ }
+
+ async isRunning() {
+ try {
+ const pidData = await fs.readFile(this.pidFile, 'utf8');
+ const pid = parseInt(pidData.trim());
+
+ // Check if process exists
+ try {
+ process.kill(pid, 0); // Signal 0 checks if process exists
+ return { running: true, pid };
+ } catch (error) {
+ // Process doesn't exist
+ await fs.unlink(this.pidFile).catch(() => {});
+ return { running: false, pid: null };
+ }
+ } catch (error) {
+ return { running: false, pid: null };
+ }
+ }
+
+ async start() {
+ const status = await this.isRunning();
+ if (status.running) {
+ await this.log(`β οΈ Automation already running (PID: ${status.pid})`);
+ return { success: false, message: 'Already running', pid: status.pid };
+ }
+
+ await this.log('π Starting 24/7 Background Automation...');
+
+ // Start the main automation loop
+ this.startAutomationLoop();
+
+ await this.log(`β
Automation started (PID: ${process.pid})`);
+ return { success: true, message: 'Started', pid: process.pid };
+ }
+
+ async startAutomationLoop() {
+ // Save PID
+ await fs.writeFile(this.pidFile, process.pid.toString());
+
+ // Handle cleanup on exit
+ process.on('SIGTERM', () => this.cleanup());
+ process.on('SIGINT', () => this.cleanup());
+ process.on('exit', () => this.cleanup());
+
+ let cycleCount = 0;
+
+ // Main automation loop
+ const runCycle = async () => {
+ try {
+ cycleCount++;
+ await this.log(`π Starting analysis cycle #${cycleCount}`);
+
+ // Get analysis
+ const analysis = await this.getAnalysis();
+ if (analysis && analysis.confidence >= this.config.autoExecuteThreshold) {
+ await this.log(`π― Executing trade: ${analysis.recommendation} (${analysis.confidence}% confidence)`);
+ await this.createPaperTrade(analysis);
+ } else if (analysis) {
+ await this.log(`βΈοΈ No trade: ${analysis.recommendation} (${analysis.confidence}% confidence < ${this.config.autoExecuteThreshold}% threshold)`);
+ }
+
+ } catch (error) {
+ await this.log(`β Cycle error: ${error.message}`);
+ }
+ };
+
+ // Run first cycle immediately
+ await runCycle();
+
+ // Schedule recurring cycles
+ setInterval(runCycle, this.config.intervalMinutes * 60 * 1000);
+
+ await this.log(`β° Scheduled to run every ${this.config.intervalMinutes} minutes`);
+ }
+
+ async getAnalysis() {
+ try {
+ // Use curl to avoid fetch dependencies
+ const { exec } = require('child_process');
+ const { promisify } = require('util');
+ const execAsync = promisify(exec);
+
+ const { stdout } = await execAsync(`curl -s "http://localhost:9001/api/ai-analysis/latest?symbol=${this.config.symbol}&timeframe=${this.config.timeframe}"`);
+
+ const data = JSON.parse(stdout);
+
+ if (data.success && data.data && data.data.analysis) {
+ return data.data.analysis;
+ }
+
+ return null;
+ } catch (error) {
+ await this.log(`β Analysis error: ${error.message}`);
+ return null;
+ }
+ }
+
+ async createPaperTrade(analysis) {
+ try {
+ // Use curl to avoid fetch dependencies
+ const { exec } = require('child_process');
+ const { promisify } = require('util');
+ const execAsync = promisify(exec);
+
+ const tradeData = {
+ symbol: this.config.symbol,
+ side: analysis.recommendation,
+ amount: 100,
+ entry: analysis.entry,
+ stopLoss: analysis.stopLoss,
+ takeProfit: analysis.takeProfit,
+ confidence: analysis.confidence,
+ reasoning: analysis.reasoning,
+ source: '24x7_daemon'
+ };
+
+ const curlCommand = `curl -s -X POST http://localhost:9001/api/safe-paper-trading/create-trade \
+ -H "Content-Type: application/json" \
+ -d '${JSON.stringify(tradeData)}'`;
+
+ const { stdout } = await execAsync(curlCommand);
+ const result = JSON.parse(stdout);
+
+ if (result.success) {
+ await this.log(`β
Paper trade created: ${result.trade.id}`);
+ } else {
+ await this.log(`β Trade creation failed: ${result.message}`);
+ }
+
+ } catch (error) {
+ await this.log(`β Trade creation error: ${error.message}`);
+ }
+ }
+
+ async stop() {
+ const status = await this.isRunning();
+ if (!status.running) {
+ await this.log('β οΈ Automation not running');
+ return { success: false, message: 'Not running' };
+ }
+
+ try {
+ process.kill(status.pid, 'SIGTERM');
+ await fs.unlink(this.pidFile).catch(() => {});
+ await this.log(`π Automation stopped (PID: ${status.pid})`);
+ return { success: true, message: 'Stopped', pid: status.pid };
+ } catch (error) {
+ await this.log(`β Stop error: ${error.message}`);
+ return { success: false, message: error.message };
+ }
+ }
+
+ async cleanup() {
+ try {
+ await fs.unlink(this.pidFile).catch(() => {});
+ await this.log('π§Ή Cleanup completed');
+ } catch (error) {
+ // Ignore cleanup errors
+ }
+ }
+
+ async getStatus() {
+ const status = await this.isRunning();
+
+ let logs = '';
+ try {
+ const logData = await fs.readFile(this.logFile, 'utf8');
+ logs = logData.split('\n').slice(-10).join('\n'); // Last 10 lines
+ } catch (error) {
+ logs = 'No logs available';
+ }
+
+ return {
+ running: status.running,
+ pid: status.pid,
+ config: this.config,
+ recentLogs: logs
+ };
+ }
+}
+
+// Create instance
+const daemon = new BackgroundAutomation();
+
+// CLI interface
+if (require.main === module) {
+ const command = process.argv[2];
+
+ switch (command) {
+ case 'start':
+ daemon.start().then(result => {
+ console.log(JSON.stringify(result, null, 2));
+ if (result.success) {
+ // Keep process alive
+ process.stdin.resume();
+ } else {
+ process.exit(1);
+ }
+ });
+ break;
+
+ case 'stop':
+ daemon.stop().then(result => {
+ console.log(JSON.stringify(result, null, 2));
+ process.exit(0);
+ });
+ break;
+
+ case 'status':
+ daemon.getStatus().then(status => {
+ console.log(JSON.stringify(status, null, 2));
+ process.exit(0);
+ });
+ break;
+
+ default:
+ console.log(`
+π€ 24/7 Background Automation Daemon
+
+Usage:
+ node automation-daemon.js start # Start in background
+ node automation-daemon.js stop # Stop daemon
+ node automation-daemon.js status # Check status
+
+Features:
+ β
True background process
+ β
Survives browser close
+ β
Auto-executes trades β₯60% confidence
+ β
Logs all activity
+ β
Safe paper trading only
+ `);
+ }
+}
+
+// Export for API use
+module.exports = { daemon };
diff --git a/check-automation.js b/check-automation.js
new file mode 100644
index 0000000..a1f3611
--- /dev/null
+++ b/check-automation.js
@@ -0,0 +1,90 @@
+#!/usr/bin/env node
+
+// Quick automation status checker
+
+const { exec } = require('child_process');
+const { promisify } = require('util');
+const execAsync = promisify(exec);
+
+async function checkStatus() {
+ console.log('π€ 24/7 AUTOMATION STATUS CHECK\n');
+
+ try {
+ // Check if process is running
+ const { stdout } = await execAsync('ps aux | grep "working-24x7" | grep -v grep');
+ if (stdout.trim()) {
+ console.log('β
AUTOMATION STATUS: RUNNING');
+ console.log(`π Process: ${stdout.trim().split(/\s+/).slice(0, 11).join(' ')}`);
+ } else {
+ console.log('β AUTOMATION STATUS: NOT RUNNING');
+ return;
+ }
+ } catch (error) {
+ console.log('β AUTOMATION STATUS: NOT RUNNING');
+ return;
+ }
+
+ try {
+ // Check recent logs
+ const { stdout: logs } = await execAsync('tail -5 nohup.out');
+ console.log('\nπ RECENT LOGS:');
+ console.log(logs);
+ } catch (error) {
+ console.log('\nβ οΈ No logs available');
+ }
+
+ try {
+ // Check current analysis
+ const { stdout } = await execAsync('curl -s "http://localhost:9001/api/ai-analysis/latest?symbol=SOLUSD&timeframe=60"');
+ const data = JSON.parse(stdout);
+
+ if (data.success && data.data && data.data.analysis) {
+ const analysis = data.data.analysis;
+ console.log('\nπ CURRENT ANALYSIS:');
+ console.log(` Signal: ${analysis.recommendation}`);
+ console.log(` Confidence: ${analysis.confidence}%`);
+ console.log(` Entry: $${analysis.entry}`);
+ console.log(` Status: ${analysis.confidence >= 60 ? 'π― WILL AUTO-EXECUTE' : 'βΈοΈ Below threshold'}`);
+ } else {
+ console.log('\nβ No analysis data available');
+ }
+ } catch (error) {
+ console.log('\nβ Analysis check failed:', error.message);
+ }
+
+ try {
+ // Check recent paper trades
+ const { stdout } = await execAsync('curl -s "http://localhost:9001/api/safe-paper-trading/create-trade"');
+ const data = JSON.parse(stdout);
+
+ if (data.success && data.trades) {
+ console.log('\nπ PAPER TRADES:');
+ console.log(` Total: ${data.summary.total}`);
+ console.log(` Open: ${data.summary.open}`);
+ console.log(` Closed: ${data.summary.closed}`);
+ console.log(` P&L: $${data.summary.totalPnL}`);
+
+ // Show recent trades
+ const recentTrades = data.trades.slice(-3);
+ if (recentTrades.length > 0) {
+ console.log('\nπ RECENT TRADES:');
+ recentTrades.forEach(trade => {
+ console.log(` ${trade.id}: ${trade.side} ${trade.symbol} @ $${trade.entry} (${trade.confidence}%)`);
+ });
+ }
+ }
+ } catch (error) {
+ console.log('\nβ οΈ Could not check paper trades');
+ }
+
+ console.log('\nπ― AUTOMATION CONFIGURATION:');
+ console.log(' Symbol: SOLUSD');
+ console.log(' Timeframe: 1 hour');
+ console.log(' Interval: Every 60 minutes');
+ console.log(' Auto-execute: β₯60% confidence');
+ console.log(' Mode: Safe paper trading only');
+
+ console.log('\n⨠System is running 24/7 in your Docker container!');
+}
+
+checkStatus();
diff --git a/enable-continuous-learning.js b/enable-continuous-learning.js
new file mode 100644
index 0000000..5ad4818
--- /dev/null
+++ b/enable-continuous-learning.js
@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+// Quick script to enable continuous learning via browser console
+console.log(`
+π§ ENABLE CONTINUOUS LEARNING MANUALLY
+
+1. Open http://localhost:9001/safe-paper-trading in your browser
+2. Open Developer Tools (F12)
+3. Go to Console tab
+4. Run this command:
+
+ window.forceEnableLearning()
+
+5. Refresh the page - you should see:
+ - Button says "π Stop Learning" (instead of Start)
+ - Auto-execute toggle becomes available: "π Locked" β "π€ OFF"
+
+6. Click the auto-execute toggle to enable it: "π€ OFF" β "π€ ON"
+
+7. Now when you get strong signals (β₯60% confidence), it will auto-create paper trades!
+
+Alternative: You can also run this in console:
+ localStorage.setItem('safePaperTrading_continuousLearning', 'true')
+ location.reload()
+
+`);
diff --git a/nohup.out b/nohup.out
new file mode 100644
index 0000000..c1254db
--- /dev/null
+++ b/nohup.out
@@ -0,0 +1,7 @@
+[2025-08-05T21:34:07.846Z] π 24/7 AUTOMATION STARTED
+[2025-08-05T21:34:07.848Z] π SOLUSD every 60m, threshold β₯60%
+[2025-08-05T21:34:07.848Z] π Analysis cycle #1
+[2025-08-05T21:34:52.488Z] π SELL (80% confidence)
+[2025-08-05T21:34:52.489Z] π― AUTO-EXECUTING: 80% β₯ 60%
+[2025-08-05T21:34:52.961Z] β
TRADE CREATED: PAPER_1754429692956_1
+[2025-08-05T21:34:53.032Z] β° Next cycle: 12:34:52 AM
diff --git a/simple-24x7-automation.js b/simple-24x7-automation.js
new file mode 100644
index 0000000..171bbdd
--- /dev/null
+++ b/simple-24x7-automation.js
@@ -0,0 +1,169 @@
+#!/usr/bin/env node
+
+/**
+ * Simple 24/7 Automation Service
+ * Direct execution without complex daemon management
+ */
+
+const { exec } = require('child_process');
+const { promisify } = require('util');
+const execAsync = promisify(exec);
+const fs = require('fs').promises;
+
+class SimpleAutomation {
+ constructor() {
+ this.isRunning = false;
+ this.config = {
+ symbol: 'SOLUSD',
+ timeframe: '60',
+ intervalMinutes: 60,
+ autoExecuteThreshold: 60
+ };
+ this.stats = {
+ startTime: new Date(),
+ totalCycles: 0,
+ totalTrades: 0
+ };
+ }
+
+ 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/automation-simple.log', logEntry + '\n');
+ } catch (error) {
+ // Ignore file errors
+ }
+ }
+
+ async start() {
+ if (this.isRunning) {
+ await this.log('β οΈ Already running');
+ return;
+ }
+
+ this.isRunning = true;
+ await this.log('π Starting Simple 24/7 Automation...');
+ await this.log(`π Config: ${this.config.symbol} ${this.config.timeframe}m, every ${this.config.intervalMinutes} minutes`);
+
+ // Run first cycle immediately
+ await this.runCycle();
+
+ // Schedule recurring cycles
+ setInterval(async () => {
+ try {
+ await this.runCycle();
+ } catch (error) {
+ await this.log(`β Cycle error: ${error.message}`);
+ }
+ }, this.config.intervalMinutes * 60 * 1000);
+
+ await this.log('β
24/7 Automation running');
+ }
+
+ async runCycle() {
+ this.stats.totalCycles++;
+ await this.log(`π Analysis cycle #${this.stats.totalCycles}`);
+
+ try {
+ // Get analysis using curl
+ const { stdout } = await execAsync(`curl -s "http://localhost:9001/api/ai-analysis/latest?symbol=${this.config.symbol}&timeframe=${this.config.timeframe}"`);
+
+ const data = JSON.parse(stdout);
+
+ if (data.success && data.data && data.data.analysis) {
+ const analysis = data.data.analysis;
+ await this.log(`π Analysis: ${analysis.recommendation} (${analysis.confidence}% confidence)`);
+
+ // Check if we should execute trade
+ if (analysis.confidence >= this.config.autoExecuteThreshold) {
+ await this.log(`π― Executing trade: confidence ${analysis.confidence}% β₯ ${this.config.autoExecuteThreshold}%`);
+ await this.executeTrade(analysis);
+ } else {
+ await this.log(`βΈοΈ No trade: confidence ${analysis.confidence}% < ${this.config.autoExecuteThreshold}%`);
+ }
+ } else {
+ await this.log('β No analysis data received');
+ }
+
+ } catch (error) {
+ await this.log(`β Cycle error: ${error.message}`);
+ }
+ }
+
+ async executeTrade(analysis) {
+ try {
+ const tradeData = {
+ symbol: this.config.symbol,
+ side: analysis.recommendation,
+ amount: 100,
+ entry: analysis.entry,
+ stopLoss: analysis.stopLoss,
+ takeProfit: analysis.takeProfit,
+ confidence: analysis.confidence,
+ reasoning: analysis.reasoning,
+ source: 'simple_24x7'
+ };
+
+ // Use curl to create paper trade
+ const curlData = JSON.stringify(tradeData).replace(/'/g, "'\\''");
+ const { stdout } = await execAsync(`curl -s -X POST http://localhost:9001/api/safe-paper-trading/create-trade -H "Content-Type: application/json" -d '${curlData}'`);
+
+ const result = JSON.parse(stdout);
+
+ if (result.success) {
+ this.stats.totalTrades++;
+ await this.log(`β
Paper trade created: ${result.trade.id}`);
+ } else {
+ await this.log(`β Trade failed: ${result.message}`);
+ }
+
+ } catch (error) {
+ await this.log(`β Trade execution error: ${error.message}`);
+ }
+ }
+
+ getStatus() {
+ const uptime = Math.floor((Date.now() - this.stats.startTime.getTime()) / 1000);
+ return {
+ isRunning: this.isRunning,
+ config: this.config,
+ stats: {
+ ...this.stats,
+ uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`,
+ nextCycle: new Date(Date.now() + (this.config.intervalMinutes * 60 * 1000))
+ }
+ };
+ }
+}
+
+// Start automation
+const automation = new SimpleAutomation();
+
+// Handle graceful shutdown
+process.on('SIGTERM', async () => {
+ await automation.log('π Received SIGTERM, shutting down...');
+ process.exit(0);
+});
+
+process.on('SIGINT', async () => {
+ await automation.log('π Received SIGINT, shutting down...');
+ process.exit(0);
+});
+
+// Start the automation
+automation.start().catch(async (error) => {
+ await automation.log(`β Startup error: ${error.message}`);
+ process.exit(1);
+});
+
+// Keep process alive
+console.log('π€ Simple 24/7 Automation Service');
+console.log('β
Running in background - press Ctrl+C to stop');
+console.log('π Logs: /tmp/automation-simple.log');
+
+// Prevent the process from exiting
+process.stdin.resume();
diff --git a/start-24-7-automation.js b/start-24-7-automation.js
new file mode 100644
index 0000000..ac4d4f9
--- /dev/null
+++ b/start-24-7-automation.js
@@ -0,0 +1,263 @@
+#!/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
+ `);
+ }
+}
diff --git a/working-24x7.js b/working-24x7.js
new file mode 100644
index 0000000..99d1179
--- /dev/null
+++ b/working-24x7.js
@@ -0,0 +1,102 @@
+#!/usr/bin/env node
+
+/**
+ * Working 24/7 Automation - No stdin issues
+ */
+
+const { exec } = require('child_process');
+const { promisify } = require('util');
+const execAsync = promisify(exec);
+const fs = require('fs').promises;
+
+class WorkingAutomation {
+ constructor() {
+ this.config = {
+ symbol: 'SOLUSD',
+ timeframe: '60',
+ intervalMinutes: 60,
+ autoExecuteThreshold: 60
+ };
+ this.stats = {
+ startTime: new Date(),
+ totalCycles: 0,
+ totalTrades: 0
+ };
+ }
+
+ async log(message) {
+ const timestamp = new Date().toISOString();
+ const logEntry = `[${timestamp}] ${message}`;
+ console.log(logEntry);
+ }
+
+ async runCycle() {
+ this.stats.totalCycles++;
+ await this.log(`π Analysis cycle #${this.stats.totalCycles}`);
+
+ try {
+ // Get current analysis
+ const { stdout } = await execAsync(`curl -s "http://localhost:9001/api/ai-analysis/latest?symbol=${this.config.symbol}&timeframe=${this.config.timeframe}"`);
+
+ const data = JSON.parse(stdout);
+
+ if (data.success && data.data && data.data.analysis) {
+ const analysis = data.data.analysis;
+ await this.log(`π ${analysis.recommendation} (${analysis.confidence}% confidence)`);
+
+ if (analysis.confidence >= this.config.autoExecuteThreshold) {
+ await this.log(`π― AUTO-EXECUTING: ${analysis.confidence}% β₯ ${this.config.autoExecuteThreshold}%`);
+
+ const tradeData = {
+ symbol: this.config.symbol,
+ side: analysis.recommendation,
+ amount: 100,
+ entry: analysis.entry,
+ stopLoss: analysis.stopLoss,
+ takeProfit: analysis.takeProfit,
+ confidence: analysis.confidence,
+ reasoning: analysis.reasoning,
+ source: 'automation_24x7'
+ };
+
+ // Create paper trade
+ const curlData = JSON.stringify(tradeData).replace(/"/g, '\\"');
+ const { stdout: tradeResult } = await execAsync(`curl -s -X POST http://localhost:9001/api/safe-paper-trading/create-trade -H "Content-Type: application/json" -d "${curlData}"`);
+
+ const result = JSON.parse(tradeResult);
+
+ if (result.success) {
+ this.stats.totalTrades++;
+ await this.log(`β
TRADE CREATED: ${result.trade.id}`);
+ } else {
+ await this.log(`β TRADE FAILED: ${result.message}`);
+ }
+ } else {
+ await this.log(`βΈοΈ NO TRADE: ${analysis.confidence}% < ${this.config.autoExecuteThreshold}%`);
+ }
+ } else {
+ await this.log('β No analysis data available');
+ }
+
+ } catch (error) {
+ await this.log(`β Cycle error: ${error.message}`);
+ }
+ }
+
+ async start() {
+ await this.log('π 24/7 AUTOMATION STARTED');
+ await this.log(`π ${this.config.symbol} every ${this.config.intervalMinutes}m, threshold β₯${this.config.autoExecuteThreshold}%`);
+
+ // Run first cycle
+ await this.runCycle();
+
+ // Schedule recurring cycles
+ setInterval(() => this.runCycle().catch(console.error), this.config.intervalMinutes * 60 * 1000);
+
+ await this.log(`β° Next cycle: ${new Date(Date.now() + this.config.intervalMinutes * 60 * 1000).toLocaleTimeString()}`);
+ }
+}
+
+// Create and start automation
+const automation = new WorkingAutomation();
+automation.start();