diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 4fc38f0..b78b7a6 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -423,25 +423,36 @@ export class PositionManager { // CRITICAL: Use original position size for P&L calculation on external closures // trade.currentSize may already be 0 if on-chain orders closed the position before // Position Manager detected it, causing zero P&L bug + // HOWEVER: If this was a phantom trade (extreme size mismatch), set P&L to 0 const sizeForPnL = trade.currentSize > 0 ? trade.currentSize : trade.positionSize + // Check if this was a phantom trade by looking at the last known on-chain size + // If last on-chain size was <50% of expected, this is a phantom + const wasPhantom = trade.currentSize > 0 && (trade.currentSize / trade.positionSize) < 0.5 + console.log(`📊 External closure detected - Position size tracking:`) console.log(` Original size: $${trade.positionSize.toFixed(2)}`) console.log(` Tracked current size: $${trade.currentSize.toFixed(2)}`) console.log(` Using for P&L calc: $${sizeForPnL.toFixed(2)}`) + if (wasPhantom) { + console.log(` ⚠️ PHANTOM TRADE: Setting P&L to 0 (size mismatch >50%)`) + } // Determine exit reason based on TP flags and realized P&L // CRITICAL: Use trade state flags, not current price (on-chain orders filled in the past!) let exitReason: 'TP1' | 'TP2' | 'SL' | 'SOFT_SL' | 'HARD_SL' = 'SL' - // Calculate P&L first - const profitPercent = this.calculateProfitPercent( - trade.entryPrice, - currentPrice, - trade.direction - ) - const accountPnL = profitPercent * trade.leverage - const realizedPnL = (sizeForPnL * accountPnL) / 100 + // Calculate P&L first (set to 0 for phantom trades) + let realizedPnL = 0 + if (!wasPhantom) { + const profitPercent = this.calculateProfitPercent( + trade.entryPrice, + currentPrice, + trade.direction + ) + const accountPnL = profitPercent * trade.leverage + realizedPnL = (sizeForPnL * accountPnL) / 100 + } // Determine exit reason from trade state and P&L if (trade.tp2Hit) {