//@version=5 strategy("BTC Trend Rider [ATR Breakout]", overlay=true, initial_capital=10000, currency=currency.USD, default_qty_type=strategy.fixed, default_qty_value=1, commission_type=strategy.commission.percent, commission_value=0.1, slippage=2, pyramiding=0, calc_on_every_tick=false) // ── Inputs ──────────────────────────────────────────────── grpT = "Trend" fastLen = input.int(21, "Fast EMA", minval=1, group=grpT) slowLen = input.int(50, "Slow EMA", minval=1, group=grpT) trendLen = input.int(200, "Trend EMA", minval=1, group=grpT) adxLen = input.int(14, "ADX Length", minval=1, group=grpT) adxMin = input.float(20, "Min ADX", minval=0, group=grpT) grpE = "Entry" donLen = input.int(20, "Breakout Lookback", minval=2, group=grpE) useShorts = input.bool(false, "Enable Shorts", group=grpE) grpR = "Risk" atrLen = input.int(14, "ATR Length", minval=1, group=grpR) slMult = input.float(2.0, "Initial Stop (ATR x)", minval=0.1, step=0.1, group=grpR) trailMult = input.float(3.0, "Trailing Stop (ATR x)", minval=0.1, step=0.1, group=grpR) riskPct = input.float(1.0, "Risk per Trade (% equity)", minval=0.1, maxval=100, step=0.1, group=grpR) grpD = "Backtest Window" startTime = input.time(timestamp("2018-01-01T00:00:00"), "Start", group=grpD) endTime = input.time(timestamp("2099-12-31T00:00:00"), "End", group=grpD) inWindow = time >= startTime and time <= endTime // ── Indicators ──────────────────────────────────────────── emaFast = ta.ema(close, fastLen) emaSlow = ta.ema(close, slowLen) emaTrend = ta.ema(close, trendLen) atr = ta.atr(atrLen) [diPlus, diMinus, adx] = ta.dmi(adxLen, adxLen) donHigh = ta.highest(high, donLen)[1] donLow = ta.lowest(low, donLen)[1] trendUp = close > emaTrend and emaFast > emaSlow trendDown = close < emaTrend and emaFast < emaSlow strong = adx > adxMin longSignal = inWindow and trendUp and strong and close > donHigh shortSignal = inWindow and useShorts and trendDown and strong and close < donLow // ── Position sizing (risk-based, no leverage) ───────────── stopDist = atr * slMult rawQty = stopDist > 0 ? (strategy.equity * riskPct / 100) / stopDist : 0.0 maxQty = strategy.equity / close qty = math.min(rawQty, maxQty) // ── Stop state ──────────────────────────────────────────── var float longStop = na var float shortStop = na flat = strategy.position_size == 0 if flat and longSignal and qty > 0 longStop := close - stopDist strategy.entry("Long", strategy.long, qty=qty) if flat and shortSignal and qty > 0 shortStop := close + stopDist strategy.entry("Short", strategy.short, qty=qty) // Ratchet trailing stops (only move in trade's favor) if strategy.position_size > 0 longStop := math.max(nz(longStop, close - stopDist), close - atr * trailMult) strategy.exit("L-Stop", from_entry="Long", stop=longStop) if close < emaSlow strategy.close("Long", comment="Trend break") if strategy.position_size < 0 shortStop := math.min(nz(shortStop, close + stopDist), close + atr * trailMult) strategy.exit("S-Stop", from_entry="Short", stop=shortStop) if close > emaSlow strategy.close("Short", comment="Trend break") // Reset stops when flat with no pending entry if flat and not longSignal longStop := na if flat and not shortSignal shortStop := na // Close everything at end of window if not inWindow and not flat strategy.close_all(comment="Window end") // ── Visuals ─────────────────────────────────────────────── plot(emaFast, "Fast EMA", color=color.new(color.aqua, 0)) plot(emaSlow, "Slow EMA", color=color.new(color.orange, 0)) plot(emaTrend, "Trend EMA", color=color.new(color.gray, 0), linewidth=2) plot(strategy.position_size > 0 ? longStop : na, "Long Stop", color=color.red, style=plot.style_linebr, linewidth=2) plot(strategy.position_size < 0 ? shortStop : na, "Short Stop", color=color.green, style=plot.style_linebr, linewidth=2) bgcolor(trendUp ? color.new(color.green, 92) : trendDown ? color.new(color.red, 92) : na, title="Regime") plotshape(longSignal and flat, "Long Signal", shape.triangleup, location.belowbar, color.green, size=size.small) plotshape(shortSignal and flat, "Short Signal", shape.triangledown, location.abovebar, color.red, size=size.small)