Home / Toolkit / Edge Turtle Donchian (20/10)
Free & open source · MIT

Edge Turtle Donchian (20/10)

Classic Turtle-style channel breakout, long/flat. Channels exclude the current bar (shift 1). Signal at close, acted on next bar. The same class of signal sold in premium breakout / price-action signals packages — except the code is below, and so are the receipts.

882
assets tested (daily bars)
22.3%
beat buy & hold out-of-sample
41.2%
median win rate (OOS)
0.21
median Sharpe (OOS)
Read the receipts before you trade it

On the median asset this rule underperformed buy-and-hold by 7.5% CAGR out-of-sample, with a median max drawdown of -38.6%. Arrows on a chart are not an edge — asset selection is. Use it where it's proven to hold up (below), skip it everywhere else. No one selling signals will print this paragraph; that's why we do.

Where it held up

Top assets by out-of-sample Sharpe

Where it failed worst

The loss column

The code

Full Pine Script source

TradingView → open the Pine Editor (bottom panel) → paste → "Add to chart". Settings: Enter: close above the prior 20-bar high. Exit: close below the prior 10-bar low..

//@version=5
// ─────────────────────────────────────────────────────────────────────────────
// Edge Turtle Donchian (20/10) — free & open source. Part of the IndicatorEdge Edge Toolkit.
// Receipts (out-of-sample backtests across 700+ assets, incl. where it LOSES):
//   https://indicatoredge.io/toolkit/edge-turtle-donchian
// Same rule our engine tested: enter long when close breaks the PRIOR 20-bar high,
// exit when close breaks the PRIOR 10-bar low (channels exclude the current bar).
// Long/flat, signal at close, act next bar. License: MIT.
// Educational/hypothetical — not financial advice.
// ─────────────────────────────────────────────────────────────────────────────
indicator("Edge Turtle Donchian (20/10) — IndicatorEdge", overlay = true)

entryLen = input.int(20, "Entry channel (bars)", minval = 2)
exitLen  = input.int(10, "Exit channel (bars)",  minval = 2)

hh = ta.highest(high, entryLen)[1]   // prior N bars — excludes the current bar, like the engine
ll = ta.lowest(low,  exitLen)[1]

var bool inPos = false
enterLong = not inPos and close > hh
exitLong  = inPos and close < ll
inPos := enterLong ? true : exitLong ? false : inPos

plot(hh, "Entry channel (20-bar high)", color = color.new(#2dd4bf, 30), style = plot.style_linebr)
plot(ll, "Exit channel (10-bar low)",   color = color.new(#f87171, 30), style = plot.style_linebr)
barcolor(inPos ? color.new(#2dd4bf, 70) : na, title = "In-position tint")

plotshape(enterLong, "Breakout LONG", shape.labelup,   location.belowbar, color.new(#2dd4bf, 0), text = "LONG", textcolor = color.white, size = size.small)
plotshape(exitLong,  "Channel EXIT",  shape.labeldown, location.abovebar, color.new(#f87171, 0), text = "EXIT", textcolor = color.white, size = size.small)

alertcondition(enterLong, "Edge Turtle — LONG", "Close broke the prior 20-bar high (engine acts next bar open)")
alertcondition(exitLong,  "Edge Turtle — EXIT", "Close broke the prior 10-bar low (engine acts next bar open)")

Published stats were computed by our engine with this exact rule: long/flat, signal at bar close acted on the next bar, 0.08% costs per side, out-of-sample = final 30% of each asset's history. Educational information only — not investment advice. Hypothetical backtested results; past performance does not guarantee future results. Trading involves risk of loss.

More from the toolkit

Free · no spam

Get the weekly edge report

The best-performing indicator per asset, what changed this week, and the honest caveats — straight to your inbox.