Monetary-policy instruments
Practicum · Session 05
Run the monthly application
Obtain the two fingerprinted inputs described in the session README and place them in data/raw/05-external-instruments/. Start MATLAB at the package root. The returned result contains the full VAR and three proxy estimates, not just the figure.
% Estimate the common monthly VAR and the GK/MAR identifying moments.
result = run_session(5);
% Display exact identification-overlap counts for the two instruments.
disp([result.proxy.n, result.mar.n]);
% Display the conventional first-stage F statistics, not robust effective-F values.
disp([result.proxy.firstStageF, result.mar.firstStageF]);The checked overlap counts are 240 and 228 months. The ordinary first-stage F statistics are approximately 29.943 and 7.924. Do not interpret their difference as evidence that one instrument has a more plausible exclusion restriction; that requires substantive evidence beyond a first stage.
Reproduce the moment ratio
The result stores the actual centered input vectors. Reconstruct the impact direction directly and check it against the function output.
% Form sample cross moments from the stored, identically dated inputs.
moment = result.proxy.U' * result.proxy.instrument / result.proxy.n;
% Normalize every response by the policy-indicator covariance.
impact = moment / moment(result.config.policy);
% Compare the complete vector, including responses not restricted by identification.
assert(norm(impact - result.proxy.impact) < 1e-12);The impact vector is approximately (0.1172,-0.1230,1,0.3991)'. There is no reason to overwrite its positive IP entry: it is unrestricted in a proxy SVAR. A restriction imposed to make a figure look conventional would define a different estimator.
Inspect the centering revision
% Put preferred and classroom policy-unit impact vectors side by side.
disp([result.proxy.impact, result.classroom.impact]);
% Confirm that each specification uses the identical instrument-overlap calendar.
assert(isequal(result.proxy.periods, result.classroom.periods));
% Both normalizations must set the policy indicator's impact to one.
assert(abs(result.proxy.impact(3) - 1) < 1e-12);The original source’s no-intercept call is reproduced as classroom, not quietly relabeled as centered. verify_session05 separately checks that path against the privately supplied original VAR and first-stage routines.
Check variance scaling
% Read the identified impact column normalized to unit structural variance.
b = result.proxy.unitImpact;
% A triangular solve evaluates the structural variance normalization stably.
normalized = chol(result.model.Sigma, 'lower') \ b;
% Its squared length must be one before computing a shock-specific FEVD.
assert(abs(normalized' * normalized - 1) < 1e-12);
% The identified shock's stored variance share must stay between zero and one.
assert(all(result.fevd(:) >= -1e-12 & result.fevd(:) <= 1 + 1e-12));The policy-unit impact and unit-variance impact answer different scaling questions. Save their labels with every exported table. A first-stage diagnostic, a policy-unit response, and a variance share cannot be substituted for one another.
Worked exercises
Recovering a direction
The policy covariance is m_p=0.4, hence
s=m/0.4=(-0.5,-0.25,1,0.3)'.
For a one-percentage-point increase in the policy indicator, the other impact responses are -0.5, -0.25, and 0.3 in their respective measurement units. They are not all automatically percentage points: the variable definitions determine that interpretation.
Multiplying the instrument by -100 gives \widetilde m=(20,10,-40,-12)'. Dividing by -40 produces exactly the same s. Both a change of units and a reversal of instrument orientation cancel in the ratio. The check is s_p=1 in both calculations. This invariance does not say that replacing the instrument with a substantively different series leaves the direction unchanged.
The two-stage algebra
Let a=z'u_p/(z'z), so \widehat u_p=az. Provided z'z>0 and a\ne0,
\widehat\delta =\frac{a z'u_q}{a^2 z'z} =\frac{z'u_q}{a z'z} =\frac{z'u_q}{z'u_p}.
The fitted policy component isolates the variation associated with the instrument. Regressing each other innovation on that component recovers its impact relative to the policy variable. Using the policy innovation itself in the second stage would generally include variation driven by other structural shocks.
For an intercept, replace z, u_p, and u_q by their deviations from their means over the same overlap sample. Then apply the derivation to the centered vectors. An intercept in the full-sample VAR makes each innovation column sum to zero over the VAR sample; it does not make a shorter subsample sum to zero. This is why the centered and original no-intercept calculations can differ.
A missing month
The usable pairs are (u_{\mathrm{Jan}},1), (u_{\mathrm{Mar}},0), and (u_{\mathrm{Apr}},-1). February is absent because its instrument is missing. March remains: its zero is observed and contributes to the sample mean, sample count, and first-stage residual variance, even though its uncentered product with the instrument is zero.
Pairing the first three residual rows with (1,0,-1) instead produces January, February, and March pairs. The final surprise is assigned to March rather than April, and February receives a fabricated observed zero. Equal vector lengths do not validate this merge.
In the revised implementation, ismember(model.periods,zPeriods) supplies the calendar mapping, and isfinite is applied after matching. The calendar-gap unit test deliberately includes an instrument-only month with a huge value; that value must never enter an identifying moment.
Unit variance and weak normalization
Here s'\Sigma_u^{-1}s=2^2/4+1^2/1=2. Therefore
b=\frac{1}{\sqrt2}(2,1)'=(\sqrt2,1/\sqrt2)'.
At impact, C_0=I. Variable one’s share is b_1^2/4=2/4=1/2. Variable two’s share is b_2^2/1=(1/2)/1=1/2. Using the policy-unit vector s instead would incorrectly give shares of one for both variables. The check b'\Sigma_u^{-1}b=1 establishes the intended variance scale.
In the weak-normalization example, the first relative impact is initially 0.2/0.001=200. Changing only the small denominator to 0.002 gives 0.2/0.002=100. Both ratios are numerically defined, but the inferred response changes by half after a covariance change of only 0.001. This illustrates denominator sensitivity. A programming guard against division by zero is not a weak-instrument-robust confidence procedure, and the example itself is not a formal weak-identification test.