Files
trading_bot_v3/simple-automation.js
mindesbunister 284e1c8b8c feat: fix Safe Paper Trading display formatting and API sync
- Fixed field mapping between API and frontend (amount→positionSize, entry→entryPrice, createdAt→timestamp)
- Updated API sync function to properly convert API trade format to frontend format
- Resolved display issues: 'Invalid Date', missing entry price, missing trade size
- Added trade monitoring system and automation improvements
- Enhanced automation with simple-automation.js for reliable 24/7 operation
- Working automation now detecting 85% confidence BUY signals and executing trades
2025-08-07 16:55:41 +02:00

157 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
/**
* Simple 24/7 Trading Automation
* Focuses on core trading without complex sentiment analysis
*/
class SimpleAutomation {
constructor() {
this.config = {
symbol: 'SOLUSD',
timeframe: '60',
intervalMinutes: 60,
autoExecuteThreshold: 60,
apiHost: '192.168.0.1:9001'
};
this.cycleCount = 0;
this.stats = {
startTime: new Date(),
totalCycles: 0,
totalTrades: 0,
lastSignal: null,
lastTrade: null
};
}
async log(message) {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] ${message}`);
}
async makeRequest(url, options = {}) {
try {
const response = await fetch(url, options);
return await response.json();
} catch (error) {
await this.log(`❌ Request failed: ${error.message}`);
return null;
}
}
async runAnalysisCycle() {
this.stats.totalCycles++;
await this.log(`🔄 Analysis cycle #${this.stats.totalCycles}`);
try {
// Get current technical analysis
const data = await this.makeRequest(`http://${this.config.apiHost}/api/ai-analysis/latest?symbol=${this.config.symbol}&timeframe=${this.config.timeframe}`);
if (data && data.success && data.data && data.data.analysis) {
const analysis = data.data.analysis;
this.stats.lastSignal = {
time: new Date(),
recommendation: analysis.recommendation,
confidence: analysis.confidence
};
await this.log(`📊 Signal: ${analysis.recommendation} (${analysis.confidence}% confidence)`);
// Execute trade if confidence is high enough
if (analysis.confidence >= this.config.autoExecuteThreshold &&
(analysis.recommendation === 'BUY' || analysis.recommendation === 'SELL')) {
await this.log(`🚀 Executing ${analysis.recommendation} trade with ${analysis.confidence}% confidence`);
const trade = await this.executeTrade(analysis);
if (trade && trade.success) {
this.stats.totalTrades++;
this.stats.lastTrade = {
time: new Date(),
type: analysis.recommendation,
confidence: analysis.confidence,
price: trade.trade?.price || 'unknown'
};
await this.log(`✅ Trade executed successfully: ${analysis.recommendation} at ${trade.trade?.price || 'unknown'}`);
} else {
await this.log(`❌ Trade execution failed`);
}
} else {
await this.log(`⏸️ Confidence ${analysis.confidence}% below threshold ${this.config.autoExecuteThreshold}% - holding`);
}
} else {
await this.log(`❌ No valid analysis data received`);
}
} catch (error) {
await this.log(`❌ Cycle error: ${error.message}`);
}
// Schedule next cycle
const nextCycle = new Date(Date.now() + this.config.intervalMinutes * 60 * 1000);
await this.log(`⏰ Next cycle: ${nextCycle.toLocaleTimeString()}`);
setTimeout(() => this.runAnalysisCycle(), this.config.intervalMinutes * 60 * 1000);
}
async executeTrade(analysis) {
try {
const tradeData = {
symbol: this.config.symbol,
side: analysis.recommendation,
amount: 100, // $100 paper trade
entry: analysis.currentPrice || 150, // Fallback price
confidence: analysis.confidence,
reasoning: analysis.reasoning,
source: 'simple_automation_24x7'
};
const result = await this.makeRequest(`http://${this.config.apiHost}/api/safe-paper-trading/create-trade`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(tradeData)
});
return result;
} catch (error) {
await this.log(`❌ Trade execution error: ${error.message}`);
return null;
}
}
async printStats() {
const uptime = Math.floor((Date.now() - this.stats.startTime) / 1000 / 60); // minutes
await this.log(`📈 Stats: ${this.stats.totalCycles} cycles, ${this.stats.totalTrades} trades, ${uptime}m uptime`);
if (this.stats.lastSignal) {
const signalAge = Math.floor((Date.now() - this.stats.lastSignal.time) / 1000 / 60);
await this.log(`🎯 Last signal: ${this.stats.lastSignal.recommendation} (${this.stats.lastSignal.confidence}%) ${signalAge}m ago`);
}
if (this.stats.lastTrade) {
const tradeAge = Math.floor((Date.now() - this.stats.lastTrade.time) / 1000 / 60);
await this.log(`💰 Last trade: ${this.stats.lastTrade.type} at ${this.stats.lastTrade.price} ${tradeAge}m ago`);
}
}
async start() {
await this.log('🚀 Simple 24/7 Trading Automation Started');
await this.log(`📊 Config: ${this.config.symbol} every ${this.config.intervalMinutes}m, threshold: ${this.config.autoExecuteThreshold}%`);
// Print stats every 30 minutes
setInterval(() => this.printStats(), 30 * 60 * 1000);
// Start first cycle
await this.runAnalysisCycle();
}
}
// Start the automation
const automation = new SimpleAutomation();
automation.start().catch(error => {
console.error('💥 Automation failed to start:', error);
process.exit(1);
});