phillips_perron#

cultivars.diagnostics.unit_roots.phillips_perron(endog, *, trend='c', kernel='bartlett', bandwidth=None)[source]#

Phillips-Perron \(Z_t\) test of a unit root.

The un-augmented Dickey-Fuller \(t\) is corrected with a kernel estimate \(\hat\lambda^2\) of the long-run variance of the residuals,

\[Z_t = \sqrt{\frac{\hat\sigma^2}{\hat\lambda^2}}\; t_{\gamma} - \frac{\hat\lambda^2 - \hat\sigma^2}{2\hat\lambda} \Bigl(T^{-2} \sum_t \tilde y_{t-1}^2\Bigr)^{-1/2},\]

so serial correlation is handled nonparametrically rather than by adding lags. The corrected statistic follows the same Dickey-Fuller law, and MacKinnon’s p-value applies. The correction is exact in the limit but is known to over-reject badly under a large negative moving-average root at any practical sample size, which is the case the ADF augmentation and the Ng-Perron tests handle better.

Parameters:
  • endog (ArrayLike) – The series, (T,).

  • trend (str) – "n", "c" or "ct".

  • kernel (str) – "bartlett" or "quadratic-spectral".

  • bandwidth (float | None) – Kernel bandwidth; None for Newey-West’s rule \(\lfloor 4 (T / 100)^{2/9} \rfloor\) (Bartlett) or Andrews’ plug-in (quadratic spectral).

Return type:

UnitRootTest

Returns:

The UnitRootTest named "Phillips-Perron"; lags reports the bandwidth used and method the kernel.

Raises:

See also

  • adf() – the parametric correction, more robust to moving-average errors.

  • ng_perron() – the same idea with an autoregressive spectral estimate and GLS detrending, which fixes the size problem.

  • long_run_variance() – the kernel estimator on its own.

References

Phillips, P. C. B., & Perron, P. (1988). Testing for a unit root in time series regression. Biometrika, 75(2), 335-346.

Newey, W. K., & West, K. D. (1994). Automatic lag selection in covariance matrix estimation. Review of Economic Studies, 61(4), 631-653.

Example

The same verdicts as ADF on the same series, with the bandwidth where the augmentation would be:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> walk = np.cumsum(rng.standard_normal(300))
>>> test = phillips_perron(walk)
>>> test.reject(), test.lags, test.method
(False, 5, 'bartlett kernel')
>>> phillips_perron(walk, bandwidth=3).lags
3