cultivars.diagnostics.unit_roots#
Unit-root and stationarity tests: the question every model in the package asks first.
A level VAR, a cointegrating system, and a differenced ARMA are answers to one question, whether the series carries a stochastic trend, and the tests here are how that question is put to the data. The difficulty is that under a unit root the least-squares \(t\) ratio on the level does not converge to a normal but to a functional of Brownian motion,
whose quantiles depend on the deterministic terms and sit far to the
left of the normal’s, and that the alternative of interest, a root just
inside the circle, is where every test in the family has least power.
The tests come in two families. The Dickey-Fuller line puts the unit
root under the null: adf() with its augmentation chosen on a
common sample, phillips_perron() with a kernel correction instead
of augmentation, dfgls() on a GLS-detrended series (Elliott,
Rothenberg & Stock 1996), which recovers most of the power the OLS
detrending loses near the null, and ng_perron(), whose \(M\)
statistics keep size under a large negative moving-average root that
inflates the others. kpss() puts stationarity under the null
instead, so that a series both families fail to reject is one the
sample cannot classify, which the record says rather than hides.
zivot_andrews() allows one break at an unknown date, because a
broken trend is the classic way a stationary series is mistaken for a
unit root (Perron 1989). long_run_variance() is the kernel
estimator the corrected tests divide by, exposed on its own.
Two commitments shape the surface. First, the two nulls share one
record. A UnitRootTest carries lower_tail so that
reject reads correctly whichever null the test put up, and a table
of an ADF and a KPSS on the same series reads side by side without the
reader translating tails. Second, a p-value is reported only where one
exists. The Dickey-Fuller law has MacKinnon’s response surface and the
KPSS table is dense enough to interpolate, and those tests carry
p-values; DF-GLS, Ng-Perron, and Zivot-Andrews are known through
asymptotic critical values at three levels and carry pvalue=None,
so their reject reads the table and refuses a level it does not
have, rather than interpolating a number that would look more precise
than it is.
Every trend argument takes "n" (nothing), "c" (constant) or
"ct" (constant and linear trend); KPSS, DF-GLS and Ng-Perron admit
only the last two, and Zivot-Andrews always carries both and takes a
model for the break instead. The trend must include every
deterministic term the alternative would need, since a trending series
tested against a constant alone has no power.
Layout. UnitRootTest is the record, a
TabulatedTest with the trend,
lags, method, and break fields; the seven functions are the producers.
The numerics live in _core: _dickey_fuller_regression runs the
augmented regression and _resolve_dickey_fuller_lags chooses the
augmentation by AIC, BIC, the t-statistic rule, or the modified AIC on
a common sample, with _schwert_max_lags as the ceiling;
_mackinnon_pvalue and _mackinnon_critical_values are the
response surface; _gls_detrend is the Elliott-Rothenberg-Stock
detrending with the local-to-unity constants in _GLS_DETREND_C;
_phillips_perron, _kpss_statistic, and _ng_perron_statistics
compute their statistics, _long_run_variance and
_newey_west_bandwidth the kernel estimate beneath the first two;
_zivot_andrews runs the search over dates; and the KPSS, DF-GLS,
Ng-Perron, and Zivot-Andrews tables are the module’s named constants,
read through _critical_value_table.
References
Dickey, D. A., & Fuller, W. A. (1979). Distribution of the estimators for autoregressive time series with a unit root. Journal of the American Statistical Association, 74(366), 427-431.
Said, S. E., & Dickey, D. A. (1984). Testing for unit roots in autoregressive-moving average models of unknown order. Biometrika, 71(3), 599-607.
Phillips, P. C. B., & Perron, P. (1988). Testing for a unit root in time series regression. Biometrika, 75(2), 335-346.
Kwiatkowski, D., Phillips, P. C. B., Schmidt, P., & Shin, Y. (1992). Testing the null hypothesis of stationarity against the alternative of a unit root. Journal of Econometrics, 54(1-3), 159-178.
Elliott, G., Rothenberg, T. J., & Stock, J. H. (1996). Efficient tests for an autoregressive unit root. Econometrica, 64(4), 813-836.
Ng, S., & Perron, P. (2001). Lag length selection and the construction of unit root tests with good size and power. Econometrica, 69(6), 1519-1554.
Perron, P., & Qu, Z. (2007). A simple modification to improve the finite sample properties of Ng and Perron’s unit root tests. Economics Letters, 94(1), 12-19.
Zivot, E., & Andrews, D. W. K. (1992). Further evidence on the great crash, the oil-price shock, and the unit-root hypothesis. Journal of Business & Economic Statistics, 10(3), 251-270.
Perron, P. (1989). The great crash, the oil price shock, and the unit root hypothesis. Econometrica, 57(6), 1361-1401.
MacKinnon, J. G. (1994). Approximate asymptotic distribution functions for unit-root and cointegration tests. Journal of Business & Economic Statistics, 12(2), 167-176.
MacKinnon, J. G. (1996). Numerical distribution functions for unit root and cointegration tests. Journal of Applied Econometrics, 11(6), 601-618.
Stock, J. H. (1994). Unit roots, structural breaks and trends. In Handbook of Econometrics, Volume 4 (pp. 2739-2841). North-Holland.
Example
The two families agree on a random walk and on white noise, from opposite tails; a test known only through its table carries no p-value and reads the table:
>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> walk = np.cumsum(rng.standard_normal(300))
>>> adf(walk).reject(), kpss(walk).reject()
(False, True)
>>> noise = rng.standard_normal(300)
>>> adf(noise).reject(), kpss(noise).reject()
(True, False)
>>> dfgls(walk).pvalue, dfgls(walk).reject(alpha=0.05)
(None, False)
Classes#
Verdict of a unit-root or stationarity test. |