Skip to main content

Kapetanios Unit Root Test

PyPI version License: MIT Python 3.8+

Python implementation of the Kapetanios (2005) unit root test with up to m structural breaks.

Overview

This package provides a comprehensive implementation of the unit root test proposed by George Kapetanios (2005), which tests for a unit root against the alternative hypothesis of stationarity with up to m structural breaks. The test is an extension of the Zivot and Andrews (1992) test and uses a sequential procedure to endogenously determine break dates.

Key Features

  • Multiple Structural Breaks: Test for up to 5 structural breaks
  • Flexible Break Types:
    • Model A: Breaks in intercept only
    • Model B: Breaks in trend only
    • Model C: Breaks in both intercept and trend
  • Sequential Search: Computationally efficient sequential procedure (Bai & Perron, 1998)
  • Automatic Lag Selection: AIC, BIC, or t-statistic methods
  • Windows Compatible: Fully tested on Windows, Linux, and macOS

Installation

pip install kapetanios-test

From source

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

Quick Start

import numpy as np
from kapetanios_test import kapetanios_test

# Generate sample data (random walk with structural break)
np.random.seed(42)
T = 200
y = np.cumsum(np.random.randn(T))
y[100:] += 5  # Add level break at t=100

# Run the test
result = kapetanios_test(
    y,
    max_breaks=3,      # Test for up to 3 breaks
    model='C',         # Allow breaks in both intercept and trend
    trimming=0.15,     # Trimming parameter
    lag_selection='aic'  # Use AIC for lag selection
)

# Display results
print(result)

Usage

Basic Usage

The simplest way to use the package is through the kapetanios_test() function:

from kapetanios_test import kapetanios_test

result = kapetanios_test(y, max_breaks=2, model='A')

Advanced Usage

For more control, use the KapetaniosTest class:

from kapetanios_test import KapetaniosTest

# Initialize test
test = KapetaniosTest(
    max_breaks=3,
    model='C',
    trimming=0.15,
    max_lags=None,  # Automatically determined
    lag_selection='aic'
)

# Run test
result = test.fit(y)

# Access results
print(f"Test statistic: {result.statistic}")
print(f"Break dates: {result.break_dates}")
print(f"Reject null: {result.reject_null}")

Model Types

  • Model A: Breaks in intercept only

    result = kapetanios_test(y, model='A')
    
  • Model B: Breaks in trend only

    result = kapetanios_test(y, model='B')
    
  • Model C: Breaks in both intercept and trend (recommended)

    result = kapetanios_test(y, model='C')
    

Lag Selection Methods

# Akaike Information Criterion (default)
result = kapetanios_test(y, lag_selection='aic')

# Bayesian Information Criterion
result = kapetanios_test(y, lag_selection='bic')

# Sequential t-statistic (Perron's method)
result = kapetanios_test(y, lag_selection='t-stat')

Interpretation

Hypotheses

  • Null Hypothesis (H₀): The series contains a unit root with drift (non-stationary)
  • Alternative Hypothesis (H₁): The series is trend-stationary with up to m structural breaks

Decision Rule

Reject H₀ if the test statistic is less than (more negative than) the critical value at your chosen significance level.

result = kapetanios_test(y)

if result.reject_null:
    print("Reject H0: Evidence of stationarity with structural breaks")
else:
    print("Fail to reject H0: Evidence consistent with unit root")

Output

The KapetaniosResult object contains:

  • statistic: The test statistic (minimum t-statistic)
  • pvalue: Approximate p-value
  • critical_values: Dictionary with 1%, 5%, and 10% critical values
  • break_dates: List of estimated break dates (indices)
  • n_breaks: Number of breaks detected
  • model_type: Type of model ('A', 'B', or 'C')
  • lags: Number of lags used
  • reject_null: Boolean indicating rejection at 5% level

Methodology

The test follows the sequential procedure outlined in Kapetanios (2005):

  1. Step 1: Search for a single break across all possible dates
  2. Step 2: Select break with minimum SSR
  3. Step 3: Conditional on first break, search for second break
  4. Step 4: Repeat until m breaks are found
  5. Step 5: Compute minimum t-statistic across all searches
  6. Step 6: Compare with critical values

The model estimated is:

Δyₜ = μ₀ + μ₁t + αyₜ₋₁ + Σⱼ cⱼΔyₜ₋ⱼ + Σᵢ φᵢDUᵢ,ₜ + Σᵢ ψᵢDTᵢ,ₜ + εₜ

Where:

  • DUᵢ,ₜ: Intercept break dummies
  • DTᵢ,ₜ: Trend break dummies
  • α: Coefficient of interest (H₀: α = 0)

Examples

Example 1: Testing Economic Time Series

import pandas as pd
from kapetanios_test import kapetanios_test

# Load GDP data
df = pd.read_csv('gdp_data.csv')
gdp = df['real_gdp'].values

# Test for unit root with up to 2 breaks
result = kapetanios_test(
    gdp,
    max_breaks=2,
    model='C',
    trimming=0.15
)

