From 7c18e81164a72105e7a35f3f3aceeade405018f2 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Sun, 2 Nov 2025 22:41:06 +0100 Subject: [PATCH] fix: update on-chain SL orders after TP1 hits CRITICAL: After TP1 closes 75%, the on-chain stop loss orders were NOT being updated - Position Manager was tracking new SL price internally but not updating Drift orders - Old SL orders (e.g., $181.69) remained active even after TP1 at $185.28 - This prevented the 'move SL to breakeven after TP1' logic from working Fix: - After TP1 hits, cancel ALL old orders on-chain - Place new SL orders at updated price (breakeven + configured %) - Place remaining TP2 order for the 25% runner position - Maintains dual-stop system if enabled Result: SL will now actually move up on Drift UI after TP1 fires --- lib/trading/position-manager.ts | 43 +++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 95f74ea..5a39346 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -532,14 +532,53 @@ export class PositionManager { // Move SL based on breakEvenTriggerPercent setting trade.tp1Hit = true trade.currentSize = trade.positionSize * ((100 - this.config.takeProfit1SizePercent) / 100) - trade.stopLossPrice = this.calculatePrice( + const newStopLossPrice = this.calculatePrice( trade.entryPrice, this.config.breakEvenTriggerPercent, // Use configured breakeven level trade.direction ) + trade.stopLossPrice = newStopLossPrice trade.slMovedToBreakeven = true - console.log(`🔒 SL moved to +${this.config.breakEvenTriggerPercent}% (${this.config.takeProfit1SizePercent}% closed, ${100 - this.config.takeProfit1SizePercent}% remaining): ${trade.stopLossPrice.toFixed(4)}`) + console.log(`🔒 SL moved to +${this.config.breakEvenTriggerPercent}% (${this.config.takeProfit1SizePercent}% closed, ${100 - this.config.takeProfit1SizePercent}% remaining): ${newStopLossPrice.toFixed(4)}`) + + // CRITICAL: Cancel old on-chain SL orders and place new ones at updated price + try { + console.log('🗑️ Cancelling old stop loss orders...') + const { cancelAllOrders, placeExitOrders } = await import('../drift/orders') + const cancelResult = await cancelAllOrders(trade.symbol) + if (cancelResult.success) { + console.log(`✅ Cancelled ${cancelResult.cancelledCount || 0} old orders`) + + // Place new SL orders at breakeven/profit level for remaining position + console.log(`🛡️ Placing new SL orders at $${newStopLossPrice.toFixed(4)} for remaining position...`) + const exitOrdersResult = await placeExitOrders({ + symbol: trade.symbol, + positionSizeUSD: trade.currentSize, + entryPrice: trade.entryPrice, + tp1Price: trade.tp2Price, // Only TP2 remains + tp2Price: trade.tp2Price, // Dummy, won't be used + stopLossPrice: newStopLossPrice, + tp1SizePercent: 100, // Close remaining 25% at TP2 + tp2SizePercent: 0, + direction: trade.direction, + useDualStops: this.config.useDualStops, + softStopPrice: trade.direction === 'long' + ? newStopLossPrice * 1.005 // 0.5% above for long + : newStopLossPrice * 0.995, // 0.5% below for short + hardStopPrice: newStopLossPrice, + }) + + if (exitOrdersResult.success) { + console.log('✅ New SL orders placed on-chain at updated price') + } else { + console.error('❌ Failed to place new SL orders:', exitOrdersResult.error) + } + } + } catch (error) { + console.error('❌ Failed to update on-chain SL orders:', error) + // Don't fail the TP1 exit if SL update fails - software monitoring will handle it + } // Save state after TP1 await this.saveTradeState(trade)