- Created persistent learning status API with trading statistics - Added comprehensive PnL and win rate display to AI Learning panel - Implemented trading stats tracking with win/loss ratios - Added persistent data storage for historical trading performance - Enhanced learning panel with real-time trading metrics - Fixed learning data visibility when bot is not running - Added sample trading data for demonstration
133 lines
4.0 KiB
JavaScript
133 lines
4.0 KiB
JavaScript
// Helper functions for updating persistent learning data
|
|
import fs from 'fs/promises';
|
|
import path from 'path';
|
|
|
|
const PERSISTENT_DATA_FILE = path.join(process.cwd(), 'data', 'learning-persistent.json');
|
|
|
|
async function loadPersistentData() {
|
|
try {
|
|
const data = await fs.readFile(PERSISTENT_DATA_FILE, 'utf8');
|
|
return JSON.parse(data);
|
|
} catch (error) {
|
|
// Return default structure if file doesn't exist
|
|
return {
|
|
totalTrades: 0,
|
|
winningTrades: 0,
|
|
losingTrades: 0,
|
|
totalPnL: 0,
|
|
winRate: 0,
|
|
avgWinAmount: 0,
|
|
avgLossAmount: 0,
|
|
bestTrade: 0,
|
|
worstTrade: 0,
|
|
learningDecisions: 0,
|
|
aiEnhancements: 0,
|
|
riskThresholds: {
|
|
emergency: 1,
|
|
risk: 2,
|
|
mediumRisk: 5
|
|
},
|
|
lastUpdated: new Date().toISOString(),
|
|
systemStatus: 'learning',
|
|
dataCollected: true
|
|
};
|
|
}
|
|
}
|
|
|
|
async function savePersistentData(data) {
|
|
try {
|
|
await fs.writeFile(PERSISTENT_DATA_FILE, JSON.stringify(data, null, 2));
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error saving persistent data:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function updateTradingStats(tradeData) {
|
|
try {
|
|
const persistentData = await loadPersistentData();
|
|
|
|
// Update trade counts
|
|
persistentData.totalTrades += 1;
|
|
|
|
// Determine if trade was winning or losing
|
|
const isWin = tradeData.pnl > 0;
|
|
if (isWin) {
|
|
persistentData.winningTrades += 1;
|
|
} else {
|
|
persistentData.losingTrades += 1;
|
|
}
|
|
|
|
// Update PnL
|
|
persistentData.totalPnL += tradeData.pnl;
|
|
|
|
// Update best/worst trades
|
|
if (tradeData.pnl > persistentData.bestTrade) {
|
|
persistentData.bestTrade = tradeData.pnl;
|
|
}
|
|
if (tradeData.pnl < persistentData.worstTrade) {
|
|
persistentData.worstTrade = tradeData.pnl;
|
|
}
|
|
|
|
// Recalculate averages and win rate
|
|
persistentData.winRate = (persistentData.winningTrades / persistentData.totalTrades) * 100;
|
|
|
|
if (persistentData.winningTrades > 0) {
|
|
// Calculate average win amount (we need to track this separately for accuracy)
|
|
const winTrades = persistentData.winTrades || [];
|
|
winTrades.push(isWin ? tradeData.pnl : null);
|
|
const wins = winTrades.filter(t => t !== null && t > 0);
|
|
persistentData.avgWinAmount = wins.reduce((sum, win) => sum + win, 0) / wins.length;
|
|
}
|
|
|
|
if (persistentData.losingTrades > 0) {
|
|
// Calculate average loss amount
|
|
const lossTrades = persistentData.lossTrades || [];
|
|
lossTrades.push(!isWin ? tradeData.pnl : null);
|
|
const losses = lossTrades.filter(t => t !== null && t < 0);
|
|
persistentData.avgLossAmount = losses.reduce((sum, loss) => sum + loss, 0) / losses.length;
|
|
}
|
|
|
|
// Update timestamp
|
|
persistentData.lastUpdated = new Date().toISOString();
|
|
persistentData.systemStatus = 'active';
|
|
|
|
// Save updated data
|
|
await savePersistentData(persistentData);
|
|
|
|
console.log(`📊 Persistent data updated: Trade PnL ${tradeData.pnl}, Total: ${persistentData.totalTrades} trades, ${persistentData.winRate.toFixed(1)}% win rate`);
|
|
|
|
return persistentData;
|
|
} catch (error) {
|
|
console.error('Error updating trading stats:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function updateLearningDecision() {
|
|
try {
|
|
const persistentData = await loadPersistentData();
|
|
persistentData.learningDecisions += 1;
|
|
persistentData.lastUpdated = new Date().toISOString();
|
|
await savePersistentData(persistentData);
|
|
return persistentData;
|
|
} catch (error) {
|
|
console.error('Error updating learning decision count:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function updateAIEnhancement() {
|
|
try {
|
|
const persistentData = await loadPersistentData();
|
|
persistentData.aiEnhancements += 1;
|
|
persistentData.lastUpdated = new Date().toISOString();
|
|
await savePersistentData(persistentData);
|
|
return persistentData;
|
|
} catch (error) {
|
|
console.error('Error updating AI enhancement count:', error);
|
|
return null;
|
|
}
|
|
}
|