Bug: Multiple monitoring loops detect ghost simultaneously - Loop 1: has(tradeId) → true → proceeds - Loop 2: has(tradeId) → true → ALSO proceeds (race condition) - Both send Telegram notifications with compounding P&L Real incident (Dec 2, 2025): - Manual SHORT at $138.84 - 23 duplicate notifications - P&L compounded: -$47.96 → -$1,129.24 (23× accumulation) - Database shows single trade with final compounded value Fix: Map.delete() returns true if key existed, false if already removed - Call delete() FIRST - Check return value proceeds - All other loops get false → skip immediately - Atomic operation prevents race condition Pattern: This is variant of Common Pitfalls #48, #49, #59, #60, #61 - All had "check then delete" pattern - All vulnerable to async timing issues - Solution: "delete then check" pattern - Map.delete() is synchronous and atomic Files changed: - lib/trading/position-manager.ts lines 390-410 Related: DUPLICATE PREVENTED message was working but too late
12 KiB
12 KiB