Class JumpRobustVolatility
SignalEngine) cannot tell a news gap from diffusion: one
headline print enters as r² and reads as a volatility regime shift for
the estimator's whole memory. Bipower variation (Barndorff-Nielsen invalid input: '&'
Shephard, 2004) fixes this with a beautifully simple trick: use the
product of CONSECUTIVE absolute returns, (π/2)·|rₜ|·|rₜ₋₁|,
instead of r². Diffusion moves both factors together, so the product
estimates the same σ²; a single jump inflates only ONE factor of two
neighboring products instead of one whole squared term — its weight in
the estimate collapses.
Both estimators run side by side on time-decayed rates per second:
volPerSqrtSecond() is the jump-robust (bipower) volatility — the
one to feed VolatilityCurve and any model that should read
regimes, not headlines — while rawVolPerSqrtSecond() is the
squared-return volatility, and jumpFraction() is the share of
raw variance the robust estimator attributes to jumps
(1 − BV/RV, clamped to [0,1]).
Gap discipline: a non-finite return or non-positive Δt drops the
sample AND resets the consecutive-return pairing — multiplying across a
feed gap would pair returns that were never neighbors. The first return
after a gap therefore updates only the raw estimator; the bipower leg
resumes one sample later. Irregular sampling is handled exactly: the
two-return product is normalized by √(Δtₜ·Δtₜ₋₁) (each |r|
scales with √ of ITS OWN interval), so event-time feeds — where
activity accelerates precisely when volatility bursts — do not bias
the estimator. Zero allocation per event, single writer, one instance
per symbol.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiondoubleThe share of raw variance attributed to jumps:clamp(1 − bipower/raw, 0, 1).voidonReturn(double ret, long dtNanos) One return observation: the relative mid change over the elapseddtNanos.doubleThe plain squared-return volatility (jumps and all), per √second.longsamples()doubleThe jump-robust volatility, as return per √second — the diffusion component, with jumps down-weighted. 0 until two consecutive valid returns exist.
-
Constructor Details
-
JumpRobustVolatility
public JumpRobustVolatility(long halfLifeNanos) - Parameters:
halfLifeNanos- decay half-life, e.g. 10s =10_000_000_000L
-
JumpRobustVolatility
public JumpRobustVolatility()10-second half-life.
-
-
Method Details
-
onReturn
public void onReturn(double ret, long dtNanos) One return observation: the relative mid change over the elapseddtNanos. Non-finite returns or non-positive gaps drop the sample and break the pairing (see class doc). -
volPerSqrtSecond
public double volPerSqrtSecond()The jump-robust volatility, as return per √second — the diffusion component, with jumps down-weighted. 0 until two consecutive valid returns exist. -
rawVolPerSqrtSecond
public double rawVolPerSqrtSecond()The plain squared-return volatility (jumps and all), per √second. -
jumpFraction
public double jumpFraction()The share of raw variance attributed to jumps:clamp(1 − bipower/raw, 0, 1). Near 0 in pure diffusion, spikes after a discontinuous move, and decays back as the jump washes out of the raw estimator's memory. 0 while either estimator is unlearned. -
samples
public long samples()
-