Ramsey policy - steady state model

Dear all,

I am currently trying to get the Ramsey allocation in a simple, benchmark GE model with public capital but I have failed to reach a stable solution using numerical entries for my four endogenous variables using the initval prompt. I have looked into most resources available on this forum but I cannot quite find what I am after. In particular, I do not have such a neat recursive solution as in the ramsey example provided by M. Julliard. What I would like to do instead is to have a separate steady state file computing the SS allocation given the values assigned by dynare.

I have copied the code of the mod file below. Note that I know this is currently not been pre-processed but I would like to know whether I can do something in the spirit of what I included in the steady_state_model block. I will really appreciate some guidance on this.

Many thanks,

Arthur

Full disclosure: I am new to Dynare (and Matlab).

Mod file

var y, c, l, k, kg, d, W, Pi, lambda, TFP,r,w,rg, tauh, tauc;

varexo z;

parameters beta, A, theta1, theta2, theta3, b, gamma, deltag, deltak;

// Calibration;

A = 1;
theta1=0.3;
theta2=0.6;
theta3=0.1;

deltak=0.1;
deltag=0.1;

gamma=3;
b=1.5;

beta=0.99;

// Dynamic system;

model;

//firm;
y = TFP*k(-1)^theta1*l^theta2*kg(-1)^theta3;
r=theta1*y/k(-1);
w=theta2*y/l;
Pi = theta3*y;
rg= theta3*y*kg(-1);

//government;
kg = kg(-1)*(1-deltag) + tauh*W + tauc*Pi;

//HH;
lambda/lambda(+1) = beta*(1 + (1-tauh)*(r(+1) - deltak));
1/(c-b*l^gamma) = lambda;
W = ((r - deltak)*k(-1) + w*l)+ d;
d = (1 - tauc)*Pi;
c + k = k(-1) + (1 - tauh)*W;
l = ((1 - tauh)*w/(gamma*b))^(1/(gamma-1));

//Technology process;
TFP = A + z;
end;

initval;
tauc=0.9;
tauh=0.05;
end;

steady_state_model;
TFP = A
x0=[0.5 2 0.5 1];
options = optimset('Algorithm','levenberg-marquardt','MaxFunEvals',2000,'Tolx',10e-12,'Tolfun',10e-12);
[SS, fval, exitflag,ouput]=csolve(@(x) SSnoDD(x,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,TFP),[0.5 2 0.5 1],options);
k=SS(2);
l=SS(3);
kg=SS(4);
d=(1 - tauc)*Pi;
y=k^theta1*l^theta2*kg^theta3;
Pi=theta3*y;
d=(1 - tauc)*Pi;
lambda=1/(c-b*l^gamma);
r=theta1*y/k;
w=theta2*y/l;
rg=theta3*y/kg;
W=((r - deltak)*k + w*l)+ d;
end;

planner_objective(ln(c-b*l^gamma));
ramsey_policy(planner_discount=0.99,order=1);

And here is the function:

function y = SSnoDD(x,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,TFP);
c=x(1);
k=x(2);
l=x(3);
kg=x(4);
y(1) = c + (1-tauh)*deltak*k - (1-tauh)*(1-tauc*theta3)*TFP*k^theta1*l^theta2*kg^theta3; %HH BC
y(2) = deltag*kg - (tauh+tauc*(1-tauh)*TFP*theta3)*k^theta1*l^theta2*kg^theta3+tauh*k*deltak; % GOV BC
y(3) = l - (theta2*(1 - tauh)/(b*gamma)*TFP*k^theta1*kg^theta3)^(1/(gamma - theta2)); % optimal l
y(4) = (1)/beta - (1 + (1 - tauh)*(theta1*TFP*k^(theta1-1)*l^theta2*kg^theta3-deltak));% EE
1 Like

I have gone through the messy algebra and expressed everything as a function of k.
I have amended the code to match the nk_ss example but I now get the following error message:

Any idea why?

Below are the amended code and function I am using.

var y, c, l, k, kg, d, W, Pi, lambda, TFP,r,w,rg, tauh, tauc;

varexo z;

parameters beta, A, theta1, theta2, theta3, b, gamma, deltag, deltak,eta, m, omega, rho1, rho3, rhotfp, zeta1, zeta2, xi;

// Calibration;

A = 1;
theta1=0.3;
theta2=0.6;
theta3=0.1;

deltak=0.1;
deltag=0.1;

gamma=3;
b=1.5;

beta=0.99;

//Temporary parameters for SS given taxes
eta = 1/(gamma - theta2);
m = (theta2*(1 - tauh)/(b*gamma))^eta;
rho1 = theta1*( 1 + theta2*eta)-1;
rho3 = theta3*( 1 + theta2*eta );
rhotfp = 1 + theta2*eta;
omega = (( (1/beta-1)/(1-tauh) + deltak )/(theta1*m^theta2))^(1/rho3);
zeta1 = theta1*eta - rho1/rho3*theta3*eta;
zeta2 = eta - rhotfp/rho3*eta*theta3;
xi = (tauh+tauc*(1-tauh)*theta3);

