diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 5cfa700..2599923 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -322,26 +322,31 @@ export class PositionManager { // Position exists - check if size changed (TP1/TP2 filled) const positionSizeUSD = position.size * currentPrice const trackedSizeUSD = trade.currentSize - const sizeDiffPercent = Math.abs(positionSizeUSD - trackedSizeUSD) / trackedSizeUSD * 100 - + const sizeDiffPercent = Math.abs(positionSizeUSD - trackedSizeUSD) / Math.max(trackedSizeUSD, 1) * 100 + + const reductionUSD = trackedSizeUSD - positionSizeUSD + const reductionPercentOfOriginal = trade.positionSize > 0 + ? (reductionUSD / trade.positionSize) * 100 + : 0 + const reductionPercentOfTracked = trackedSizeUSD > 0 + ? (reductionUSD / trackedSizeUSD) * 100 + : 0 + // If position size reduced significantly, TP orders likely filled if (positionSizeUSD < trackedSizeUSD * 0.9 && sizeDiffPercent > 10) { console.log(`📊 Position size changed: tracking $${trackedSizeUSD.toFixed(2)} but found $${positionSizeUSD.toFixed(2)}`) - - // Detect which TP filled based on size reduction - const reductionPercent = ((trackedSizeUSD - positionSizeUSD) / trade.positionSize) * 100 - - if (!trade.tp1Hit && reductionPercent >= (this.config.takeProfit1SizePercent * 0.8)) { + + if (!trade.tp1Hit && reductionPercentOfOriginal >= (this.config.takeProfit1SizePercent * 0.8)) { // TP1 fired (should be ~75% reduction) - console.log(`🎯 TP1 detected as filled! Reduction: ${reductionPercent.toFixed(1)}%`) + console.log(`🎯 TP1 detected as filled! Reduction: ${reductionPercentOfOriginal.toFixed(1)}% of original`) trade.tp1Hit = true trade.currentSize = positionSizeUSD - + await this.handlePostTp1Adjustments(trade, 'on-chain TP1 detection') - - } else if (trade.tp1Hit && !trade.tp2Hit && reductionPercent >= 85) { - // TP2 fired (total should be ~95% closed, 5% runner left) - console.log(`🎯 TP2 detected as filled! Reduction: ${reductionPercent.toFixed(1)}%`) + + } else if (trade.tp1Hit && !trade.tp2Hit && reductionPercentOfTracked >= (this.config.takeProfit2SizePercent * 0.8)) { + // TP2 fired (should clear remaining runner allocation) + console.log(`🎯 TP2 detected as filled! Reduction: ${reductionPercentOfTracked.toFixed(1)}% of remaining`) trade.tp2Hit = true trade.currentSize = positionSizeUSD trade.trailingStopActive = true @@ -349,16 +354,16 @@ export class PositionManager { console.log( `🏃 Runner active: $${positionSizeUSD.toFixed(2)} with trailing buffer ${trade.runnerTrailingPercent?.toFixed(3)}%` ) - + await this.saveTradeState(trade) - + } else { // Partial fill detected but unclear which TP - just update size console.log(`⚠️ Unknown partial fill detected - updating tracked size to $${positionSizeUSD.toFixed(2)}`) trade.currentSize = positionSizeUSD await this.saveTradeState(trade) } - + // Continue monitoring the remaining position return }