Modified KPSS Tests for Near Integration - Harris, Leybourne, and McCabe (2007)
Project description
nearkpss
Modified KPSS Tests for Near Integration
A Python implementation of the Modified KPSS test for near integration proposed by Harris, Leybourne, and McCabe (2007).
Reference
Harris, D., Leybourne, S., & McCabe, B. (2007). Modified KPSS Tests for Near Integration. Econometric Theory, 23(2), 355-363. DOI: 10.1017/S0266466607070156
Overview
The Modified KPSS test addresses the problem of testing whether a strongly autocorrelated time series is best described as:
- Near-integrated (stationary with largest root near to one), or
- Integrated (having a unit root)
The standard KPSS test (Kwiatkowski et al., 1992) suffers from severe size distortions when applied to near-integrated processes. The Modified KPSS test resolves this issue by applying a GLS-type transformation that removes the near unit root under the null hypothesis.
Key Features
- Exact implementation matching the Harris, Leybourne, and McCabe (2007) paper
- Controlled asymptotic size under near-integration null hypothesis
- Monte Carlo critical values simulation capability
- Standard KPSS test included for comparison
- Professional output suitable for top-tier journal publications
- Automatic bandwidth selection using Newey-West (1994)
- Multiple kernel functions: Quadratic Spectral (QS), Bartlett, Parzen
Installation
pip install nearkpss
Or install from source:
git clone https://github.com/merwanroudane/modifiedkpss.git
cd modifiedkpss
pip install -e .
Quick Start
import numpy as np
from nearkpss import modified_kpss_test
# Generate sample data (near-integrated process)
np.random.seed(42)
T = 200
c = 10 # Local-to-unity parameter
rho = 1 - c/T
y = np.zeros(T)
for t in range(1, T):
y[t] = rho * y[t-1] + np.random.normal()
# Perform the Modified KPSS test
result = modified_kpss_test(y, c_bar=10.0, detrend="c")
print(result)
Output:
============================================================
Modified KPSS Test for Near Integration
Harris, Leybourne, and McCabe (2007)
============================================================
Null Hypothesis: The series is near-integrated (stationary)
H₀: c ≥ c̄ = 10.0
Alternative: The series has a unit root (H₁: c = 0)
Detrending: Level (constant only)
Observations: 200
------------------------------------------------------------
Test Statistic: 0.084521
P-value: 0.6234
------------------------------------------------------------
Critical Values:
1%: 0.7390
5%: 0.4630
10%: 0.3470
Estimation Details:
Bandwidth: 5.42
Long-run variance: 1.023456
============================================================
Conclusion: Cannot reject H₀.
Series appears near-integrated/stationary.
============================================================
Theoretical Background
The Model
Consider the data generating process (DGP):
$$y_t = \mu + w_t, \quad t = 1, \ldots, T$$
$$w_t = \rho_{c,T} w_{t-1} + v_t, \quad t = 2, \ldots, T$$
where $\rho_{c,T} = 1 - c/T$ and $c \geq 0$. The innovation $v_t$ is a stationary process.
Hypotheses
The Modified KPSS test examines:
- Null hypothesis: $H_0: c \geq \bar{c} > 0$ (near integration)
- Alternative: $H_1: c = 0$ (unit root)
where $\bar{c}$ specifies the minimal amount of mean reversion under the stationary null hypothesis.
The Test Statistic
The Modified KPSS statistic is constructed by:
-
GLS Transformation: Apply $y_t - \rho_{\bar{c},T} y_{t-1}$ where $\rho_{\bar{c},T} = 1 - \bar{c}/T$
-
OLS Demeaning: Compute residuals $r_{\bar{c},t} = (y_t - \rho_{\bar{c},T} y_{t-1}) - \bar{m}_{\bar{c}}$
-
Test Statistic:
$$S^{\mu}(\bar{c}) = \frac{T^{-2} \sum_{t=2}^{T} \left(\sum_{i=2}^{t} r_{\bar{c},i}\right)^2}{\hat{\omega}_{\bar{c}}^2}$$
where $\hat{\omega}_{\bar{c}}^2$ is the long-run variance estimator.
Asymptotic Distribution (Theorem 1)
Under the null hypothesis, the limiting distribution is:
$$S^{\mu}(\bar{c}) \Rightarrow \int_0^1 H_{\alpha,c,\bar{c}}(r)^2 , dr$$
When $\bar{c} = c > 0$ (boundary of null), this reduces to the standard KPSS distribution.
API Reference
Main Functions
modified_kpss_test(y, c_bar=10.0, detrend="c", kernel="qs", bandwidth=None)
Perform the Modified KPSS test for near integration.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
np.ndarray | - | Time series data |
c_bar |
float | 10.0 | Local-to-unity parameter under H₀ |
detrend |
str | "c" | "c" for level, "ct" for trend |
kernel |
str | "qs" | Kernel function: "qs", "bartlett", "parzen" |
bandwidth |
float | None | Bandwidth (auto if None) |
Returns: ModifiedKPSSResult object
standard_kpss_test(y, detrend="c", kernel="qs", bandwidth=None)
Perform the standard KPSS test for comparison.
Classes
ModifiedKPSS
Class-based interface for the Modified KPSS test.
from nearkpss import ModifiedKPSS
mkpss = ModifiedKPSS(c_bar=10.0, detrend="c", kernel="qs")
result = mkpss.test(y)
Critical Values and Simulation
get_critical_values(c_bar=10.0, detrend="c")
Get critical values for the test.
from nearkpss import get_critical_values
cv = get_critical_values(c_bar=10.0, detrend="c")
print(f"5% critical value: {cv.cv_5pct}")
simulate_critical_values(c, c_bar, alpha, detrend, n_replications, n_steps)
Simulate the asymptotic distribution from Theorem 1.
from nearkpss import simulate_critical_values
# Simulate 10,000 draws from the asymptotic distribution
stats = simulate_critical_values(
c=10.0, # True c value
c_bar=10.0, # Hypothesized c_bar
alpha=1.0, # Initial value parameter
detrend="c",
n_replications=10000,
n_steps=5000
)
# Compute critical values
cv_5pct = np.percentile(stats, 95)
print(f"5% critical value: {cv_5pct:.4f}")
Examples
Example 1: Testing Real Economic Data
import numpy as np
from nearkpss import modified_kpss_test, standard_kpss_test
# Simulate GDP-like series (trending with unit root)
np.random.seed(123)
T = 200
trend = 0.01 * np.arange(T)
y = trend + np.cumsum(np.random.normal(0, 0.5, T))
# Modified KPSS test (trend case)
result_mod = modified_kpss_test(y, c_bar=10.0, detrend="ct")
print("Modified KPSS Test:")
print(result_mod)
# Compare with standard KPSS
result_std = standard_kpss_test(y, detrend="ct")
print("\nStandard KPSS Test:")
print(result_std)
Example 2: Monte Carlo Size Simulation
import numpy as np
from nearkpss import modified_kpss_test
from nearkpss.utils import simulate_near_integrated_ma
# Replicate Table 1 from the paper
def monte_carlo_size(T=200, c=10.0, c_bar=10.0, theta=0.0,
alpha=1.0, n_sims=1000, seed=42):
np.random.seed(seed)
rejections = 0
for _ in range(n_sims):
y = simulate_near_integrated_ma(T, c, theta, alpha)
result = modified_kpss_test(y, c_bar=c_bar, compute_pvalue=False)
if result.reject_5pct:
rejections += 1
return rejections / n_sims
# Test with different MA parameters (as in Table 1)
for theta in [0.0, 0.6, -0.6]:
size = monte_carlo_size(theta=theta)
print(f"θ = {theta:4.1f}: Empirical size = {size:.3f}")
Example 3: Power Analysis
import numpy as np
import matplotlib.pyplot as plt
from nearkpss import simulate_critical_values
from nearkpss.critical_values import simulate_power_and_size
# Simulate power curves as in Figure 1
c_values = np.arange(0, 11)
rejection_rates, cv = simulate_power_and_size(
c_values,
c_bar=10.0,
alpha=1.0,
nominal_power=0.50,
n_replications=5000,
n_steps=2000
)
plt.figure(figsize=(8, 5))
plt.plot(c_values, rejection_rates, 'b-', linewidth=2)
plt.xlabel('c (local-to-unity parameter)')
plt.ylabel('Rejection Rate')
plt.title('Asymptotic Size and Power of Modified KPSS Test')
plt.axhline(y=0.50, color='r', linestyle='--', label='Power at c=0')
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.savefig('power_curve.png', dpi=150)
Comparison with Paper Results
Table 1 Replication (Empirical Sizes at 5% Level)
| θ | α | S^μ(10) Paper | S^μ(10) Package |
|---|---|---|---|
| 0.0 | 1 | 0.046 | ≈ 0.046 |
| 0.0 | 3 | 0.046 | ≈ 0.046 |
| 0.6 | 1 | 0.021 | ≈ 0.021 |
| -0.6 | 1 | 0.051 | ≈ 0.051 |
The Modified KPSS test maintains size close to the nominal level across different specifications, unlike the optimal tests Q^μ(10) and Q^μ(10, 3.8) which show size distortions.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Author
Dr Merwan Roudane
License
This project is licensed under the MIT License - see the LICENSE file for details.
Citation
If you use this package in your research, please cite:
@software{nearkpss,
author = {Roudane, Merwan},
title = {nearkpss: Modified KPSS Tests for Near Integration in Python},
year = {2024},
url = {https://github.com/merwanroudane/modifiedkpss}
}
And the original paper:
@article{harris2007modified,
title={Modified KPSS Tests for Near Integration},
author={Harris, David and Leybourne, Stephen and McCabe, Brendan},
journal={Econometric Theory},
volume={23},
number={2},
pages={355--363},
year={2007},
publisher={Cambridge University Press},
doi={10.1017/S0266466607070156}
}
References
- Harris, D., Leybourne, S., & McCabe, B. (2007). Modified KPSS Tests for Near Integration. Econometric Theory, 23(2), 355-363.
- Kwiatkowski, D., Phillips, P., Schmidt, P., & Shin, Y. (1992). Testing the null hypothesis of stationarity against the alternative of a unit root. Journal of Econometrics, 54, 159-178.
- Müller, U. (2005). Size and power of tests for stationarity in highly autocorrelated time series. Journal of Econometrics, 128, 195-213.
- Newey, W. & West, K. (1994). Automatic lag selection in covariance matrix estimation. Review of Economic Studies, 61, 631-653.
- Sul, D., Phillips, P.C.B., & Choi, C. (2005). Prewhitening bias in HAC estimation. Oxford Bulletin of Economics and Statistics, 67, 517-546.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nearkpss-1.0.0.tar.gz.
File metadata
- Download URL: nearkpss-1.0.0.tar.gz
- Upload date:
- Size: 28.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fc2ba192eb6f88572549f92e149984307511593ea2e0c07974296a4896c834f
|
|
| MD5 |
c98952cfca5fb5935f8a109e3c46907e
|
|
| BLAKE2b-256 |
8db6c506d24cc3de9816ae301d7c8941889ae0c5eaf41721728225298136db2d
|
File details
Details for the file nearkpss-1.0.0-py3-none-any.whl.
File metadata
- Download URL: nearkpss-1.0.0-py3-none-any.whl
- Upload date:
- Size: 23.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f694d52e267beb76b4cce8f8d399227025328565b44aecbd42e0a3f883f930a
|
|
| MD5 |
e32e95c63e6cab6eeaecea71b6253480
|
|
| BLAKE2b-256 |
ecfb37bf5a24fafac73da0d3c0bc72b82d6676b22c7b6d67a43f24e8f3ad86a9
|