Outlier-Robust Cointegration Analysis based on Franses & Lucas (1998)
Project description
robcointeg
Outlier-Robust Cointegration Analysis
A Python implementation of outlier-robust cointegration testing based on the methodology of Franses & Lucas (1998).
Author: Dr Merwan Roudane
Email: merwanroudane920@gmail.com
GitHub: https://github.com/merwanroudane/robcointeg
Overview
Standard unit-root and cointegration tests are sensitive to atypical events such as outliers and structural breaks. This package implements the outlier-robust cointegration test proposed by Franses & Lucas (1998), which provides:
-
Robust Cointegration Testing: A pseudolikelihood ratio (PLR) test based on the Student-t distribution that is less sensitive to outliers than the standard Gaussian-based Johansen test.
-
Outlier Detection: Observation weights that identify which data points may be driving the cointegration results.
-
Diagnostic Tools: Methods for comparing robust and non-robust test results to signal when standard cointegration results might be influenced by aberrant observations.
Installation
From PyPI (when published)
pip install robcointeg
From Source
git clone https://github.com/merwanroudane/robcointeg.git
cd robcointeg
pip install -e .
With Plotting Support
pip install robcointeg[plotting]
Full Installation (all optional dependencies)
pip install robcointeg[full]
Quick Start
Basic Usage
import numpy as np
from robcointeg import RobustVAR, compare_tests, diagnostic_report
# Generate sample data
np.random.seed(42)
T = 100
y = np.cumsum(np.random.randn(T, 2), axis=0)
# Add an outlier
y[50, 0] += 5
# Fit robust VAR model
model = RobustVAR(p=2, nu=5)
model.fit(y)
# View results
print(model.summary())
print(f"Observation weights: {model.weights}")
Cointegration Testing
from robcointeg import plr_test, johansen_trace_test
# Robust test (Student-t based)
robust_result = plr_test(y, p=2, nu=5, r=0)
print(f"Robust PLR statistic: {robust_result.test_statistic:.2f}")
print(f"Reject at 5%: {robust_result.reject[0.05]}")
# Standard Johansen test for comparison
johansen_result = johansen_trace_test(y, p=2, r=0)
print(f"Johansen statistic: {johansen_result.test_statistic:.2f}")
Compare Robust and Non-Robust Tests
from robcointeg import compare_tests
comparison = compare_tests(y, p=2, nu=5)
print(comparison['summary'])
if comparison['conflict']:
print("⚠ Tests give different results!")
print(f"Gaussian rank: {comparison['gaussian_rank']}")
print(f"Robust rank: {comparison['robust_rank']}")
Full Diagnostic Report
from robcointeg import diagnostic_report
report = diagnostic_report(
y, p=2, nu=5,
variable_names=['Y1', 'Y2'],
significance_level=0.05
)
Methodology
This package implements the methodology from:
Franses, P.H. & Lucas, A. (1998). "Outlier Detection in Cointegration Analysis", Journal of Business & Economic Statistics, 16:4, 459-468.
Key Equations
1. VAR/VECM Model (Equation 1):
$$\Delta y_t = \alpha\beta' y_{t-1} + \Phi_1 \Delta y_{t-1} + \cdots + \Phi_{p-1} \Delta y_{t-p+1} + \mu + \varepsilon_t$$
2. Student-t Pseudolikelihood (Equation 2):
$$\mathcal{L}(\theta) = \prod_{t=1}^{T} \frac{\Gamma((\nu+k)/2)}{\Gamma(\nu/2)|\pi\nu V|^{1/2}} \left(1 + \frac{\varepsilon_t' V^{-1} \varepsilon_t}{\nu}\right)^{-(\nu+k)/2}$$
3. Pseudolikelihood Ratio Test (Equation 3):
$$\text{PLR} = 2 \ln\left(\frac{\mathcal{L}(\hat{\theta})}{\mathcal{L}(\tilde{\theta})}\right)$$
4. Observation Weights (Equation 8):
$$w_t = \left(\frac{\nu}{\nu + \varepsilon_t' V^{-1} \varepsilon_t}\right)^{1/2}$$
Interpretation of Weights
- Low weight ($w_t < 0.67$ for $\nu=5$, $k=2$): The observation does not correspond to the general pattern of the model and deserves closer inspection.
- Consecutive low weights may indicate additive outliers (AO).
- Low weights at the start and end of a period may indicate level shifts.
- Many consecutive low weights may indicate variance shifts.
API Reference
Core Classes
RobustVAR
from robcointeg import RobustVAR
model = RobustVAR(p=2, nu=5, with_constant=True)
model.fit(y)
# Attributes
model.weights # Observation weights
model.residuals # Model residuals
model.log_likelihood # Log pseudolikelihood
model.Pi # Long-run impact matrix
model.alpha # Loading matrix
model.beta # Cointegrating vectors
model.eigenvalues # Eigenvalues
RobustCointegrationTest
from robcointeg import sequential_plr_test
result = sequential_plr_test(y, p=2, nu=5)
# Attributes
result.test_results # List of test results for each rank
result.selected_rank # Determined cointegrating rank
result.weights # Observation weights
result.outlier_indices # Detected outlier indices
result.summary # Text summary
Main Functions
| Function | Description |
|---|---|
plr_test() |
Perform PLR test for a specific rank |
johansen_trace_test() |
Standard Johansen trace test |
compare_tests() |
Compare robust and non-robust tests |
compute_weights() |
Compute observation weights |
detect_outliers() |
Identify outlying observations |
diagnostic_report() |
Generate full diagnostic report |
Critical Values
The package includes critical values from Table 1 of Franses & Lucas (1998):
from robcointeg import get_critical_value, CriticalValueTable
# Get single critical value
cv = get_critical_value(k_minus_r=2, nu=5, significance_level=0.05)
# Access full table
table = CriticalValueTable(with_drift=True)
print(table.print_table())
Examples
Example 1: Finland/U.S. Real Exchange Rate
This replicates the empirical application from Section 3 of the paper:
import numpy as np
from robcointeg import compare_tests, plot_comparison_panel
# Load Finland/U.S. exchange rate data (hypothetical)
# y should contain: log(CPI_US), log(CPI_Finland), log(Exchange_Rate)
comparison = compare_tests(y, p=2, nu=5)
print(comparison['summary'])
# Visualize (requires matplotlib)
plot_comparison_panel(
y, comparison['weights'], comparison['outlier_indices'],
nu=5, k=3, title='Finland/U.S. Real Exchange Rate Analysis'
)
Example 2: Monte Carlo Simulation
from robcointeg import monte_carlo_critical_values
# Simulate critical values
cv = monte_carlo_critical_values(
k_minus_r=2, nu=5, n_sim=10000, T=100, with_drift=True
)
print(f"95% critical value: {cv[0.95]:.2f}")
Citation
If you use this package in your research, please cite the original paper:
@article{franses1998outlier,
title={Outlier Detection in Cointegration Analysis},
author={Franses, Philip Hans and Lucas, Andr{\'e}},
journal={Journal of Business \& Economic Statistics},
volume={16},
number={4},
pages={459--468},
year={1998},
publisher={Taylor \& Francis}
}
And this software:
@software{robcointeg,
author = {Roudane, Merwan},
title = {robcointeg: Outlier-Robust Cointegration Analysis in Python},
year = {2025},
url = {https://github.com/merwanroudane/robcointeg}
}
References
- Franses, P.H. & Lucas, A. (1998). "Outlier Detection in Cointegration Analysis", Journal of Business & Economic Statistics, 16:4, 459-468.
- Johansen, S. (1988). "Statistical Analysis of Cointegration Vectors", Journal of Economic Dynamics and Control, 12, 231-254.
- Johansen, S. (1991). "Estimation and Hypothesis Testing of Cointegration Vectors in Gaussian Vector Autoregressive Models", Econometrica, 59, 1551-1580.
- Lucas, A. (1997). "Cointegration Testing Using Pseudo Likelihood Ratio Tests", Econometric Theory, 13, 149-169.
- Lucas, A. (1998). "Inference on Cointegrating Ranks Using LR and LM Tests Based on Pseudo Likelihoods", Econometric Reviews, 17, 185-214.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Changelog
Version 0.0.1 (2025)
- Initial release
- Implementation of Franses & Lucas (1998) methodology
- Student-t pseudolikelihood ratio (PLR) test
- Observation weight computation
- Outlier detection
- Comparison with standard Johansen test
- Visualization tools
- Critical value tables from the original paper
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 robcointeg-0.0.2.tar.gz.
File metadata
- Download URL: robcointeg-0.0.2.tar.gz
- Upload date:
- Size: 44.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aeff0c9965f94c25b8939432f634198337627b9394c6d2b0a8dabe76b056339e
|
|
| MD5 |
e7d65ba70200c438358529047ab56879
|
|
| BLAKE2b-256 |
a5c0dc5c69c71f855e634fa74e5351f66b46d6248446df78f9f6de3bec5f2064
|
File details
Details for the file robcointeg-0.0.2-py3-none-any.whl.
File metadata
- Download URL: robcointeg-0.0.2-py3-none-any.whl
- Upload date:
- Size: 41.1 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 |
2add44f01044b782b335f8f58d7af89312a78bc237393556a678a43df5404105
|
|
| MD5 |
6b0e63eb49d30471f9c8e9dccac712e6
|
|
| BLAKE2b-256 |
371dba96e6000b417df085f7ec375ee0fa8a0d3cd4c25402641ec7436392f310
|