Donchian Channel: The Breakout Rule That Fires Zero Times
A Donchian channel is the simplest indicator in the whole engine. Take the highest high of the last twenty bars, take the lowest low, and draw both. batch_donchian does exactly that and nothing else — no smoothing, no deviation, no weighting. Richard Donchian's original rule was equally blunt: buy the new high, sell the new low.
That bluntness is why the port check on this page reads 0.000e+00 everywhere, and it is also why the rule as usually written cannot fire even once. Both facts come out of the same line of code, and the second one is the more useful thing to know before you build anything on top of a trading indicators channel.
What a Donchian channel is
Three rows, one window, no arithmetic beyond a maximum and a minimum.
batch_donchian emits an upper row, a lower row and a midpoint. Upper is the largest high inside the lookback, lower is the smallest low, and the midpoint is their average. Because nothing is averaged and nothing is smoothed, the rails only move when a genuine new extreme enters the window or an old one drops out of it. They sit still, then step.
That midpoint turns out to be the most reused window in the whole crate. The identical fold appears in batch_donchian, in the helper behind batch_donchian_width, in batch_midprice, and inside batch_ichimoku — where it builds tenkan, kijun and senkou B. I checked that claim rather than repeating it: computed both ways across 353,117 values, the Donchian midpoint and batch_midprice matched exactly, and so did the 55-bar pair over 343,492 more. The Ichimoku cloud is, arithmetically, three Donchian midpoints wearing a disguise.
The window includes the bar you are comparing
Now the trap, and it is worth slowing down for.
Our window is inclusive of the current bar: the upper row at bar i is the maximum over highs i−19 through i, and that set contains bar i's own high. A maximum can never be beaten by a member of the set it was taken over. So the rule everybody writes — price exceeds the upper channel — describes an event that is arithmetically impossible.
When I first hit this I assumed a bug in my own scan, so I ran the condition across all 337,442 eligible bars to see it fail in public. It fired 0 times. Not rarely, not on illiquid pairs only — zero, on every bar of every symbol in nine years of daily data.
One index fixes it. Compare today's close against yesterday's channel and the rule becomes the thing Donchian actually meant. Everything measured below uses that form. A backtest built on the other one returns an empty trade list, and an empty trade list is exactly the kind of silence that gets read as "no signals in this regime" rather than "the code is wrong".
Width in price, not in percent
The companion row, batch_donchian_width, is the upper rail minus the lower one. That is all it is, and the units are the trap this time.
Bollinger's sibling row divides by the middle band, which makes it comparable across assets and across time. Donchian's does not divide by anything. Bitcoin's twenty-bar width in 2018 and in 2026 are the same quantity measured against prices twenty times apart, so charting one series over a long history mostly draws the price. Comparing two symbols with it is meaningless outright.
Nothing is broken here — the row is honest about being a price difference, and batch_bbands_width is right there when you want the normalized form. But the asymmetry between two neighbouring functions is the sort of thing that ends up quietly wrong in a screener, so this page names it instead of plotting past it.
What the breakout actually returned
Every outcome here resolves first-touch over twenty bars against a symmetric 8% bracket, so break-even is exactly 50% before fees. A bar tagging both levels is scored a loss. The tape is 275 Binance pairs out of prod's own archive, 358,342 daily bars deep, and each symbol runs to wherever its export stops.
Upside breakouts of the twenty-bar channel — Donchian's System 1 — fired 12,408 times and resolved 47.0% against a 49.1% base rate. Two points below simply entering long on an arbitrary bar. Widening to the 55-bar channel that the Turtles used for System 2 made it worse, not better: 44.8%, or 4.3 points under the base rate, across 6,179 signals.
Then look at the same signals a second way, and the verdict inverts. Mean return over the following twenty bars was +6.30% after a breakout against +1.14% on any bar — more than five times as much. The median breakout, meanwhile, lost 2.45%. Nineteen percent of them ran at least 25% versus 12.7% of arbitrary bars, and the ninetieth percentile came in at +44.9% against +30.4%.
Both readings are correct, and together they are the whole of trend following in two lines. Most breakouts lose. A symmetric bracket truncates precisely the tail that pays for them, which is why a win rate is the wrong instrument for measuring this rule and the right one for measuring the band-touch trades on the next page over.
Where the Donchian breakout fails
Three real failures below, chosen because they are the three shapes rather than the three worst.
Breakouts fail loudly when the new high was the whole move. One of the instances shown closed 14.3% through its twenty-bar high and then gave back 21.8% before it ever gained; the extreme was not a beginning but an exhaustion. Short breakdowns fail differently and more often — the downside signals came back 48.8% and their median twenty-bar return was positive, which means the average breakdown was followed by a bounce rather than a slide.
I use the channel as a state description now, never as a trigger. New twenty-bar high means the last month's sellers are all underwater, which is worth knowing. It does not mean the next twenty bars belong to buyers, and the candlestick evidence at the breakout bar tells you more about that than the channel ever will.
Frequently asked questions
What is a Donchian channel?
The highest high and lowest low of the last n bars, plus their midpoint, emitted by batch_donchian. Our default lookback is twenty.
Does the Donchian breakout still work? Not on win rate: 47.0% against a 49.1% base across 12,408 signals. On mean return it beat the base rate more than fivefold, because a small share of signals ran very far.
Why does my breakout backtest find no trades? Almost certainly the inclusive window. Compare the close against the previous bar's channel, not the current one, or the condition can never be true.
What lookback should I use? Twenty and 55 are the Turtle numbers and both are measured above. Neither cleared its base rate on hit rate, and picking a third number because it backtests better is how curve-fitting starts.
How is it different from a Keltner or Bollinger channel? Donchian uses raw extremes with no averaging. Keltner builds from an average true range, and Bollinger from a standard deviation of closes, so both breathe with volatility while this one steps.
This is educational material, not financial advice. Every figure here was measured on past bars, past behavior generalizes poorly to future bars, and trading carries real risk of loss — size any position so that being wrong stays survivable.