SETAR#

class cultivars.univariate.threshold.SETAR(endog, *, order, delay=None, trim=0.15, n_grid=300)[source]

Bases: _ThresholdModel[SETARResult]

Self-exciting threshold autoregression with two regimes.

The regime is decided by the series’ own lag \(y_{t-d}\) against a threshold \(r\),

\[\begin{split}y_t = \begin{cases} \phi_L' x_t + \varepsilon_t & y_{t-d} \le r \\ \phi_U' x_t + \varepsilon_t & y_{t-d} > r \end{cases}, \qquad x_t = (1, y_{t-1}, \ldots, y_{t-p})',\end{split}\]

with \((r, d)\) estimated by grid search and the two coefficient blocks by least squares at each candidate. The candidate thresholds are n_grid quantiles of the transition variable with trim of each tail removed, so neither regime can be estimated from a handful of extreme points; a split leaving either regime fewer than order + 2 observations is skipped. Leaving delay as None searches 1..order jointly with the threshold, at the cost of order times the grid; each candidate is two closed-form regressions, so even the joint search is fast.

Variables:
  • _endog – The observed series as a float array, shape (n,).

  • _order – The autoregressive order within each regime.

  • _delays – The candidate delays, one entry when fixed.

  • _trim – The fraction trimmed from each tail of the grid.

  • _n_grid – The number of candidate thresholds per delay.

  • _threshold_variable – None; the series is its own driver.

Parameters:
  • endog (ArrayLike) – The series.

  • order (int) – Autoregressive order within each regime, at least 1.

  • delay (int | None) – Threshold delay, at least 1; None searches 1..order.

  • trim (float) – Fraction trimmed from each tail of the quantile grid, in (0, 0.5), so that neither regime can be estimated from a handful of extreme points.

  • n_grid (int) – Candidate thresholds per delay, at least 1.

Raises:
  • SpecificationError – If order, delay or n_grid is below 1 or trim is outside (0, 0.5).

  • DimensionError – If the series is not one-dimensional or shorter than 2 (order + 2) + max(delay).

See also

  • SETARResult – the record fit returns.

  • TAR – the same estimator with an external transition variable.

  • LSTAR – the smooth-weight counterpart; a SETAR is its limit as the speed goes to infinity.

  • TARNN – the same hard switch with a neural mean per regime.

References

Tong, H., & Lim, K. S. (1980). Threshold autoregression, limit cycles and cyclical data. Journal of the Royal Statistical Society B, 42(3), 245-268.

Hansen, B. E. (1997). Inference in TAR models. Studies in Nonlinear Dynamics and Econometrics, 2(1), 1-14.

Example

A switch at zero with a fixed delay, then a delay-2 process whose delay the grid recovers:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros(400)
>>> for t in range(1, 400):
...     phi = 0.6 if y[t - 1] <= 0.0 else -0.4
...     y[t] = phi * y[t - 1] + rng.standard_normal()
>>> res = SETAR(y, order=1, delay=1).fit()
>>> res.n_lower + res.n_upper == res.nobs, bool(abs(res.threshold) < 0.3)
(True, True)
>>> rng = np.random.default_rng(1)
>>> w = np.zeros(600)
>>> for t in range(2, 600):
...     phi = 0.5 if w[t - 2] <= 0.0 else -0.5
...     w[t] = phi * w[t - 1] + rng.standard_normal()
>>> searched = SETAR(w, order=2).fit()
>>> searched.delay, searched.searched_delay, searched._comparison_label()
(2, True, 'SETAR(2, d=2)')
>>> SETAR(y, order=1, trim=0.5)
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: trim must lie in (0.0, 0.5); got 0.5.