Direct answer
Keltner Channels are calculated by drawing three lines around price: a middle line that is typically a moving average, and two outer bands that are offset from the middle line by a multiple of the Average True Range (ATR). The core requirement is time-series price data so you can compute both the moving average and ATR, then combine them using fixed parameters (periods and a multiplier).
Mechanism and definition
Components
- Middle line (basis): usually a moving average of the chosen price series (for example, closing prices). A moving average “smooths” data by averaging the most recent N observations.
- Volatility measure: ATR estimates average price movement over a lookback window. ATR uses the True Range (TR) each period, which reflects how far price moved in a way that accounts for gaps relative to the prior close.
- Band construction: the upper and lower bands are built by adding and subtracting a volatility-based distance from the middle line.
Step-by-step formula (generic form)
Let:
- (P_t) be the selected input price at time (t) (commonly the close).
- (MA_t) be the moving average of (P_t) over (m) periods (the “basis” period).
- (ATR_t) be the ATR at time (t) over (n) periods.
- (k) be the band multiplier (a scaling factor for how wide the channels are).
Then the Keltner Channel lines are typically:
- Upper band: (Upper_t = MA_t + k \cdot ATR_t)
- Middle line: (Middle_t = MA_t)
- Lower band: (Lower_t = MA_t - k \cdot ATR_t)
How ATR is computed (what data you need)
To compute ATR you first compute True Range (TR_t). For each period (t), the True Range is based on:
- current high (H_t)
- current low (L_t)
- prior close (C_{t-1})
A common definition is: [ TR_t = \max\big(H_t - L_t,\ |H_t - C_{t-1}|,\ |L_t - C_{t-1}|\big) ] Then ATR is typically an average of (TR_t) over (n) periods (often using a moving-average method such as a Wilder-style smoothing, but different implementations can use different averaging methods). This means two providers can show different ATR values even with the same (n) if their smoothing differs.
Moving-average choice matters
Even within the “basis is a moving average” idea, there are multiple choices:
- which price series is used (close vs. typical price vs. other combinations)
- the moving-average type (simple vs. exponential, etc.)
- how the moving average is initialized at the start of the dataset
These choices change (MA_t), which shifts the entire channel up or down.
Evidence or example you can reproduce
Below is a reproducible numerical setup. It does not use live prices; it shows the dependencies.
Assumptions
- Time step: one bar per period (for example, one candle).
- Input series per period (t): (H_t, L_t, C_t).
- Middle line uses a moving average of closes: (MA_t = SMA_m(C_t)) (choose (m)).
- ATR is computed from (TR_t) and averaged over (n) periods.
- Multiplier (k) is fixed.
Calculation flow
- Compute TR for each period (t\ge 2):
- (TR_t = \max(H_t-L_t, |H_t-C_{t-1}|, |L_t-C_{t-1}|))
- Compute ATR at each period where enough data exists:
- (ATR_t = \text{average of } TR \text{ over the last } n \text{ periods})
- Compute middle line:
- (MA_t = \text{moving average of } C \text{ over } m \text{ periods})
- Compute bands:
- (Upper_t = MA_t + k\cdot ATR_t)
- (Lower_t = MA_t - k\cdot ATR_t)
What you should check when you compare results
If you implement this in a spreadsheet or script and compare to a charting tool, common mismatches come from:
- using a different price for the basis
- using a different ATR averaging method (simple average vs. Wilder-style smoothing)
- an ATR offset applied at a different point in time (for example, whether (ATR_t) uses the current bar or ends at the prior bar)
- different definitions of true range with special handling of missing data
Limitations and failure modes
1) Different conventions produce different channels
Keltner Channels are not a single universal formula with one fixed parameter set. The structure is consistent (basis ± scaled ATR), but implementations can differ in:
- basis price (close vs. other)
- moving-average type
- ATR smoothing method
- bar alignment and initialization
So if two sources display different bands, it may be due to calculation conventions rather than “incorrect” values.
2) Early periods are unstable or undefined
At the beginning of the dataset, you may not have enough bars to compute:
- a full moving average over (m) periods
- a full ATR over (n) periods
Many charting tools output partial values, delay output, or initialize averages differently. Any comparison should focus on the region where both (MA_t) and (ATR_t) are fully formed.
3) Channel width reflects volatility, not direction
Even though bands react to volatility, they do not inherently “predict” outcomes. A wider band means the volatility measure is larger; it does not tell you which direction price will move.
4) Data quality and bar construction affect TR and ATR
ATR depends on (H_t), (L_t), and the prior close (C_{t-1}). If your input data has:
- missing or corrected highs/lows
- different session cutoffs
- time zone shifts
then (TR_t) changes, which changes ATR and therefore the channel width.
Verification and next question
To verify your own calculation, pick one dataset and explicitly write down your conventions: the basis (which moving average, which price series, and (m)), the ATR method (definition of TR and averaging method over (n)), and the multiplier (k). Then compute TR, compute ATR, compute the basis, and finally compute (Upper_t) and (Lower_t).
If you want to go further, a useful next question is how changing (m), (n), or (k) changes the bands’ responsiveness and width. That can be tested by re-running the same data with different parameter values and observing how quickly (Upper_t) and (Lower_t) expand or contract over time.