Skip to content
Open RaamTrade

DonchianMid — Donchian Mid

The midpoint of the close-based Donchian channel: halfway between the highest and lowest close of the last N bars. A common mean-reversion target and a slow, wick-immune trend line.

DonchianMid is the identifier a strategy writes; Donchian Mid is the label the chart’s indicator picker shows. Single value — .value is the only accessor.

Signature

DonchianMid(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes Lookback window. Default 20, bounds 2–200.
on= symbol, OHLCV field, or indicator No Source. Defaults to the trade symbol’s close.

Formula

$$ \text{DonchianMid}t = \frac{\max(\text{close}{t-N+1..t}) + \min(\text{close}_{t-N+1..t})}{2} $$

This is the midpoint of the range, not an average of the closes. It moves only when a new extreme enters or an old extreme leaves the window, so it steps rather than drifts — unlike SMA, which every bar nudges.

Warmup

period bars.

Before the window fills, this indicator does something the other two Donchian rails do not: it returns the current close. The leading bars of the chart therefore show the midline lying exactly on price, then detaching once the buffer is full. A strategy never sees it (execute() waits until every indicator is ready), but it explains the shape of the plot’s left edge.

Reading the value

mid.value # midpoint of the N-bar closing range
mid.value_at(1)
mid > 100
mid.crossed_above(other_indicator)

Example

class ChannelMidReversion(Strategy):
"""Buy the channel floor, take profit back at the midpoint."""
period = Param(20, min=2, max=200)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
mid = DonchianMid(self.period, on=self.trade)
bottom = DonchianLow(self.period, on=self.trade)
self.stop_loss(3.0)
floor_level = bottom.value_at(1)
if self.trade.close < floor_level and self.trade.is_flat:
self.buy(self.trade, reason="Broke to the channel floor")
if self.trade.close > mid.value and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason=f"Back to mid {mid.value:.2f}")

Notes

  • Midpoint of the range, not the mean of the window. Two outliers set the whole line; the sixteen closes between them contribute nothing. That is what makes it a stable target — and what makes it a poor trend estimate when one spike dominates the window.
  • It is flat while price stays inside the established range, and steps when the range changes. A “cross of the mid” is therefore about price moving, not about the indicator moving.
  • DonchianMid = (DonchianHigh + DonchianLow) / 2 over the same period — you can compute it from the two rails if you already have them, but the single indicator is cheaper and reads better.
  • For a mean that responds to every bar, use SMA or EMA; for the width of this same channel, use PriceChannelWidth.