documentation/cookbook/sql/finance/keltner-channels.md
Keltner Channels are volatility-based bands set above and below an EMA. Unlike Bollinger Bands which use standard deviation, Keltner Channels use Average True Range (ATR), making them less sensitive to sudden price spikes.
You want volatility bands that adapt to market conditions but are smoother than Bollinger Bands. Bollinger Bands can expand rapidly on single large moves, while Keltner Channels respond more gradually to sustained volatility changes.
DECLARE
@symbol := 'EURUSD',
@lookback := '$now - 1M..$now'
WITH with_prev AS (
SELECT
timestamp,
symbol,
high,
low,
close,
lag(close) OVER (PARTITION BY symbol ORDER BY timestamp) AS prev_close
FROM market_data_ohlc_15m
WHERE symbol = @symbol
AND timestamp IN @lookback
),
with_tr AS (
SELECT
timestamp,
symbol,
high,
low,
close,
greatest(
high - low,
abs(high - prev_close),
abs(low - prev_close)
) AS tr
FROM with_prev
WHERE prev_close IS NOT NULL
),
with_indicators AS (
SELECT
timestamp,
symbol,
close,
avg(close, 'period', 20) OVER (PARTITION BY symbol ORDER BY timestamp) AS ema20,
avg(tr, 'period', 20) OVER (PARTITION BY symbol ORDER BY timestamp) AS atr
FROM with_tr
)
SELECT
timestamp,
symbol,
round(close, 5) AS close,
round(ema20, 5) AS middle,
round(ema20 + 2 * atr, 5) AS upper,
round(ema20 - 2 * atr, 5) AS lower
FROM with_indicators
ORDER BY timestamp;
The query:
When Bollinger Bands move inside Keltner Channels, it signals extremely low volatility (a "squeeze"). See the Bollinger BandWidth recipe for measuring squeeze conditions.
:::info Related documentation