Skip to main content

pycointbreak

Tests for breaks in fractional cointegration — a Python implementation of the Hassler & Breitung (2006) residual-based LM test and the Rodrigues, Sibbertsen & Voges (2019) supremum tests for breaks in the cointegrating relationship.

python status license


Author

Dr. Merwan Roudane Email: merwanroudane920@gmail.com GitHub: https://github.com/merwanroudane/pycointbreak

If you use this library in academic work, please cite both the underlying papers and this package — see pycointbreak.cite() for ready-made BibTeX entries.


What does it do?

Given a scalar series y and a (possibly multivariate) series x, each integrated of order d, pycointbreak lets you test whether

y_t = β' x_t + z_t,        z_t ~ I(d − b),   b ≥ 0,

is

  1. Cointegrated at all (b > 0) — using the Hassler & Breitung (2006) LM-type test.
  2. Cointegrated only on part of the sample (segmented fractional cointegration) — using the Rodrigues, Sibbertsen & Voges (2019) sup-tests over split, forward incremental, backward incremental, and rolling sub-samples.

When the answer is "yes, breaks", the library can also estimate the break date via the consistent estimator of RSV (2019, eq. 19).


Installation

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

Dependencies: numpy, pandas, scipy, statsmodels, matplotlib, seaborn. Optional: yfinance (for the real-data example).


Quick start

import pycointbreak as pcb

# 1. Generate (or load) two I(d) series.
y, x = pcb.simulate_segmented_cointegration(
    T=500, d=1.0, b=0.4, break_frac=0.5,
    regime="coint_then_spurious", seed=2024,
)

# 2. Full-sample Hassler-Breitung test.
hb = pcb.hassler_breitung_test(y, x, d=1.0, p=0)
print(hb.summary())

# 3. RSV (2019) sup-test battery.
battery = pcb.rsv_battery(y, x, d=1.0, lam0=0.5, n_grid=120)
for k, r in battery.items():
    print(r.summary())

# 4. Estimate the break date.
bp = pcb.estimate_break_point(y, x, d=1.0, direction="auto")
print(bp.summary())

# 5. Paper-style summary table.
df = pcb.battery_to_dataframe(battery, hb=hb, label="my pair")
print(pcb.render_table(df, fmt="text",
                       title="Tests for segmented cointegration"))

# 6. Plots.
import matplotlib.pyplot as plt
pcb.plot_series_with_breaks({"y": y, "x": x}, {"break": bp.obs})
pcb.plot_rsv_battery(battery)
pcb.plot_breakpoint_objective(bp)
plt.show()

Mathematical compatibility with the papers

The implementation follows the papers' notation closely. The key ingredients are exposed as building blocks:

Symbol Function
Δ⁺ᵈ x_t — truncated (Type II) fractional difference pcb.fdiff(x, d)
π_j(d) — coefficients of (1−L)^d pcb.frac_coefs(d, n)
x*_{t−1} = Σ_{j=1}^{t−1} x_{t−j}/j — harmonic-weighted sum (HB eq. 3) pcb.harmonic_running_sum(x)
(1−L)^{−d} x_t — fractional integration pcb.frac_integrate(x, d)
Geweke & Porter-Hudak d̂ pcb.gph(x)
HB test (eqs. 12–14, iid case) pcb.hassler_breitung_test(..., p=0)
HB test with AR(p) augmentation (eqs. 17–18) pcb.hassler_breitung_test(..., p=p)
RSV sub-sample t-stat (eq. 5) internal _hb_subsample_tstat
Sup-statistics 𝒯_S, 𝒯_S*, 𝒯_If, 𝒯_Ib, 𝒯_R (eqs. 10–15) pcb.rsv_sup_test(..., kind=...)
RSV break-point estimator (eq. 19) pcb.estimate_break_point(...)
Critical values from Table 1 of RSV2019 pcb.rsv_critical_value(test, T, alpha)

On the eq.-(5) √n factor

Equation (5) of RSV (2019) literally reads

t(ê(λ₁,λ₂)) = √(⌊λ₂T⌋ − ⌊λ₁T⌋) · Σ ê_t · ê*_{t−1}
              / [√Σ ê*²_{t−1} · √((T−1)⁻¹ · Σ ê²_t)]

With the full-sample variance 1/(T−1) and the extra √n factor, under H0 this statistic is O_p(√T) rather than asymptotically N(0,1), which would contradict Theorem 2 (sup χ²₁ limit) and the critical values of Table 1 (5%-cv ≈ 4–6 for T = 500). We therefore interpret the formula as the standard HB statistic (eq. 14 of HB2006) applied to the sub-sample, with sub-sample variance 1/(n−1) — the same convention used by Davidson & Monticini (2010). This yields t → N(0, 1) per Proposition 3 of HB2006 and T_K → sup χ²₁ consistent with Theorem 2 of RSV2019.

On the critical values

The tabulated critical values in pcb.RSV_TABLE1 reproduce Table 1 of RSV (2019) for T = 250 and T = 500 with λ₀ = 0.5. They are the result of a Monte Carlo simulation in the paper averaged over several values of d. For configurations far from (T ∈ {250, 500}, λ₀ = 0.5, d ≈ 1), use the bootstrap helper

