Files
wickra/docs/wiki/indicators/volume/Indicator-ChaikinOscillator.md
T
kingchenc d2f99efd78 F13c: restructure the indicator catalogue into eight families
The original taxonomy was four classical families plus a statistics group,
with the F1-F12 expansion slotted in as sub-categories. This regroups the
whole 71-indicator catalogue into eight top-level families, each with at
least five members:

  Moving Averages (12), Momentum Oscillators (13), Trend & Directional (9),
  Price Oscillators (5), Volatility & Bands (12), Trailing Stops (5),
  Volume (9), Price Statistics (7).

- Wiki: docs/wiki/indicators/ reorganised into eight family folders; all 71
  indicator pages moved with `git mv`. Every internal cross-link is
  normalised to `../<family>/Indicator-X.md`, each page's `Family` field is
  set to its new family, and two pre-existing `../Indicator-Chaining.md`
  links (should have been `../../`) are corrected. A link check confirms
  every relative wiki link resolves.
- Indicators-Overview.md fully rewritten around the eight families;
  Home.md indicator reference and the README family table follow suit.
- Warmup-Periods.md gains the eight F13 indicators; CHANGELOG records the
  46-indicator expansion (25 -> 71) and the eight-family taxonomy.
- Tests: Node indicators.test.js and Python test_new_indicators.py cover
  all eight new indicators (Node 91/91, Python 117/117 green).

cargo fmt + clippy (core/wickra/data/wasm/node) clean; 508 core tests,
25 data tests and 74 doctests green.
2026-05-22 21:21:56 +02:00

4.7 KiB
Raw Blame History

ChaikinOscillator

Chaikin Oscillator — the MACD of the Accumulation/Distribution Line: a fast EMA of the ADL minus a slow EMA of the ADL.

Quick reference

Field Value
Family Volume
Input type Candle (uses high, low, close, volume)
Output type f64
Output range unbounded around zero
Default parameters fast = 3, slow = 10 (Python)
Warmup period slow
Interpretation Momentum of accumulation/distribution; zero-line crossings are the signal.

Formula

ChaikinOsc_t = EMA(ADL, fast)_t  EMA(ADL, slow)_t

The Adl is an unbounded line that drifts with cumulative volume — useful for its slope but awkward to trade directly. The Chaikin Oscillator applies the MACD construction to it: difference a fast and a slow EMA of the ADL to get a zero-centred momentum reading. Positive values mean short-term accumulation is outrunning the longer trend; negative values mean distribution leads.

Parameters

  • fast — period of the fast EMA on the ADL (classic 3).
  • slow — period of the slow EMA on the ADL (classic 10).

fast must be strictly less than slow. ChaikinOscillator::classic() returns the (3, 10) configuration.

Inputs / Outputs

From crates/wickra-core/src/indicators/chaikin_oscillator.rs:

impl Indicator for ChaikinOscillator {
    type Input = Candle;
    type Output = f64;
    // update(&mut self, input: Candle) -> Option<f64>
}

It is a candle-input indicator (the ADL inside it needs high, low, close, volume). Python's streaming update accepts a 6-tuple or a dict; the batch helper takes high, low, close, volume numpy arrays. Node and WASM expose update(high, low, close, volume) and the matching batch.

Warmup

ChaikinOscillator::classic().warmup_period() == 10. The ADL emits a value from the very first candle, so both EMAs are fed every bar and the slow EMA gates the first output — the warmup is exactly slow.

Edge cases

  • Flat market. A flat candle has zero money-flow volume, so the ADL never moves and both EMAs of the constant-zero series stay at zero — the oscillator sits at 0.0 (flat_market_yields_zero pins this).
  • fast >= slow. Rejected at construction with an error.
  • Reset. osc.reset() clears the ADL and both EMAs.

Examples

Rust

use wickra::{BatchExt, Candle, Indicator, ChaikinOscillator};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut osc = ChaikinOscillator::classic();   // EMA(ADL, 3)  EMA(ADL, 10)
    // A flat market: the ADL never moves, so the oscillator sits at zero.
    let candles: Vec<Candle> = (0..20)
        .map(|i| Candle::new(10.0, 10.0, 10.0, 10.0, 100.0, i).unwrap())
        .collect();
    let out = osc.batch(&candles);
    println!("{:?}", out.last().unwrap());
    Ok(())
}

Output:

Some(0.0)

A flat series produces a flat ADL and therefore a zero oscillator. This matches the flat_market_yields_zero test in crates/wickra-core/src/indicators/chaikin_oscillator.rs.

Python

import numpy as np
import wickra as ta

osc = ta.ChaikinOscillator(3, 10)
n = 20
flat = np.full(n, 10.0)
print(osc.batch(flat, flat, flat, np.full(n, 100.0))[-1])

Output:

0.0

Node

const ta = require('wickra');
const osc = new ta.ChaikinOscillator(3, 10);
const flat = Array(20).fill(10);
const vol = Array(20).fill(100);
const out = osc.batch(flat, flat, flat, vol);
console.log(out[out.length - 1]);

Output:

0

Interpretation

Trade the Chaikin Oscillator like any MACD-style line: a cross above zero is a bullish accumulation signal, a cross below is bearish. Divergence between the oscillator and price is the higher-conviction setup — for example, price making a new high while the oscillator does not is the same warning the raw ADL gives, but packaged as a bounded, zero-centred series.

Common pitfalls

  • Treating the level as meaningful. Only the sign and the slope carry information; the magnitude scales with the instrument's volume.
  • Feeding it scalar prices. It needs the full OHLCV bar.

References

Marc Chaikin's Chaikin Oscillator — the MACD construction applied to his Accumulation/Distribution Line (StockCharts).

See also