critical: Fix ADX-based runner SL in on-chain fill detection path

The ADX-based runner SL logic was only applied in the direct price
check path (lines 1065-1086) but NOT in the on-chain fill detection
path (lines 590-650).

When TP1 fills via on-chain order (most common), the system was using
hard-coded breakeven SL instead of ADX-based positioning.

Bug Impact:
- ADX 20.0 trade got breakeven SL ($138.355) instead of -0.3% ($138.77)
- Runner has $0.42 less room to breathe than intended
- Weak trends protected correctly but moderate/strong trends not

Fix:
- Applied same ADX-based logic to on-chain fill detection
- Added detailed logging for each ADX tier
- Runner SL now correct regardless of TP1 trigger path

Current trade (cmi5zpx5s0000lo07ncba1kzh):
- Already hit TP1 via old code (breakeven SL active)
- New ADX-based SL will apply to NEXT trade
- Current position: SHORT $138.3550, runner at breakeven

Code paths with ADX logic:
1. Direct price check (lines 1050-1100) 
2. On-chain fill detection (lines 607-642)  FIXED
This commit is contained in:
mindesbunister
2025-11-19 14:56:24 +01:00
parent 57790d04d6
commit b2cb6a3ecd

View File

@@ -614,16 +614,36 @@ export class PositionManager {
trade.tp1Hit = true trade.tp1Hit = true
trade.currentSize = positionSizeUSD trade.currentSize = positionSizeUSD
// CRITICAL: Use DATABASE entry price for breakeven (Drift recalculates after partial closes) // ADX-based runner SL positioning (Nov 19, 2025)
// Drift's position.entryPrice is the COST BASIS of remaining position, NOT original entry // Strong trends get more room, weak trends protect capital
// For a true breakeven SL, we need the ORIGINAL entry price from when position opened let runnerSlPercent: number
const breakevenPrice = trade.entryPrice const adx = trade.adxAtEntry || 0
console.log(`📊 Breakeven SL: Using original entry price $${breakevenPrice.toFixed(4)} (Drift shows $${position.entryPrice.toFixed(4)} for remaining position)`)
// Move SL to TRUE breakeven after TP1 if (adx < 20) {
trade.stopLossPrice = breakevenPrice runnerSlPercent = 0 // Weak trend: breakeven, preserve capital
console.log(`🔒 ADX-based runner SL: ${adx.toFixed(1)} → 0% (breakeven - weak trend)`)
} else if (adx < 25) {
runnerSlPercent = -0.3 // Moderate trend: some room
console.log(`🔒 ADX-based runner SL: ${adx.toFixed(1)} → -0.3% (moderate trend)`)
} else {
runnerSlPercent = -0.55 // Strong trend: full retracement room
console.log(`🔒 ADX-based runner SL: ${adx.toFixed(1)} → -0.55% (strong trend)`)
}
// CRITICAL: Use DATABASE entry price (Drift recalculates after partial closes)
const newStopLossPrice = this.calculatePrice(
trade.entryPrice,
runnerSlPercent,
trade.direction
)
console.log(`📊 Runner SL calculation: Entry $${trade.entryPrice.toFixed(4)} ${runnerSlPercent >= 0 ? '+' : ''}${runnerSlPercent}% = $${newStopLossPrice.toFixed(4)}`)
console.log(` (${this.config.takeProfit1SizePercent}% closed, ${100 - this.config.takeProfit1SizePercent}% remaining)`)
// Move SL to ADX-based position after TP1
trade.stopLossPrice = newStopLossPrice
trade.slMovedToBreakeven = true trade.slMovedToBreakeven = true
console.log(`🛡️ Stop loss moved to breakeven: $${trade.stopLossPrice.toFixed(4)}`) console.log(`🛡️ Stop loss moved to: $${trade.stopLossPrice.toFixed(4)}`)
// CRITICAL: Update on-chain orders to reflect new SL at breakeven // CRITICAL: Update on-chain orders to reflect new SL at breakeven
try { try {