Skip to content

ENH: Add PreWhitenedRecolored (VAR-HAC and PWRC) long-run covariance - #874

Open
WatchTree-19 wants to merge 4 commits into
bashtage:mainfrom
WatchTree-19:feat/prewhitened-recolored
Open

WatchTree-19 wants to merge 4 commits into
bashtage:mainfrom
WatchTree-19:feat/prewhitened-recolored

Conversation

@WatchTree-19

Copy link
Copy Markdown
Contributor

This picks up #363 and the varhac branch, the VAR-HAC and pre-whitened recolored items on the roadmap in #351. The first commit is your 2020 var.py, test_var.py and covariance_data.py exactly as they were on the branch, so the history shows where it came from. The second ports it to current main and fixes the recoloring step.

Port:

  • arch._typing, functools.cached_property, arch.vendor._decorators.Appender, current type hints, np.int in the tests.
  • ZeroLag added to kernel.py for kernel=None, but kept out of KERNELS, so the kernel list used by arch.unitroot is unchanged. var.py builds its own name lookup from arch.covariance.kernel, normalised the same way as _check_kernel, so there is no import from arch.unitroot.
  • The fixture is registered in arch/conftest.py, the debug to_csv in covariance_data.py is removed, and the "Vector AR-based Estimators" section is in the docs. The Notes TODO is replaced and there is a runnable example.

Fix: cov recolored kern_cov.short_run, so the kernel and bandwidth had no effect on the long run. It now recolors the kernel long run of the VAR residuals, D @ Omega_e @ D.T, keeping your T / (T - N) scale. With bandwidth=0 or kernel=None nothing changes, which is why the existing tests passed. For a 3-series VAR(3) sample with lags=2, QuadraticSpectral and bandwidth 7.5, the [0, 0] element was 159.64 against 120.49 from a direct computation.

Tests: test_recolored_kernel_long_run fits the VAR with lstsq, runs the kernel on the residuals and recolors, over all kernels, two bandwidths and center. 576 cases fail before the fix and pass after. arch/tests/covariance and arch/tests/unitroot pass (5783 passed, 2 skipped). black, isort and ruff are clean.

Cross-check with R sandwich (univariate, VAR(1) prewhitening, Bartlett, adjust=FALSE, sandwich=FALSE): identical to about 1e-14 once R's bandwidth is taken as arch's plus one and the scale is converted (arch equals R times n/(n-2) here).

A few things I left as they were and would value your view on:

  • short_run is the residual covariance rather than the covariance of x, so long_run = short_run + oss + oss' does not hold even at bandwidth 0.
  • The one-sided terms are model implied and do not use the kernel, so with a positive bandwidth they no longer tie to long_run. They are documented as such for now.
  • bandwidth reports the value computed on x, while the kernel runs on the residuals.
  • df_adjust is accepted but the kernel is built with df_adjust=0 and the fixed T / (T - N) scale is used.

Happy to change any of these whichever way you prefer.

bashtage and others added 2 commits September 27, 2026 20:32
Files from the varhac branch (6b1cc78) as of April 2020.
… long run

Port arch.covariance.var to current main: arch._typing, functools.cached_property,
arch.vendor._decorators.Appender and modern type hints. Add a ZeroLag kernel used
for VAR-HAC (kernel=None). ZeroLag is not added to KERNELS so the kernel names
accepted by arch.unitroot are unchanged. Kernel names are normalized in the same
way as arch.unitroot._shared._check_kernel.

Recolor the kernel long-run covariance of the VAR residuals, D Omega_e D', as in
Andrews & Monahan (1992). The previous code recolored the residual short-run
covariance, so the kernel and bandwidth had no effect on the long run. Add a
regression test that computes the recolored long run directly for positive
bandwidths.

Document the prewhitening, lag selection, kernel and recoloring steps and what
each returned covariance contains, add examples, register the covariance_data
fixture and add the VAR-based estimators to the docs.
Comment thread arch/covariance/var.py Fixed
Comment thread arch/tests/covariance/test_var.py Fixed
@codecov

codecov Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.56%. Comparing base (88ffcf8) to head (d22479c).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #874      +/-   ##
==========================================
+ Coverage   99.54%   99.56%   +0.01%     
==========================================
  Files          78       81       +3     
  Lines       15847    16364     +517     
  Branches     1296     1358      +62     
==========================================
+ Hits        15775    16292     +517     
  Misses         38       38              
  Partials       34       34              
Flag Coverage Δ
adder 99.52% <100.00%> (+0.01%) ⬆️
subtractor 99.52% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Adds tests for kernel=None against a direct D Sigma_e D' computation, the
ZeroLag kernel, the bandwidth check when kernel is None, the error raised
for a nonstationary VAR, and sample_autocov without centering.

This branch has not been deployed

No deployments
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.

3 participants