// Dynamic system;

model;

//firm;
y = TFP*k(-1)^theta1*l^theta2*kg(-1)^theta3;
r = theta1*y/k(-1);
w = theta2*y/l;
Pi = theta3*y;
rg = theta3*y*kg(-1);

//government;
kg = kg(-1)*(1-deltag) + tauh*W + tauc*Pi;

//HH;
lambda/lambda(+1) = beta*(1 + (1-tauh)*(r(+1) - deltak));
1/(c-b*l^gamma) = lambda;
W = ((r - deltak)*k(-1) + w*l)+ d;
d = (1 - tauc)*Pi;
c + k = k(-1) + (1 - tauh)*W;
l = ((1 - tauh)*w/(gamma*b))^(1/(gamma-1));

//Technology process;
TFP = A + z;
end;

initval;
tauc=0.9;
tauh=0.05;
end;

steady_state_model;
TFP = A;
k = find_kben(2,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,zeta1,zeta2,xi,TFP);
l = m*omega^(theta3*eta)*k^zeta1*TFP^zeta2;
kg = omega*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3));
c = (1-tauh)*(1-tauc*theta3)*TFP*k^theta1*l^theta2*kg^theta3 - (1-tauh)*deltak*k;
y=k^theta1*l^theta2*kg^theta3;
Pi=theta3*y;
d=(1 - tauc)*Pi;
lambda=1/(c-b*l^gamma);
r=theta1*y/k;
w=theta2*y/l;
rg=theta3*y/kg;
W=((r - deltak)*k + w*l)+ d;
end;

planner_objective(ln(c-b*l^gamma));
ramsey_policy(planner_discount=0.99,order=1,instruments=(tauc,tauh));

and the function:

function k = find_kben(k0,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,zeta1,zeta2,xi,TFP)
k = csolve(@ben_ss,k0,],1e-8,100,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,zeta1,zeta2,xi,TFP);
    function g = ben_ss(k,beta,tauh,tauc,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,zeta1,zeta2,xi,TFP);
    g = deltag*omega*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3)) - xi*TFP*k^theta1*(m*omega^(theta3*eta)*k^zeta1*TFP^zeta2)^theta2*(omega*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3)))^theta3 + tauh*deltak*k;
    end
end
1 Like

Please try the unstable version. 4.4.3 has a bug related to the use of instruments. The unstable version will tell you that

The problem may be related to your mod-file not correctly handling parameter dependence. Try using model-local variables instead.

Dear Johannes,

Thanks for your help much appreciated. I set-up the unstable version and rewrote the model as per your instructions leaving only the 4 endogenous variables, technology and the two tax instruments as endogenous variables but I am still faced with a similar error message to yours. I have doubled-check my code by running the exact same model taking taxes as given and using the command steady and it works. Similarly running the function on its own to find k yields the right result.

Any other ideas I could explore?

Thanks,

A

I don’t understand your strategy from what you write. You are supposed to provide a conditional steady state. For any value of the instruments, you need to provide the steady state for the other endogenous variables.

Sorry for not replying earlier. I was away for a few days. My problem came from the use of some temporary calculations involving some of the instruments in the parameters’ block. Eliminating those and following the example from M. Monfils solved my issue. I have a unique optimal policy for this benchmark model. I have implemented an identical approach in other models with success so thanks for your help and patience.

I am however puzzled with a new thing. Csolve returns a steadty state capital calculation that I know is wrong for one of my models. I checked it by running dynare with instruments in the parameters block and running my steady state code with fsolve. Note that the csolve discrepancy is only true for low values of some of the instruments. Any idea of what may cause this? I am thinking this is may be down to the algorithm used by Csolve. I have included the code below.

Many thanks,

Script:

A = 1;
theta1=0.3;
theta2=0.6;
theta3=0.1;

deltak=0.1;
deltag=0.1;

gamma=3;
b=1.5;

beta=0.99;

deltaka=0;
alpha=0.05;

eta = 1/(gamma - theta2);
m = (theta2/(b*gamma))^eta;
rho1 = theta1*( 1 + theta2*eta)-1;
rho3 = theta3*( 1 + theta2*eta );
rhotaul = theta2*eta;
rhotfp = 1 + theta2*eta;
omega = (1/(theta1*m^theta2))^(1/rho3);
zeta1 = theta1*eta - rho1/rho3*theta3*eta;
zeta2 = eta - rhotfp/rho3*eta*theta3;
zetataul = eta*(1-theta3*rhotaul/rho3);

tauc=0.02;
taud=0.9;
taul=0.02;
tauk=0.02;

TFP = A;
ka = (alpha/((1-tauc)*(1/beta-1+deltaka)))^(1/(1-alpha))

