Keltner Channel wraps an Exponential Moving Average (EMA) with bands based on Average True Range (ATR). The middle band tracks trend direction via EMA smoothing; the upper and lower bands expand and contract with market volatility. Unlike Bollinger Bands that use standard deviation (sensitive to outliers), Keltner uses ATR—a volatility measure designed specifically for price movement that includes gaps.
Chester W. Keltner introduced the original Keltner Channel in his 1960 book "How to Make Money in Commodities." His version used a 10-period Simple Moving Average of the "typical price" (HLC/3) with bands at the 10-period average range.
Linda Bradford Raschke modernized the formula in the 1980s, replacing SMA with EMA for smoother trend following and swapping average range for Average True Range to properly account for gaps. Most modern implementations—including this one—follow Raschke's formulation with a 20-period EMA and 2× ATR width.
The PineScript reference algorithm adds warmup compensation: instead of the traditional EMA formula that converges slowly from the first value, it tracks cumulative weighted sums to produce accurate values even during warmup. This implementation replicates that approach for both EMA and ATR (via RMA/Wilder smoothing).
where $S$ is the cumulative weighted sum, $W$ is the cumulative weight, and $P$ is the close price. The division by $W_t$ compensates for the geometric decay during warmup, producing accurate values from the first bar rather than requiring period bars to converge.
### 2. True Range
True Range captures the full price movement including gaps:
$$
\text{TR}_t = \max\begin{cases}
H_t - L_t \\
|H_t - C_{t-1}| \\
|L_t - C_{t-1}|
\end{cases}
$$
where $H$ is high, $L$ is low, and $C$ is close. The first bar uses $H_0 - L_0$ (no previous close available).
### 3. Average True Range (via RMA)
ATR uses Wilder's RMA smoothing with warmup compensation:
Price spending extended time outside the bands indicates strong trend momentum (continuation) or potential exhaustion (reversal), depending on context.
Skender's implementation uses a different warmup approach (SMA seeding for initial values), causing 2-4% divergence during the first ~period bars. After warmup, values converge within floating-point tolerance.
1.**Warmup Period**: Keltner requires `period × 2` bars before `IsHot` becomes true. The ATR component needs its own warmup on top of the EMA warmup. Using the indicator before full warmup produces less accurate values (though warmup compensation minimizes this).
2.**ATR vs. Standard Deviation**: Keltner uses ATR (absolute range including gaps); Bollinger uses standard deviation (statistical dispersion). They're not interchangeable—ATR is more stable for gap-heavy instruments like futures or weekend-gapping equities.
3.**RMA vs. EMA for ATR**: True ATR uses Wilder's RMA smoothing ($\alpha = 1/\text{period}$), not EMA ($\alpha = 2/(\text{period}+1)$). Using EMA for ATR produces faster-reacting but less smooth bands.
4.**Multiplier Sensitivity**: The default multiplier of 2.0 places bands at ±2 ATR. Changing to 1.5 or 3.0 dramatically alters signal frequency. Backtest your multiplier choice—don't assume the default is optimal.
5.**Gap Handling**: ATR explicitly handles gaps via true range. On gap-up, TR includes $|H_t - C_{t-1}|$, expanding the channel. This is intentional—gaps represent volatility that SMA-based channels ignore.
6.**Memory Footprint**: The implementation stores minimal state—just the running sums/weights for EMA and ATR. Approximately 64 bytes per instance. For 5,000 symbols, budget ~320 KB.
7.**Bar Correction (isNew=false)**: When correcting the current bar, the indicator restores the previous state and recalculates. State consists of 6 scalar values—efficient to copy and restore.