@pond-ts/financial API Reference
    Preparing search index...

    Function keltner

    • Keltner Channel — a moving average of typical price with bands a multiple of the average true range away:

      middle = MA((high + low + close) / 3, period)     ${prefix}Middle
      upper = middle + multiplier × ATR(atrPeriod) ${prefix}Upper
      lower = middle − multiplier × ATR(atrPeriod) ${prefix}Lower

      Appends three columns. Reads high, low and close, each named by an option defaulting to its DEFAULT_OHLCV name (the atr precedent).

      There are two in circulation and they are not close to each other:

      • Keltner's own (1960): a 10-bar simple average of typical price, bands at ±1 × the 10-bar simple average of the bar's plain high − low range.
      • The modern form (Linda Bradford Raschke's restatement, and what ChartIQ, StockCharts and TradingView all default to): a 20-bar EMA of typical price, bands at ±2 × ATR(10)true range, Wilder- smoothed, so an overnight gap widens the channel.

      This study ships the modern formperiod 20, atrPeriod 10, multiplier 2, maType 'ema' — because it is what every charting package a caller is likely to be comparing against draws. The original is a call away ({ period: 10, atrPeriod: 10, multiplier: 1, maType: 'sma' }) apart from one deliberate delta: the half-width is ATR, never the plain range, so the original cannot be reproduced exactly. Plain range is not a quantity this package computes anywhere, and adding a range | trueRange knob to recover a 1960 convention nobody's chart draws would be a knob with one useful value. Said here rather than left to be discovered from a chart that doesn't line up.

      maType is the shared MaType menu, so 'sma', 'wma', 'smma' and the rest are all available on the centre line; TA-Lib has no Keltner to arbitrate, and the oracle is a pandas replication reusing the same true-range and typical-price definitions atr and vwap already ship.

      The centre starts at the MA's own first bar (period − 1 for the window types on gap-free input, later for the composed ones — see movingAverageValues); the ATR at bar atrPeriod. The bands therefore start at the later of the two, max(centre, atr), and the centre is emitted where it is genuinely defined rather than being masked back to the bands — the same per-column warm-up macd uses for its line. At the defaults that is bar 19 for all three (the EMA's 19 beats the ATR's 10); at { period: 5, atrPeriod: 20 } the centre lands at bar 4 and the bands at bar 20.

      • In the units of the price, like atr and donchian: scaling every bar scales the whole channel. It does not normalise.
      • A leading gap shifts the start rather than emptying the study: the MA steps over its input's warm-up (so Keltner over another study's output starts late), and so does the Wilder seed.
      • An interior gap is the Wilder asymmetry, and the two halves of this study genuinely differ: the ATR propagates it to the end (a recursion has no state to carry across a hole), while the centre line follows its own maType's rule — window types recover, the ema family skips the bar and carries on, smma and kama propagate. So a hole past the warm-up leaves the centre drawn and the bands blank at the defaults. Neither answer is fixable here; a caller who needs continuity across interior gaps fills before smoothing.
      • No division anywhere, so there is no zero-denominator case: a flat stretch gives ATR = 0 and a zero-width channel, which is the honest reading — and since [PND-BBFLAT] the same one bollinger gives at σ = 0.

      Type Parameters

      • S extends SeriesSchema
      • const Prefix extends string = "kc"

      Parameters

      Returns TimeSeries<
          readonly [
              S[0],
              ValueColumnsForSchema<
                  readonly [
                      S[0],
                      ValueColumnsForSchema<
                          readonly [
                              S[0],
                              ValueColumnsForSchema<S>,
                              OptionalNumberColumn<`${Prefix}Middle`>,
                          ],
                      >,
                      OptionalNumberColumn<`${Prefix}Upper`>,
                  ],
              >,
              OptionalNumberColumn<`${Prefix}Lower`>,
          ],
      >