Repository navigation
BUG: Use the expected variance path in RiskMetrics2006 forecasts - #885
raashish1601 wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #885 +/- ##
=======================================
Coverage 99.61% 99.61%
=======================================
Files 85 85
Lines 19811 19835 +24
Branches 1588 1591 +3
=======================================
+ Hits 19735 19759 +24
Misses 41 41
Partials 35 35
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
The only failing job is LinuxTest python_311_cython_coverage, which Azure cancelled with "Job cancelled due to worker timeout" during the test step. All the other Linux and Windows jobs and both codecov checks passed. |
bashtage
left a comment
There was a problem hiding this comment.
Not completely sure this is the right fix, even if it is internally consistent.
| components = components.T[start + 1 :] | ||
| for i in range(1, horizon): | ||
| forecasts[:, i] = forecasts[:, 0] | ||
| sigma2 = components @ w |
There was a problem hiding this comment.
I fully agree that this is wrong -- however, the paper suggests that forecasts should be reweighted combinations of the final component values, rather than iterating in the usual GARCH method. It is possible these are equivalent, but it is not obvious at a single look.
There was a problem hiding this comment.
They are the same thing. Let s(t) be the vector of component values at the forecast origin and A = diag(mu) + (1 - mu) w'. Taking expectations of the component update gives E[s(t+j)] = A^j s(t), so the h-step forecast is w' A^(h-1) s(t) = w(h)' s(t) with w(h)' = w' A^(h-1). That is a reweighted combination of the final component values, with w(1) = w and w(h+1) = mu * w(h) + w * sum((1 - mu) * w(h)). The rows of A sum to one, so the weights do too.
This is the form in eq. 15 of Zumbach (arXiv:0901.2275), where the forward variance comes from the conditional expectation of the process equations and the weights from a recursion in mu_k (RM2006 is the linear case, so there is no mean variance term).
In e1757e7 I changed the code to compute it this way so it reads like the paper. The test still checks it against the independent iteration of the expected components, and the two agree to machine precision.
f7c3d42 to
96c23f7
Compare
The analytic forecast repeated the one-step forecast for every horizon, which is only exact for a single EWMA. Iterate the expected values of the EWMA components instead, so multi-step analytic forecasts agree with the simulation forecasts.
The expected components follow a linear recursion, so iterating them is the same as applying horizon-dependent weights to the final component values, which is the form used in the RiskMetrics 2006 papers.
e1757e7 to
cfc8de5
Compare
|
Thanks. These changes merged in #934 |
The analytic multi-step forecast for
RiskMetrics2006repeats the one-step forecast for every horizon. That is only right for a single EWMA. RiskMetrics2006 is a weighted sum of EWMA components with different smoothing parameters, and each component is updated with the squared residual, whose expected value is the combined variance:E[s2_k(t+h+1)] = mu_k E[s2_k(t+h)] + (1 - mu_k) sum_j w_j E[s2_j(t+h)]
So the expected variance drifts toward the long components as the horizon grows, and the flat forecast disagrees with the simulation and bootstrap forecasts of the same model. With a ConstantMean model fit on 2,000 simulated GJR-GARCH returns, the analytic forecast was 1.4% below the simulated one (100,000 paths) at h=2 and 8.3% below at h=10. With this change the two agree to within simulation noise (largest gap 0.2% over 10 horizons).
The change computes the EWMA components at each forecast origin (as the simulation forecast already does) and iterates the recursion above. The one-step forecast is unchanged.
EWMAVariancekeeps its flat forecast, which is exact for a single EWMA.test_rm2006_forecastasserted that every horizon equals the one-step forecast, so I changed it to check the recursion, computed independently from the residuals.arch/tests/univariate/test_variance_forecasting.pypasses, and so do the RiskMetrics2006 cases intest_forecast.py(I ran the rest of the univariate suite only partly, since it is slow without the compiled extensions here). black, isort, ruff and flake8 report nothing new on the changed lines.