From 5b2ec408a81fda9f70842be20999cd2a2df20c21 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Sat, 15 Nov 2025 19:37:05 +0100 Subject: [PATCH] fix: Update on-chain SL to breakeven after TP1 hit (CRITICAL) CRITICAL BUG: After TP1 filled, Position Manager updated internal stopLossPrice but NEVER updated the actual on-chain orders on Drift. Runner had NO real stop loss protection at breakeven. Fix: - After TP1 detection, call cancelAllOrders() to remove old orders - Then call placeExitOrders() with updated SL at breakeven - Place TP2 as new TP1 for runner (activates trailing at that level) - Logs: 'Cancelling old exit orders', 'Placing new exit orders' Impact: Runner now properly protected at breakeven on-chain, not just in Position Manager tracking. Found: User screenshot showed SL still at original levels (46.57) after TP1 hit, when it should have been at entry (42.89). --- lib/trading/position-manager.ts | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index c6947a4..adb9bfe 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -494,6 +494,40 @@ export class PositionManager { trade.slMovedToBreakeven = true console.log(`🛡️ Stop loss moved to breakeven: $${trade.stopLossPrice.toFixed(4)}`) + // CRITICAL: Update on-chain orders to reflect new SL at breakeven + try { + const { cancelAllOrders, placeExitOrders } = await import('../drift/orders') + + console.log(`🔄 Cancelling old exit orders...`) + const cancelResult = await cancelAllOrders(trade.symbol) + if (cancelResult.success) { + console.log(`✅ Cancelled ${cancelResult.cancelledCount} old orders`) + } + + console.log(`🛡️ Placing new exit orders with SL at breakeven...`) + const orderResult = await placeExitOrders({ + symbol: trade.symbol, + direction: trade.direction, + entryPrice: trade.entryPrice, + positionSizeUSD: trade.currentSize, // Runner size + stopLossPrice: trade.stopLossPrice, // At breakeven now + tp1Price: trade.tp2Price, // TP2 becomes new TP1 for runner + tp2Price: 0, // No TP2 for runner + tp1SizePercent: 0, // Close 0% at TP2 (activates trailing) + tp2SizePercent: 0, // No TP2 + softStopPrice: 0, + hardStopPrice: 0, + }) + + if (orderResult.success) { + console.log(`✅ Exit orders updated with SL at breakeven`) + } else { + console.error(`❌ Failed to update exit orders:`, orderResult.error) + } + } catch (error) { + console.error(`❌ Failed to update on-chain orders after TP1:`, error) + } + await this.saveTradeState(trade) } else if (trade.tp1Hit && !trade.tp2Hit && reductionPercent >= 85) {