Skip to content

Add Yang Zhang Volatility (YZV) indicator#9389

Closed
claygeo wants to merge 3 commits intoQuantConnect:masterfrom
claygeo:feature-8145-yang-zhang-volatility
Closed

Add Yang Zhang Volatility (YZV) indicator#9389
claygeo wants to merge 3 commits intoQuantConnect:masterfrom
claygeo:feature-8145-yang-zhang-volatility

Conversation

@claygeo
Copy link
Copy Markdown

@claygeo claygeo commented Apr 12, 2026

Summary

Implements the Yang Zhang (2000) drift-independent volatility estimator, the most efficient known estimator of historical volatility for financial time series. Closes #8145.

New indicator: YangZhangVolatility combines three variance components with an optimal weighting factor:

  • Overnight variance σ²_o = Var(ln(Open_i / Close_{i-1}))
  • Intraday variance σ²_c = Var(ln(Close_i / Open_i))
  • Rogers-Satchell variance σ²_RS = (1/n) Σ[ln(H/C)·ln(H/O) + ln(L/C)·ln(L/O)]
  • Combined: σ²_YZ = σ²_o + k·σ²_c + (1-k)·σ²_RS where k = 0.34 / (1.34 + (n+1)/(n-1))

Files changed:

  • Indicators/YangZhangVolatility.cs — New indicator extending BarIndicator, IIndicatorWarmUpPeriodProvider. Uses 5 internal Sum sub-indicators for O(1) rolling computation. Guards zero/negative prices and uninitialized state.
  • Algorithm/QCAlgorithm.Indicators.csYZV() helper method (same pattern as RSV())
  • Tests/Indicators/YangZhangVolatilityTests.cs — Extends CommonIndicatorTests<IBaseDataBar> with hand-computed verification test (YzvComputesCorrectly)
  • Tests/TestData/spy_with_yzv.csv — 500-row SPY reference data generated with independent Python implementation

Design decisions

  • WarmUpPeriod = period + 1: First bar is a seed (stores _previousClose), computation starts on bar 2, IsReady at bar period+1.
  • Sample variance for overnight/intraday, population mean for RS: Matches the Yang Zhang (2000) paper formulation.
  • Math.Max(0m, yzVariance) before sqrt: Prevents NaN from floating-point rounding. Matches Variance.cs convention.
  • <= 0 guards on all OHLC prices and _previousClose: Prevents Math.Log of zero/negative values producing Infinity/NaN.
  • Period >= 2 validation: Constructor throws ArgumentOutOfRangeException to prevent divide-by-zero in (period - 1).

Test Coverage

All 8 code paths tested (100%):

  • Constructor validation, seed bar, _previousClose guard, not-ready state, full computation, rolling window (500 bars via CSV), and Reset.

Test plan

  • All NUnit tests pass (CommonIndicatorTests suite + YzvComputesCorrectly)
  • CSV reference data matches Python-generated expected values
  • Edge cases: zero prices, negative prices, period=2, reset mid-stream

Plan Completion

13/13 plan items DONE (1 CHANGED: <= 0 guards instead of == 0). All files created, all specifications met.

Reference

Yang, D. and Zhang, Q. (2000). "Drift Independent Volatility Estimation Based on High, Low, Open, and Close Prices." Journal of Business, 73(3), 477-491.

claygeo added 3 commits April 12, 2026 14:01
Implements the Yang Zhang (2000) drift-independent volatility estimator,
which combines overnight returns variance, intraday (close-to-open)
returns variance, and Rogers-Satchell volatility using an optimal
weighting factor k = 0.34 / (1.34 + (n+1)/(n-1)).

This is the most efficient known estimator of historical volatility
for financial time series, producing tighter estimates than close-to-close
or Parkinson estimators with the same amount of data.

Includes unit tests with reference data and hand-computed verification.

Closes QuantConnect#8145
- Reject period < 2 (division by zero in k formula)
- Guard against zero/negative prices (prevents NaN from Math.Log)
- Guard against _previousClose <= 0 (prevents Infinity poisoning)
- Remove unnecessary using directive
Adds tests for minimum period (2), flat market (zero returns),
large overnight gap (20% gap up), invalid period throws, and
reset-then-continue producing identical results.
@Martin-Molinero
Copy link
Copy Markdown
Member

Closing for now until previous PR is approved and merged #9388

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Yang Zhang Volatility

2 participants