%Fsolve call
x0=[2];
options = optimset('Algorithm','levenberg-marquardt','MaxFunEvals',2000,'Tolx',10e-12,'Tolfun',10e-12);
[SS, fval, exitflag,ouput]=fsolve(@(x) divd4fsolve(x,beta,tauk,tauc,taud,taul,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka),x0,options);
k=SS(1)

%Csolve call
k = find_kdivd4(2.3,beta,taud,tauc,taul,tauk,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka);

Fsolve:

function g = divd4fsolve(x,beta,tauk,tauc,taud,taul,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka); k= x(1); g(1) = deltag*omega*((1/beta-1)/(1-tauk)+deltak)^(1/rho3)*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3))*(1-taul)^(-rhotaul/rho3)... -( tauk*theta1 + theta2*taul + theta3*(taud + tauc*(1-taud)))*TFP*k^theta1*... (m*(1-taul)^zetataul*((1/beta-1)/(1-tauk)+deltak)^(theta3*eta/rho3)*omega^(theta3*eta)*k^zeta1*TFP^zeta2)^theta2*... (omega*((1/beta-1)/(1-tauk)+deltak)^(1/rho3)*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3))*(1-taul)^(-rhotaul/rho3))^theta3... + tauk*deltak*k... - taud*alpha*ka^alpha... + (taud + tauc*(1-taud))*deltaka*ka; end

Csolve:
function k = find_kdivd4(k0,beta,tauk,tauc,taud,taul,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka)

k = csolve(@divd_ss4,k0,],1e-15,100,beta,tauk,tauc,taud,taul,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka);
    
    function g = divd_ss4(k,beta,tauk,tauc,taud,taul,theta1,theta2,theta3,b,gamma,deltag,deltak,eta,m,omega,rho1,rho3,rhotfp,rhotaul,zeta1,zeta2,zetataul,TFP,alpha,deltaka,ka);
    g = deltag*omega*((1/beta-1)/(1-tauk)+deltak)^(1/rho3)*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3))*(1-taul)^(-rhotaul/rho3)...
    -( tauk*theta1 + theta2*taul + theta3*(taud + tauc*(1-taud)))*TFP*k^theta1*...
    (m*(1-taul)^zetataul*((1/beta-1)/(1-tauk)+deltak)^(theta3*eta/rho3)*omega^(theta3*eta)*k^zeta1*TFP^zeta2)^theta2*...
    (omega*((1/beta-1)/(1-tauk)+deltak)^(1/rho3)*(k^(-rho1/rho3)*TFP^(-rhotfp/rho3))*(1-taul)^(-rhotaul/rho3))^theta3... 
    + tauk*deltak*k...
    - taud*alpha*ka^alpha...
    + (taud + tauc*(1-taud))*deltaka*ka;
    end

end

What you describe may be related to github.com/DynareTeam/dynare/pull/1262

Had look now and will come back to it in the morning, thanks.

To be clear the problem is occurring while I try to solve for k outside of dynare using a script that calls csolve. It worked fine with other model but not with this one. So my questions are (i) whether you know of any shortcomings coming with csolve and of a quick fix and (ii) whether I can use fsolve instead of csolve to solve for k in my recursive steady state?

Further, is there something built in in dynare to easily find the range in which blanchard khan conditions are verified if we allow say 1 or two parameters to vary? I have two taxes rates varying between 0 and 1 and want to find out for which values of the two I have determinacy.

Many thanks,

A

Problem solved. The issue was arising from not declaring parameters in the exact same order in different lines of the nested functions…

Glad to hear the problem is solved.

I am now looking at welfare. I basically want to compute the welfare of a calibrated model with tax instruments value given and contrast it to the approximation I obtained running ramsey_policy. Is there a way to compute lifetime utility when not using Ramsey in a purely deterministic setting?

Uping on this. Is there any way to run ramsey with no degree of freedom for the instruments so that to get the welfare approximation? Many thanks.

You can always define recursive utility in the model, i.e.

V=U+beta*V(+1)

Due to its forward-looking nature it should capture future changes in states. But please keep in mind that you cannot have this definition in the Ramsey model if it coincides with the planner objective. In that case you will have singularity of the static Jacobian.

Your last question puzzles me. How is Ramey policy supposed to work if everything is already determined for the planner? Before policy choices are made, there must be degrees of freedom that are filled by optimal policy.

1 Like

Thanks Johannes. I was more thinking of a dirty hack to use the welfare approximation of ramsey_policy. Is that clearer?

But all good. Using the recursive formulation works well. Thanks.

Just a quick check but I do need to lag all predetermined variables such as capital when plotting their time path against say output or labour, right?

Short answer: yes.
Longer answer: your capital stock in the model used for production at time t is

k(-1)

What dynare plots is

k(0)

Therefore, if you are thinking about stock at the beginning of period notation, you need to lag the path of capital, because you want to plot k(-1) and not k(0)

Thanks Johannes, I wanted to check that the adjustment was not carried out by Dynare.