TVPSVARResult#

class cultivars.multivariate.nonlinear.time_varying.TVPSVARResult(*, source, impacts)[source]

Bases: _SummaryMixin, _ConvergenceMixin

A structurally interpreted TVP-VAR: one recursive declaration, a path of answers.

Holds the fitted reduced form and the posterior mean structural impact matrix \(B_t\) at every estimation date, lower triangular in the order of names. For a homoskedastic source \(B_t\) is the Cholesky factor of the posterior mean covariance, the same at every date; for a stochastic-volatility source it is the posterior mean of \(A^{-1} H_t^{1/2}\) over the kept draws, so the impact of each shock drifts with its volatility while the contemporaneous ordering stays fixed. Structural responses at a date are the date’s coefficient stack propagated and rotated by its impact.

Note

Both the impacts and the responses are posterior-mean plug-ins: \(B_t\) is averaged over draws before it is combined with the averaged coefficient path, so a response here is not the posterior mean of the response. The source result retains beta_draws (and h_draws, impact_draws under SV) for a draw-by-draw propagation. This record retains no draw arrays of its own, so convergence() must be read on the source.

Variables:
  • source – The fitted reduced-form result, homoskedastic or SV.

  • impacts – (nobs, k, k) posterior mean structural impact path – constant rows repeated for the homoskedastic model.

See also

References

Primiceri, G. E. (2005). Time varying structural vector autoregressions and monetary policy. Review of Economic Studies, 72(3), 821-852.

Example

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros((140, 2))
>>> for t in range(1, 140):
...     y[t] = 0.5 * y[t - 1] + rng.standard_normal(2)
>>> source = TVPVAR(y, order=1, training=40).fit(n_draws=40, n_burn=15, seed=0)
>>> svar = TVPSVAR(source).identify()
>>> svar.names, svar.nobs, svar.impacts.shape
(('y1', 'y2'), 99, (99, 2, 2))
>>> bool(np.allclose(svar.impact(0), np.linalg.cholesky(source.sigma_u)))
True
>>> bool(np.allclose(svar.impact(0), svar.impact(98)))
True
>>> svar.irf(4, t=50).shape
(5, 2, 2)

Private methods#

_summary_table()

Build the structured summary.