StochasticVolatilitySVAR#

class cultivars.multivariate.structural.stochastic_volatility.StochasticVolatilitySVAR(result, *, shock_names=None)[source]#

Identification through stochastic volatility, Lewis (2021) / Bertsche-Braun (2022).

Every structural shock carries a latent log-AR(1) variance; the impact matrix is identified up to column order and sign because the shocks’ variance paths are not proportional. Nothing is declared – no regime dates, no restrictions – and the price is that the shocks come back labelled by statistics, not economics.

Parameters:
  • result (ClosedSystemResult) – A fitted closed reduced-form result (a VAR, VECM, …).

  • shock_names (Sequence[str] | None) – One label per shock column, in the convention order (shock j loads most on variable j). Defaults to shock_<variable>.

Raises:

SpecificationError – If the result is not a closed system, or the labels do not match the number of variables.

Example

>>> rng = np.random.default_rng(0)
>>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR
>>> n = 400
>>> phi, sigma = np.array([0.97, 0.6]), np.array([0.2, 0.6])
>>> h = np.zeros((n, 2))
>>> for t in range(1, n):
...     h[t] = phi * h[t - 1] + sigma * rng.standard_normal(2)
>>> shocks = np.exp(h / 2) * rng.standard_normal((n, 2))
>>> y = np.zeros((n, 2))
>>> for t in range(1, n):
...     y[t] = 0.4 * y[t - 1] + shocks[t] @ np.array([[1.0, 0.5], [0.3, 1.0]]).T
>>> res = VAR(y, order=1).fit()
>>> post = StochasticVolatilitySVAR(res).identify(n_draws=300, n_burn=100, seed=0)
>>> post.impact.shape
(2, 2)
>>> post.to_point().is_complete
True

Attributes#

k_endog

Number of variables in the source system.

names

Variable labels of the source system.

shock_names

One label per shock column.

source

The fitted reduced-form result being identified.

Methods#

identify(*[, n_draws, n_burn, thin, prior, seed])

Sample the posterior over impact matrices and volatility paths.