//@version=5 strategy("BTC Trend Breakout + ATR Risk", overlay = true, initial_capital = 10000, default_qty_type = strategy.fixed, commission_type = strategy.commission.percent, commission_value = 0.1, slippage = 2, pyramiding = 0, process_orders_on_close = false) // ───────── Inputs ───────── grpT = "Trend" fastLen = input.int(21, "Fast EMA", minval = 1, group = grpT) slowLen = input.int(55, "Slow EMA", minval = 1, group = grpT) regimeLen = input.int(200, "Regime EMA", minval = 1, group = grpT) adxLen = input.int(14, "ADX length", minval = 1, group = grpT) adxMin = input.float(20.0, "Min ADX", minval = 0, group = grpT) grpE = "Entry" dcLen = input.int(20, "Donchian breakout length", minval = 2, group = grpE) allowShorts = input.bool(false, "Allow shorts", group = grpE) startDate = input.time(timestamp("2018-01-01T00:00:00"), "Backtest start", group = grpE) grpR = "Risk" atrLen = input.int(14, "ATR length", minval = 1, group = grpR) stopMult = input.float(2.0, "Initial stop (x ATR)", minval = 0.1, step = 0.1, group = grpR) trailMult = input.float(3.0, "Trailing stop (x ATR)", minval = 0.1, step = 0.1, group = grpR) riskPct = input.float(1.0, "Risk per trade (% equity)", minval = 0.1, maxval = 10, step = 0.1, group = grpR) maxExposure = input.float(1.0, "Max exposure (x equity)", minval = 0.1, maxval = 1.0, step = 0.1, group = grpR) // ───────── Indicators ───────── emaFast = ta.ema(close, fastLen) emaSlow = ta.ema(close, slowLen) emaRegime = ta.ema(close, regimeLen) atr = ta.atr(atrLen) [diPlus, diMinus, adx] = ta.dmi(adxLen, adxLen) dcHigh = ta.highest(high, dcLen)[1] dcLow = ta.lowest(low, dcLen)[1] inWindow = time >= startDate ready = not na(atr) and not na(dcHigh) and not na(adx) and bar_index > regimeLen // ───────── Signals ───────── longSignal = ready and inWindow and close > dcHigh and close > emaRegime and emaFast > emaSlow and adx > adxMin shortSignal = ready and inWindow and allowShorts and close < dcLow and close < emaRegime and emaFast < emaSlow and adx > adxMin // ───────── Position sizing (fixed fractional risk) ───────── stopDist = atr * stopMult riskCash = strategy.equity * riskPct / 100 qtyRisk = stopDist > 0 ? riskCash / stopDist : 0.0 qtyCap = strategy.equity * maxExposure / close qty = math.max(math.min(qtyRisk, qtyCap), 0.0) // ───────── Orders ───────── var float longStop = na var float shortStop = na flat = strategy.position_size == 0 if longSignal and flat and qty > 0 longStop := close - stopDist strategy.entry("Long", strategy.long, qty = qty) strategy.exit("L-Exit", "Long", stop = longStop) else if strategy.position_size > 0 longStop := math.max(nz(longStop, close - stopDist), close - trailMult * atr) strategy.exit("L-Exit", "Long", stop = longStop) if close < emaSlow strategy.close("Long", comment = "Trend exit") if shortSignal and flat and qty > 0 shortStop := close + stopDist strategy.entry("Short", strategy.short, qty = qty) strategy.exit("S-Exit", "Short", stop = shortStop) else if strategy.position_size < 0 shortStop := math.min(nz(shortStop, close + stopDist), close + trailMult * atr) strategy.exit("S-Exit", "Short", stop = shortStop) if close > emaSlow strategy.close("Short", comment = "Trend exit") if flat and not longSignal longStop := na if flat and not shortSignal shortStop := na // ───────── Plots ───────── plot(emaFast, "Fast EMA", color = color.new(color.teal, 0)) plot(emaSlow, "Slow EMA", color = color.new(color.orange, 0)) plot(emaRegime, "Regime EMA", color = color.new(color.gray, 0), linewidth = 2) plot(dcHigh, "Donchian High", color = color.new(color.green, 70)) plot(dcLow, "Donchian Low", color = color.new(color.red, 70)) plot(strategy.position_size > 0 ? longStop : na, "Long Stop", color = color.green, style = plot.style_linebr, linewidth = 2) plot(strategy.position_size < 0 ? shortStop : na, "Short Stop", color = color.red, style = plot.style_linebr, linewidth = 2)