In this video I focus on Optimal Policy in the baseline New Keynesian model and discuss concepts like the Divine Coincidence, Indeterminacy, Taylor Principle, Optimal Policy under Commitment, Optimal Policy under Discretion, Simple Implementable Rules and how to compare different policy regimes.
Even though this video provides some insight on the theory behind these concepts, I try to not get caught up in the details, but focus mainly on the implementation aspects in Dynare.
Optimal Policy in Baseline New Keynesian Model
Implementing Optimal Policy in Baseline New Keynesian Model with simple rules
Policy Trade-Offs and Breaking Divine Coincidence
Optimal Policy Under Commitment
Optimal Policy Under Discretion
Comparison of Optimal Policy
Simple Implementable Rules
Optimal Simple Implementable Rules
Outro & References
/*
* 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/>.
*/
var
a ${a}$ (long_name='technology shock process (log dev ss)')
z ${z}$ (long_name='preference shock process (log dev ss)')
c ${c}$ (long_name='consumption (log dev ss)')
y ${y}$ (long_name='output (log dev ss)')
y_nat ${y^{nat}}$ (long_name='natural output (log dev ss)')
y_gap ${\tilde y}$ (long_name='output gap (log dev ss)')
r_nat ${r^{nat}}$ (long_name='natural interest rate (log dev ss)')
r_real ${r}$ (long_name='real interest rate (log dev ss)')
ii ${i}$ (long_name='nominal interest rate (log dev ss)')
pie ${\pi}$ (long_name='inflation (log dev ss)')
n ${n}$ (long_name='hours worked (log dev ss)')
w ${w}$ (long_name='real wage (log dev ss)')
;
varexo
eps_a ${\varepsilon_a}$ (long_name='technology shock')
eps_z ${\varepsilon_z}$ (long_name='preference shock')
;
parameters
ALPHA ${\alpha}$ (long_name='one minus labor share in production')
BETA ${\beta}$ (long_name='discount factor')
RHOA ${\rho_a}$ (long_name='autocorrelation technology process')
RHOZ ${\rho_{z}}$ (long_name='autocorrelation preference process')
SIGMA ${\sigma}$ (long_name='inverse EIS')
VARPHI ${\varphi}$ (long_name='inverse Frisch elasticity')
EPSILON ${\epsilon}$ (long_name='Dixit-Stiglitz demand elasticity')
THETA ${\theta}$ (long_name='Calvo probability')
@#if MONPOL != 1
PHI_PIE ${\phi_{\pi}}$ (long_name='inflation feedback Taylor Rule')
PHI_Y ${\phi_{y}}$ (long_name='output feedback Taylor Rule')
@#endif
;
model(linear);
//Composite parameters
#OMEGA=(1-ALPHA)/(1-ALPHA+ALPHA*EPSILON);
#PSI_YA=(1+VARPHI)/(SIGMA*(1-ALPHA)+VARPHI+ALPHA);
#LAMBDA=(1-THETA)*(1-BETA*THETA)/THETA*OMEGA;
#KAPPA=LAMBDA*(SIGMA+(VARPHI+ALPHA)/(1-ALPHA));
[name='New Keynesian Phillips Curve']
pie=BETA*pie(+1)+KAPPA*y_gap;
[name='Dynamic IS Curve']
y_gap=-1/SIGMA*(ii-pie(+1)-r_nat)+y_gap(+1);
[name='Production function']
y=a+(1-ALPHA)*n;
[name='labor demand']
w = SIGMA*c+VARPHI*n;
[name='resource constraint']
y=c;
[name='TFP process']
a=RHOA*a(-1)+eps_a;
[name='Preference shifter']
z = RHOZ*z(-1) + eps_z;
[name='Definition natural rate of interest']
r_nat=-SIGMA*PSI_YA*(1-RHOA)*a+(1-RHOZ)*z;
[name='Definition real interest rate']
r_real=ii-pie(+1);
[name='Definition natural output']
y_nat=PSI_YA*a;
[name='Definition output gap']
y_gap=y-y_nat;
@#if MONPOL == 1
[name='Interest Rate Rule: Exogenous One-To-One']
ii = r_nat;
@#elseif MONPOL == 2
ii = r_nat + PHI_PIE*pie+PHI_Y*y_gap;
@#else
ii = PHI_PIE*pie+PHI_Y*y;
@#endif
end;
shocks;
var eps_z = 1;
var eps_a = 1;
end;
% -------------------------- %
% Exogenous one-for-one rule %
% -------------------------- %
@#define MONPOL = 1
@#include "NK_linear_common.inc"
SIGMA = 1;
VARPHI = 5;
THETA = 3/4;
RHOZ = 0.5;
RHOA = 0.9;
BETA = 0.99;
ALPHA = 1/4;
EPSILON = 9;
steady;
check;
%stoch_simul(order = 1,irf=30);
% ---------------------------------------------- %
% optimal rule with feedback to target variables %
% ---------------------------------------------- %
@#define MONPOL = 2
@#include "NK_linear_common.inc"
SIGMA = 1;
VARPHI = 5;
THETA = 3/4;
RHOZ = 0.5;
RHOA = 0.9;
BETA = 0.99;
ALPHA = 1/4;
EPSILON = 9;
PHI_PIE = 1.5;
PHI_Y = 0.125;
steady;
check;
stoch_simul(order=1,irf=30);
estimated_params;
PHI_PIE, 1.5, 0, 2;
PHI_Y, 0.125, 0, 2;
end;
varobs a z c y y_nat y_gap r_nat r_real ii pie n w; % dynare_sensitivity requires varobs block
% alternative and quick way to assume all variables are observbable:
% options_.varobs = M_.endo_names;
dynare_sensitivity;
/*
* 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/>.
*/
var
a ${a}$ (long_name='technology shock process (log dev ss)')
z ${z}$ (long_name='preference shock process (log dev ss)')
c ${c}$ (long_name='consumption (log dev ss)')
y ${y}$ (long_name='output (log dev ss)')
y_nat ${y^{nat}}$ (long_name='natural output (log dev ss)')
y_gap ${\tilde y}$ (long_name='output gap (log dev ss)')
y_e ${y^{e}}$ (long_name='efficient output (log dev steady state)')
x ${x}$ (long_name='welfare-relevant output gap (log dev steady state)')
r_e ${r^{e}}$ (long_name='efficient interest rate (log dev ss)')
r_real ${r}$ (long_name='real interest rate (log dev ss)')
ii ${i}$ (long_name='nominal interest rate (log dev ss)')
pie ${\pi}$ (long_name='inflation (log dev ss)')
n ${n}$ (long_name='hours worked (log dev ss)')
w ${w}$ (long_name='real wage (log dev ss)')
u ${u}$ (long_name='cost push process (log dev steady state)')
;
varexo
eps_a ${\varepsilon_a}$ (long_name='technology shock')
eps_z ${\varepsilon_z}$ (long_name='preference shock')
eps_u ${\varepsilon_u}$ (long_name='cost-push shock')
;
parameters
ALPHA ${\alpha}$ (long_name='one minus labor share in production')
BETA ${\beta}$ (long_name='discount factor')
RHOA ${\rho_a}$ (long_name='autocorrelation technology process')
RHOZ ${\rho_{z}}$ (long_name='autocorrelation preference process')
RHOU ${\rho_{u}}$ (long_name='autocorrelation cost-push process')
SIGMA ${\sigma}$ (long_name='inverse EIS')
VARPHI ${\varphi}$ (long_name='inverse Frisch elasticity')
EPSILON ${\epsilon}$ (long_name='Dixit-Stiglitz demand elasticity')
THETA ${\theta}$ (long_name='Calvo probability')
KAPPA ${\kappa}$ (long_name='Composite parameter Phillips curve')
VARTHETA ${\vartheta}$ (long_name='weight of x in loss function')
;
model(linear);
//Composite parameters
#PSI_YA=(1+VARPHI)/(SIGMA*(1-ALPHA)+VARPHI+ALPHA);
[name='New Keynesian Phillips Curve']
pie=BETA*pie(+1)+KAPPA*x + u;
[name='Dynamic IS Curve']
x = x(+1) - 1/SIGMA*(ii-pie(+1)-r_e);
[name='Production function']
y=a+(1-ALPHA)*n;
[name='labor demand']
w = SIGMA*c+VARPHI*n;
[name='resource constraint']
y=c;
[name='TFP process']
a=RHOA*a(-1)+eps_a;
[name='Preference shifter']
z = RHOZ*z(-1) + eps_z;
[name='Definition efficient interest rate']
r_e=SIGMA*(y_e(+1)-y_e)+(1-RHOZ)*z;
[name='Definition real interest rate']
r_real=ii-pie(+1);
[name='Definition efficient output']
y_e=PSI_YA*a;
[name='Definition output gap']
y_gap=y-y_nat;
[name='Definition linking various output gaps']
y_gap=x+(y_e-y_nat);
[name='Implicit definition of natural output, following from definition of u']
u = KAPPA*(y_e-y_nat);
[name='cost push process']
u=RHOU*u(-1)+eps_u;
end;
steady_state_model;
% We need these parameters to evaluate loss function!
KAPPA=(1-THETA)*(1-BETA*THETA)/THETA*(1-ALPHA)/(1-ALPHA+ALPHA*EPSILON)*(SIGMA+(VARPHI+ALPHA)/(1-ALPHA));
VARTHETA=KAPPA/EPSILON;
% All other variables are zero in steady state
pie=0;y_gap=0;y_nat=0;y=0;y_e=0;x=0;ii=0;r_e=0;r_real=0;c=0;n=0;u=0;a=0;z=0;w=0;
end;
@#include "NK_linear_costpush_common.inc"
shocks;
var eps_a = 0; %shut off
var eps_u = 1;
var eps_z = 0; %shut off
end;
SIGMA = 1;
VARPHI=5;
THETA=3/4;
RHOZ = 0.5;
RHOA = 0.9;
BETA = 0.99;
ALPHA = 1/4;
EPSILON= 9;
@#ifndef VALUERHOU
RHOU=0; % Response to transitory cost-push shock under commitment
%RHOU=0.8; % Response to persistent cost-push shock under commitment
@#else
RHOU = @{VALUERHOU};
@#endif
planner_objective pie^2 +VARTHETA*x^2;
ramsey_model(instruments=(ii),planner_discount=BETA);
stoch_simul(order=1,irf=30) x pie u;
evaluate_planner_objective;
@#include "NK_linear_costpush_common.inc"
shocks;
var eps_a = 0; %shut off
var eps_u = 1;
var eps_z = 0; %shut off
end;
SIGMA = 1;
VARPHI=5;
THETA=3/4;
RHOZ = 0.5;
RHOA = 0.9;
BETA = 0.99;
ALPHA = 1/4;
EPSILON= 9;
@#ifndef VALUERHOU
RHOU=0; % Response to transitory cost-push shock under commitment
%RHOU=0.8; % Response to persistent cost-push shock under commitment
@#else
RHOU = @{VALUERHOU};
@#endif
planner_objective pie^2 +VARTHETA*x^2;
discretionary_policy(instruments=(ii),irf=30,planner_discount=BETA,discretionary_tol=1e-12) x pie u;
/*
* 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/>.
*/
var
a ${a}$ (long_name='technology shock process (log dev ss)')
z ${z}$ (long_name='preference shock process (log dev ss)')
c ${c}$ (long_name='consumption (log dev ss)')
y ${y}$ (long_name='output (log dev ss)')
y_nat ${y^{nat}}$ (long_name='natural output (log dev ss)')
y_gap ${\tilde y}$ (long_name='output gap (log dev ss)')
y_e ${y^{e}}$ (long_name='efficient output (log dev steady state)')
x ${x}$ (long_name='welfare-relevant output gap (log dev steady state)')
r_e ${r^{e}}$ (long_name='efficient interest rate (log dev ss)')
r_real ${r}$ (long_name='real interest rate (log dev ss)')
ii ${i}$ (long_name='nominal interest rate (log dev ss)')
pie ${\pi}$ (long_name='inflation (log dev ss)')
n ${n}$ (long_name='hours worked (log dev ss)')
w ${w}$ (long_name='real wage (log dev ss)')
u ${u}$ (long_name='cost push process (log dev steady state)')
;
varexo
eps_a ${\varepsilon_a}$ (long_name='technology shock')
eps_z ${\varepsilon_z}$ (long_name='preference shock')
eps_u ${\varepsilon_u}$ (long_name='cost-push shock')
;
parameters
ALPHA ${\alpha}$ (long_name='one minus labor share in production')
BETA ${\beta}$ (long_name='discount factor')
RHOA ${\rho_a}$ (long_name='autocorrelation technology process')
RHOZ ${\rho_{z}}$ (long_name='autocorrelation preference process')
RHOU ${\rho_{u}}$ (long_name='autocorrelation cost-push process')
SIGMA ${\sigma}$ (long_name='inverse EIS')
VARPHI ${\varphi}$ (long_name='inverse Frisch elasticity')
EPSILON ${\epsilon}$ (long_name='Dixit-Stiglitz demand elasticity')
THETA ${\theta}$ (long_name='Calvo probability')
PHI_PIE ${\phi_{\pi}}$ (long_name='inflation feedback Taylor Rule')
PHI_Y ${\phi_{y}}$ (long_name='output feedback Taylor Rule')
;
model(linear);
//Composite parameters
#PSI_YA=(1+VARPHI)/(SIGMA*(1-ALPHA)+VARPHI+ALPHA);
#KAPPA=(1-THETA)*(1-BETA*THETA)/THETA*(1-ALPHA)/(1-ALPHA+ALPHA*EPSILON)*(SIGMA+(VARPHI+ALPHA)/(1-ALPHA));
[name='New Keynesian Phillips Curve']
pie=BETA*pie(+1)+KAPPA*x + u;
[name='Dynamic IS Curve']
x = x(+1) - 1/SIGMA*(ii-pie(+1)-r_e);
[name='Production function']
y=a+(1-ALPHA)*n;
[name='labor demand']
w = SIGMA*c+VARPHI*n;
[name='resource constraint']
y=c;
[name='TFP process']
a=RHOA*a(-1)+eps_a;
[name='Preference shifter']
z = RHOZ*z(-1) + eps_z;
[name='Definition efficient interest rate']
r_e=SIGMA*(y_e(+1)-y_e)+(1-RHOZ)*z;
[name='Definition real interest rate']
r_real=ii-pie(+1);
[name='Definition efficient output']
y_e=PSI_YA*a;
[name='Definition output gap']
y_gap=y-y_nat;
[name='Definition linking various output gaps']
y_gap=x+(y_e-y_nat);
[name='Implicit definition of natural output, following from definition of u']
u = KAPPA*(y_e-y_nat);
[name='cost push process']
u=RHOU*u(-1)+eps_u;
[name='Interest Rate Rule']
ii = PHI_PIE*pie+PHI_Y*y;
end;
steady_state_model;
% All other variables are zero in steady state
pie=0;y_gap=0;y_nat=0;y=0;y_e=0;x=0;ii=0;r_e=0;r_real=0;c=0;n=0;u=0;a=0;z=0;w=0;
end;
shocks;
var eps_a = 0;
var eps_u = 1;
var eps_z = 0;
end;
SIGMA = 1;
VARPHI=5;
THETA=3/4;
RHOZ = 0.5;
RHOA = 0.9;
RHOU = 0.5;
BETA = 0.99;
ALPHA = 1/4;
EPSILON= 9;
PHI_PIE = 1.5;
PHI_Y = 0.125;
optim_weights;
pie 1;
y 1;
end;
osr_params PHI_PIE PHI_Y;
osr_params_bounds;
PHI_PIE, 0, 2;
PHI_Y, 0, 2;
end;
osr(opt_algo=9,irf=30) u y y_nat y_e y_gap x pie;
oo_.osr.optim_params
clear all; close all; clc;
dynare NK_linear_costpush_discretion -DVALUERHOU=0
irfs_discretion_transitory = oo_.irfs;
dynare NK_linear_costpush_discretion -DVALUERHOU=0.8
irfs_discretion_persistent = oo_.irfs;
dynare NK_linear_costpush_commitment -DVALUERHOU=0
irfs_commitment_transitory = oo_.irfs;
dynare NK_linear_costpush_commitment -DVALUERHOU=0.8
irfs_commitment_persistent = oo_.irfs;
close all;
irf_horizon = 15;
figure
subplot(2,3,1)
plot(0:irf_horizon-1,irfs_discretion_transitory.x_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_transitory.x_eps_u(1:irf_horizon),'-x')
axis tight
title('Output gap (transitory shock)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')
subplot(2,3,2)
plot(0:irf_horizon-1,irfs_discretion_transitory.pie_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_transitory.pie_eps_u(1:irf_horizon),'-x')
axis tight
title('Inflation (transitory shock)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')
subplot(2,3,3)
plot(0:irf_horizon-1,irfs_discretion_transitory.u_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_transitory.u_eps_u(1:irf_horizon),'-x')
axis tight
title('Cost-Push process (transitory)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')
subplot(2,3,4)
plot(0:irf_horizon-1,irfs_discretion_persistent.x_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_transitory.x_eps_u(1:irf_horizon),'-x')
axis tight
title('Output gap (persistent shock)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')
subplot(2,3,5)
plot(0:irf_horizon-1,irfs_discretion_persistent.pie_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_persistent.pie_eps_u(1:irf_horizon),'-x')
axis tight
title('Inflation (persistent shock)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')
subplot(2,3,6)
plot(0:irf_horizon-1,irfs_discretion_persistent.u_eps_u(1:irf_horizon),'-o')
hold on
plot(0:irf_horizon-1,irfs_commitment_persistent.u_eps_u(1:irf_horizon),'-x')
axis tight
title('Cost-Push process (persistent)')
legend({'Discretion' 'Commitment'},'Location','SouthEast')