SignRestrictedSVAR#

class cultivars.multivariate.structural.sign_restrictions.SignRestrictedSVAR(result, restrictions, *, horizons=(0,), draws=1000, max_attempts=None, seed=0)[source]

Bases: _IdentificationModel[SignRestrictedSVARResult]

Set identification by declared response signs, Uhlig (2005) via RWZ draws.

Rotations \(Q\) of the Cholesky factor are drawn uniformly over the orthogonal group (the QR of a Gaussian matrix with the sign fix that makes it Haar, Rubio-Ramírez, Waggoner and Zha 2010) and kept when every declared sign holds at every declared lead:

\[\operatorname{sign}\!\big(e_i' \Psi_h L Q e_j\big) = s_{ij}, \qquad h \in \mathcal{H},\]

for each restricted column \(j\) and each declared pair \((i, s_{ij})\). A restricted column may be flipped wholesale, since a shock and its negative are the same rotation; what is never done is relabeling columns to rescue a draw, so a shock’s identity is its declared position.

Parameters:
  • result (ClosedSystemResult) – The fitted closed reduced-form result to identify.

  • restrictions (Mapping[str, Mapping[str, str]]) – Mapping from shock label to its sign pattern, itself a mapping from variable name to "+" or "-". Declared shocks occupy the leading columns in declaration order; remaining columns are unrestricted.

  • horizons (Sequence[int]) – Leads at which every declared sign must hold.

  • draws (int) – Accepted rotations to collect.

  • max_attempts (int | None) – Rotations to try before giving up; defaults to one thousand per requested draw.

  • seed (int | None) – Seed for the rotation draws, so an identified set is reproducible.

Raises:

SpecificationError – If the result is not a closed system, or the declaration, horizons, or draw budget are malformed.

Variables:
  • _source – The closed reduced-form result being identified.

  • _compiled – Per-column (variable index, +-1.0) sign pairs.

  • _labels – The shock labels, declared first, then unrestrictedN.

  • _leads – The horizons at which the signs bind.

  • _draws – Accepted rotations requested.

  • _budget – Rotations to attempt before giving up.

  • _seed – The seed behind the draws.

  • _restriction – The declaration, stated as a sentence.

See also

References

Uhlig, H. (2005). What are the effects of monetary policy on output? Results from an agnostic identification procedure. Journal of Monetary Economics, 52(2), 381-419.

Rubio-Ramírez, J. F., Waggoner, D. F., & Zha, T. (2010). Structural vector autoregressions: Theory of identification and algorithms for inference. Review of Economic Studies, 77(2), 665-696.

Example

Two shocks declared, a demand shock moving both variables up and a supply shock moving them apart. The set is sharper than with one shock – fewer draws pass – and the median impact responses carry the declared signs:

>>> import numpy as np
>>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR
>>> rng = np.random.default_rng(0)
>>> B = np.array([[1.0, 0.5], [0.3, 1.0]])
>>> A = np.array([[0.5, 0.1], [0.0, 0.4]])
>>> eps = rng.standard_normal((402, 2))
>>> y = np.zeros((402, 2))
>>> for t in range(1, 402):
...     y[t] = A @ y[t - 1] + B @ eps[t]
>>> res = VAR(y, order=1, names=("gdp", "infl")).fit()
>>> signs = {"demand": {"gdp": "+", "infl": "+"}, "supply": {"gdp": "+", "infl": "-"}}
>>> sset = SignRestrictedSVAR(res, signs, draws=200, seed=0).identify()
>>> sset.shock_names, sset.n_accepted, sset.attempts
(('demand', 'supply'), 200, 753)
>>> median = sset.irf(0)[1, 0]
>>> np.sign(median).tolist()
[[1.0, 1.0], [1.0, -1.0]]
>>> SignRestrictedSVAR(res, {**signs, "third": {"gdp": "+"}})
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: 3 restricted shocks exceed the 2 shocks ...

Private attributes#