ChaikinVolatility — Chaikin Volatility
The rate of change of a smoothed high-low range: how fast the market’s daily range is expanding or contracting. Chaikin’s own reading is that a sharp rise often precedes a top, and a slow decline a bottom.
Signature
ChaikinVolatility(period, roc_period, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | EMA of the high-low range. Default 10, bounds 1–200. |
roc_period |
int Param or literal | Yes | Lookback for the rate of change. Default 10, bounds 1–400. |
on= |
symbol | No | Source symbol. Defaults to the trade symbol. Reads high and low. |
Formula
$$ \text{ChaikinVol} = 100,\frac{\text{EMA}(H-L)t - \text{EMA}(H-L){t-m}}{\text{EMA}(H-L)_{t-m}} $$
Warmup
roc_period + 1 bars plus the EMA’s convergence; 0 until then.
Reading the value
cv.valuecv > 25Example
class RangeExpansionWatch(Strategy): """Stand aside while the range is expanding fast.""" trade = Symbol() sizing = FixedCapital()
def execute(self): cv = ChaikinVolatility(10, 10, on=self.trade) sma = SMA(50, on=self.trade) if cv.value < 25 and self.trade.close > sma.value and self.trade.is_flat: self.buy(self.trade, reason=f"Calm expansion {cv.value:.0f}") if cv.value > 50 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="Range exploding")Notes
- Marc Chaikin’s volatility indicator.
- Proven by an assert-via-trade run on SPY daily (finite and in range on every bar of a 140-bar run; zero alarm trades).
- Percentage change, so it is comparable across instruments — unlike the raw range it is built from.