mtnardl 1.0.0
Multiple Threshold Nonlinear ARDL Models for Python
License: MIT
Requires Python: >=3.8
Keywords: econometrics, ARDL, NARDL, threshold, cointegration, asymmetry, time series, nonlinear, structural breaks, QLR test

# MTNARDL: Multiple Threshold Nonlinear ARDL

[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![GitHub](https://img.shields.io/badge/GitHub-merwanroudane/mtnardl-black.svg)](https://github.com/merwanroudane/mtnardl)

**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

```bash
pip install mtnardl
```

Or install from source:

```bash
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)

```python
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)

```python
model5 = mt.MTNARDL(
    data=data,
    depvar='gasoline',
    threshold_var='crude_oil',
    n_regimes=5,
    threshold_method='quantile'
)
model5.fit()
```

### 10-Regime Decile MTNARDL

```python
model10 = mt.MTNARDL(
    data=data,
    depvar='gasoline',
    threshold_var='crude_oil',
    n_regimes=10,
    threshold_method='quantile'
)
model10.fit()
```

### Custom Quantiles

```python
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

```python
from mtnardl.tests import BoundsTest

bt = BoundsTest(model)
result = bt.test(case='case3')
print(bt.summary())
```

### Asymmetry Tests (Long-run, Short-run, Joint)

```python
from mtnardl.tests import AsymmetryTests

at = AsymmetryTests(model)
asym_results = at.test()
print(at.summary())
```

### Diagnostic Tests

```python
from mtnardl.tests import DiagnosticTests

dt = DiagnosticTests(model)
diag_results = dt.test()
print(dt.summary())
```

### QLR Test for Structural Breaks

```python
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

```python
from mtnardl.visualization import plot_dynamic_multipliers

fig = plot_dynamic_multipliers(model, horizon=20)
fig.savefig('multipliers.png', dpi=300)
```

### Stability Analysis (CUSUM/CUSUMQ)

```python
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

```python
from mtnardl.output import to_excel

to_excel(model, 'results.xlsx',
         asymmetry_results=asym_results,
         diagnostics=diag_results,
         bounds_result=result)
```

### LaTeX

```python
from mtnardl.output import to_latex

to_latex(model, 'results.tex', style='booktabs')
```

### HTML Report

```python
from mtnardl.output import to_html

to_html(model, 'report.html', style='modern')
```

## 🔧 API Reference

### MTNARDL Class

```python
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 values
- `model.partial_sums_` - Decomposed partial sum series
- `model.results` - Complete estimation results

### Result Attributes

- `results.coefficients` - Estimated coefficients
- `results.std_errors` - Standard errors
- `results.t_stats` - T-statistics
- `results.p_values` - P-values
- `results.long_run` - Long-run multipliers
- `results.ec_term` - Error correction term
- `results.r_squared` - R-squared
- `results.aic`, `results.bic` - Information criteria

## 📖 Examples

See the `examples/` directory for complete notebooks:

- `01_basic_usage.ipynb` - Getting started
- `02_oil_prices.ipynb` - Replicating Pal & Mitra (2015)
- `03_exchange_rates.ipynb` - Exchange rate asymmetry
- `04_custom_thresholds.ipynb` - Custom configurations

## 📜 Citation

If you use this library in your research, please cite:

```bibtex
@software{roudane2026mtnardl,
  author = {Roudane, Merwan},
  title = {MTNARDL: Multiple Threshold Nonlinear ARDL for Python},
  year = {2026},
  url = {https://github.com/merwanroudane/mtnardl}
}
```

## 📚 References

1. Cho, J., Greenwood-Nimmo, M., & Shin, Y. (2020c). Testing for the Threshold Autoregressive Distributed Lag Model. *Mimeo: University of York*.

2. Cho, J., Greenwood-Nimmo, M., & Shin, Y. (2020d). The Threshold Autoregressive Distributed Lag Model. *Mimeo: University of York*.

3. 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.

4. Pal, D., & Mitra, S.K. (2015). Asymmetric impact of crude price on oil product pricing in the United States. *Economic Modelling*, 51, 436-443.

5. 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](LICENSE) file.

## 👤 Contact

**Dr. Merwan Roudane**
- GitHub: [@merwanroudane](https://github.com/merwanroudane)