diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index a158fcb..86082d3 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -289,6 +289,47 @@ export class PositionManager { if (position === null || position.size === 0) { // Position closed externally (by on-chain TP/SL order) console.log(`⚠️ Position ${trade.symbol} was closed externally (by on-chain order)`) + } else { + // CRITICAL: Verify this position matches the trade we're tracking + // Different entry price means this is a NEW position, not ours + const entryPriceDiff = Math.abs(position.entryPrice - trade.entryPrice) + const entryPriceDiffPercent = (entryPriceDiff / trade.entryPrice) * 100 + + if (entryPriceDiffPercent > 0.5) { + // Entry prices differ by >0.5% - this is a DIFFERENT position + console.log(`⚠️ Position ${trade.symbol} entry mismatch: tracking $${trade.entryPrice.toFixed(4)} but found $${position.entryPrice.toFixed(4)}`) + console.log(`🗑️ This is a different/newer position - removing old trade from monitoring`) + + // Mark the old trade as closed (we lost track of it) + try { + await updateTradeExit({ + positionId: trade.positionId, + exitPrice: trade.lastPrice, + exitReason: 'SOFT_SL', // Unknown - just mark as closed + realizedPnL: 0, + exitOrderTx: 'UNKNOWN_CLOSURE', + holdTimeSeconds: Math.floor((Date.now() - trade.entryTime) / 1000), + maxDrawdown: 0, + maxGain: trade.peakPnL, + }) + console.log(`💾 Old trade marked as closed (lost tracking)`) + } catch (dbError) { + console.error('❌ Failed to save lost trade closure:', dbError) + } + + // Remove from monitoring WITHOUT cancelling orders (they belong to the new position!) + console.log(`🗑️ Removing old trade WITHOUT cancelling orders`) + this.activeTrades.delete(trade.id) + + if (this.activeTrades.size === 0 && this.isMonitoring) { + this.stopMonitoring() + } + + return + } + } + + if (position === null || position.size === 0) { // Save currentSize before it becomes 0 const sizeBeforeClosure = trade.currentSize