MTNARDL: Multiple Threshold Nonlinear ARDL
Author: Dr. Merwan Roudane
A comprehensive Python library for estimating Multiple Threshold Nonlinear Autoregressive Distributed Lag (MTNARDL) models with support for arbitrary number of regimes.
📚 Overview
MTNARDL extends the standard NARDL framework by:
- Multiple quantile-based thresholds (not just positive/negative)
- Endogenous threshold detection via grid search (minimizing RSS)
- Any number of regimes (2, 3, 5, 10, or custom quantiles)
- Complete statistical testing suite
🔬 Methodology
Based on the following econometric papers:
- Cho, Greenwood-Nimmo, and Shin (2020c): "Testing for the Threshold Autoregressive Distributed Lag Model"
- Cho, Greenwood-Nimmo, and Shin (2020d): "The Threshold Autoregressive Distributed Lag Model"
- Shin, Yu, and Greenwood-Nimmo (2014): Festschrift in Honor of Peter Schmidt
- Pal and Mitra (2015): Economic Modelling, 51, 436-443
- Pesaran, Shin, and Smith (2001): Journal of Applied Econometrics
📦 Installation
pip install mtnardl
Or install from source:
git clone https://github.com/merwanroudane/mtnardl.git
cd mtnardl
pip install -e .
Dependencies
numpy>=1.20.0
pandas>=1.3.0
scipy>=1.7.0
statsmodels>=0.13.0
matplotlib>=3.4.0
tabulate>=0.8.9
openpyxl>=3.0.0
🚀 Quick Start
Basic 3-Regime TNARDL (like Stata tnardl)
import mtnardl as mt
import pandas as pd
# Load your data
data = pd.read_csv('oil_prices.csv', parse_dates=['date'])
data.set_index('date', inplace=True)
# Estimate 3-regime TNARDL model
model = mt.MTNARDL(
data=data,
depvar='gasoline',
threshold_var='crude_oil',
control_vars=['volume'],
n_regimes=3,
max_lags=4,
criterion='aic'
)
# Fit the model
model.fit(verbose=True)
# Print results
print(model.summary())
5-Regime Quintile MTNARDL (Pal & Mitra 2015)
model5 = mt.MTNARDL(
data=data,
depvar='gasoline',
threshold_var='crude_oil',
n_regimes=5,
threshold_method='quantile'
)
model5.fit()
10-Regime Decile MTNARDL
model10 = mt.MTNARDL(
data=data,
depvar='gasoline',
threshold_var='crude_oil',
n_regimes=10,
threshold_method='quantile'
)
model10.fit()
Custom Quantiles
model_custom = mt.MTNARDL(
data=data,
depvar='gasoline',
threshold_var='crude_oil',
quantiles=[0.25, 0.5, 0.75], # Creates 4 regimes
threshold_method='quantile'
)
model_custom.fit()
📊 Statistical Tests
Bounds Test for Cointegration
from mtnardl.tests import BoundsTest
bt = BoundsTest(model)
result = bt.test(case='case3')
print(bt.summary())
Asymmetry Tests (Long-run, Short-run, Joint)
from mtnardl.tests import AsymmetryTests
at = AsymmetryTests(model)
asym_results = at.test()
print(at.summary())
Diagnostic Tests
from mtnardl.tests import DiagnosticTests
dt = DiagnosticTests(model)
diag_results = dt.test()
print(dt.summary())
QLR Test for Structural Breaks
from mtnardl.tests import QLRTest
qlr = QLRTest(model)
result = qlr.test(trim=0.15)
print(qlr.summary())
# Plot F-statistics over potential break dates
qlr.plot()
📈 Visualization
Dynamic Multiplier Plots
from mtnardl.visualization import plot_dynamic_multipliers
fig = plot_dynamic_multipliers(model, horizon=20)
fig.savefig('multipliers.png', dpi=300)
Stability Analysis (CUSUM/CUSUMQ)
from mtnardl.visualization import plot_cusum, plot_cusumq, plot_stability
# Individual plots
plot_cusum(model, save_path='cusum.png')
plot_cusumq(model, save_path='cusumq.png')
# Combined plot
plot_stability(model, save_path='stability.png')
📋 Export Results
Excel
from mtnardl.output import to_excel
to_excel(model, 'results.xlsx',
asymmetry_results=asym_results,
diagnostics=diag_results,
bounds_result=result)
LaTeX
from mtnardl.output import to_latex
to_latex(model, 'results.tex', style='booktabs')
HTML Report
from mtnardl.output import to_html
to_html(model, 'report.html', style='modern')
🔧 API Reference
MTNARDL Class
MTNARDL(
data, # pd.DataFrame: Input data
depvar, # str: Dependent variable name
threshold_var, # str: Variable for threshold decomposition
control_vars=None, # list: Additional control variables
max_lags=4, # int: Maximum lags for ARDL
criterion='aic', # str: Lag selection criterion
n_regimes=3, # int: Number of regimes
trim=0.15, # float: Trimming for grid search
threshold_method='grid_search', # str: 'grid_search' or 'quantile'
quantiles=None, # list: Custom quantile positions
ec=True # bool: Error correction form
)
Key Properties
model.thresholds_- Detected threshold valuesmodel.partial_sums_- Decomposed partial sum seriesmodel.results- Complete estimation results
Result Attributes
results.coefficients- Estimated coefficientsresults.std_errors- Standard errorsresults.t_stats- T-statisticsresults.p_values- P-valuesresults.long_run- Long-run multipliersresults.ec_term- Error correction termresults.r_squared- R-squaredresults.aic,results.bic- Information criteria
📖 Examples
See the examples/ directory for complete notebooks:
01_basic_usage.ipynb- Getting started02_oil_prices.ipynb- Replicating Pal & Mitra (2015)03_exchange_rates.ipynb- Exchange rate asymmetry04_custom_thresholds.ipynb- Custom configurations
📜 Citation
If you use this library in your research, please cite:
@software{roudane2026mtnardl,
author = {Roudane, Merwan},
title = {MTNARDL: Multiple Threshold Nonlinear ARDL for Python},
year = {2026},
url = {https://github.com/merwanroudane/mtnardl}
}
📚 References
-
Cho, J., Greenwood-Nimmo, M., & Shin, Y. (2020c). Testing for the Threshold Autoregressive Distributed Lag Model. Mimeo: University of York.
-
Cho, J., Greenwood-Nimmo, M., & Shin, Y. (2020d). The Threshold Autoregressive Distributed Lag Model. Mimeo: University of York.
-
Shin, Y., Yu, B., & Greenwood-Nimmo, M. (2014). Modelling Asymmetric Cointegration and Dynamic Multipliers in a Nonlinear ARDL Framework. Festschrift in Honor of Peter Schmidt, 281-314.
-
Pal, D., & Mitra, S.K. (2015). Asymmetric impact of crude price on oil product pricing in the United States. Economic Modelling, 51, 436-443.
-
Pesaran, M.H., Shin, Y., & Smith, R.J. (2001). Bounds testing approaches to the analysis of level relationships. Journal of Applied Econometrics, 16(3), 289-326.
📄 License
MIT License - see LICENSE file.
👤 Contact
Dr. Merwan Roudane
- GitHub: @merwanroudane
Metadata
Release files for mtnardl 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mtnardl-1.0.0.tar.gz | 44.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mtnardl-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.6 kB
Release files / mtnardl-1.0.0.tar.gz
| Download URL | mtnardl-1.0.0.tar.gz |
|---|---|
| Size | 44.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fb3996ad4699a0f476c374109274757408bfa0b20d5549f62f72052dc8fba9eb
|
|
BLAKE2b-256 checksum How to use checksums |
55bfe3929857ae119930949325ad6f9b8bfcbb7f3808bf8f88270e9d21199f5d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / mtnardl-1.0.0-py3-none-any.whl
| Download URL | mtnardl-1.0.0-py3-none-any.whl |
|---|---|
| Size | 51.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
50c5e0e7eac49bdb74ef68b17ffa79c7fbace44b5432c320cd15c59ae147b1c0
|
|
BLAKE2b-256 checksum How to use checksums |
d7a4e90e085b976eb57a175ae8c1756e3bf45d209f1e65c2f37a1fb9d25bcacd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for mtnardl 1.0.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.