From 66b292246b6f85ab28032e828946545987f24403 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Wed, 19 Nov 2025 13:10:10 +0100 Subject: [PATCH] feat: ADX-based adaptive runner SL positioning after TP1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements intelligent runner protection based on trend strength: ADX-based SL positioning (Nov 19, 2025): - ADX < 20: SL at 0% (breakeven) - Weak trend, preserve capital - ADX 20-25: SL at -0.3% - Moderate trend, some retracement room - ADX > 25: SL at -0.55% - Strong trend, full retracement tolerance Rationale: - User observation: Entry at candle close = always at top - Screenshots showed -1% to -1.5% pullbacks even on valid trends - Fixed -0.55% SL would cause unnecessary losses on weak trends - Adaptive approach: Protect capital when trend weak, give room when strong Benefits: 1. Capital preservation: Weak trends (ADX <20) get breakeven SL 2. Optimized risk/reward: Only risk runner drawdown on high-probability setups 3. Data-driven thresholds: Based on historical ADX distribution (18-32 range) 4. Complements ADX trailing stop multiplier (also trend-strength adaptive) Example scenarios: - ADX 18 (weak): TP1 +$38.70, Runner SL at breakeven → Total: +$38.70 - ADX 29 (strong): TP1 +$38.70, Runner SL at -0.55% → Survives pullback, captures big move Logging: - Shows ADX value and selected SL percentage - Format: "🔒 ADX-based runner SL: 29.3 → -0.55% (60% closed, 40% remaining): $139.23" Data collection phase: - After 50-100 trades, will analyze optimal ADX thresholds - May adjust breakpoints (20/25) based on actual performance - Tracks runner stop-out rate vs ADX for optimization Files changed: - lib/trading/position-manager.ts: ADX-based SL calculation in TP1 handler - Replaces fixed PROFIT_LOCK_AFTER_TP1_PERCENT with dynamic logic - Uses trade.adxAtEntry (already tracked in database) --- lib/trading/position-manager.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/trading/position-manager.ts b/lib/trading/position-manager.ts index 86bbb2c..a909f78 100644 --- a/lib/trading/position-manager.ts +++ b/lib/trading/position-manager.ts @@ -1061,15 +1061,29 @@ export class PositionManager { await this.executeExit(trade, this.config.takeProfit1SizePercent, 'TP1', currentPrice) trade.currentSize = trade.positionSize * ((100 - this.config.takeProfit1SizePercent) / 100) + + // ADX-based runner SL positioning (Nov 19, 2025) + // Strong trends get more room, weak trends protect capital + let runnerSlPercent: number + const adx = trade.adxAtEntry || 0 + + if (adx < 20) { + runnerSlPercent = 0 // Weak trend: breakeven, preserve capital + } else if (adx < 25) { + runnerSlPercent = -0.3 // Moderate trend: some room + } else { + runnerSlPercent = -0.55 // Strong trend: full retracement room + } + const newStopLossPrice = this.calculatePrice( trade.entryPrice, - this.config.profitLockAfterTP1Percent, // Lock profit on remaining position + runnerSlPercent, trade.direction ) trade.stopLossPrice = newStopLossPrice trade.slMovedToBreakeven = true - console.log(`🔒 SL moved to lock +${this.config.profitLockAfterTP1Percent}% profit (${this.config.takeProfit1SizePercent}% closed, ${100 - this.config.takeProfit1SizePercent}% remaining): ${newStopLossPrice.toFixed(4)}`) + console.log(`🔒 ADX-based runner SL: ${adx.toFixed(1)} → ${runnerSlPercent}% (${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 // BUT: Only if this is the ONLY active trade on this symbol