ProxySVAR.identify#
- ProxySVAR.identify()[source]#
Recover the proxied shock’s impact column.
The first stage regresses the normalization innovation on the instruments; the fitted values stand in for the shock, each innovation’s covariance with them gives the column relative to the anchor, and the column is rescaled to unit shock variance. The anchor entry is positive by construction.
- Return type:
- Returns:
A structural result carrying the one identified column, with the first-stage F statistic, the instrument count and the normalization in its diagnostics.
- Raises:
NumericalError – If the instrument has no first-stage relationship with the normalization innovation, or there are no more residual rows than instruments.
Example
The anchor’s sign is fixed whatever the instrument’s sign, so a proxy and its negative identify the same column; an unrelated series still produces a column, but a weak first stage says it is not to be trusted:
>>> 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.0], [0.5, 1.0]]) >>> eps = rng.standard_normal((302, 2)) >>> y = np.zeros((302, 2)) >>> for t in range(1, 302): ... y[t] = 0.4 * y[t - 1] + B @ eps[t] >>> proxy = eps[:, 0] + 0.5 * rng.standard_normal(302) >>> res = VAR(y, order=1, names=("r", "x")).fit() >>> plus, minus = ProxySVAR(res, proxy[1:]), ProxySVAR(res, -proxy[1:]) >>> bool(np.allclose(plus.identify().impact, minus.identify().impact)) True >>> strong = dict(plus.identify().diagnostics) >>> strong["Normalization"], float(strong["First-stage F"]) > 100 ('r > 0 on impact', True) >>> weak = ProxySVAR(res, rng.standard_normal(301)).identify() >>> float(dict(weak.diagnostics)["First-stage F"]) < 10 True >>> ProxySVAR(res, np.ones(301)).identify() Traceback (most recent call last): cultivars.exceptions.NumericalError: the instrument has no first-stage relationship ...