New Keynesian Baseline Model in Dynare - Zero-Lower-Bound


Here are the materials I use in the video.

Please feel free to raise any comments or issues on the website’s Github repository. Pull requests are very much appreciated.

Slides

Presentation

Codes

NK_ZLB_discretion.mod

/*
 * Copyright (C) 2016-2021 Johannes Pfeifer
 * Copyright (C) 2021 Willi Mutschler
 *
 * This is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * For a copy of the GNU General Public License,
 * see <http://www.gnu.org/licenses/>.
 */

% This implementation was originally written by Johannes Pfeifer.
% Some notes:
% - all model variables are expressed in deviations from steady state, except for the interest rates.
% - The dummy-variable ZLB_indicator is used to shut off the Taylor rule during the 
%   ZLB period and to switch it on again after the ZLB-period. This is necessary,
%   because without a Taylor rule to govern monetary policy after the ZLB period,
%   there is scope for multiple equilibria. Switching on the Taylor rule assures that
%   the solution pi=x=0 is selected. Otherwise, one would need to set the number of 
%   simulation periods to 6 so that the terminal condition of all variables being back
%   to steady state is imposed immediately after the end of the ZLB period.


var
  pie             ${\pi}$         (long_name='inflation')
  x               ${x}$           (long_name='welfare-relevant output gap')
  ii              ${i}$           (long_name='nominal interest rate')
  r_nat_ann       ${r^{nat,ann}}$ (long_name='annualized natural interest rate')
  pie_ann         ${\pi^{ann}}$   (long_name='annualized inflation rate')
  xi_2            ${\xi_2}$       (long_name='Langrange multiplier')
  ii_ann          ${i^{ann}}$     (long_name='annualized nominal interest rate')  
  ii_taylor       ${i^{Taylor}}$  (long_name='nominal interest rate Taylor rule')  
;     

varexo 
  r_nat           ${r^n}$         (long_name='natural rate of interest')
  ZLB_indicator   ${ZLB\_IND}$    (long_name='ZLB Indicator')
;

parameters
  ALPHA           ${\alpha}$      (long_name='One minus labor income share')
  BETA            ${\beta}$       (long_name='discount factor')
  SIGMA           ${\sigma}$      (long_name='risk aversion')
  VARPHI          ${\varphi}$     (long_name='inverse Frisch elasticity')
  EPSILON         ${\epsilon}$    (long_name='demand elasticity')
  THETA           ${\theta}$      (long_name='Calvo parameter')
  PHI_PIE         ${\phi_\pi}$    (long_name='Taylor rule inflation feedback')
;

%----------------------------------------------------------------
% Parametrization
%----------------------------------------------------------------
SIGMA   = 1;
VARPHI  = 5;
THETA   = 3/4;
BETA    = 0.99;
ALPHA   = 1/4;
EPSILON = 9;
PHI_PIE = 1.5;

model; 
#KAPPA=(1-THETA)*(1-BETA*THETA)/THETA*(1-ALPHA)/(1-ALPHA+ALPHA*EPSILON)*(SIGMA+(VARPHI+ALPHA)/(1-ALPHA));
#VARTHETA=KAPPA/EPSILON;
#ii_ = ZLB_indicator*ii + (1-ZLB_indicator)*ii_taylor;

[name='New Keynesian Phillips Curve']
pie = BETA*pie(+1) + KAPPA*x;

[name='Dynamic IS Curve']
x = x(+1) - 1/SIGMA*( ii_ - pie(+1) - r_nat);

[name='Taylor rule']
ii_taylor = 1 + PHI_PIE*pie;

[name='Combined FOC wrt pie and wrt x']
VARTHETA*x=-KAPPA*pie-xi_2;

[name='FOC wrt to ii',mcp='ii>0']
xi_2*1/SIGMA=0;

[name='Annualized natural interest rate']
r_nat_ann=4*r_nat;

[name='Annualized inflation']
pie_ann=4*pie;

