Skip to main content

Multiple Structural Break Detection in Vector Error Correction Models

Project description

vecmbreak

PyPI version Python 3.9+ License: MIT

Multiple Structural Break Detection in Vector Error Correction Models

A Python implementation of the methodology from Franjic, Mößler, and Schweikert (2025) for detecting and estimating multiple structural breaks in Vector Error Correction Models (VECMs) using Group LASSO with Backward Elimination.

Features

  • Two-Step Estimation: Group LASSO screening followed by Backward Elimination refinement
  • Two Cases Supported:
    • Case 1: Constant adjustment coefficients (α), regime-specific cointegrating vectors (β)
    • Case 2: Both α and β vary across regimes
  • Principal Component Estimation: Efficient estimation of cointegrating parameters
  • Automatic Break Detection: Data-driven selection of break locations and number of breaks
  • Impulse Response Functions: Regime-specific IRF computation
  • Monte Carlo Simulation: Tools for simulation studies and model validation

Installation

pip install vecmbreak

For development installation:

pip install vecmbreak[dev]

Quick Start

import numpy as np
from vecmbreak import VECMBreak, generate_dgp_case1

# Generate simulated data with one structural break
np.random.seed(42)
data = generate_dgp_case1(T=300, break_fractions=[0.5])
Y = data['Y']

# Detect structural breaks
model = VECMBreak(case=1, rank=1)
results = model.fit(Y)

# View results
print(results.summary())
print(f"Detected breaks: {results.breaks}")
print(f"Number of regimes: {results.n_regimes}")

Detailed Usage

Basic Break Detection

from vecmbreak import VECMBreak, fit_vecm_breaks

# Method 1: Using the class
model = VECMBreak(
    case=2,              # Both α and β change
    rank=1,              # Cointegration rank
    k_ar=2,              # VAR lag order
    deterministic='c',   # Include constant
    max_breaks=5         # Maximum breaks to consider
)
results = model.fit(Y)

# Method 2: Using convenience function
results = fit_vecm_breaks(Y, rank=1, case=2)

Accessing Results

# Break locations
print(results.breaks)        # [100, 200] - break indices
print(results.break_dates)   # Alias for breaks

# Estimated parameters
print(results.alpha)         # Adjustment coefficients
print(results.beta)          # Cointegrating vectors (list, one per regime)

# Model diagnostics
print(results.n_breaks)      # Number of detected breaks
print(results.n_regimes)     # Number of regimes
print(results.ic_value)      # Information criterion value
print(results.residuals)     # Model residuals

# Export to dictionary
results_dict = results.to_dict()

Data Generation for Simulation

from vecmbreak import (
    generate_dgp_case1,
    generate_dgp_case2,
    generate_dgp_with_short_run,
    simulate_vecm_breaks
)

# Case 1: Only β changes at breaks
data1 = generate_dgp_case1(
    T=300, 
    break_fractions=[0.33, 0.67],  # Two breaks
    sigma_u=1.0,
    seed=42
)

# Case 2: Both α and β change
data2 = generate_dgp_case2(
    T=300,
    break_fractions=[0.5],
    seed=42
)

# With short-run dynamics
data3 = generate_dgp_with_short_run(
    T=300,
    break_fractions=[0.5],
    k_ar=2,  # VAR(2) short-run dynamics
    seed=42
)

# Custom simulation
alpha_list = [np.array([[-0.3], [0.2]]), np.array([[-0.5], [0.3]])]
beta_list = [np.array([[1.0], [-1.0]]), np.array([[1.0], [-0.8]])]

Y, info = simulate_vecm_breaks(
    T=300,
    N=2,
    alpha_list=alpha_list,
    beta_list=beta_list,
    breaks=[150],
    seed=42
)

Impulse Response Functions

from vecmbreak import compute_irf, plot_irf

# Compute IRFs for each regime
irfs = compute_irf(results, horizon=20)

# Plot IRFs (requires matplotlib)
plot_irf(irfs, variable_names=['y1', 'y2', 'y3'])

Monte Carlo Simulation

from vecmbreak import monte_carlo_simulation

