ParkinsonVolatility — Parkinson Volatility
תוכן זה אינו זמין עדיין בשפה שלך.
A volatility estimator built from the high-low range rather than closes. Because the range uses more of each bar’s information, it is roughly five times more efficient than the close-to-close estimator — the same accuracy from a fifth of the data.
Signature
ParkinsonVolatility(period, annualization, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | Window. Default 20, bounds 1–400. |
annualization |
int Param or literal | Yes | Bars per year. 252 daily. Bounds 1–100000. |
on= |
symbol | No | Source symbol. Defaults to the trade symbol. Reads high and low. |
Formula
$$ \sigma_P = \sqrt{\frac{A}{4\ln 2}\cdot\frac{1}{n}\sum_i \ln^2!\left(\frac{H_i}{L_i}\right)} \times 100 $$
Warmup
period bars; partial average during the lead-in.
Reading the value
pv.valuepv.value > hv.valueExample
class RangeVsCloseVol(Strategy): """Compare range volatility against close-to-close: a gap between them is trend.""" trade = Symbol() sizing = FixedCapital()
def execute(self): pv = ParkinsonVolatility(20, 252, on=self.trade) hv = HistoricalVolatility(20, 252, on=self.trade) sma = SMA(50, on=self.trade) if pv.value < hv.value and self.trade.close > sma.value and self.trade.is_flat: self.buy(self.trade, reason="Trending, not just noisy") if pv.value > hv.value * 1.5 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="Range churn")Notes
- Michael Parkinson, Journal of Business (1980).
- Assumes no drift and no gaps. It cannot see overnight moves at all, so it understates volatility on gappy instruments — which is exactly why comparing it to the close-to-close estimator is informative.
- Proven by an assert-via-trade run on SPY daily (matched a strategy-side log-range reference to 0.01 on every bar; zero alarm trades).