Skip to main content

Quantile Cointegrating Regression - Implementation based on Xiao (2009) Journal of Econometrics

Project description

Quantilecoint

Python 3.8+ License: MIT Version

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 class
  • QuantileCointegrationResults - 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


Download files

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

Source Distribution

quantilecoint-1.0.1.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

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

quantilecoint-1.0.1-py3-none-any.whl (47.8 kB view details)

Uploaded Python 3

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

Hashes for quantilecoint-1.0.1.tar.gz
Algorithm Hash digest
SHA256 2fd947ad9178214b9fe90e862d378da87cdcd47c2bc1d72be3482904250ce062
MD5 f8d2066a197e916c8f35e2a9d85929a6
BLAKE2b-256 1dae2ab756b6d70329ab11736dc5f622cd78318e05aa34997e0e2c7f2f84fa1c

See more details on using hashes here.

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

Hashes for quantilecoint-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 31bb8c4301865d7e1ddedd4647a73a5d32cfa792219e5ebac6cffc067b2df427
MD5 a4820baed84d744f4c1a0a1952f7540f
BLAKE2b-256 3f349949d16ff0e704b56ff1b677961c38df51e65d0d2610d5d7a5f3076c7b15

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