SETARResult#

class cultivars.univariate.threshold.SETARResult(*, endog, fittedvalues, resid, llf, nobs, n_params, order, delay, threshold, threshold_values, lower_params, upper_params, sigma2, ssr, self_exciting, n_lower, n_upper, searched_delay)[source]#

A fitted hard-threshold autoregression.

Two linear autoregressions selected by an indicator on a lagged transition variable,

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

with \(z_t = y_t\) for the self-exciting SETAR and an external series for TAR. Conditional on \((r, d)\) the model is two least-squares problems, so the estimator is a grid search: every candidate threshold on a trimmed quantile grid of the transition variable (and every candidate delay, when the caller left it open) is scored by the total sum of squares and the minimizer is kept. The record stores the split point, the regime assignment and the two coefficient blocks; the inherited fields, the per-regime stability verdicts, the information criteria and the refusal of the likelihood-ratio test come from _ObservedRegimeResult.

Note

The assignment is z <= r to the lower regime, and every reader of the fit – regime_weight, _weight_at, simulate and nonlinear_state_space – uses the same strict comparison on the upper side, so a transition value landing exactly on the threshold is counted as it was when the coefficients were solved for. n_params counts the two coefficient blocks and the threshold, not the variance, so the criteria are comparable with STARResult but sit one parameter below the linear families’ convention. searched_delay is True only when more than one delay was on the grid: SETAR(y, order=1) has nothing to search.

Variables:
  • self_exciting – Whether the transition variable is a lag of the series itself (SETAR) or an external variable (TAR).

  • n_lower – Observations assigned to the lower regime.

  • n_upper – Observations assigned to the upper regime.

  • searched_delay – Whether the delay was chosen by the grid search rather than fixed by the caller.

See also

  • SETAR – the self-exciting model that produces this record.

  • TAR – the externally driven model that produces this record.

  • STARResult – the same two regimes blended by a smooth weight.

  • MarkovSwitchingARResult – regimes driven by a latent chain rather than an observed variable.

References

Tong, H. (1990). Non-linear Time Series: A Dynamical System Approach. Oxford University Press, ch. 3.

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

Example

A two-regime AR(1) with a switch at zero, recovered with its split:

>>> 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.self_exciting, res.searched_delay, res.n_lower, res.n_upper, res.nobs
(True, False, 288, 111, 399)
>>> bool(abs(res.threshold) < 0.3), bool(abs(res.lower_params[1] - 0.6) < 0.1)
(True, True)
>>> bool(abs(res.upper_params[1] + 0.4) < 0.25), res.is_regimewise_stationary
(True, True)
>>> res.n_params, round(res.sigma2, 2)
(5, 0.99)

Attributes#

self_exciting

Whether the transition variable is the series' own lag (SETAR) or external.

n_lower

Observations assigned to the lower regime (z <= r).

n_upper

Observations assigned to the upper regime (z > r).

searched_delay

Whether the delay was selected by the grid rather than fixed by the caller.

delay

endog

fittedvalues

information_criteria

AIC, BIC, and HQIC derived from the likelihood and parameter count.

is_regimewise_stationary

Whether both regimes are stationary read as linear autoregressions.

llf

lower_params

lower_stability

Companion-eigenvalue verdict for the lower-regime AR block.

n_params

nobs

order

params

Estimated parameters keyed by display name, in table order.

regime_weight

1.0 above the threshold, else 0.0.

resid

sigma2

ssr

threshold

threshold_values

upper_fraction

Share of the effective sample assigned to the upper regime.

upper_params

upper_stability

Companion-eigenvalue verdict for the upper-regime AR block.

Methods#

compare(*others[, criterion])

Rank this result against others by an information criterion.

likelihood_ratio_test(unrestricted)

Refuse the test: the threshold is unidentified under the null.

nonlinear_state_space(measurement_variance)

The fitted threshold mean as a noisily observed state space.

simulate([n, seed, burn])

A fresh sample path at the fitted parameters.

summary()

The estimation summary, renderable as text, HTML, or a dataframe.

to_dict()

The aligned per-observation outputs as plain numpy arrays.

to_pandas(*[, index])

The aligned per-observation outputs as a pandas.DataFrame.

to_polars()

The aligned per-observation outputs as a polars.DataFrame.