Skip to main content

Nonlinear Unit Root Testing Library — 17+ tests with embedded critical values, automatic decisions, and publication-quality output

Project description

TARUR

Nonlinear Unit Root Testing Library for Python

17+ tests · Embedded critical values · Automatic decisions · Publication-quality output

PyPI Python License

--- ## Why TARUR? Most nonlinear unit root test implementations in R (e.g., `NonlinearTSA`) **do not include critical values**, forcing researchers to manually look them up in the original papers every single time. This is tedious, error-prone, and slows empirical research. **TARUR** solves this by: | Feature | Description | |---------|-------------| | ✅ **Embedded CVs** | All critical values from the original papers (asymptotic + finite-sample) | | ✅ **Auto decisions** | Reject / fail-to-reject at 1%, 5%, 10% — no manual comparison | | ✅ **One-line API** | `tarur.kss_test(y)` gives you everything | | ✅ **Full battery** | `tarur.run_all_tests(y)` runs 11+ tests at once | | ✅ **Bug fixes** | Corrects errors in R implementations (Kruse, Hu-Chen, Sollis 2009) | | ✅ **LaTeX export** | Publication-ready tables for your papers | --- ## Installation ```bash pip install tarur ``` From source: ```bash git clone https://github.com/merwanroudane/tarur.git cd tarur && pip install -e . ``` **Dependencies:** `numpy`, `scipy`, `pandas`, `matplotlib` (all standard scientific stack). --- ## Quick Start ```python import numpy as np import tarur # Load your time series (level, not differenced) y = np.cumsum(np.random.randn(300)) # Single test result = tarur.kss_test(y, case='demeaned', max_lags=8) print(result) # Full battery batch = tarur.run_all_tests(y, case='demeaned', max_lags=8) ``` Output: ``` ============================================================ KSS (2003) Nonlinear Unit Root Test ============================================================ H0: Unit root (linear random walk) H1: Globally stationary ESTAR process ------------------------------------------------------------ Test Statistic (tNL) | -1.649 Selected Lag | 4 (AIC) Case | demeaned ------------------------------------------------------------ Critical Values: 1%: -3.930 | 5%: -3.400 | 10%: -3.130 Source: Kapetanios, Shin & Snell (2003), Table 1 ------------------------------------------------------------ 1%: [ACCEPT] H0 5%: [ACCEPT] H0 10%: [ACCEPT] H0 ------------------------------------------------------------ >> Fail to reject H0. Unit root (linear random walk). ============================================================ ``` --- ## Researcher's Guide — Complete Test Reference ### 1. ESTAR-Based Unit Root Tests These tests are based on the Exponential Smooth Transition Autoregressive (ESTAR) model: $$y_t = y_{t-1} + \phi y_{t-1} G(\theta; y_{t-1}) + \varepsilon_t$$ where $G(\theta; y_{t-1}) = 1 - \exp(-\theta y_{t-1}^2)$ is the exponential transition function. Under H₀ ($\theta = 0$), the process is a unit root. Under H₁ ($\theta > 0$), the process is globally stationary with nonlinear mean reversion. --- #### 1.1 KSS (2003) — `kss_test()` **Reference:** Kapetanios, G., Shin, Y., & Snell, A. (2003). *Testing for a unit root in the nonlinear STAR framework.* Journal of Econometrics, 112(2), 359–379. **Auxiliary regression:** $$\Delta y_t = \beta_1 y_{t-1}^3 + \sum_{i=1}^{p} \rho_i \Delta y_{t-i} + u_t$$ **Test statistic:** $t_{NL} = \hat{\beta}_1 / \text{se}(\hat{\beta}_1)$ — a standard t-ratio. **Decision rule:** Reject H₀ when $t_{NL} < \text{CV}$ (left-tailed). **Critical values (asymptotic, Table 1):** | Case | 1% | 5% | 10% | |------|-----|-----|------| | Raw | −3.48 | −2.93 | −2.66 | | Demeaned | −3.93 | −3.40 | −3.13 | | Detrended | −3.40 | −2.93 | −2.66 | ```python result = tarur.kss_test(y, case='demeaned', max_lags=12, lag_method='aic') ``` **Interpretation:** If rejected, the series exhibits **globally stationary ESTAR dynamics** — it may wander away from its mean but will always revert back, with the speed of reversion increasing with the distance from equilibrium. --- #### 1.2 Kruse (2011) — `kruse_test()` **Reference:** Kruse, R. (2011). *A new unit root test against ESTAR based on a class of modified statistics.* Statistical Papers, 52(1), 71–85. **Improvement over KSS:** Allows a **nonzero location parameter** $c$ in the ESTAR model, which the KSS test implicitly restricts to zero. **Auxiliary regression:** $$\Delta y_t = \beta_1 y_{t-1}^3 + \beta_2 y_{t-1}^2 + \sum_{i=1}^{p} \rho_i \Delta y_{t-i} + u_t$$ **Test statistic (Modified Wald):** $$\tau = t^2_{\beta_{2\perp}=0} + \mathbb{1}(\hat{\beta}_1 < 0) \cdot t^2_{\beta_1=0}$$ **Decision rule:** Reject H₀ when $\tau > \text{CV}$ (right-tailed). > ⚠️ **Bug fix:** The R `NonlinearTSA` package incorrectly uses a standard Chi-squared test. TARUR implements the correct modified Wald τ with the indicator function from the paper. **Critical values (asymptotic, T=1000, Table 1):** | Case | 1% | 5% | 10% | |------|------|------|------| | Raw | 13.15 | 9.53 | 7.85 | | Demeaned | 13.75 | 10.17 | 8.60 | | Detrended | 17.10 | 12.82 | 11.10 | ```python result = tarur.kruse_test(y, case='demeaned', max_lags=12) ``` --- #### 1.3 Sollis (2009) — `sollis2009_test()` **Reference:** Sollis, R. (2009). *A simple unit root test against asymmetric STAR nonlinearity with an application to real exchange rates.* Economic Modelling, 26(1), 118–125. **Key contribution:** Tests whether mean reversion is **symmetric or asymmetric** — i.e., whether the speed of adjustment differs for positive vs negative deviations. **Auxiliary regression:** $$\Delta y_t = \phi_1 y_{t-1}^3 + \phi_2 y_{t-1}^4 + \sum_{i=1}^{p} \kappa_i \Delta y_{t-i} + \eta_t$$ **Two test statistics:** - **$F_{AE}$:** Joint F-test of $\phi_1 = \phi_2 = 0$ (unit root test, reject when $F > \text{CV}$) - **$F_{as}$:** F-test of $\phi_2 = 0$ (symmetry test) > ⚠️ **Bug fix:** The R code uses the wrong auxiliary regression. TARUR implements the correct AESTAR formulation from the paper. ```python result = tarur.sollis2009_test(y, case='demeaned', max_lags=12) # Access symmetry test print(f"Symmetry Fas: {result.extra['Fas']:.3f} (p={result.extra['Fas_pvalue']:.4f})") print(f" → {result.extra['symmetry_test']}") ``` **Interpretation:** If $F_{AE}$ rejects H₀ and $F_{as}$ also rejects, the series has **asymmetric** nonlinear mean reversion (e.g., real exchange rates that adjust faster from overvaluation than undervaluation). --- #### 1.4 Hu & Chen (2016) — `hu_chen_test()` **Reference:** Hu, J., & Chen, Z. (2016). *A unit root test against globally stationary ESTAR models when local condition is non-stationary.* Economics Letters, 146, 89–94. **Key contribution:** Allows for **locally explosive** but **globally stationary** ESTAR — the process can be locally non-stationary near the equilibrium but still globally mean-reverting. **Auxiliary regression:** $$\Delta y_t = \beta_1 y_{t-1} + \beta_2 y_{t-1}^2 + \beta_3 y_{t-1}^3 + \sum \rho_i \Delta y_{t-i} + u_t$$ **Test statistic:** 3-parameter modified Wald τ (right-tailed, reject when τ > CV). ```python result = tarur.hu_chen_test(y, case='demeaned', max_lags=12) ``` --- ### 2. Threshold / Asymmetric Unit Root Tests #### 2.1 Enders & Granger (1998) — `enders_granger_test()` **Reference:** Enders, W., & Granger, C.W.J. (1998). *Unit-root tests and asymmetric adjustment.* JBES, 16(3), 304–311. **Model:** Momentum Threshold Autoregression (MTAR): $$\Delta \hat{u}_t = I_t \rho^+ \hat{u}_{t-1} + (1 - I_t) \rho^- \hat{u}_{t-1} + \sum \delta_i \Delta \hat{u}_{t-i} + \varepsilon_t$$ where $I_t = 1$ if $\Delta y_{t-1} \geq 0$ (momentum indicator). **Test statistic:** $\Phi$ (joint F-test $\rho^+ = \rho^- = 0$, right-tailed). ```python result = tarur.enders_granger_test(y, case='demeaned', max_lags=12) # Asymmetric coefficients print(f"ρ⁺ = {result.extra['rho_pos']:.4f}, ρ⁻ = {result.extra['rho_neg']:.4f}") print(f"Symmetry test: F = {result.extra['F_symmetry']:.3f} (p={result.extra['F_sym_pvalue']:.4f})") ``` #### 2.2 Sollis (2004) — `sollis2004_test()` **Reference:** Sollis, R. (2004). *Asymmetric adjustment and smooth transitions.* J. Time Series Analysis, 25(3), 409–417. Combines smooth transition detrending with TAR-type asymmetric adjustment. ```python result = tarur.sollis2004_test(y, model='A', max_lags=8) ``` --- ### 3. Smooth Transition Unit Root Tests These tests first estimate a nonlinear smooth transition trend function via NLS, then apply an ADF test to the residuals. **Each has its own distinct critical values.** #### 3.1 LNV (1998) — `lnv_test()` **Reference:** Leybourne, S., Newbold, P., & Vougas, D. (1998). *Unit roots and smooth transitions.* J. Time Series Analysis, 19(1), 83–97. **Model A:** $y_t = \alpha_1 + \alpha_2 S_t(\gamma, \tau) + \nu_t$ (transition in mean) **Model B:** $y_t = \alpha_1 + \beta_1 t + \alpha_2 S_t(\gamma, \tau) + \nu_t$ (transition in intercept + trend) **Model C:** $y_t = \alpha_1 + \beta_1 t + \alpha_2 S_t(\gamma, \tau) + \beta_2 t S_t(\gamma, \tau) + \nu_t$ (transition in both) where $S_t(\gamma, \tau) = [1 + \exp(-\gamma(t - \tau T))]^{-1}$ is the logistic function. **Critical values (LNV 1998, Table I — Model A):** | T | 1% | 5% | 10% | |---|------|------|------| | 25 | −5.669 | −4.750 | −4.280 | | 50 | −5.095 | −4.363 | −4.009 | | 100 | −4.882 | −4.232 | −3.909 | | 200 | −4.761 | −4.161 | −3.851 | | 500 | −4.685 | −4.103 | −3.797 | ```python result = tarur.lnv_test(y, model='A', max_lags=12) ``` #### 3.2 Vougas (2006) — `vougas_test()` **Reference:** Vougas, D. (2006). *On unit root testing with smooth transitions.* Computational Statistics & Data Analysis, 51(2), 797–800. Extends LNV with **5 functional forms** (Models A–E), including trend-only transitions. ```python # Test all 5 models for m in ['A', 'B', 'C', 'D', 'E']: r = tarur.vougas_test(y, model=m, max_lags=12) cv5 = r.critical_values.cv5 print(f"Model {m}: t = {r.statistic:.3f}, CV(5%) = {cv5:.3f}, {'REJECT' if r.decision.get('5%') else 'ACCEPT'}") ``` #### 3.3 Harvey & Mills (2002) — `harvey_mills_test()` **Reference:** Harvey, D.I., & Mills, T.C. (2002). *Unit roots and double smooth transitions.* J. Applied Statistics, 29(5), 675–683. **Key feature:** Allows **two** smooth transitions (double structural break). The critical values are substantially larger in absolute value than LNV because the more flexible alternative shifts the null distribution. **Critical values (Harvey & Mills 2002, Table 1 — Model A):** | T | 1% | 5% | 10% | |---|------|------|------| | 50 | −6.49 | −5.73 | −5.33 | | 100 | −6.05 | −5.37 | −5.04 | | 200 | −5.80 | −5.20 | −4.90 | | 1000 | −5.64 | −5.07 | −4.79 | ```python result = tarur.harvey_mills_test(y, model='A', max_lags=12) ``` #### 3.4 Cook & Vougas (2009) — `cook_vougas_test()` **Reference:** Cook, S., & Vougas, D. (2009). *Unit root testing against an ST–MTAR alternative.* Applied Economics, 41(11), 1397–1404. Combines smooth transition detrending with **MTAR** asymmetric adjustment (F-statistic). --- ### 4. Grid-Search Tests #### 4.1 Kılıç (2011) — `kilic_test()` **Reference:** Kılıç, R. (2011). *Testing for a unit root in a stationary ESTAR process.* Econometric Reviews, 30(3), 274–302. Uses a **grid search** over the transition parameter γ to find the infimum of the t-statistic, which has greater power than fixing γ. ```python result = tarur.kilic_test(y, case='demeaned', max_lags=12) print(f"Optimal γ: {result.extra['optimal_gamma']:.4f}") ``` #### 4.2 Park & Shintani (2016) — `park_shintani_test()` **Reference:** Park, J.Y., & Shintani, M. (2016). *Testing for a unit root against transitional autoregressive models.* International Economic Review, 57(2), 635–664. ```python result = tarur.park_shintani_test(y, case='raw', max_lags=12) ``` --- ### 5. Extended Tests #### 5.1 Pascalau (2007) — `pascalau_test()` Tests against **asymmetric NLSTAR** with y⁴, y³, y² regressors (F-test, right-tailed). #### 5.2 Cuestas & Garratt (2011) — `cuestas_garratt_test()` **Cubic polynomial detrending** followed by KSS-type regression. χ² test statistic. #### 5.3 Cuestas & Ordóñez (2014) — `cuestas_ordonez_test()` **NLS logistic detrending** (allows smooth transition in trend) followed by KSS test on residuals. ```python result = tarur.cuestas_garratt_test(y, max_lags=12) result = tarur.cuestas_ordonez_test(y, max_lags=12) ``` --- ### 6. Cointegration Tests #### 6.1 KSS Nonlinear Cointegration — `kss_cointegration_test()` Tests whether two series are cointegrated in a **nonlinear** sense (ESTAR stationary residuals). ```python result = tarur.kss_cointegration_test(y1, y2, case='demeaned', max_lags=12) ``` #### 6.2 Enders & Siklos (2001) — `enders_siklos_test()` **Threshold cointegration** — tests for cointegration with asymmetric adjustment in the equilibrium error. ```python result = tarur.enders_siklos_test(y1, y2, max_lags=12) ``` --- ### 7. Linearity & Diagnostics #### 7.1 Teräsvirta (1994) — `terasvirta_test()` Tests linearity and suggests whether **LSTAR** or **ESTAR** is more appropriate. ```python result = tarur.terasvirta_test(y, d=1) print(f"Suggested model: {result.extra['suggested_model']}") ``` #### 7.2 ARCH Test — `arch_test()` Engle (1982) LM test for ARCH effects. #### 7.3 McLeod-Li Test — `mcleod_li_test()` Portmanteau test for nonlinear dependence in squared residuals. --- ## API Reference ### Common Parameters | Parameter | Options | Description | |-----------|---------|-------------| | `case` | `'raw'`, `'demeaned'`, `'detrended'` | Deterministic terms | | `max_lags` | integer (default 8) | Maximum lag order for augmentation | | `lag_method` | `'aic'`, `'bic'`, `'t-stat'` | Automatic lag selection criterion | | `model` | `'A'`–`'E'` | Smooth transition model specification | ### TestResult Object ```python result.statistic # Test statistic value result.statistic_name # Label (e.g., "tNL", "τ", "F_AE") result.critical_values # CriticalValues with .cv1, .cv5, .cv10 result.decision # {"1%": bool, "5%": bool, "10%": bool} result.interpretation # Plain-English interpretation result.selected_lag # Optimal lag order result.case # Deterministic specification used result.model_summary # Regression coefficients, R², AIC, BIC result.extra # Test-specific extras result.reference # Full citation # Export result.to_dict() # Flat dictionary for DataFrame result.to_latex() # LaTeX table snippet result.plot() # Visualization ``` ### BatchResult Object ```python batch = tarur.run_all_tests(y, case='demeaned', max_lags=8) batch.summary() # Comparison DataFrame batch.to_latex() # Full LaTeX table batch.plot() # Dashboard visualization print(batch) # Formatted table ``` --- ## Recommended Workflow for Researchers ```python import numpy as np import tarur # 1. Load your data (log-levels for financial data) y = np.log(your_price_series) # 2. Test for linearity first lin = tarur.terasvirta_test(np.diff(y), d=1) print(f"Linearity p-value: {lin.extra['p_linearity']:.4f}") print(f"Suggested model: {lin.extra['suggested_model']}") # 3. Run the full nonlinear unit root battery batch = tarur.run_all_tests(y, case='demeaned', max_lags=12) # 4. Get summary table for your paper df = batch.summary() print(df[['test', 'statistic', 'cv_5%', 'reject_5%']].to_string(index=False)) # 5. Export to LaTeX print(batch.to_latex()) # 6. Visualization for presentations batch.plot() ``` --- ## Critical Values — Complete Mapping Every test uses its **own distinct critical values** from its original paper: | Test | Source | Table | Type | Tail | |------|--------|-------|------|------| | KSS (2003) | KSS, Table 1 | Asymptotic | t-type | Left | | Kruse (2011) | Kruse, Table 1 | Asymptotic (T=1000) | Wald τ | Right | | Sollis (2009) | Sollis, Table 1 | Finite-sample (T=50–200) | F-type | Right | | Hu & Chen (2016) | Hu & Chen, Table 1 | Asymptotic (T=1000) | Wald τ | Right | | Enders & Granger (1998) | E&G, Table 1 | Asymptotic | F-type | Right | | LNV (1998) | LNV, Table I | Finite-sample (T=25–500) | t-type | Left | | Vougas (2006) | Vougas, Table 1 | Finite-sample (T=25–500) | t-type | Left | | Harvey & Mills (2002) | H&M, Table 1 | Finite-sample (T=50–1000) | t-type | Left | | Cook & Vougas (2009) | C&V, Table 1 | Finite-sample (T=50–500) | F-type | Right | | Sollis (2004) | Sollis, Table II | Simulated (T=100) | F-type | Right | | Kılıç (2011) | Kılıç, Table 1 | Asymptotic (grid-search) | t-type | Left | | Park & Shintani (2016) | P&S, Table 1 | Asymptotic | t-type | Left | | Pascalau (2007) | Pascalau | Simulated | F-type | Right | | Cuestas & Garratt (2011) | C&G | Simulated | χ²-type | Right | --- ## Bug Fixes vs R `NonlinearTSA` Package | Issue | R Code | TARUR (Correct) | |-------|--------|-----------------| | **Kruse (2011)** | Uses standard Wald/Chi² | Modified Wald τ with indicator function | | **Hu & Chen (2016)** | Same as above | 3-parameter modified Wald with orthogonalization | | **Sollis (2009)** | Wrong auxiliary regression | Correct AESTAR with y³ and y⁴ | | **TAR/MTAR** | Depends on `tsDyn` R package | Fully native Python implementation | | **Critical values** | Not included | All embedded from original papers | --- ## Visualization ```python # Series diagnostic plot tarur.plot_series_analysis(y, title='Real Exchange Rate') # Individual test result result = tarur.kss_test(y) result.plot() # Full battery dashboard batch = tarur.run_all_tests(y) batch.plot() ``` --- ## Citation If you use TARUR in your research, please cite: ```bibtex @software{tarur2024, author = {Roudane, Merwan}, title = {TARUR: Nonlinear Unit Root Testing Library for Python}, year = {2024}, url = {https://github.com/merwanroudane/tarur} } ``` --- ## Author **Dr. Merwan Roudane** 📧 merwanroudane920@gmail.com 🔗 [github.com/merwanroudane/tarur](https://github.com/merwanroudane/tarur) ## License MIT License — see [LICENSE](LICENSE) for details. ]]>

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

tarur-1.0.0.tar.gz (39.7 kB view details)

Uploaded Source

Built Distribution

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

tarur-1.0.0-py3-none-any.whl (45.1 kB view details)

Uploaded Python 3

File details

Details for the file tarur-1.0.0.tar.gz.

File metadata

  • Download URL: tarur-1.0.0.tar.gz
  • Upload date:
  • Size: 39.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for tarur-1.0.0.tar.gz
Algorithm Hash digest
SHA256 12d3c835df87846755bb7ae9bcb2f557a878a9fe8f9aedd9e0aed585ec70223f
MD5 303d572af64da5d4c8f3ea602d8e1ecb
BLAKE2b-256 6a7a277b7b8fdedfb8b83c9e41ae114af742fe5e2a035dd94a51b9faf6a46756

See more details on using hashes here.

File details

Details for the file tarur-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: tarur-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 45.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for tarur-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 39ec610fd60a84745e0dc469f5da00d12971e5efead3ad2075364f23561d0c7f
MD5 88406e916b8272cd14d464a324ab4956
BLAKE2b-256 a4c3e6b3a338d73a15612117ab669b1ee97253d2542c33c28912f5bb2cca3b66

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