Class RangeVolatility
java.lang.Object
com.quantfinlib.volatility.RangeVolatility
RANGE-BASED volatility estimators — the free lunch hiding inside every
OHLC bar: the high-low range carries far more information about the
day's variance than the close alone, so a range estimator reaches a
given precision with several times fewer bars than close-to-close.
Four classics, in increasing order of what they use:
- Parkinson (1980) — range only:
sigma^2 = mean( ln(H/L)^2 ) / (4 ln 2). About 4.9x more efficient than close-to-close under driftless GBM; biased UP by drift (it books trend as range) and DOWN by discrete sampling (the observed high underestimates the true high). - Garman-Klass (1980) — range plus open/close:
sigma^2 = mean( 0.5 ln(H/L)^2 - (2 ln 2 - 1) ln(C/O)^2 ). Roughly 7.4x efficient; still assumes zero drift. - Rogers-Satchell (1991) — drift-INDEPENDENT:
sigma^2 = mean( ln(H/C) ln(H/O) + ln(L/C) ln(L/O) ). The one to reach for on trending series. - Yang-Zhang (2000) — adds the OVERNIGHT gap the others
ignore:
sigma^2 = sigma_o^2 + k sigma_c^2 + (1-k) sigma_rs^2withsigma_o^2the sample variance of open-over-prior-close log returns,sigma_c^2the sample variance of close-over-open log returns,sigma_rs^2the Rogers-Satchell term, andk = 0.34 / (1.34 + (m+1)/(m-1))overmperiods — the weighting that minimizes the estimator's variance. Drift independent AND jump-aware; the practical default for daily bars on markets that close.
All methods return ANNUALIZED volatility (not variance):
sqrt(perPeriodVariance * periodsPerYear), with the annualization
factor supplied by the caller (252 for daily bars, 52 for weekly, ...) —
this class does not choose your calendar. Estimates are computed over
the full arrays passed in; slice (BarSeries.slice(int, int)) for rolling
windows. Static, deterministic, research lane.
-
Method Summary
Modifier and TypeMethodDescriptionstatic doublegarmanKlass(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Garman-Klass estimator, annualized.static doublegarmanKlass(BarSeries bars, double periodsPerYear) Garman-Klass over a wholeBarSeries.static doubleparkinson(double[] high, double[] low, double periodsPerYear) Parkinson estimator from highs/lows, annualized.static doubleParkinson over a wholeBarSeries.static doublerogersSatchell(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Rogers-Satchell (drift-independent) estimator, annualized.static doublerogersSatchell(BarSeries bars, double periodsPerYear) Rogers-Satchell over a wholeBarSeries.static doubleyangZhang(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Yang-Zhang estimator, annualized.static doubleYang-Zhang over a wholeBarSeries.
-
Method Details
-
parkinson
public static double parkinson(double[] high, double[] low, double periodsPerYear) Parkinson estimator from highs/lows, annualized. -
parkinson
-
garmanKlass
public static double garmanKlass(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Garman-Klass estimator, annualized. -
garmanKlass
-
rogersSatchell
public static double rogersSatchell(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Rogers-Satchell (drift-independent) estimator, annualized. -
rogersSatchell
-
yangZhang
public static double yangZhang(double[] open, double[] high, double[] low, double[] close, double periodsPerYear) Yang-Zhang estimator, annualized. Uses bars1..n-1as the estimation periods (bar 0 only supplies the prior close for the first overnight return), so it needs at least 3 bars for the sample variances to exist. -
yangZhang
-