fix: Resolve win rate and P&L discrepancies between Status and AI Learning sections
- Fixed analysis-details API to use stored profit field as fallback when exit prices missing - Updated UI to use Status API data instead of calculating from limited recent trades - Modified AI Learning Status to use real database trade data instead of demo numbers - Enhanced price monitor with automatic trade closing logic for TP/SL hits - Modified automation service to create trades with OPEN status for proper monitoring - Added test scripts for creating OPEN trades and validating monitoring system Key changes: - Status section now shows accurate 50% win rate from complete database - AI Learning Status shows consistent metrics based on real trading performance - Both sections display same correct P&L (8.62) from actual trade results - Real-time price monitor properly detects and tracks OPEN status trades - Fixed trade lifecycle: OPEN → monitoring → COMPLETED when TP/SL hit All trading performance metrics now display consistent, accurate data from the same source.
This commit is contained in:
@@ -142,6 +142,14 @@ class PriceMonitor extends EventEmitter {
|
||||
// Update trade in database with current PnL
|
||||
await this.updateTradeCurrentData(trade.id, currentPrice, monitoring.currentPnL!)
|
||||
|
||||
// Check if trade should be closed (TP/SL hit)
|
||||
const shouldClose = await this.checkTradeClose(trade, currentPrice)
|
||||
if (shouldClose) {
|
||||
await this.closeTrade(trade.id, currentPrice, shouldClose.reason)
|
||||
console.log(`🔒 Trade ${trade.id.slice(-8)} closed: ${shouldClose.reason} at $${currentPrice}`)
|
||||
continue // Skip further processing for this trade
|
||||
}
|
||||
|
||||
// Check if analysis is needed
|
||||
const needsAnalysis = this.shouldTriggerAnalysis(monitoring)
|
||||
if (needsAnalysis) {
|
||||
@@ -384,6 +392,67 @@ class PriceMonitor extends EventEmitter {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Check if a trade should be closed based on TP/SL
|
||||
private async checkTradeClose(trade: any, currentPrice: number): Promise<{ reason: string } | null> {
|
||||
const entryPrice = trade.entryPrice || trade.price
|
||||
|
||||
// Check Take Profit
|
||||
if (trade.takeProfit) {
|
||||
const tpHit = (trade.side === 'BUY' && currentPrice >= trade.takeProfit) ||
|
||||
(trade.side === 'SELL' && currentPrice <= trade.takeProfit)
|
||||
if (tpHit) {
|
||||
return { reason: 'TAKE_PROFIT' }
|
||||
}
|
||||
}
|
||||
|
||||
// Check Stop Loss
|
||||
if (trade.stopLoss) {
|
||||
const slHit = (trade.side === 'BUY' && currentPrice <= trade.stopLoss) ||
|
||||
(trade.side === 'SELL' && currentPrice >= trade.stopLoss)
|
||||
if (slHit) {
|
||||
return { reason: 'STOP_LOSS' }
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Close a trade by updating its status and exit data
|
||||
private async closeTrade(tradeId: string, exitPrice: number, reason: string): Promise<void> {
|
||||
try {
|
||||
const trade = await prisma.trade.findUnique({ where: { id: tradeId } })
|
||||
if (!trade) return
|
||||
|
||||
const entryPrice = trade.entryPrice || trade.price
|
||||
const pnl = this.calculatePnL(trade.side, entryPrice, exitPrice, trade.amount)
|
||||
const tradingAmount = trade.amount * entryPrice // Estimate trading amount
|
||||
const pnlPercent = ((pnl / tradingAmount) * 100)
|
||||
|
||||
await prisma.trade.update({
|
||||
where: { id: tradeId },
|
||||
data: {
|
||||
status: 'COMPLETED',
|
||||
exitPrice: exitPrice,
|
||||
closedAt: new Date(),
|
||||
profit: pnl,
|
||||
pnlPercent: pnlPercent,
|
||||
outcome: pnl > 0 ? 'WIN' : pnl < 0 ? 'LOSS' : 'BREAK_EVEN'
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error closing trade:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate P&L for a trade
|
||||
private calculatePnL(side: string, entryPrice: number, exitPrice: number, amount: number): number {
|
||||
if (side === 'BUY') {
|
||||
return (exitPrice - entryPrice) * amount
|
||||
} else {
|
||||
return (entryPrice - exitPrice) * amount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const priceMonitor = PriceMonitor.getInstance()
|
||||
|
||||
Reference in New Issue
Block a user