- Fixed EnhancedAILearningPanel React error with recommendation objects - Converted automation-with-learning-v2.js to pure ES6 modules - Fixed singleton automation instance management - Resolved ES module/CommonJS compatibility issues - Added proper null safety checks for learning system data - Fixed API import paths for automation endpoints - Enhanced learning status display with proper error handling
117 lines
3.9 KiB
JavaScript
117 lines
3.9 KiB
JavaScript
// API route for persistent learning data that works regardless of automation status
|
|
import { NextResponse } from 'next/server';
|
|
import { PrismaClient } from '@prisma/client';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
export async function GET() {
|
|
try {
|
|
// Get persistent learning statistics from database using raw SQL
|
|
const [
|
|
totalDecisions,
|
|
recentDecisions,
|
|
totalTrades,
|
|
successfulTrades,
|
|
recentTrades
|
|
] = await Promise.all([
|
|
// Total AI decisions count
|
|
prisma.$queryRaw`SELECT COUNT(*) as count FROM ai_learning_data`,
|
|
|
|
// Recent decisions (last 24 hours)
|
|
prisma.$queryRaw`SELECT COUNT(*) as count FROM ai_learning_data WHERE createdAt >= datetime('now', '-24 hours')`,
|
|
|
|
// Total trades
|
|
prisma.$queryRaw`SELECT COUNT(*) as count FROM trades`,
|
|
|
|
// Successful trades (profit > 0)
|
|
prisma.$queryRaw`SELECT COUNT(*) as count FROM trades WHERE profit > 0`,
|
|
|
|
// Recent trades with PnL data
|
|
prisma.$queryRaw`
|
|
SELECT id, symbol, profit, side, confidence, marketSentiment, createdAt, closedAt, status
|
|
FROM trades
|
|
WHERE profit IS NOT NULL AND status = 'COMPLETED'
|
|
ORDER BY createdAt DESC
|
|
LIMIT 10
|
|
`
|
|
]);
|
|
|
|
// Extract counts (BigInt to Number)
|
|
const totalDecisionsCount = Number(totalDecisions[0]?.count || 0);
|
|
const recentDecisionsCount = Number(recentDecisions[0]?.count || 0);
|
|
const totalTradesCount = Number(totalTrades[0]?.count || 0);
|
|
const successfulTradesCount = Number(successfulTrades[0]?.count || 0);
|
|
|
|
// Calculate metrics
|
|
const successRate = totalTradesCount > 0 ? (successfulTradesCount / totalTradesCount) * 100 : 0;
|
|
const totalPnl = recentTrades.reduce((sum, trade) => sum + (Number(trade.profit) || 0), 0);
|
|
const avgPnl = recentTrades.length > 0 ? totalPnl / recentTrades.length : 0;
|
|
|
|
// Get wins and losses
|
|
const wins = recentTrades.filter(trade => Number(trade.profit) > 0).length;
|
|
const losses = recentTrades.filter(trade => Number(trade.profit) < 0).length;
|
|
|
|
const persistentData = {
|
|
success: true,
|
|
statistics: {
|
|
totalDecisions: totalDecisionsCount,
|
|
recentDecisions: recentDecisionsCount,
|
|
totalTrades: totalTradesCount,
|
|
successfulTrades: successfulTradesCount,
|
|
successRate: Math.round(successRate * 100) / 100,
|
|
totalPnl: Math.round(totalPnl * 100) / 100,
|
|
avgPnl: Math.round(avgPnl * 100) / 100,
|
|
wins,
|
|
losses,
|
|
winRate: wins + losses > 0 ? Math.round((wins / (wins + losses)) * 100 * 100) / 100 : 0
|
|
},
|
|
recentTrades: recentTrades.map(trade => ({
|
|
id: trade.id,
|
|
symbol: trade.symbol,
|
|
pnl: Number(trade.profit),
|
|
result: Number(trade.profit) > 0 ? 'WIN' : 'LOSS',
|
|
confidence: trade.confidence,
|
|
side: trade.side,
|
|
sentiment: trade.marketSentiment,
|
|
date: trade.createdAt,
|
|
closedAt: trade.closedAt
|
|
})),
|
|
systemHealth: {
|
|
dataAvailability: totalDecisionsCount > 0 ? 'Good' : 'Limited',
|
|
lastActivity: recentTrades.length > 0 ? recentTrades[0].createdAt : null,
|
|
databaseConnected: true,
|
|
activeDataSources: {
|
|
aiDecisions: totalDecisionsCount,
|
|
completedTrades: totalTradesCount,
|
|
recentActivity: recentDecisionsCount
|
|
}
|
|
}
|
|
};
|
|
|
|
return NextResponse.json(persistentData);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error fetching persistent learning data:', error);
|
|
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: error.message,
|
|
statistics: {
|
|
totalDecisions: 0,
|
|
totalTrades: 0,
|
|
successRate: 0,
|
|
totalPnl: 0,
|
|
wins: 0,
|
|
losses: 0,
|
|
winRate: 0
|
|
},
|
|
systemHealth: {
|
|
dataAvailability: 'Error',
|
|
databaseConnected: false
|
|
}
|
|
}, { status: 500 });
|
|
} finally {
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|