# Run Monte Carlo study
mc_results = monte_carlo_simulation(
    n_simulations=100,
    T=300,
    case=1,
    true_breaks=[150],
    seed=42
)

print(f"Break detection rate: {mc_results['detection_rate']:.2%}")
print(f"Mean break location error: {mc_results['mean_location_error']:.2f}")

Methodology

The package implements the two-step procedure from Franjic, Mößler, and Schweikert (2025):

Step 1: Group LASSO Screening

The VECM is reformulated to allow for potential breaks at each time point:

$$\Delta Y_t = \Pi_t Y_{t-1} + \sum_{i=1}^{K-1} \Gamma_i \Delta Y_{t-i} + \mu_0 + u_t$$

where $\Pi_t = \alpha \beta'_t$ (Case 1) or $\Pi_t = \alpha_t \beta'_t$ (Case 2).

Group LASSO is applied with the modified BIC penalty:

$$\lambda_T = c \cdot T^{-3/4} \sqrt{\log(T)}$$

Step 2: Backward Elimination

Starting from Group LASSO candidates, breaks are sequentially removed if removal improves the information criterion:

$$IC(m) = \log|\hat{\Sigma}_u| + p(m) \cdot \frac{\log(T)}{T}$$

where $p(m)$ is the effective number of parameters.

Parameter Estimation

Regime-specific parameters are estimated via Principal Components:

  1. For each regime, compute $\hat{\beta}j$ from eigenvectors of $S{11,j}^{-1} S_{10,j} S_{00,j}^{-1} S_{01,j}$
  2. Estimate $\hat{\alpha}j = S{01,j} \hat{\beta}_j (\hat{\beta}'j S{11,j} \hat{\beta}_j)^{-1}$

API Reference

Main Classes

  • VECMBreak: Main estimation class
  • VECMBreakResults: Results container with summary methods

Key Functions

  • fit_vecm_breaks(): Convenience function for break detection
  • generate_dgp_case1(): Generate Case 1 DGP data
  • generate_dgp_case2(): Generate Case 2 DGP data
  • simulate_vecm_breaks(): Custom VECM simulation
  • compute_irf(): Impulse response function computation

Utility Functions

  • vec_operator(): Matrix vectorization (column-major)
  • inv_vec_operator(): Inverse vectorization
  • normalize_cointegrating_vectors(): β normalization
  • check_stationarity(): Stationarity verification

References

Franjic, D., Mößler, M., & Schweikert, K. (2025). Multiple Structural Breaks in Vector Error Correction Models. University of Hohenheim Working Paper.

Citation

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

@article{franjic2025vecmbreak,
  title={Multiple Structural Breaks in Vector Error Correction Models},
  author={Franjic, D. and M{\"o}{\ss}ler, M. and Schweikert, K.},
  journal={University of Hohenheim Working Paper},
  year={2025}
}

License

MIT License - see LICENSE for details.

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

Changelog

See CHANGELOG.md for version history.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vecmbreak-0.1.0.tar.gz (60.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vecmbreak-0.1.0-py3-none-any.whl (63.4 kB view details)

Uploaded Python 3

File details

Details for the file vecmbreak-0.1.0.tar.gz.

File metadata

  • Download URL: vecmbreak-0.1.0.tar.gz
  • Upload date:
  • Size: 60.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for vecmbreak-0.1.0.tar.gz
Algorithm Hash digest
SHA256 224feeb56082942d761f45ae06cad5695aa196b9e0dc3808f3934325e76300c7
MD5 ebc28f90fcfdda545ea315f597b6f583
BLAKE2b-256 762fea9a96edf3c0bd66eec60da3183655b2e96973ee55849c3e662cf3d24fe9

See more details on using hashes here.

File details

Details for the file vecmbreak-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vecmbreak-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 63.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for vecmbreak-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ad046f0971576b7800974108f3b14153e8d50eccfe54fa0449fa6ef45b3dfd4
MD5 7e7ee4f9dfae79dedb2957f24efd7cd1
BLAKE2b-256 b62c949739062de14630948e01e6b652073e4aff1240b157bdcca63e49e07308

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page