CRITICAL BUG FIX: - Position Manager monitoring loop (every 2s) could trigger TP1/TP2 multiple times - tp1Hit flag was set AFTER async executeExit() completed - Multiple concurrent executeExit() calls happened before flag was set - Result: Position closed 6 times (70% close × 6 = entire position + failed attempts) ROOT CAUSE: - Race window: ~0.5-1s between check and flag set - Multiple monitoring loops entered if statement simultaneously FIX APPLIED: - Set tp1Hit = true IMMEDIATELY before calling executeExit() - Same fix for tp2Hit flag - Prevents concurrent execution by setting flag synchronously EVIDENCE: - Test trade at 04:47:09: TP1 triggered 6 times - First close: Remaining $13.52 (correct 30%) - Closes 2-6: Remaining $0.00 (closed entire position) - Position Manager continued tracking $13.02 runner that didn't exist IMPACT: - User had unprotected $42.73 position (Position Manager tracking phantom) - No TP/SL monitoring, no trailing stop - Had to manually close position Files changed: - lib/trading/position-manager.ts: Move tp1Hit/tp2Hit flag setting before async calls - Prevents race condition on all future trades Testing required: Execute test trade and verify TP1 triggers only once.
43 KiB
43 KiB