Skip to main content

nearkpss

Modified KPSS Tests for Near Integration

Python 3.8+ License: MIT

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:

  1. GLS Transformation: Apply $y_t - \rho_{\bar{c},T} y_{t-1}$ where $\rho_{\bar{c},T} = 1 - \bar{c}/T$

  2. OLS Demeaning: Compute residuals $r_{\bar{c},t} = (y_t - \rho_{\bar{c},T} y_{t-1}) - \bar{m}_{\bar{c}}$

  3. 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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. 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.

Metadata

Release files for nearkpss 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nearkpss 1.0.0
File Size Uploaded Provenance
nearkpss-1.0.0.tar.gz 28.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nearkpss 1.0.0
File Interpreter ABI Platform
nearkpss-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 51.5 kB

Release files / nearkpss-1.0.0.tar.gz

Download URL nearkpss-1.0.0.tar.gz
Size 28.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0fc2ba192eb6f88572549f92e149984307511593ea2e0c07974296a4896c834f
BLAKE2b-256 checksum
How to use checksums
8db6c506d24cc3de9816ae301d7c8941889ae0c5eaf41721728225298136db2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / nearkpss-1.0.0-py3-none-any.whl

Download URL nearkpss-1.0.0-py3-none-any.whl
Size 23.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8f694d52e267beb76b4cce8f8d399227025328565b44aecbd42e0a3f883f930a
BLAKE2b-256 checksum
How to use checksums
ecfb37bf5a24fafac73da0d3c0bc72b82d6676b22c7b6d67a43f24e8f3ad86a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for nearkpss 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page