Enhanced trade analysis display and fixed automation persistence
- Enhanced frontend trade display with comprehensive analysis details * Added trigger analysis showing original trade signals and confidence * Added current metrics for active trades (P&L, time in trade, price changes) * Added exit analysis for completed trades (accuracy, actual vs expected R/R) * Added detailed trade context explaining analysis-trade relationships - Fixed automation session persistence after server restarts * Modified getStatus() to check database first instead of in-memory state * Added auto-restart functionality when active session exists but automation stopped * Improved session tracking and state management - Enhanced API response structure * Added triggerAnalysis, currentMetrics, exitMetrics to trade objects * Added analysisContext explaining signal changes (BUY → HOLD scenarios) * Added comprehensive trade quality assessment and performance tracking Features: Detailed analysis-trade correlation display Real-time P&L tracking for active trades Analysis accuracy assessment for completed trades Automation session persistence across server restarts Enhanced trade information with meaningful context
This commit is contained in:
@@ -475,18 +475,19 @@ export default function AutomationPage() {
|
||||
<div className="card card-gradient p-6">
|
||||
<h2 className="text-xl font-bold text-white mb-4">Recent Automated Trades</h2>
|
||||
{recentTrades.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-4">
|
||||
{recentTrades.slice(0, 5).map((trade, idx) => (
|
||||
<div key={idx} className="p-3 bg-gray-800 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center">
|
||||
<div key={idx} className="p-4 bg-gray-800 rounded-lg border border-gray-700">
|
||||
{/* Trade Header */}
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className={`font-semibold px-2 py-1 rounded text-xs ${
|
||||
trade.side === 'BUY' ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
|
||||
}`}>
|
||||
{trade.side}
|
||||
</span>
|
||||
<span className="text-white ml-2 font-semibold">{trade.amount}</span>
|
||||
<span className={`ml-2 px-2 py-1 rounded text-xs ${
|
||||
<span className="text-white font-semibold">{trade.amount}</span>
|
||||
<span className={`px-2 py-1 rounded text-xs ${
|
||||
trade.isActive ? 'bg-blue-600 text-white' :
|
||||
trade.result === 'PROFIT' ? 'bg-green-600 text-white' :
|
||||
trade.result === 'LOSS' ? 'bg-red-600 text-white' :
|
||||
@@ -500,33 +501,114 @@ export default function AutomationPage() {
|
||||
<div className="text-sm text-gray-400">{trade.confidence}% confidence</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 mb-1">
|
||||
{trade.reason}
|
||||
</div>
|
||||
<div className="flex justify-between items-center text-xs">
|
||||
<div className="text-gray-400">
|
||||
{trade.duration}
|
||||
</div>
|
||||
<div className={`font-semibold ${
|
||||
trade.isActive ?
|
||||
(trade.unrealizedPnl > 0 ? 'text-green-400' : 'text-red-400') :
|
||||
(trade.pnl > 0 ? 'text-green-400' : 'text-red-400')
|
||||
}`}>
|
||||
{trade.isActive ?
|
||||
`P&L: ${trade.unrealizedPnl > 0 ? '+' : ''}${trade.unrealizedPnl}` :
|
||||
`P&L: ${trade.pnl > 0 ? '+' : ''}${trade.pnl}`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{trade.isActive && (
|
||||
<div className="mt-2 pt-2 border-t border-gray-700">
|
||||
<div className="flex justify-between text-xs">
|
||||
<span className="text-gray-400">SL: ${trade.stopLoss}</span>
|
||||
<span className="text-gray-400">Current: ${trade.currentPrice.toFixed(2)}</span>
|
||||
<span className="text-gray-400">TP: ${trade.takeProfit}</span>
|
||||
|
||||
{/* Analysis Context */}
|
||||
{trade.triggerAnalysis && (
|
||||
<div className="mb-3 p-3 bg-gray-900 rounded border border-gray-600">
|
||||
<h4 className="text-blue-400 font-semibold text-sm mb-2">📊 Trigger Analysis</h4>
|
||||
<div className="space-y-1 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Decision:</span>
|
||||
<span className="text-white">{trade.triggerAnalysis.decision} ({trade.triggerAnalysis.confidence}%)</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Market Condition:</span>
|
||||
<span className="text-white">{trade.triggerAnalysis.marketCondition}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Expected R/R:</span>
|
||||
<span className="text-white">{trade.triggerAnalysis.riskReward}</span>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-gray-300">Key Signals:</span>
|
||||
<ul className="text-white ml-2 mt-1">
|
||||
{trade.triggerAnalysis.keySignals.map((signal, signalIdx) => (
|
||||
<li key={signalIdx} className="text-xs">• {signal}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Current Metrics (Active Trades) */}
|
||||
{trade.isActive && trade.currentMetrics && (
|
||||
<div className="mb-3 p-3 bg-blue-900/20 rounded border border-blue-600/30">
|
||||
<h4 className="text-blue-400 font-semibold text-sm mb-2">📈 Current Status</h4>
|
||||
<div className="grid grid-cols-2 gap-2 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Current Price:</span>
|
||||
<span className="text-white">${trade.currentMetrics.currentPrice.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Price Change:</span>
|
||||
<span className={`${trade.currentMetrics.priceChange > 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||||
{trade.currentMetrics.priceChange > 0 ? '+' : ''}${trade.currentMetrics.priceChange.toFixed(2)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Unrealized P&L:</span>
|
||||
<span className={`${trade.currentMetrics.unrealizedPnL > 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||||
{trade.currentMetrics.unrealizedPnL > 0 ? '+' : ''}${trade.currentMetrics.unrealizedPnL.toFixed(2)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Time in Trade:</span>
|
||||
<span className="text-white">{trade.currentMetrics.timeInTrade}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Exit Metrics (Completed Trades) */}
|
||||
{!trade.isActive && trade.exitMetrics && (
|
||||
<div className="mb-3 p-3 bg-gray-900/50 rounded border border-gray-600">
|
||||
<h4 className="text-gray-400 font-semibold text-sm mb-2">📊 Exit Analysis</h4>
|
||||
<div className="space-y-1 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Exit Reason:</span>
|
||||
<span className="text-white">{trade.exitMetrics.exitReason}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Exit Price:</span>
|
||||
<span className="text-white">${trade.exitMetrics.exitPrice.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Analysis Accuracy:</span>
|
||||
<span className={`${trade.exitMetrics.analysisAccuracy.includes('Excellent') ? 'text-green-400' :
|
||||
trade.exitMetrics.analysisAccuracy.includes('Good') ? 'text-yellow-400' : 'text-red-400'}`}>
|
||||
{trade.exitMetrics.analysisAccuracy}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-300">Actual R/R:</span>
|
||||
<span className="text-white">{trade.exitMetrics.actualRiskReward}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Trade Summary */}
|
||||
<div className="flex justify-between items-center text-xs border-t border-gray-700 pt-2">
|
||||
<div className="text-gray-400">
|
||||
{trade.duration}
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="text-gray-400">
|
||||
SL: ${trade.stopLoss} | TP: ${trade.takeProfit}
|
||||
</div>
|
||||
<div className={`font-semibold ${
|
||||
trade.isActive ?
|
||||
(trade.unrealizedPnl > 0 ? 'text-green-400' : 'text-red-400') :
|
||||
(trade.pnl > 0 ? 'text-green-400' : 'text-red-400')
|
||||
}`}>
|
||||
{trade.isActive ?
|
||||
`P&L: ${trade.unrealizedPnl > 0 ? '+' : ''}${trade.unrealizedPnl}` :
|
||||
`P&L: ${trade.pnl > 0 ? '+' : ''}${trade.pnl}`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user