Repository navigation
Conversation
Add NGARCH(p, o, q), the nonlinear asymmetric GARCH of Engle and Ng (1993), which
rugarch calls NAGARCH,
sigma2[t] = omega + sum_i alpha[i] (e[t-i] - theta[i] sigma[t-i])**2
+ sum_j beta[j] sigma2[t-j]
with o <= p, as in APARCH. A positive theta is the leverage effect, the sign
convention of rugarch (Engle and Ng write +gamma sigma and expect gamma < 0).
The recursion, ngarch_recursion, and NGARCHUpdater are implemented in Cython and in
Python with numba, so that ARCHInMean works with the process. The pre-sample shock
term is alpha (1 + theta**2) times the backcast. Analytic forecasts are exact at
every horizon, since E[(z - theta)**2] = 1 + theta**2 for any standardized
distribution. Estimation uses the linear constraint sum(alpha) + sum(beta) < 1, as
APARCH does, and not the stationarity condition sum(alpha (1 + theta**2)) +
sum(beta) < 1, which is not linear. The process is available as vol="ngarch" in
arch_model.
Tests compare the recursion with an independent NumPy implementation and with the
variances, log-likelihoods and forecasts of rugarch 1.5-6, the Cython and Python
implementations with each other, the analytic forecasts with an independent forecast
recursion and with simulated paths, and the estimates with the parameters of
simulated data for normal, Student's t and skew t errors.
xref #636
Add NGARCH to the API reference, to the list of volatility processes in the theoretical background with the reference of Engle and Ng (1993), and a section to the volatility process page that states the model, the sign convention of theta, the difference between the persistence and the constraint that is used in estimation, and the exact analytic forecasts. xref #636
| self.q: int = _check_count("q", q, 0) | ||
| if self.o > self.p: | ||
| _fail(ValueError, "o", f"an integer <= p ({self.p})", _describe(o)) | ||
| self._num_params = 1 + self.p + self.o + self.q |
| if self.o > self.p: | ||
| _fail(ValueError, "o", f"an integer <= p ({self.p})", _describe(o)) | ||
| self._num_params = 1 + self.p + self.o + self.q | ||
| self._name = "NGARCH" |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #966 +/- ##
==========================================
+ Coverage 98.95% 98.97% +0.02%
==========================================
Files 136 137 +1
Lines 30043 31091 +1048
Branches 2331 2404 +73
==========================================
+ Hits 29729 30773 +1044
- Misses 256 258 +2
- Partials 58 60 +2
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:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Target 9.1: merge after v9.0.0 is tagged. Closes #636.
Adds
arch.univariate.NGARCH(p=1, o=1, q=1)(o <= p): the nonlinear asymmetric GARCH ofEngle and Ng (1993), which rugarch calls NAGARCH.
Sign convention: theta > 0 is the leverage effect. It was settled from the NBER working
paper (w3681), whose estimated model reads (e - 0.2683 sqrt(h))^2, and it matches rugarch's
eta21. The class Notes explain the naming clash with Higgins and Bera (1992).What is included:
ngarch_recursionwith a numba/Python twin and a.pyistub.NGARCHUpdater, soARCHInMeanworks with NGARCH, including pickling.arch_model(vol="ngarch").odefaults to 0 as for everyvol, soo=1gives theshift.
phi = sum alpha (1 + theta^2) + sum beta, for any standardized distribution, because
E[(z - theta)^2] = 1 + theta^2.
simulate, and the crash guards.The Notes and the docs example tell users to check the stationarity condition
sum(alpha (1 + theta^2)) + sum(beta) < 1.
Validation: rugarch 1.5-6 on R 4.6.1,
fGARCH/NAGARCH.with matched initial values. rugarch's fGARCH filter adds an undocumented 1e-6 inside
(z - eta)^2. That was confirmed on three parameter sets and is accounted for.
validated against an independent NumPy recursion and simulation instead.
Tests:
test_ngarch.py(154): the recursion against NumPy for 7 orders; Cython against numbaagainst Python; theta = 0 equals GARCH; the updaters against the recursion.
skew-t), and parameter recovery for (1,1,1), (2,1,1) and (2,2,1).
arch_model,fixandARCHInMeanintegration.integer-input lists.
Python 3.10. numpydoc lint 0, and the docs build has no new warnings.
For review:
arch_model(vol="ngarch")defaultoto 1?Thanks to @itsNH98 for the request.
🤖 Generated with Claude Code