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

    Function chaikinVolatility

    • Chaikin Volatility (Marc Chaikin) — the percent rate of change of a smoothed bar range: how much wider (or narrower) the average bar has become over the last rocPeriod bars.

      E = EMA(high − low, period)
      ${output} = 100 × (E[i] − E[i − rocPeriod]) / E[i − rocPeriod]

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

      Chaikin's reading of it: a rising value means the range is expanding, which he associated with tops (panic widens bars), and a slow decline with bottoms (accumulation narrows them). It is a rate, not a level — the number says nothing about whether the market is volatile, only whether it is becoming more so.

      TA-Lib has no Chaikin Volatility, so the oracle is a pandas replication of the definition above with the analytic first-valid bar asserted, and the two forks below are pinned rather than left to a vendor:

      • Plain range, not true range. high − low per Chaikin, through the shared barRangeValues kernel; an overnight gap widens atr and does not widen this. The corpus maps it that way and every published statement of it agrees. There is no range | trueRange knob — that would be two indicators behind a flag (the keltner precedent).
      • The EMA is pond's, first-sample seed, α = 2/(period + 1) — the same recursion ema() runs, through the K2 engine's array door, so this study cannot disagree with ema() inside the package (the macd and trix precedent). TA-Lib would seed on the SMA of the first period values; nothing here is checked against it because there is nothing to check against.
      • period and rocPeriod are separate, both defaulting to 10. Chaikin's own statement uses 10 for both and most vendors expose one number; two options is the honest shape, because the smoothing span and the look-back are different quantities and a caller comparing against a chart that splits them (ChartIQ does) needs to be able to say so.
      • A percent, not a fraction. × 100, matching percentChange whose kernel this composes on — so chaikinVolatility and percentChange cannot drift on the base case or on the zero-base rule.

      The EMA's array door emits once period finite ranges have been consumed, so E first lands on bar period − 1; the rate of change reads a bar rocPeriod back, so the column first lands on period − 1 + rocPeriod — bar 19 at the defaults. Length-preserving.

      • Scale-invariant, and shift-invariant. The range is a difference (so adding a constant to every price leaves it alone) and the reading is a ratio of two ranges (so scaling every price leaves it alone too). Both halves are pinned by property tests — an implementation that dropped the normalisation would keep the shift invariance and lose the scale one.
      • Unbounded, and signed. A range that doubled reads +100; one that halved reads −50. The floor is −100 (a range that fell to zero), the ceiling is not bounded at all.
      • A zero base → undefined, inherited from percentChangeValues rather than restated: percent change off a zero range has no answer, and x/0 would be an infinity withColumn rejects. E[i − rocPeriod] = 0 needs every bar from the series' start to that one to have had no range at all — a halted instrument, reachable and unit-tested. (A negative base still produces a number, per the same kernel's === 0 rule; that only arises if high and low are redirected at columns that cross.)
      • A leading gap shifts the start; an interior gap blanks the bar and the bar rocPeriod later (the rate of change reads a predecessor), and the EMA then carries on — the ema family's skip rule, not the Wilder family's carry-to-the-end.

      Type Parameters

      • S extends SeriesSchema
      • const Output extends string = "chaikinVol"

      Parameters

      Returns TimeSeries<
          readonly [S[0], ValueColumnsForSchema<S>, OptionalNumberColumn<Output>],
      >