PROBLEM: Ghost positions caused death spirals - Position Manager tracked 2 positions that were actually closed - Caused massive rate limit storms (100+ RPC calls) - Telegram /status showed wrong data - Periodic validation SKIPPED during rate limiting (fatal flaw) - Created death spiral: ghosts → rate limits → validation skipped → more rate limits USER REQUIREMENT: "bot has to work all the time especially when i am not on my laptop" - System MUST be fully autonomous - Must self-heal from ghost accumulation - Cannot rely on manual container restarts SOLUTION: 3-layer protection system (Nov 15, 2025) **LAYER 1: Database-based age check** - Runs every 5 minutes during validation - Removes positions >6 hours old (likely ghosts) - Doesn't require RPC calls - ALWAYS works even during rate limiting - Prevents long-term ghost accumulation **LAYER 2: Death spiral detector** - Monitors close attempt failures during rate limiting - After 20+ failed close attempts (40+ seconds), forces removal - Breaks rate limit death spirals immediately - Prevents infinite retry loops **LAYER 3: Monitoring loop integration** - Every 20 price checks (~40 seconds), verifies position exists on Drift - Catches ghosts quickly during normal monitoring - No 5-minute wait - immediate detection - Silently skips check during RPC errors (no log spam) **Key fixes:** - validatePositions(): Now runs database cleanup FIRST before Drift checks - Changed 'skipping validation' to 'using database-only validation' - Added cleanupStalePositions() function (>6h age threshold) - Added death spiral detection in executeExit() rate limit handler - Added ghost check in checkTradeConditions() every 20 price updates - All layers work together - if one fails, others protect **Impact:** - System now self-healing - no manual intervention needed - Ghost positions cleaned within 40-360 seconds (depending on layer) - Works even during severe rate limiting (Layer 1 always runs) - Telegram /status always shows correct data - User can be away from laptop - bot handles itself **Testing:** - Container restart cleared ghosts (as expected - DB shows all closed) - New fixes will prevent future accumulation autonomously Files changed: - lib/trading/position-manager.ts (3 layers added)
56 KiB
56 KiB