var y pi i; varexo e_y e_pi e_i; parameters a1 a2 a3 b1 b2 b3 c1 c2 c3; a1 = .2; a2 = .8; a3 = .05; b1 = .3; b2 = .7; b3 = .1; c1 = 0.9; c2 = 1.5; c3 = 0.5; model(bytecode); y = a1*y(-1) + a2*y(1) - a3*(i-pi(1)) + e_y ; pi = b1*pi(-1) + b2*pi(1) + b3*y + e_pi ; i = c1*i(-1) + c2*pi(1) + c3*y + e_i ; end; steady; check; shocks; var e_y = 0.002; var e_pi = 0.004; var e_i = 0.001; end; // Set the periods where some of the endogenous variables will be constrained. subsample = 2Y:100Y; // Load all the data generated by simulate.mod SimulatedData = dseries('truedata.mat'); // Set the constrained paths for the endogenous variables. constrainedpaths = SimulatedData{'i'}(subsample); /* REMARKS ** ** In this example we constrain only the nominal interest rate from 2Y to 100Y to match the same variable as given by simulated.mod. ** When we invert the model, we search the sequence of innovations e_i that leads to these realizations of the nominal interest rate. If ** the model is the same, the sequence of innovations returned by the inversion routine has to match the true sequence of shocks (used ** in simulated.mod and available for reference in SimulatedData dseries object). In this example, we invert the model with a slightly ** different model by removing the max operator in the Taylor rule. Because of this difference, the innovations returned by the inversion ** routine are not equal to the true innovations. ** */ // Set the instruments (innovations used to control the nominal interest rate). exodata = SimulatedData{'e_y', 'e_pi', 'e_i'}.data; exodata(2:100,3) = NaN; exogenousvariables = dseries(exodata, 1Y, {'e_y';'e_pi';'e_i'}); /* REMARK ** ** We need as many instruments as contrained endogenous variables. In this case we control the nominal interest rate path with the shock ** in the Taylor rule. The other shocks have non NaN values (we use the values generated by simulation.mod). These shocks are considered as observed ** exogenous variables. ** */ // Invert the model by calling the model_inversion routine. [endogenousvariables, exogenousvariables] = model_inversion(constrainedpaths, exogenousvariables, SimulatedData, M_, options_, oo_); // Check the path for the nominal interest rate if max(abs(endogenousvariables.i(subsample).data-SimulatedData.i(subsample).data))>1e-6 error('Constrained on endogenous variable paths are not all satisfied!') end // Save the simulations on disk. endogenousvariables.save('endogenousvariables', 'mat'); exogenousvariables.save('exogenousvariables', 'mat'); // Plot the differences on e_y (shock in the Euler equation) figure(1) plot(exogenousvariables.e_y-SimulatedData.e_y) % Not zero because of the misspecification related to the ZLB title('e_y') // Plot the differences on e_pi (shock in the Phillips curve) figure(2) plot(exogenousvariables.e_pi-SimulatedData.e_pi) % Not zero because of the misspecification related to the ZLB title('e_pi') // Plot the differences on e_ik (shock in the Taylor rule) figure(3) plot(exogenousvariables.e_i-SimulatedData.e_i) % Not zero because of the misspecification related to the ZLB title('e_i') hold on id = find(endogenousvariables.i.data==-.05); plot(id, zeros(1,length(id)), 'or') hold off figure(4) plot(endogenousvariables.i,'-k','linewidth',2) hold on plot(SimulatedData.i(1Y:100Y),'--r','linewidth',2) hold off title('Nominal interest rate') figure(5) plot(endogenousvariables.y,'-k','linewidth',2) hold on plot(SimulatedData.y(1Y:100Y),'--r','linewidth',2) hold off title('Output gap') figure(6) plot(endogenousvariables.pi,'-k','linewidth',2) hold on plot(SimulatedData.pi(1Y:100Y),'--r','linewidth',2) hold off title('Inflation gap')