Min-Max Channel (MMCHANNEL) tracks the highest high and lowest low over a lookback period, creating a pure price envelope without any midpoint calculation. Unlike Donchian Channels which include a middle band, MMCHANNEL delivers only the raw extremes—exactly what breakout traders and range analysis need. This implementation uses monotonic deques for O(1) amortized updates, making it suitable for high-frequency applications and long lookback periods.
Min-Max channels represent the simplest form of price envelope analysis, predating most technical indicators. The concept is intuitive: track where price has been at its highest and lowest points over a defined period.
The approach gained prominence through Richard Donchian's work in the 1960s and later through the Turtle Trading system. While Donchian Channels include a midpoint average, MMCHANNEL strips this away, focusing purely on support and resistance levels defined by actual price extremes.
Most implementations suffer from O(n) complexity per update—scanning the entire window to find max/min values. For period=200 on tick data, this means 200 comparisons per tick. QuanTAlib uses monotonic deques that maintain sorted order implicitly, achieving O(1) amortized updates regardless of period length.
where $H$ is the high price and $n$ is the period. New highs immediately update the upper band; the band only decreases when the previous maximum exits the lookback window.
The key insight is maintaining sorted order without explicit sorting:
**For maximum (upper band):**
1.**Back removal:** Remove elements from the back that are ≤ the new value
2.**Insert:** Add the new (value, index) pair to the back
3.**Front expiry:** Remove elements from the front whose indices are outside the window
4.**Query:** The front element is always the maximum
**For minimum (lower band):**
1.**Back removal:** Remove elements from the back that are ≥ the new value
2.**Insert:** Add the new (value, index) pair to the back
3.**Front expiry:** Remove elements from the front whose indices are outside the window
4.**Query:** The front element is always the minimum
**Amortized Analysis:**
Each element enters the deque exactly once and leaves at most once (either from the back during insertion or from the front during expiry). Over $n$ operations, total work is $O(n)$, yielding $O(1)$ amortized per update.
### Channel Width
The distance between bands measures the price range:
**Complexity:** O(1) amortized per bar. Worst case O(n) occurs only when a monotonically increasing (for max) or decreasing (for min) sequence forces clearing the entire deque—rare in practice.
- **Stale Extremes:** The bands stay flat until a new extreme occurs or the old extreme exits the window. A band that hasn't moved in 15 bars isn't broken—it's waiting for price to exceed the current extreme or for that extreme to age out.
- **O(n) Implementation Trap:** Naive implementations rescan the window every bar. For period=200 on 60,000 bars/day, that's 12 million comparisons per symbol. The monotonic deque approach reduces this to ~120,000 operations.
- **Breakout vs. Touch:** Price touching the upper band differs from breaking out. True breakouts require closes above/below the band. Intrabar spikes that don't close outside the channel often reverse.
- **No Middle Band:** Unlike Donchian Channels, MMCHANNEL has no middle line. If you need a centerline, use Donchian or compute `(Upper + Lower) / 2` separately.
- **Asymmetric Movement:** Upper and lower bands move independently.
- **Gap Handling:** Overnight gaps immediately adjust the relevant band.
- **Memory Footprint:** The monotonic deque stores (value, index) pairs. Worst case is `2 * period` pairs per deque.
- **Bar Correction:** When `isNew=false`, the indicator must restore prior state before computing.