Skip to main content

Phillips Unit Root Tests for Polynomials of Integrated Processes

Project description

polynomial_unitroot

PyPI version Python 3.8+ License: MIT

Phillips Unit Root Tests for Polynomials of Integrated Processes

A comprehensive Python library implementing the Phillips unit root tests for polynomials of integrated processes, based on the seminal papers:

  • Wagner, M. (2012). "The Phillips unit root tests for polynomials of integrated processes." Economics Letters, 114, 299-303.

  • Stypka, O., & Wagner, M. (2019). "The Phillips unit root tests for polynomials of integrated processes revisited." Economics Letters, 176, 109-113.

Motivation

In empirical economics, it is common to analyze relationships involving powers or polynomials of integrated processes. A key example is the Environmental Kuznets Curve (EKC) hypothesis, which postulates an inverse U-shaped relationship between pollution and per capita GDP. Testing this hypothesis requires regressing emissions on GDP and its square.

However, if GDP is an I(1) process, its square is NOT an I(1) process. Standard unit root tests (ADF, PP, etc.) applied to y² when y ~ I(1) will produce misleading results due to inappropriate critical values.

This package provides the correct test statistics and critical values for unit root testing on polynomials of integrated processes.

Installation

pip install polynomial_unitroot

Or install from source:

git clone https://github.com/merwanroudane/polyunitroottest.git
cd polyunitroottest
pip install -e .

Quick Start

import numpy as np
from polynomial_unitroot import (
    phillips_polynomial_test,
    all_phillips_tests,
    print_all_tests_summary
)

# Generate a random walk (I(1) process)
np.random.seed(42)
y = np.cumsum(np.random.randn(200))

# Test unit root on y² (k=2)
result = phillips_polynomial_test(y, k=2, statistic='Z_rho')
print(result)

# Run all six test statistics
results = all_phillips_tests(y, k=2)
print_all_tests_summary(results)

Test Statistics

The package implements six test statistics from Stypka & Wagner (2019):

Statistic Description Limiting Distribution
Z_ρ Phillips coefficient statistic Eq. (8) in Stypka & Wagner (2019)
Z_t Phillips t-statistic Eq. (9) in Stypka & Wagner (2019)
Z*_ρ Bias-corrected coefficient Eq. (14) - removes additive bias term
Z*_t Bias-corrected t-statistic Eq. (15) - removes additive bias term
Z**_ρ Itô-based coefficient Eq. (16) - uses W(1)^{2k} numerator
Z**_t Itô-based t-statistic Eq. (17) - uses W(1)^{2k} numerator

Test Regression

All tests are based on the regression:

$$x_t = \rho x_{t-1} + v_t$$

where $x_t = y_t^k$ and $y_t$ is the original I(1) process.

Critical Values

Critical values are provided for k = 1, 2, 3 at significance levels 1%, 2.5%, 5%, 50%, 95%, 97.5%, and 99%.

For k = 1, the tests reduce to the standard Phillips (1987) unit root tests.

Detailed Usage

Single Test

from polynomial_unitroot import phillips_polynomial_test

# Z_rho test for k=2 (squared process)
result = phillips_polynomial_test(y, k=2, statistic='Z_rho')

print(f"Test statistic: {result.statistic:.4f}")
print(f"Critical value (5%): {result.critical_values[0.05]:.4f}")
print(f"p-value: {result.p_value:.4f}")
print(f"Reject H0 at 5%: {result.reject_null['5%']}")

All Six Tests

from polynomial_unitroot import all_phillips_tests, print_all_tests_summary

# Run all six test statistics
results = all_phillips_tests(y, k=2)

# Print formatted summary
print_all_tests_summary(results)

Convenience Functions

from polynomial_unitroot import (
    Z_rho_test, Z_t_test,
    Z_rho_star_test, Z_t_star_test,
    Z_rho_dstar_test, Z_t_dstar_test
)

# Each function returns a PolynomialUnitRootResult
result = Z_t_test(y, k=2)

Custom Kernel and Bandwidth

result = phillips_polynomial_test(
    y, k=2, 
    statistic='Z_rho',
    kernel='parzen',           # 'bartlett', 'parzen', 'qs', 'tukey_hanning'
    bandwidth=10,              # Fixed bandwidth
    # Or automatic bandwidth:
    # bandwidth_method='andrews'  # or 'newey_west'
)

Simulating Critical Values

from polynomial_unitroot import (
    generate_critical_value_table,
    print_critical_value_table
)

# Replicate Table 1 from Stypka & Wagner (2019)
cv_table = generate_critical_value_table(
    k_values=[1, 2, 3],
    n_simulations=50000,
    T=1000,
    seed=42
)

print_critical_value_table(cv_table, 'Z_rho')

