TVARResult#

class cultivars.multivariate.nonlinear.threshold.TVARResult(*, endog, names, order, trend, delay, threshold, threshold_name, threshold_values, transition_series, lower_coefficients, upper_coefficients, lower_deterministic, upper_deterministic, resid, fittedvalues, llf, nobs, n_params, self_exciting, searched_delay, n_lower, n_upper, lower_sigma_u, upper_sigma_u)[source]

Bases: _VectorObservedRegimeResult

A fitted two-regime threshold vector autoregression.

The estimate of

\[\begin{split}y_t = \begin{cases} c_L + \sum_{i=1}^{p} A_{L,i}\, y_{t-i} + u_t, & u_t \sim N(0, \Sigma_L), & z_t \le r, \\ c_U + \sum_{i=1}^{p} A_{U,i}\, y_{t-i} + u_t, & u_t \sim N(0, \Sigma_U), & z_t > r, \end{cases} \qquad z_t = s_{t-d},\end{split}\]

two complete systems – coefficients, deterministics and innovation covariance – glued along a threshold \(r\) on the delayed transition variable, which is a column of the system itself (self-exciting) or an external series. The split is found by exhaustive grid search over trimmed quantiles of \(z\), with regime-wise multivariate least squares at each candidate and the total Gaussian log-likelihood under separate covariances as the criterion; when the delay is searched, the grid runs over 1..order as well. The record extends the observed-regime surface – the two coefficient stacks, regime-conditional irf, fevd, ma_representation and forecast, the stability of each regime, and comparison by information criteria – with the regime sizes and the two covariances.

Note

Observations with \(z_t \le r\) belong to the lower regime, so a transition value exactly at the threshold is lower; the threshold itself is a grid quantile of the sample, so it is always an observed value of \(z\). n_params counts both regimes’ coefficients, both covariances and the threshold, but not a searched delay. The threshold is not identified under linearity, so information criteria rank specifications but do not test for a threshold, and likelihood_ratio_test() refuses rather than return a chi-squared p-value that is not one. Standard errors are not yet available.

Variables:
  • self_exciting – Whether the transition variable is a column of the system itself.

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

  • n_lower – Observations assigned to the lower regime.

  • n_upper – Observations assigned to the upper regime.

  • lower_sigma_u – Lower-regime innovation covariance, dof-corrected.

  • upper_sigma_u – Upper-regime innovation covariance, dof-corrected.

See also

  • TVAR – the model that produces this record.

  • STVARResult – the smooth blend of the same two regimes, with one covariance.

  • SETARResult – the univariate counterpart.

References

Tsay, R. S. (1998). Testing and modeling multivariate threshold models. Journal of the American Statistical Association, 93(443), 1188-1202.

Hansen, B. E. (1996). Inference when a nuisance parameter is not identified under the null hypothesis. Econometrica, 64(2), 413-430.

Example

A bivariate system that is persistent when y1’s lag is at or below zero and mean-reverting above it; the fit places the threshold near zero, recovers both regimes, and reports the regime sizes and covariances:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((300, 2))
>>> for t in range(1, 300):
...     a = 0.6 if y[t - 1, 0] <= 0.0 else -0.3
...     y[t] = a * y[t - 1] + rng.standard_normal(2)
>>> res = TVAR(y, order=1, transition_variable="y1", delay=1).fit()
>>> res.self_exciting, res.searched_delay, res.delay, res.threshold_name
(True, False, 1, 'y1')
>>> bool(abs(res.threshold) < 0.3), res.n_lower + res.n_upper == res.nobs, res.n_params
(True, True, 19.0)
>>> lower, upper = np.diag(res.lower_coefficients[0]), np.diag(res.upper_coefficients[0])
>>> bool(np.all(np.abs(lower - 0.6) < 0.15)), bool(np.all(np.abs(upper + 0.3) < 0.2))
(True, True)
>>> res.lower_sigma_u.shape, bool(np.all(np.diag(res.lower_sigma_u) > 0.0))
((2, 2), True)
>>> bool(np.isclose(res.regime_weight.mean(), res.n_upper / res.nobs))
True

Private methods#

_comparison_label()

Short specification label for a ranking table.

_from_fit(fit, model)

Assemble the public result from a raw fit and its specification.

_regime_sigma(regime)

The named regime's own innovation covariance.

_summary_table()

Build the structured summary.

_weight_at(values)

The upper-regime indicator at arbitrary transition values.