cv = pcb.bootstrap_rsv_cv(
    T=1000, d=1.0, kind="T_If", n_sim=2000,
)
print(cv)   # {0.10: ..., 0.05: ..., 0.01: ...}

which returns critical values calibrated to your exact sample size, grid, and d.


Modules

Module Contents
pycointbreak.fracdiff Truncated (Type II) fractional difference operators
pycointbreak.gph GPH log-periodogram estimator of d
pycointbreak.hassler_breitung HB (2006) LM-type test
pycointbreak.rsv_tests RSV (2019) sup-tests for breaks
pycointbreak.breakpoint Break-fraction estimator (RSV eq. 19)
pycointbreak.critical_values Tabulated and bootstrap critical values
pycointbreak.simulate DGPs from HB2006 §5 and RSV2019 §4 (Experiments 1–3)
pycointbreak.reporting Paper-style tables (text/markdown/LaTeX/HTML)
pycointbreak.plots Publication-quality figures (matplotlib + seaborn)

API at a glance

Tests

hassler_breitung_test(y1, y2, d=1.0, p=0, include_const=True)
    → HBResult(t_stat, p_value, reject, ...)

rsv_sup_test(y1, y2, d=1.0, kind="T_If", lam0=0.5, n_grid=200, ...)
    → RSVResult(statistic, argmax, t2_path, ...)

rsv_battery(y1, y2, d=1.0, tests=("T_S_star", "T_If", "T_Ib", "T_R"), ...)
    → dict[str, RSVResult]

estimate_break_point(y1, y2, d=1.0, delta=0.05, direction="auto", ...)
    → BreakPointResult(tau_hat, obs, date, objective, ...)

Reporting

df = battery_to_dataframe(battery, hb=hb, label="series")
print(render_table(df, fmt="text"))      # ASCII
print(render_table(df, fmt="markdown"))   # for GitHub / Jupyter
print(render_table(df, fmt="latex"))      # for papers
print(render_table(df, fmt="html"))       # for web

Plots

plot_series_with_breaks(series_dict, breaks_dict)
plot_rsv_profile(rsv_result)            # one sup-test
plot_rsv_battery(battery_dict)          # 2×2 panel of all four
plot_breakpoint_objective(bp_result)
plot_residual_diagnostics(residuals)
plot_split_heatmap(y, x, d=1.0, ...)    # 2-D (λ₁, λ₂) heatmap

Simulation

simulate_rsv_dgp(T=500, d=1.0, b=0.0)
    # Experiment 1 — constant cointegration over the whole sample

simulate_segmented_cointegration(
    T=500, d=1.0, b=0.4, break_frac=0.5,
    regime="coint_then_spurious",
)
    # Experiments 2 & 3 — one break in the cointegrating relationship

Examples

The examples/ folder contains three runnable scripts:

  • example_basic.py — minimal end-to-end demo on simulated data.
  • example_real_data.py — applies the full pipeline to real stock prices (Coca-Cola / Pepsi by default via yfinance; falls back to simulated data when the network is unavailable).
  • example_simulation_study.py — small Monte Carlo reproducing a slice of Table 2 of RSV (2019).

References

  • Hassler, U. and Breitung, J. (2006). A Residual-Based LM Type Test Against Fractional Cointegration. Econometric Theory, 22(6), 1091–1111.
  • Rodrigues, P. M. M., Sibbertsen, P. and Voges, M. (2019). Testing for breaks in the cointegrating relationship: On the stability of government bond markets' equilibrium. Discussion Paper 656.
  • Davidson, J. and Monticini, A. (2010). Tests for cointegration with structural breaks based on subsamples. Computational Statistics & Data Analysis, 54(11), 2498–2511.
  • Robinson, P. M. (1991). Testing for strong serial correlation and dynamic conditional heteroskedasticity in multiple regression. Journal of Econometrics, 47, 67–84.
  • Breitung, J. and Hassler, U. (2002). Inference on the cointegration rank in fractionally integrated processes. Journal of Econometrics, 110, 167–185.
  • Demetrescu, M., Kuzin, V. and Hassler, U. (2008). Long memory testing in the time domain. Econometric Theory, 24(1), 176–215.
  • Geweke, J. and Porter-Hudak, S. (1983). The Estimation and Application of Long Memory Time Series Models. Journal of Time Series Analysis, 4, 221–238.

License

MIT

Metadata

Release files for pycointbreak 0.1.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 pycointbreak 0.1.0
File Size Uploaded Provenance
pycointbreak-0.1.0.tar.gz 39.1 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 79.8 kB

Release files / pycointbreak-0.1.0.tar.gz

Download URL pycointbreak-0.1.0.tar.gz
Size 39.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f286671fad5d5245888df1ba5795a2dec4a7b3d713b51215c19d62f466957282
BLAKE2b-256 checksum
How to use checksums
cb20838da683202abe20f30935ea445ab7a2302805287c2047141771bcda98a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Release files / pycointbreak-0.1.0-py3-none-any.whl

Download URL pycointbreak-0.1.0-py3-none-any.whl
Size 40.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1d998bc0c9b51091b2b3a068c3b6d646f26feca8034dab756c547c1ba04b83fe
BLAKE2b-256 checksum
How to use checksums
46599b78b8431ece147426cbf107bca5e0d8c12eb0505f2c3f764b7b6b4433c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Security for pycointbreak 0.1.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

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