Monte Carlo Size Analysis

from polynomial_unitroot import monte_carlo_size

# Replicate Table 2 from Wagner (2012)
result = monte_carlo_size(
    T=200, 
    k=2, 
    statistic='Z_t',
    gamma=0.6,           # AR(1) coefficient for innovations
    n_replications=10000,
    significance=0.05
)

print(f"Empirical rejection rate: {result.rejection_rate:.4f}")

Data Generation for Simulations

from polynomial_unitroot import (
    generate_random_walk,
    generate_ar1_random_walk,
    generate_near_integrated
)

# Simple random walk
y = generate_random_walk(T=200, sigma=1.0, seed=42)

# Random walk with AR(1) errors (Wagner 2012 DGP)
y = generate_ar1_random_walk(T=200, gamma=0.5, seed=42)

# Near-integrated process (for power analysis)
y = generate_near_integrated(T=1000, c=10, seed=42)

Critical Value Tables

From Wagner (2012) - Table 1

Limiting distributions for serially uncorrelated innovations:

Coefficient Statistic T(ρ̂ - 1):

k 1% 5% 50% Mean Std
1 -13.58 -7.95 -0.85 -1.77 9.93
2 -21.49 -13.22 -2.21 -3.29 27.43
3 -35.01 -22.01 -4.49 -6.14 73.06

t-Statistic:

k 1% 5% 50% Mean Std
1 -2.56 -1.94 -0.50 -0.42 0.96
2 -3.26 -2.53 -0.94 -0.73 1.76
3 -4.18 -3.30 -1.41 -1.17 2.65

From Stypka & Wagner (2019) - Table 1

Updated critical values based on 50,000 replications (see paper for all six statistics).

Theoretical Background

The Problem

When $y_t \sim I(1)$ (e.g., a random walk), standard unit root tests assume:

  • The process being tested is itself I(1)
  • Critical values from the Dickey-Fuller distribution

However, $y_t^k$ for $k > 1$ is not an I(1) process. The limiting distributions differ substantially:

For k=1 (standard case): $$T(\hat{\rho} - 1) \Rightarrow \frac{\int_0^1 W(r)dW(r)}{\int_0^1 W(r)^2 dr}$$

For k > 1: $$T(\hat{\rho} - 1) \Rightarrow \frac{k\int_0^1 W(r)^{2k-1}dW(r) + \binom{k}{2}\int_0^1 W(r)^{2(k-1)}dr}{\int_0^1 W(r)^{2k}dr}$$

Implications

Using standard DF critical values for $y^2$ or $y^3$ leads to:

  • Conservative tests (under-rejection of true null)
  • Increasing conservativeness with higher k

Applications

This methodology is relevant for:

  1. Environmental Kuznets Curve (EKC) analysis
  2. Intensity of use studies (GDP vs. energy/metals usage)
  3. Exchange rate target zone models
  4. Any regression involving powers of integrated regressors

Citation

If you use this package in your research, please cite:

@article{wagner2012phillips,
  title={The {Phillips} unit root tests for polynomials of integrated processes},
  author={Wagner, Martin},
  journal={Economics Letters},
  volume={114},
  number={3},
  pages={299--303},
  year={2012},
  publisher={Elsevier}
}

@article{stypka2019phillips,
  title={The {Phillips} unit root tests for polynomials of integrated processes revisited},
  author={Stypka, Oliver and Wagner, Martin},
  journal={Economics Letters},
  volume={176},
  pages={109--113},
  year={2019},
  publisher={Elsevier}
}

Author

Dr Merwan Roudane

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgments

This implementation is based on the theoretical work of Martin Wagner and Oliver Stypka. The critical values and test statistics are reproduced exactly as specified in their papers.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polynomial_unitroot-0.0.2.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polynomial_unitroot-0.0.2-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file polynomial_unitroot-0.0.2.tar.gz.

File metadata

  • Download URL: polynomial_unitroot-0.0.2.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for polynomial_unitroot-0.0.2.tar.gz
Algorithm Hash digest
SHA256 7c0f240daa3bf3779782205d92fedde36c8c13a06298dfb941150c47bee05130
MD5 966502cbaed0e94a4a2dece0f4ae897c
BLAKE2b-256 6eeff9f30ad2a1bc4a5abc6e39f60b9348de797df0edc95e2a22a071c415e1af

See more details on using hashes here.

File details

Details for the file polynomial_unitroot-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for polynomial_unitroot-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 79d97586414ff12154efd2ba6f185b5308a4c6ac2f24a67696a0ae792d85a7da
MD5 ec5e4096e7748cba51cb9dfc86366bd5
BLAKE2b-256 a660200f8afaeef4a70116a598e22940902f92dbc9344ca51d687d7d171541d2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page