ProxySVAR#

class impulso.identification.ProxySVAR(*, instrument, policy_variable, shock_name='instrumented', scale=None)[source]#

Bases: ImpulsoBaseModel

External-instrument (proxy) identification for one structural shock.

Identifies a single structural shock from an external instrument z_t that is correlated with the target shock (relevance) and uncorrelated with all others (exogeneity). Under those conditions the covariance between the instrument and the reduced-form residuals is proportional to the target shock’s impact column: E[z_t u_t] = phi * p_1.

Per posterior draw, the impact column is estimated as the sample covariance between the (date-aligned) instrument and that draw’s reconstructed residuals, normalised on policy_variable. The remaining columns are completed orthogonally, consistent with the draw’s shock covariance, so downstream code that needs a full invertible matrix (historical decomposition) keeps working — but those columns are rotation-arbitrary and are labelled unidentified_1.. accordingly. Downstream guard rails respond to that labelling: IdentifiedVAR.fevd masks the unidentified columns’ shares to NaN, and IdentifiedVAR.historical_decomposition collapses them into a single unidentified_remainder column (their sum is well-defined even though the split is not).

Parameters:
instrument#

Instrument series with a DatetimeIndex. Aligned to the estimation sample by date at identify() time (inner join — months missing from the instrument are dropped, matching the reindex-and-drop convention in the proxy-SVAR literature). Periods where no event occurred should be zero, not NaN.

Type:

pandas.Series

policy_variable#

Endogenous variable used to normalise the shock.

Type:

str

shock_name#

Label of the identified shock column.

Type:

str

scale#

If None (default), the identified column is a one-standard- deviation shock, consistent with the draw’s shock covariance (P @ P.T = Sigma holds exactly). If a float, the column is rescaled per draw so the shock moves policy_variable by scale units on impact (unit-effect normalisation, e.g. scale=10.0 for a +10% impact on a log*100 variable); the matrix then no longer reproduces Sigma, which is inherent to unit-effect normalisation.

Type:

float | None

first_stage(posterior, data, n_lags)[source]#

Posterior draws of the first-stage F statistic.

Regresses the policy variable’s reconstructed reduced-form residuals on the date-aligned instrument (with a constant), per posterior draw. Because the residuals differ draw by draw, the instrument-relevance F is itself a posterior quantity.

Parameters:
  • posterior (xr.Dataset) – Posterior Dataset with B and intercept draws (the fit’s posterior group).

  • data (VARData) – The VARData used at fit time.

  • n_lags (int) – Lag order of the fitted VAR.

Returns:

F statistics, shape (chains, draws).

Return type:

ndarray

identify(L, var_names, posterior=None, data=None, n_lags=None)[source]#

Apply external-instrument identification.

Parameters:
  • L (ndarray) – Lower-triangular Cholesky factor, shape (chains, draws, n_vars, n_vars).

  • var_names (list[str]) – Variable names in the data’s natural order.

  • posterior (xr.Dataset | None) – Full posterior; required (residual reconstruction needs B and intercept draws).

  • data (VARData | None) – The VARData used at fit time; required for residual reconstruction and date alignment.

  • n_lags (int | None) – Lag order of the fitted VAR; required.

Returns:

Structural shock matrix, shape (chains, draws, n_vars, n_vars). Column 0 is the identified shock; columns 1.. are an arbitrary orthogonal completion.

Raises:

ValueError – If posterior/data/n_lags are missing, the policy variable is unknown, or the instrument does not overlap the estimation sample.

Return type:

ndarray

property last_diagnostics: dict[str, float]#

Diagnostics from the most recent identify() call.

Scheme-prefixed scalars (see CONTEXT.md “Identification diagnostics”), overwritten per call and surfaced onto IdentifiedVAR.shock_matrix().attrs by the pipeline. Returns a copy.

model_config = {'arbitrary_types_allowed': True, 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context, /)#

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

shock_coords(n_vars)[source]#

Identified shock first, then rotation-arbitrary padding.

Parameters:

n_vars (int)

Return type:

list[str]