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.1.tar.gz (25.4 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.1-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: polynomial_unitroot-0.0.1.tar.gz
  • Upload date:
  • Size: 25.4 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.1.tar.gz
Algorithm Hash digest
SHA256 f90951a8a0006088d72a7d4ec67da447d7fb032ace96767fa3d50016373d3edf
MD5 d6f5f31f6f7dae041017707d1cafdab3
BLAKE2b-256 c5ca6942bf749740ba405adab7703c0a43e9288abc36f57e23aa65ace1c1ad25

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for polynomial_unitroot-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 92ac0f140dbb692321230a1e424200ab303596c0abd6b02907483e6a4c0cf3e9
MD5 c2959e51b790d53ee848e1b43a8b2a7b
BLAKE2b-256 778c5885dc473d23bfc9cf63b2f21ebd950e410cbcfc235cf910b626462857d8

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