[name='Annualized nominal interest rate']
ii_ann=4*max(ii_,0);
end;

%----------------------------------------------------------------------
% set initial and terminal condition to steady state of non-ZLB period;
% note that all variables have steady state of 0, except interest rates
%----------------------------------------------------------------------
initval;
  ZLB_indicator = 0;
  r_nat     = 1;
  ii        = 1;
  ii_taylor = 1;
  ii_ann    = 4*ii;
  r_nat_ann = 4*r_nat;  
end;
steady;

%-----------------------------------
% define negative natural rate shock
%-----------------------------------
shocks;
  var r_nat;         periods 1:6; values -1;
  var ZLB_indicator; periods 1:6; values 1;
end;

perfect_foresight_setup(periods=20);
perfect_foresight_solver(lmmcp);

%-----------------------------------
% Make figures
%-----------------------------------
figure
subplot(2,2,1)
plot(0:12,oo_.endo_simul(strmatch('x',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-o')
axis([0 12 -15 5])
title 'Output gap'

subplot(2,2,2)
plot(0:12,oo_.endo_simul(strmatch('pie_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-o')
axis([0 12 -25 5])
title 'Annualized Inflation'

subplot(2,2,3)
plot(0:12,oo_.endo_simul(strmatch('ii_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-o')
axis([0 12 -2 6])
title 'Annualized Nominal Interest Rate'

subplot(2,2,4)
plot(0:12,oo_.endo_simul(strmatch('r_nat_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-')
axis([0 12 -6 6])
title 'Annualized Natural Interest Rate'

NK_ZLB_commitment.mod

/*
 * Copyright (C) 2016-2021 Johannes Pfeifer
 * Copyright (C) 2021 Willi Mutschler
 *
 * This is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * For a copy of the GNU General Public License,
 * see <http://www.gnu.org/licenses/>.
 */

% This implementation was originally written by Johannes Pfeifer.
% Some notes:
% - all model variables are expressed in deviations from steady state, except for the interest rates.

var
  pie             ${\pi}$         (long_name='inflation')
  x               ${x}$           (long_name='welfare-relevant output gap')
  ii              ${i}$           (long_name='nominal interest rate')
  r_nat_ann       ${r^{nat,ann}}$ (long_name='annualized natural interest rate')
  pie_ann         ${\pi^{ann}}$   (long_name='annualized inflation rate')
  xi_1            ${\xi_1}$       (long_name='Langrange multiplier')
  xi_2            ${\xi_2}$       (long_name='Langrange multiplier')
  ii_ann          ${i^{ann}}$     (long_name='annualized nominal interest rate')  
; 

varexo
  r_nat           ${r^n}$         (long_name='natural rate of interest')
;

parameters
  ALPHA           ${\alpha}$      (long_name='One minus labor income share')
  BETA            ${\beta}$       (long_name='discount factor')
  SIGMA           ${\sigma}$      (long_name='risk aversion')
  VARPHI          ${\varphi}$     (long_name='inverse Frisch elasticity')
  EPSILON         ${\epsilon}$    (long_name='demand elasticity')
  THETA           ${\theta}$      (long_name='Calvo parameter')
;

%----------------------------------------------------------------
% Parametrization
%----------------------------------------------------------------
SIGMA   = 1;
VARPHI  = 5;
THETA   = 3/4;
BETA    = 0.99;
ALPHA   = 1/4;
EPSILON = 9;

model; 
#KAPPA=(1-THETA)*(1-BETA*THETA)/THETA*(1-ALPHA)/(1-ALPHA+ALPHA*EPSILON)*(SIGMA+(VARPHI+ALPHA)/(1-ALPHA));
#VARTHETA=KAPPA/EPSILON; 

[name='New Keynesian Phillips Curve']
pie = BETA*pie(+1) + KAPPA*x;

[name='Dynamic IS Curve']
x = x(+1) - 1/SIGMA*( ii - pie(+1) - r_nat);

[name='FOC wrt pie']
pie + xi_1 - xi_1(-1)-1/(BETA*SIGMA)*xi_2(-1)=0;

[name='FOC wrt x']
VARTHETA*x-KAPPA*xi_1+xi_2-1/BETA*xi_2(-1)=0;

[name='FOC wrt to ii',mcp='ii>0']
xi_2*1/SIGMA=0;

[name='Annualized natural interest rate']
r_nat_ann=4*r_nat;

[name='Annualized inflation']
pie_ann=4*pie;

[name='Annualized nominal interest rate']
ii_ann=4*max(ii,0);
end;

%----------------------------------------------------------------------
% set initial and terminal condition to steady state of non-ZLB period;
% note that all variables have steady state of 0, except interest rates
%----------------------------------------------------------------------
initval;
  r_nat     = 1;
  ii        = 1;
  ii_ann    = 4*ii;
  r_nat_ann = 4*r_nat;
end;
steady;

%-----------------------------------
% define negative natural rate shock
%-----------------------------------
shocks;
var r_nat; periods 1:6; values -1;
end;

perfect_foresight_setup(periods=50);
perfect_foresight_solver(lmmcp);

%-----------------------------------
% Make figures
%-----------------------------------
figure
subplot(2,2,1)
plot(0:12,oo_.endo_simul(strmatch('x',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-x')
axis([0 12 -15 5])
title 'Output gap'

subplot(2,2,2)
plot(0:12,oo_.endo_simul(strmatch('pie_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-x')
axis([0 12 -25 5])
title 'Annualized Inflation'

subplot(2,2,3)
plot(0:12,oo_.endo_simul(strmatch('ii_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-x')
axis([0 12 -2 6])
title 'Annualized Nominal Interest Rate'

subplot(2,2,4)
plot(0:12,oo_.endo_simul(strmatch('r_nat_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13),'-')
axis([0 12 -6 6])
title 'Annualized Natural Interest Rate'

NK_ZLB_compare_plots.m

close all; clear all;clc;
options_.nograph = true;

% Run discretion and save simulated variables
dynare NK_ZLB_discretion;
x_discretion = oo_.endo_simul(strmatch('x',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
pie_ann_discretion = oo_.endo_simul(strmatch('pie_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
ii_ann_discretion = oo_.endo_simul(strmatch('ii_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
r_nat_ann_discretion = oo_.endo_simul(strmatch('r_nat_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);

% Run commitment and save simulated variables
dynare NK_ZLB_commitment;
x_commitment = oo_.endo_simul(strmatch('x',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
pie_ann_commitment = oo_.endo_simul(strmatch('pie_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
ii_ann_commitment = oo_.endo_simul(strmatch('ii_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);
r_nat_ann_commitment = oo_.endo_simul(strmatch('r_nat_ann',M_.endo_names,'exact'),M_.maximum_lag+1:M_.maximum_lag+13);

%-----------------------------------
% Make figures
%-----------------------------------
figure
subplot(2,2,1)
plot(0:12,x_discretion,'-o')
hold on
plot(0:12,x_commitment,'-x')
axis([0 12 -15 5])
title 'Output gap'
legend {'Discretion','Commitment'}

subplot(2,2,2)
plot(0:12,pie_ann_discretion,'-o')
hold on
plot(0:12,pie_ann_commitment,'-x')
axis([0 12 -25 5])
title 'Annualized Inflation'
legend {'Discretion','Commitment'}

subplot(2,2,3)
plot(0:12,ii_ann_discretion,'-o')
hold on
plot(0:12,ii_ann_commitment,'-x')
axis([0 12 -2 6])
title 'Annualized Nominal Interest Rate'
legend {'Discretion','Commitment'}

subplot(2,2,4)
plot(0:12,r_nat_ann_discretion,'-o')
hold on
plot(0:12,r_nat_ann_commitment,'-x')
axis([0 12 -6 6])
title 'Annualized Natural Interest Rate'
legend {'Discretion','Commitment'}

Did you find this page helpful? Consider sharing it 🙌

Previous
Next