print(result)

Example 2: Monte Carlo Simulation

import numpy as np
from kapetanios_test import kapetanios_test

# Simulate stationary process with break
np.random.seed(123)
T = 150
t = np.arange(T)
epsilon = np.random.randn(T)

# AR(1) with structural break
y = np.zeros(T)
y[0] = epsilon[0]
for i in range(1, T):
    if i < 75:
        y[i] = 0.5 + 0.1 * t[i] + 0.7 * y[i-1] + epsilon[i]
    else:
        y[i] = 2.0 + 0.1 * t[i] + 0.7 * y[i-1] + epsilon[i]  # Break at t=75

result = kapetanios_test(y, max_breaks=3, model='C')
print(f"Detected breaks at: {result.break_dates}")

Example 3: Comparing Different Models

from kapetanios_test import kapetanios_test

# Test all three models
models = ['A', 'B', 'C']
for model in models:
    result = kapetanios_test(y, max_breaks=2, model=model)
    print(f"\nModel {model}:")
    print(f"  Statistic: {result.statistic:.4f}")
    print(f"  Reject H0: {result.reject_null}")

Critical Values

Critical values are from Table I in Kapetanios (2005) and are automatically used based on:

  • Model type (A, B, or C)
  • Maximum number of breaks
  • Significance level (1%, 5%, 10%)

Limitations

  1. Sample Size: Requires sufficient observations relative to number of breaks and trimming parameter
  2. Trimming: The trimming parameter must ensure adequate observations between breaks
  3. Power: Power decreases as the maximum number of breaks increases
  4. Null Hypothesis: Breaks are only considered under the alternative hypothesis, not under the null

Requirements

  • Python >= 3.8
  • NumPy >= 1.20.0
  • Pandas >= 1.3.0
  • SciPy >= 1.7.0
  • statsmodels >= 0.13.0

References

Primary Reference

Kapetanios, G. (2005). Unit-root testing against the alternative hypothesis of up to m structural breaks. Journal of Time Series Analysis, 26(1), 123-133.

  • Bai, J., & Perron, P. (1998). Estimating and testing linear models with multiple structural changes. Econometrica, 66(1), 47-78.
  • Zivot, E., & Andrews, D. W. K. (1992). Further evidence on the great crash, the oil-price shock, and the unit-root hypothesis. Journal of Business & Economic Statistics, 10(3), 251-270.
  • Perron, P. (1989). The great crash, the oil price shock, and the unit root hypothesis. Econometrica, 57(6), 1361-1401.

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

Testing

Run the test suite:

pytest tests/

With coverage:

pytest --cov=kapetanios_test tests/

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Dr. Merwan Roudane

Citation

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

@article{kapetanios2005,
  title={Unit-root testing against the alternative hypothesis of up to m structural breaks},
  author={Kapetanios, George},
  journal={Journal of Time Series Analysis},
  volume={26},
  number={1},
  pages={123--133},
  year={2005},
  publisher={Wiley Online Library}
}

@software{roudane2024kapetanios,
  author = {Roudane, Merwan},
  title = {kapetanios-test: Python implementation of the Kapetanios unit root test},
  year = {2024},
  url = {https://github.com/merwanroudane/kapetanios}
}

Acknowledgments

  • Original methodology by George Kapetanios
  • Sequential procedure based on Bai & Perron (1998)
  • Gretl package by Andrea E. Sánchez Urbina, Ricardo Ramírez & Daniel Ventosa-Santaulària

Support

For issues, questions, or suggestions:

Changelog

Version 1.0.0 (2024)

  • Initial release
  • Implementation of Kapetanios (2005) test
  • Support for up to 5 structural breaks
  • Three model types (A, B, C)
  • Multiple lag selection methods
  • Comprehensive documentation and examples

Metadata

Release files for kapetanios-test 1.0.1

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

Source distribution (sdist)

Source distribution for kapetanios-test 1.0.1
File Size Uploaded Provenance
kapetanios_test-1.0.1.tar.gz 19.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for kapetanios-test 1.0.1
File Interpreter ABI Platform
kapetanios_test-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 33.8 kB

Release files / kapetanios_test-1.0.1.tar.gz

Download URL kapetanios_test-1.0.1.tar.gz
Size 19.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f9c4a1dd37b9f61d1a9ed6bdc277ff55e72210d127fa0c64074c9e057e36c63f
BLAKE2b-256 checksum
How to use checksums
a3fd811ef15ab873cd72a1aa81edf750667c7d3bd8a797de443f80c5e333802d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / kapetanios_test-1.0.1-py3-none-any.whl

Download URL kapetanios_test-1.0.1-py3-none-any.whl
Size 14.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a5f7244bc3139fe364ae1a89b4fec4e10c35e682bb8e527111a263b92aa83b89
BLAKE2b-256 checksum
How to use checksums
43c0de62075b48ef3c5b45648040a8dbc0505d83f157e5ef380767f1b472ac7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Security for kapetanios-test 1.0.1

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