Quantile Autoregressive Distributed Lag (QARDL) Model Estimation and Testing
Project description
CORRECTED QARDL Package
Complete Python implementation of Cho, Kim & Shin (2015) with ALL CRITICAL CORRECTIONS.
๐จ CRITICAL CORRECTIONS IMPLEMENTED
This package fixes ALL 8 MAJOR GAPS identified in the original implementation:
โ 1. FIXED: Standard Errors (Theorem 1)
Original Error: Used generic sandwich formula
Correction: Exact formula with H_t projection
H_t = K_t(ฯ) - E[K_t(ฯ)W_t']E[W_tW_t']^{-1}W_t
Var(ฯ) = ฯ(1-ฯ)f_ฯ^{-2}E[H_tH_t']^{-1}
โ 2. FIXED: Long-Run Wald Tests (Corollary 1)
Original Error: Used n scaling
Correction: nยฒ scaling
W = nยฒ(Rฮฒ-r)'[R(ฮฃโMโปยน)R']โปยน(Rฮฒ-r) ~ ฯยฒ(r)
โ 3. FIXED: Short-Run Wald Tests (Corollaries 2, 3)
Original Error: Wrong scaling
Correction: n scaling for short-run
W(ฯ) = n(Rฯ-r)'[Rฮ R']โปยน(Rฯ-r) ~ ฯยฒ(r)
W(ฮณ) = n(Rฮณ-r)'[Rฮฒฮน'โฮ ฮนโฮฒ'R']โปยน(Rฮณ-r) ~ ฯยฒ(1) [rank 1!]
โ 4. FIXED: ECM Representation (Equation 6)
Original Error: Incomplete 10-line placeholder
Correction: Complete 453-line implementation
ฮYโ = ฮฑ*(ฯ) + ฮถ*(ฯ)[Yโโโ - ฮฒ*(ฯ)'Xโโโ] + ฮฃฯ*โฑผ(ฯ)ฮYโโโฑผ + ฮฃฮธ*โฑผ(ฯ)ฮXโโโฑผ + Uโ(ฯ)
โ 5. FIXED: Lag Selection
Original Error: Used quantile-based BIC
Correction: OLS-based BIC at MEAN (icmean.m)
# CORRECT: Estimate at MEAN using OLS, then compute BIC
BIC = log(ฯยฒ) + (# parameters) * log(n) / n
โ 6. FIXED: M Matrix (Theorem 2)
Original Error: Generic computation
Correction: Exact formula with projection
M = nโปยฒX'[I - W(W'W)โปยนW']X
โ 7. FIXED: Rolling Estimation
Original Error: Basic 50-line placeholder
Correction: Complete implementation with ALL parameters
โ 8. FIXED: Multi-Quantile Tests (Corollary 4)
Original Error: Missing covariance structures
Correction: Complete ฮ(ฯ) and ฮฃ(ฯ)โMโปยน
Installation
# From source
git clone https://github.com/merwanroudane/qardl
cd qardl-corrected
pip install -e .
Quick Start
import numpy as np
from qardl import QARDLCorrected
# Load data
data = np.loadtxt('data.csv', delimiter=',') # [Y, X1, X2, ...]
# Estimate QARDL with CORRECTED methods
model = QARDLCorrected(
data=data,
p=2, # AR order
q=1, # DL order
tau=0.5, # Median
constant=True
)
# Fit with CORRECT standard errors
results = model.fit(
bandwidth_method='bofinger',
cov_type='correct', # Uses H_t projection!
verbose=True
)
# View results
print(results.summary())
Complete Example: All Corrections
import numpy as np
from qardl import (
QARDLCorrected,
WaldTestsCorrected,
QARDLtoECM,
ECMWaldTests,
select_qardl_orders,
RollingQARDL
)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# STEP 1: LAG SELECTION (CORRECTED - Uses OLS at mean)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
p_opt, q_opt = select_qardl_orders(
data=data,
p_max=8,
q_max=8,
criterion='bic', # Uses OLS-based BIC at MEAN!
verbose=True
)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# STEP 2: QARDL ESTIMATION (CORRECTED - Proper standard errors)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
model = QARDLCorrected(
data=data,
p=p_opt,
q=q_opt,
tau=[0.25, 0.5, 0.75], # Multiple quantiles
constant=True
)
results = model.fit(verbose=True)
# Long-run parameters with CORRECT standard errors
print("\nLong-Run Parameters (ฮฒ):")
for tau in [0.25, 0.5, 0.75]:
beta = results.beta[tau]
beta_se = results.beta_se[tau] # Uses nยฒ convergence rate!
print(f"ฯ={tau}: ฮฒ={beta[0]:.4f} (se={beta_se[0]:.4f})")
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# STEP 3: WALD TESTS (CORRECTED - Proper nยฒ and n scaling)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
wald = WaldTestsCorrected(results)
# Test long-run ฮฒ=0 (uses nยฒ scaling!)
R = np.array([[1, 0]]) # Test ฮฒโ = 0
r = np.array([0])
test_beta = wald.wtestlrb(R, r, tau=0.5)
print(f"\nLong-run test: W={test_beta['statistic']:.2f}, "
f"p={test_beta['p_value']:.4f} (nยฒ scaling)")
# Test short-run ฯ (uses n scaling!)
Q = np.array([[1, 0]]) # Test ฯโ = 0
q = np.array([0])
test_phi = wald.wtestsrp(Q, q, tau=0.5)
print(f"Short-run test: W={test_phi['statistic']:.2f}, "
f"p={test_phi['p_value']:.4f} (n scaling)")
# Test equality across quantiles (multi-quantile test)
test_equality = wald.test_equality_across_quantiles(
parameter='beta',
quantiles=[0.25, 0.5, 0.75]
)
print(f"\nEquality test: W={test_equality['statistic']:.2f}, "
f"p={test_equality['p_value']:.4f}")
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# STEP 4: ECM REPRESENTATION (CORRECTED - Complete implementation)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ecm = QARDLtoECM(results)
# View ECM parameters
print("\nECM Representation:")
print(ecm.summary_ecm(tau=0.5))
# ECM-specific tests
ecm_tests = ECMWaldTests(ecm)
# Test no error correction
test_no_ec = ecm_tests.test_no_error_correction(tau=0.5)
print(f"\nNo error correction test: W={test_no_ec['statistic']:.2f}, "
f"p={test_no_ec['p_value']:.4f}")
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# STEP 5: ROLLING ESTIMATION (CORRECTED - Complete with all params)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
rolling = RollingQARDL(
data=data,
p=p_opt,
q=q_opt,
tau=0.5,
window=320, # 320 quarters as in paper
constant=True
)
rolling.fit(verbose=True)
# Plot time-varying parameters
rolling.plot_results(
parameters=['beta', 'zeta', 'half_life'],
variable_indices={'beta': 0},
save_path='rolling_results.pdf'
)
# Export to DataFrame
df = rolling.to_dataframe()
df.to_csv('rolling_estimates.csv', index=False)
print("\n" + "="*70)
print("ALL CORRECTIONS APPLIED SUCCESSFULLY!")
print("="*70)
Key Features
โ Correct Asymptotic Theory
- Proper โn convergence for short-run parameters
- Proper n convergence for long-run parameters
- Correct mixture normal distributions
โ Correct Wald Tests
- Long-run: nยฒ scaling with ฮฃโMโปยน covariance
- Short-run: n scaling with ฮ (ฯ) covariance
- Multi-quantile: ฮ(ฯ) and ฮฃ(ฯ) structures
โ Complete ECM
- Error correction coefficient ฮถ
- Half-life computation
- All short-run dynamics ฯ*, ฮธ*
- ECM-specific tests
โ Correct Lag Selection
- OLS-based BIC at conditional mean
- Matches icmean.m from MATLAB
- Stability diagnostics
โ Complete Rolling Estimation
- All parameters tracked over time
- Wald test sequences
- Publication-ready plots
- Matches rolling_qardl from GAUSS
API Reference
Core Estimation
model = QARDLCorrected(data, p, q, tau, constant=True)
results = model.fit(
bandwidth_method='bofinger', # or 'hall-sheather'
cov_type='correct', # Uses H_t projection
verbose=True
)
Wald Tests
wald = WaldTestsCorrected(results)
# Long-run (nยฒ scaling)
wald.wtestlrb(R, r, tau)
# Short-run ฯ (n scaling)
wald.wtestsrp(Q, q, tau)
# Short-run ฮณ (n scaling, rank 1!)
wald.wtestsrg(R, r, tau)
# Multi-quantile
wald.wald_multi_quantile_beta(S, s, quantiles)
wald.wald_multi_quantile_phi(F, f, quantiles)
ECM Representation
ecm = QARDLtoECM(results)
ecm_params = ecm.get_ecm_params(tau)
ecm_tests = ECMWaldTests(ecm)
ecm_tests.test_no_error_correction(tau)
ecm_tests.test_granger_causality(variable_idx, tau)
Lag Selection
# Grid search (recommended)
p_opt, q_opt = select_qardl_orders(
data, p_max=8, q_max=8, criterion='bic'
)
# Sequential search (faster)
p_opt, q_opt = select_orders_sequential(
data, p_max=8, q_max=8
)
# Stability check
stability = evaluate_order_stability(data, p, q)
Rolling Estimation
rolling = RollingQARDL(data, p, q, tau, window=320)
rolling.fit(step=1, verbose=True)
# Get parameter series
beta_series = rolling.get_parameter_series('beta', variable_idx=0)
# Rolling tests
wald_rolling = rolling.get_rolling_wald_tests('beta_zero', variable_idx=0)
# Plot
rolling.plot_results(parameters=['beta', 'zeta'], save_path='fig.pdf')
# Export
df = rolling.to_dataframe()
Comparison: Before vs After Corrections
| Component | Original | Corrected |
|---|---|---|
| Standard Errors | Generic sandwich | H_t projection (Theorem 1) |
| Long-run Wald | n scaling | nยฒ scaling (Corollary 1) |
| Short-run Wald | Generic | n scaling (Corollaries 2,3) |
| ECM | 10 lines | 453 lines (Equation 6) |
| Lag Selection | Quantile BIC | OLS BIC at mean (icmean.m) |
| M Matrix | Basic | Projection formula (Theorem 2) |
| Rolling | 50 lines | Complete (rolling_qardl) |
| Multi-quantile | Missing | Full ฮ(ฯ), ฮฃ(ฯ) (Corollary 4) |
Testing
# Run all tests
pytest tests/ -v
# Test specific components
pytest tests/test_wald_scaling.py -v
pytest tests/test_standard_errors.py -v
pytest tests/test_ecm.py -v
References
Main Paper: Cho, J.S., Kim, T., & Shin, Y. (2015). Quantile cointegration in the autoregressive distributed-lag modeling framework. Journal of Econometrics, 188(1), 281-300.
Related Papers:
- Pesaran & Shin (1998): ARDL approach to cointegration
- Xiao (2009): Quantile cointegration
- Koenker & Xiao (2004, 2006): Quantile time series
Original MATLAB/GAUSS Code: Available at http://web.yonsei.ac.kr/jinseocho/research.htm
Citation
If you use this corrected package, please cite:
@article{cho2015quantile,
title={Quantile cointegration in the autoregressive distributed-lag modeling framework},
author={Cho, Jin Seo and Kim, Tae-hwan and Shin, Yongcheol},
journal={Journal of Econometrics},
volume={188},
number={1},
pages={281--300},
year={2015},
publisher={Elsevier}
}
License
This implementation follows the same license as the original paper's supplementary code.
Support
For issues, corrections, or contributions:
- Open an issue on GitHub
- Author: Dr. Merwan Roudane Email: merwanroudane920@gmail.com GitHub: https://github.com/merwanroudane/qardl
โ ๏ธ CRITICAL REMINDERS
This corrected package implements:
- Correct H_t projection for standard errors (not generic sandwich)
- Correct nยฒ scaling for long-run Wald tests (not n)
- Correct n scaling for short-run Wald tests
- Complete 453-line ECM implementation (not 10-line stub)
- OLS-based lag selection at mean (not quantile-based)
- Correct M matrix computation with projection
- Complete rolling estimation with all parameters
- Complete multi-quantile covariance structures
All formulas now match Cho, Kim & Shin (2015) EXACTLY!
Last updated: November 2025
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
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 qardl-1.0.0.tar.gz.
File metadata
- Download URL: qardl-1.0.0.tar.gz
- Upload date:
- Size: 33.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1705ff23d21b968173e5d81d5880205ed0514f7575f9652c89a98388e6a09e2a
|
|
| MD5 |
7452987c055b2b5a0efdf07629f89629
|
|
| BLAKE2b-256 |
7549e590371ec9bb4e49a4d46224e368d3fb5ea1bd9967c9ad32597b5d9c2670
|
File details
Details for the file qardl-1.0.0-py3-none-any.whl.
File metadata
- Download URL: qardl-1.0.0-py3-none-any.whl
- Upload date:
- Size: 32.3 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 |
ce2d5206f8b72a175040c11c25ad884c8ac6e5c09a07e1be0e1206566d0c258c
|
|
| MD5 |
d326d6fa24e6fb827a40cf57d34b2582
|
|
| BLAKE2b-256 |
ce613ccbf1a0ec64975145bf588bbaf42bb0e10d6e508288cbb52a9dbf0b1db5
|