CUSUM Tests for Structural Change in Dynamic Models
Project description
dyncusum
CUSUM Tests for Structural Change in Dynamic Models
A Python library implementing the CUSUM tests for structural change as described in:
Krämer, W., Ploberger, W., & Alt, R. (1988). "Testing for Structural Change in Dynamic Models." Econometrica, Vol. 56, No. 6, pp. 1355-1369.
Overview
This library provides a complete implementation of the CUSUM (Cumulative Sum) test for detecting structural change in linear regression models with lagged dependent variables. The implementation follows the original paper exactly, including:
- Dynamic CUSUM Test: The straightforward CUSUM test applied to dynamic models
- Dufour Test: Modified procedure from Dufour (1982) that first eliminates dynamics
- Critical Values: Both tabulated values from BDE (1975) and Monte Carlo simulation
- Power Analysis: Tools to analyze test power under various structural change scenarios
- Visualization: Publication-quality plots for CUSUM processes
- Tables: Formatted output for academic publications
Installation
pip install dyncusum
Or install from source:
git clone https://github.com/merwanroudane/cusum.git
cd cusum
pip install -e .
Quick Start
Basic Usage
import numpy as np
from dyncusum import dynamic_cusum_test, plot_cusum, print_test_summary
# Generate sample data
np.random.seed(42)
T = 100
y = np.zeros(T)
u = np.random.normal(0, 1, T)
# AR(1) process: y_t = 0.5 * y_{t-1} + u_t
for t in range(1, T):
y[t] = 0.5 * y[t-1] + u[t]
# Prepare data for test
y_current = y[1:]
y_lagged = y[:-1]
X = np.ones((T-1, 1)) # Constant term
# Perform the Dynamic CUSUM test
result = dynamic_cusum_test(y_current, X, y_lagged, significance_level=0.05)
# Print summary
print_test_summary(result)
# Plot the CUSUM process
fig = plot_cusum(result, save_path='cusum_plot.png')
Comparing Tests
from dyncusum import dynamic_cusum_test, dufour_test, plot_comparison
# Run both tests
result_dc = dynamic_cusum_test(y_current, X, y_lagged)
result_duf = dufour_test(y_current, X, y_lagged)
# Compare results
fig = plot_comparison(result_dc, result_duf, save_path='comparison.png')
Theoretical Background
The Model
The library considers the dynamic linear regression model:
$$y_t = \gamma y_{t-1} + \beta_1 x_{t1} + \cdots + \beta_K x_{tK} + u_t \quad (t = 1, \ldots, T)$$
where:
- $y_t$ is the dependent variable
- $\gamma$ is the coefficient of the lagged dependent variable ($|\gamma| < 1$)
- $x_{t1}, \ldots, x_{tK}$ are exogenous regressors
- $u_t$ are iid$(0, \sigma^2)$ disturbances
The CUSUM Test
The test statistic is based on recursive residuals:
$$w_r = (y_r - z'_r \hat{\delta}^{(r-1)}) / f_r$$
where $f_r = (1 + z'_r(Z^{(r-1)'}Z^{(r-1)})^{-1}z_r)^{1/2}$
The CUSUM process is:
$$W^{(r)} = \frac{1}{\hat{\sigma}} \sum_{t=K+2}^{r} w_t$$
And the test statistic is:
$$S = \max_{K+1 < r \leq T} \left| \frac{W^{(r)}}{\sqrt{T-K-1}} \right| / \left(1 + 2\frac{r-K-1}{T-K-1}\right)$$
Key Theorems
Theorem 1: Both the Dynamic CUSUM test and the Dufour test retain their asymptotic nominal significance levels in dynamic models.
Theorem 2: If the structural change $g(z)$ is orthogonal to the mean regressor $d$ for almost all $z$, the limiting rejection probability equals the nominal significance level (no power).
Critical Values
Critical values are based on Brownian motion theory (BDE, 1975):
| Significance Level | Critical Value |
|---|---|
| 0.01 | 1.143 |
| 0.025 | 1.035 |
| 0.05 | 0.948 |
| 0.10 | 0.850 |
API Reference
Core Functions
dynamic_cusum_test(y, X, y_lagged=None, significance_level=0.05, sigma_method='harvey', n_simulations=10000)
Perform the Dynamic CUSUM test for structural change.
Parameters:
y: Dependent variable vectorX: Exogenous regressors matrixy_lagged: Lagged dependent variable (optional)significance_level: Significance level (default: 0.05)sigma_method: 'harvey' or 'ols' (default: 'harvey')n_simulations: Monte Carlo simulations for p-value
Returns: CUSUMResult object
dufour_test(y, X, y_lagged, significance_level=0.05, sigma_method='harvey', n_simulations=10000)
Perform the Dufour (1982) modified CUSUM test.
Power Analysis
monte_carlo_power(gamma, psi, z_star, b, T=120, n_simulations=1000, ...)
Compute power via Monte Carlo simulation.
replicate_table_1(T=120, n_simulations=1000, ...)
Replicate Table I from the original paper.
Visualization
plot_cusum(result, title=None, figsize=(10, 6), ...)
Plot the CUSUM process with critical boundaries.
create_summary_figure(result, figsize=(14, 10), ...)
Create a comprehensive summary figure with multiple panels.
Examples
Detecting Structural Change
import numpy as np
from dyncusum import dynamic_cusum_test, generate_dynamic_data
# Generate data with a structural break at t = 60
T = 100
gamma = 0.5
beta = np.array([2, 10])
# Break: coefficients change by 20% after observation 60
structural_break = {
'z_star': 0.6, # Break at 60% of sample
'delta_delta': np.array([0, 0.4, 2.0]) # Change in [γ, β_1, β_2]
}
y, X, y_lagged = generate_dynamic_data(T, gamma, beta,
structural_break=structural_break,
seed=42)
# Test for structural change
result = dynamic_cusum_test(y, X, y_lagged)
print(f"Test Statistic: {result.statistic:.4f}")
print(f"P-value: {result.p_value:.4f}")
print(f"Reject H0: {result.reject_null}")
Power Analysis
from dyncusum import analyze_power_vs_angle, plot_power_curve
# Analyze how power varies with the angle ψ
results = analyze_power_vs_angle(gamma=0.0, z_star=0.5, b=12, T=120)
# Plot power curve
fig = plot_power_curve(
np.array(results['angles']),
np.array(results['powers']),
save_path='power_curve.png'
)
Replicating Paper Results
The library can replicate the Monte Carlo results from Table I:
from dyncusum import replicate_table_1, format_power_table
# Note: This takes several hours with default settings
results = replicate_table_1(
T=120,
n_simulations=100, # Use 1000 for publication
gamma_values=[-0.5, 0, 0.5],
psi_values=[0, 30, 60, 90],
z_star_values=[0.3, 0.5, 0.7],
b_values=[3, 6, 12]
)
# Format as table
print(format_power_table(results))
Citation
If you use this library in your research, please cite both the original paper and this implementation:
@article{kramer1988testing,
title={Testing for Structural Change in Dynamic Models},
author={Kr{\"a}mer, Walter and Ploberger, Werner and Alt, Raimund},
journal={Econometrica},
volume={56},
number={6},
pages={1355--1369},
year={1988}
}
@software{roudane2024dyncusum,
author = {Roudane, Merwan},
title = {dyncusum: CUSUM Tests for Structural Change in Dynamic Models},
year = {2024},
url = {https://github.com/merwanroudane/cusum}
}
References
- Brown, R. L., Durbin, J., & Evans, J. M. (1975). Techniques for Testing the Constancy of Regression Relationships over Time. Journal of the Royal Statistical Society, Series B, 37, 149-163.
- Dufour, J. M. (1982). Recursive Stability Analysis of Linear Regression Relationships. Journal of Econometrics, 19, 31-76.
- Harvey, A. (1975). Comment on the Paper by Brown, Durbin and Evans. Journal of the Royal Statistical Society, B, 37, 179-180.
License
MIT License - see LICENSE file for details.
Author
Dr. Merwan Roudane
- Email: merwanroudane920@gmail.com
- GitHub: https://github.com/merwanroudane/cusum
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
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 dyncusum-1.0.0.tar.gz.
File metadata
- Download URL: dyncusum-1.0.0.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84feb0c0fb540f6ec17fc25318e299039b9bfb2d11c13a468b6b2ed992d42d32
|
|
| MD5 |
c3a9b5d80cc13d5b87983c5680d23d1c
|
|
| BLAKE2b-256 |
2a33f64295a35e7995d995d4f44502c2ca5b1e00b930dd3f9f160d73bd4e9e6b
|
File details
Details for the file dyncusum-1.0.0-py3-none-any.whl.
File metadata
- Download URL: dyncusum-1.0.0-py3-none-any.whl
- Upload date:
- Size: 30.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a25555823c62e35ed6a2387da052fbf575cb5303ed9e254e4c4ec62f8878ed9
|
|
| MD5 |
4d6389c611229ee6c921d4e3e568e359
|
|
| BLAKE2b-256 |
f767101bfce58d9a3d97524c357445623fbc78060a750eaba97504a829b2c914
|