Quantile Cointegrating Regression - Implementation based on Xiao (2009) Journal of Econometrics
Project description
Quantilecoint
Quantile Cointegrating Regression - A Python implementation based on Xiao (2009) "Quantile cointegrating regression", Journal of Econometrics, 150, 248-260.
Author
Dr Merwan Roudane
Email: merwanroudane920@gmail.com
GitHub: https://github.com/merwanroudane/quantilecoint
Overview
This package implements quantile regression methods for cointegrated time series, including:
- Quantile Cointegrating Regression: Estimate cointegrating relationships at different quantiles
- Fully-Modified Quantile Regression: Bias-corrected estimator for endogenous regressors
- Augmented Quantile Cointegrating Regression: Uses leads and lags to handle endogeneity
- Wald Test: Test linear restrictions on cointegrating coefficients
- Stability Test: Bootstrap-based test for constant vs. time-varying coefficients
- CUSUM Cointegration Test: Robust test for the null of cointegration
Installation
pip install quantilecoint
Or install from source:
git clone https://github.com/merwanroudane/quantilecoint.git
cd quantilecoint
pip install -e .
Complete Example: All Functions Demonstrated
import numpy as np
from quantilecoint import QuantileCointegration
# =============================================================================
# 1. GENERATE COINTEGRATED DATA
# =============================================================================
np.random.seed(42)
n = 200
# x_t is an I(1) process (random walk)
x = np.cumsum(np.random.randn(n))
# y_t is cointegrated with x_t: y = α + β*x + u
alpha_true = 2.0
beta_true = 1.5
y = alpha_true + beta_true * x + np.random.randn(n) * 0.5
print("=" * 70)
print("QUANTILECOINT LIBRARY - COMPLETE DEMONSTRATION")
print("Based on Xiao (2009) Journal of Econometrics")
print("=" * 70)
# =============================================================================
# 2. CREATE MODEL
# =============================================================================
model = QuantileCointegration(y, x, n_lags=4)
print(f"\nModel created with {n} observations, K=4 leads/lags")
# =============================================================================
# 3. FIT AT SINGLE QUANTILE (tau=0.5 for median)
# =============================================================================
print("\n" + "-" * 70)
print("3. SINGLE QUANTILE ESTIMATION (τ = 0.5)")
print("-" * 70)
results_single = model.fit(tau=0.5)
res = results_single[0.5]
print(f" Intercept α(0.5): {res.alpha:.4f} (true: {alpha_true})")
print(f" Slope β(0.5): {res.beta[0]:.4f} (true: {beta_true})")
# =============================================================================
# 4. FIT AT MULTIPLE QUANTILES
# =============================================================================
print("\n" + "-" * 70)
print("4. MULTIPLE QUANTILE ESTIMATION")
print("-" * 70)
quantiles = [0.1, 0.25, 0.5, 0.75, 0.9]
results = model.fit(tau=quantiles)
print(f"{'τ':>8} {'α(τ)':>12} {'β(τ)':>12}")
print("-" * 35)
for tau in quantiles:
res = results[tau]
print(f"{tau:>8.2f} {res.alpha:>12.4f} {res.beta[0]:>12.4f}")
# =============================================================================
# 5. FULLY-MODIFIED QUANTILE REGRESSION (bias-corrected)
# =============================================================================
print("\n" + "-" * 70)
print("5. FULLY-MODIFIED QUANTILE REGRESSION (Theorem 2)")
print("-" * 70)
fm_result = model.fit_fully_modified(tau=0.5)
print(f" β̂⁺(0.5): {fm_result.beta[0]:.6f}")
print(f" Std. Error: {fm_result.std_errors[1]:.6f}")
print(f" t-statistic: {fm_result.tvalues[1]:.4f}")
print(f" p-value: {fm_result.pvalues[1]:.6f}")
ci = fm_result.conf_int()
print(f" 95% CI: [{ci[1, 0]:.4f}, {ci[1, 1]:.4f}]")
# =============================================================================
# 6. WALD TEST FOR LINEAR RESTRICTIONS
# =============================================================================
print("\n" + "-" * 70)
print("6. WALD TEST (Theorem 3): H₀: β = 1.5")
print("-" * 70)
R = np.array([[0, 1]]) # Test the slope coefficient
r = np.array([1.5]) # Against value 1.5
wald_result = model.wald_test(R, r, tau=0.5)
print(f" Wald statistic: {wald_result.statistic:.4f}")
print(f" Degrees of freedom: {wald_result.df}")
print(f" P-value: {wald_result.pvalue:.4f}")
if wald_result.pvalue > 0.05:
print(" Conclusion: FAIL TO REJECT H₀ (β = 1.5)")
else:
print(" Conclusion: REJECT H₀")
# =============================================================================
# 7. STABILITY TEST (constant vs. time-varying coefficients)
# =============================================================================
print("\n" + "-" * 70)
print("7. STABILITY TEST (Section 3.2): H₀: β(τ) = β (constant)")
print("-" * 70)
stability = model.test_stability(
quantiles=np.arange(0.1, 0.91, 0.1),
n_bootstrap=200 # Use more (e.g., 1000) for publication
)
print(f" Test statistic sup|V̂ₙ(τ)|: {stability.statistic:.4f}")
print(f" τ with max deviation: {stability.tau_max:.2f}")
print(f" Bootstrap p-value: {stability.pvalue:.4f}")
print(f" Critical values:")
print(f" 10%: {stability.critical_values['10%']:.4f}")
print(f" 5%: {stability.critical_values['5%']:.4f}")
print(f" 1%: {stability.critical_values['1%']:.4f}")
if stability.reject_at_05:
print(" Conclusion: REJECT H₀ - Evidence of time-varying coefficients")
else:
print(" Conclusion: FAIL TO REJECT H₀ - Coefficients appear constant")
# =============================================================================
# 8. CUSUM COINTEGRATION TEST
# =============================================================================
print("\n" + "-" * 70)
print("8. CUSUM COINTEGRATION TEST (Section 3.3): H₀: Cointegrated")
print("-" * 70)
coint_test = model.test_cointegration(tau=0.5, test_type='ks')
print(f" CUSUM statistic: {coint_test.statistic:.4f}")
print(f" Test type: {coint_test.test_type.upper()}")
print(f" P-value: {coint_test.pvalue:.4f}")
if coint_test.reject_at_05:
print(" Conclusion: REJECT H₀ - Evidence against cointegration")
else:
print(" Conclusion: FAIL TO REJECT H₀ - Series appear cointegrated")
# =============================================================================
# 9. GET FORMATTED SUMMARY
# =============================================================================
print("\n" + "-" * 70)
print("9. PUBLICATION-READY SUMMARY OUTPUT")
print("-" * 70)
summary = results.summary()
print("\nText format (first 500 chars):")
print(summary.as_text()[:500] + "...")
# =============================================================================
# 10. LATEX OUTPUT FOR PAPERS
# =============================================================================
print("\n" + "-" * 70)
print("10. LATEX TABLE OUTPUT")
print("-" * 70)
latex = summary.as_latex()
print(latex[:400] + "...\n")
print("=" * 70)
print("ALL FUNCTIONS DEMONSTRATED SUCCESSFULLY!")
print("=" * 70)
Quick Reference
Basic Usage
from quantilecoint import QuantileCointegration
model = QuantileCointegration(y, x, n_lags=4)
# Fit at single quantile
results = model.fit(tau=0.5)
# Fit at multiple quantiles
results = model.fit(tau=[0.1, 0.25, 0.5, 0.75, 0.9])
# Access coefficients
beta = results[0.5].beta
alpha = results[0.5].alpha
Fully-Modified Estimates (Bias-Corrected)
fm_result = model.fit_fully_modified(tau=0.5)
print(fm_result.summary())
Statistical Tests
# Test H₀: β = 1.0
wald = model.wald_test(R=np.array([[0, 1]]), r=np.array([1.0]), tau=0.5)
# Test for time-varying coefficients
stability = model.test_stability(n_bootstrap=1000)
# Test for cointegration
coint = model.test_cointegration(tau=0.5)
Output Formats
results = model.fit(tau=[0.1, 0.5, 0.9])
summary = results.summary()
# Plain text
print(summary.as_text())
# LaTeX (for papers)
print(summary.as_latex())
# HTML (for web)
print(summary.as_html())
API Reference
Classes
QuantileCointegration- Main model classQuantileCointegrationResults- Results container
Methods
| Method | Description |
|---|---|
fit(tau=, method=) |
Fit quantile regression at specified quantile(s) |
fit_fully_modified(tau=) |
Fit bias-corrected estimator |
wald_test(R, r, tau=) |
Test linear restrictions on β |
test_stability(n_bootstrap=) |
Test for constant coefficients |
test_cointegration(tau=) |
CUSUM test for cointegration |
References
- Xiao, Z. (2009). Quantile cointegrating regression. Journal of Econometrics, 150(2), 248-260.
- Koenker, R., & Bassett, G. (1978). Regression quantiles. Econometrica, 46(1), 33-50.
- Koenker, R., & Xiao, Z. (2006). Quantile autoregression. Journal of the American Statistical Association, 101(475), 980-990.
License
MIT License - see LICENSE file for details.
Citation
@software{roudane2026quantilecoint,
author = {Roudane, Merwan},
title = {quantilecoint: Quantile Cointegrating Regression in Python},
year = {2026},
version = {1.0.1},
url = {https://github.com/merwanroudane/quantilecoint}
}
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 quantilecoint-1.0.1.tar.gz.
File metadata
- Download URL: quantilecoint-1.0.1.tar.gz
- Upload date:
- Size: 38.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fd947ad9178214b9fe90e862d378da87cdcd47c2bc1d72be3482904250ce062
|
|
| MD5 |
f8d2066a197e916c8f35e2a9d85929a6
|
|
| BLAKE2b-256 |
1dae2ab756b6d70329ab11736dc5f622cd78318e05aa34997e0e2c7f2f84fa1c
|
File details
Details for the file quantilecoint-1.0.1-py3-none-any.whl.
File metadata
- Download URL: quantilecoint-1.0.1-py3-none-any.whl
- Upload date:
- Size: 47.8 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 |
31bb8c4301865d7e1ddedd4647a73a5d32cfa792219e5ebac6cffc067b2df427
|
|
| MD5 |
a4820baed84d744f4c1a0a1952f7540f
|
|
| BLAKE2b-256 |
3f349949d16ff0e704b56ff1b677961c38df51e65d0d2610d5d7a5f3076c7b15
|