SignRestrictedSVAR#
- class cultivars.multivariate.structural.sign_restrictions.SignRestrictedSVAR(result, restrictions, *, horizons=(0,), draws=1000, max_attempts=None, seed=0)[source]#
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
SignRestrictedSVARResult– the accepted set returned.NarrativeSignRestrictedSVAR– the same draws filtered additionally by declared history.SetIdentifiedSVAR– the exact bounds of the set for one restricted shock, with no prior over rotations.
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 ...
Attributes#
Methods#
|
Draw rotations and keep those satisfying every declared sign. |