<<<<<<< HEAD
=======
A Python implementation of unit root tests for bounded time series based on Carrion-i-Silvestre and Gadea (2013).
boundedtest provides comprehensive tools for testing unit roots in time series that are constrained within bounds. The package implements:
- GLS-detrending with bound-specific non-centrality parameter κ̅(c,c̄)
- OLS-detrending for comparison
- M-type test statistics: MZα, MSB, and MZt
- Parametric and non-parametric long-run variance estimation
- Critical values tailored to different bound configurations
This package implements the methodology from:
Carrion-i-Silvestre, J.L. and Gadea, M.D. (2013). "GLS-based unit root tests for bounded processes." Economics Letters, 120(2), 184-187.
pip install boundedtestOr install from source:
git clone https://github.com/merwanroudane/boundedtest.git
cd boundedtest
pip install -e .import numpy as np
from boundedtest import bounded_unit_root_test
# Generate bounded data
np.random.seed(42)
data = np.cumsum(np.random.randn(200))
data = np.clip(data, -10, 10) # Apply bounds
# Test for unit root with GLS-BOUNDS method (recommended)
result = bounded_unit_root_test(
data=data,
bounds=(-10, 10),
statistic='mz_alpha',
detrending='gls_bounds',
lrv_method='np'
)
print(result)'ols': Standard OLS detrending'gls_ers': GLS detrending with standard κ = -7 (Elliott et al., 1996)'gls_bounds': GLS detrending with bound-specific κ̅(c,c̄) (recommended)
- MZα: Modified Phillips-Perron statistic
- MSB: Modified Sargan-Bhargava statistic
- MZt: Modified t-statistic
- Non-parametric (
'np'): Newey-West with automatic bandwidth selection - Parametric (
'ar'): AR-based with MAIC lag selection (Ng & Perron, 2001)
import numpy as np
from boundedtest import bounded_unit_root_test
# Generate data
np.random.seed(123)
T = 200
data = np.cumsum(np.random.randn(T))
bounds = (-5, 5)
data = np.clip(data, bounds[0], bounds[1])
# Run test
result = bounded_unit_root_test(
data=data,
bounds=bounds,
detrending='gls_bounds'
)
print(result)
print(f"\nReject H0 at 5%: {result.reject_5pct}")results = bounded_unit_root_test(
data=data,
bounds=bounds,
statistic='all', # Compute all statistics
detrending='gls_bounds'
)
# Results is a dictionary
for stat_name, result in results.items():
print(f"\n{stat_name}:")
print(f" Statistic: {result.statistic:.4f}")
print(f" Critical (5%): {result.critical_values['5%']:.4f}")
print(f" Reject H0: {result.reject_5pct}")methods = ['ols', 'gls_ers', 'gls_bounds']
for method in methods:
result = bounded_unit_root_test(
data=data,
bounds=bounds,
statistic='mz_alpha',
detrending=method
)
print(f"\n{method.upper()}:")
print(f" MZα = {result.statistic:.4f}")
print(f" Reject H0 = {result.reject_5pct}")import pandas as pd
# Create DataFrame
df = pd.DataFrame({
'date': pd.date_range('2020-01-01', periods=200, freq='D'),
'series': data
})
# Test using the series
result = bounded_unit_root_test(
data=df['series'],
bounds=bounds,
detrending='gls_bounds'
)# Unemployment rate bounded between 0 and 100
unemployment = np.random.uniform(3, 10, size=100) # Example data
unemployment += np.cumsum(np.random.randn(100)) * 0.2
result = bounded_unit_root_test(
data=unemployment,
bounds=(0, 100),
detrending='gls_bounds'
)The output includes:
- Test Statistic Value: The computed test statistic
- Critical Values: At 1%, 5%, and 10% significance levels
- Rejection Decision: Whether to reject the unit root null hypothesis
- Bounds Information: Original bounds and estimated c-parameters
- Non-centrality Parameter (κ̅): Used in GLS detrending
- LRV Estimate: Estimated long-run variance
- MZα and MZt: Left-tail tests. Reject H₀ if statistic < critical value.
- MSB: Right-tail test. Reject H₀ if statistic > critical value.
- H₀: Series has a unit root (is I(1))
- H₁: Series is stationary (is I(0))
from boundedtest.regulated_ou import generate_bounded_ar1
# Generate bounded AR(1) process
data = generate_bounded_ar1(
T=200,
bounds=(-5, 5),
rho=1.0, # Unit root
sigma=1.0,
burnin=100,
seed=42
)from boundedtest.regulated_ou import compute_critical_values
# Compute critical values for specific bounds
cv = compute_critical_values(
c_lower=-0.5,
c_upper=0.5,
kappa=0,
n_sim=10000,
alpha=0.05
)
print(cv)from boundedtest import (
ols_detrend,
gls_detrend,
compute_mz_alpha,
estimate_lrv_np,
get_kappa
)
# Manual detrending
y_tilde, _, _ = ols_detrend(data)
# Compute LRV
from boundedtest.statistics import compute_ar1_residuals
residuals = compute_ar1_residuals(y_tilde)
s2 = estimate_lrv_np(residuals)
# Compute statistic
mz_alpha = compute_mz_alpha(y_tilde, s2)bounded_unit_root_test(
data, # array-like: Time series data
bounds, # tuple: (lower_bound, upper_bound)
statistic='mz_alpha', # str: Test statistic to compute
detrending='gls_bounds', # str: Detrending method
lrv_method='np', # str: LRV estimation method
deterministics='constant' # str: Deterministic components
) -> BoundedTestResultThe package includes utilities for Monte Carlo experiments:
from boundedtest.regulated_ou import simulate_bounded_process
# Simulate under H0
data_h0 = simulate_bounded_process(
T=200,
b_lower=-5,
b_upper=5,
alpha=1.0, # Unit root
sigma=1.0
)
# Simulate under H1
data_h1 = simulate_bounded_process(
T=200,
b_lower=-5,
b_upper=5,
alpha=0.95, # Stationary
sigma=1.0
)- Python >= 3.8
- NumPy >= 1.20.0
- SciPy >= 1.7.0
- Pandas >= 1.3.0
- Statsmodels >= 0.13.0
If you use this package in your research, please cite:
@article{carrion2013gls,
title={GLS-based unit root tests for bounded processes},
author={Carrion-i-Silvestre, Josep Llu{\'\i}s and Gadea, Mar{\'\i}a Dolores},
journal={Economics Letters},
volume={120},
number={2},
pages={184--187},
year={2013},
publisher={Elsevier}
}This project is licensed under the MIT License - see the LICENSE file for details.
Merwan Roudane
Email: merwanroudane920@gmail.com
GitHub: @merwanroudane
Contributions are welcome! Please feel free to submit a Pull Request.
This implementation is based on the methodology developed by Josep Lluís Carrion-i-Silvestre and María Dolores Gadea. The original MATLAB code and methodological guidance were instrumental in developing this Python package.
- Original paper: Economics Letters (2013)
- Elliott, Rothenberg & Stock (1996): "Efficient Tests for an Autoregressive Unit Root"
- Ng & Perron (2001): "Lag Length Selection and the Construction of Unit Root Tests"
- Cavaliere (2005): "Limited Time Series with a Unit Root"
936ef7c (Initial commit: boundedtest 1.0.0 (code, docs, packaging))