KELTNER (Keltner Channels)
Keltner Channels use an EMA as the middle line with upper and lower bands offset by a multiple of ATR. They are smoother than Bollinger Bands because ATR is less volatile than standard deviation.
Declaration
function init(ctx) { ctx.indicator('keltner', 'KELTNER', { period: 20, multiplier: 2 }); }
Options
| Option | Type | Default | Description |
|---|---|---|---|
period | number | 20 | EMA and ATR period |
multiplier | number | 2 | ATR multiplier for band width |
Output
Returns an object with three series, accessed via underscore naming:
| Property | Description |
|---|---|
upper | Upper channel (EMA + multiplier x ATR) |
middle | Middle line (EMA) |
lower | Lower channel (EMA - multiplier x ATR) |
Accessing Values
function onBar(ctx, i) { const upper = ctx.ind.keltner_upper[i]; const middle = ctx.ind.keltner_middle[i]; const lower = ctx.ind.keltner_lower[i]; }
Use Cases
Channel Breakout
function onBar(ctx, i) { const close = ctx.series.close[i]; if (close > ctx.ind.keltner_upper[i]) { ctx.order.market('ASSET', 1, { signal: 'buy', reason: 'keltner_breakout' }); } if (close < ctx.ind.keltner_lower[i]) { ctx.order.close('ASSET', { signal: 'sell', reason: 'keltner_breakdown' }); } }
Bollinger-Keltner Squeeze
function init(ctx) { ctx.indicator('bb', 'BBANDS', { period: 20, stdDev: 2 }); ctx.indicator('kc', 'KELTNER', { period: 20, multiplier: 1.5 }); } function onBar(ctx, i) { const bbInside = ctx.ind.bb_lower[i] > ctx.ind.kc_lower[i] && ctx.ind.bb_upper[i] < ctx.ind.kc_upper[i]; // Squeeze: Bollinger Bands inside Keltner = low volatility // Expansion after squeeze = potential strong move }
Calculation
- Middle = EMA(Close, period)
- Upper = Middle + multiplier x ATR(period)
- Lower = Middle - multiplier x ATR(period)
Related
- Bollinger Bands - StdDev-based bands (more reactive)
- ATR - Underlying volatility measure
- Donchian - Price-range channel
indicatorkeltnerchannelvolatilityatrbandsqsl