The Zero Lower Bound Constraint on Nominal Int. Rate

I am trying to write a medium scale DSGE model and analyze the effects of ZLB, however, I cannot write the ZLB constraint in dynare.

is there anybody having dynare code on this topic? It would be quite useful for me to see an example of this type of codes.

I think that you can enforce ZLB on interest rate with max() function, but you can run only deterministic simulations on such a model.

For example, in case where interest rate is set by a Taylor rule, you could define it like this:

model;
...
i = max(0, phi*pi + rho*y); 
...
end;

Hope this helps.

Damir

thank you for your response, however i have already tried such an algorithm; and it does not work due to the non linear nature of ZLB constraint… When i introduced max() function the results did not change.

I have tried a lot of different cases however, i started to think that dynare is not the right program for writing ZLB codes. That is why i asked whether someone has codes. I believe no one does it in dynare, or is there someone?

As stated above, Dynare can perform analyses of ZLB in a deterministic setup (using the “simul” command, where nonlinearities are fully handled), but not in a stochastic setup (using “stoch_simul”).

If you want to analyze ZLB in a stochastic setup, then use a global method or the extended path methods. These methods will be incorporated in Dynare at some point in the future, but are not yet there.

Thanks to Tom Holden (tholden.org/), I was able to implement an algorithm to simulate a standard NKM with a zero lower bound. I attached all necessary files. I only included a negative inflation shock, but you could add any other shock quite easily. A detailed description of Tom’s algorithm can be found in the appendix of his paper:

dynare.org/wp-repo/dynarewp004.pdf

To run the model just execute NKM_lowerbound.mod. This file will call all other functions in the zip-file, needed to solve the model, and creates impulse responses for the bounded and unbounded model in one figure. In line 6 and 7 you have to define the number of periods you would like to simulate the IRFs (TIRF), and the number of periods, after which you believe the constraint will no longer bind (TShadowI).

I benefit a lot from the discussions in this forum. Hopefully, this time I could help someone.

Best
Michael
lowerbound.zip (3.99 KB)

I’m Tom Holden, if anyone has any further questions about the algorithm.

2 Likes

Dear Michael,

Many thanks for making this code available (and also to Tom for the innovation). Just to be clear, have you extended Tom’s method to deal with the ZLB in full stochastic simulations in Dynare, or is the code only valid for calculating IRFs with and without the ZLB constraint?

Best,
Michael

Hey Michael,

no, I did not extend anything. I just implemented the algorithm propsed by Tom in a standard New Keynesian Model. So the fame goes to Tom.

Just to understand you right: What do you mean by full stochastic simulations? The calculation of variances, shock decompositions and so on? I am working on a paper using this method, and calculate the accumulated sum of deviations from equilibrium (from the IRFs) as a measure of volatility to compare different policies in this framework. I think this should be a good proxy for the variances of the variables, right?

Best,
Michael

Linearity means you can simulate a (zero-mean) model without bounds by the following method:

  1. Generate one s.d. infinite length IRFs to all shocks. Denote these by z(t,v,e) where t>=0 is the time since the shock hit, v is the variable being examined and e is the shock.
  2. Let x(t,v) denote the simulated value of the variable v at t, and let s(t,e) be a draw from an NIID(0,1) variable for all times t and shocks e. Then:
    x(t,v) = sum( sum( s(t-k,e) * z(k,v,e) , e in the set of shocks ), k = 0 … infinity )

Therefore:
E[x(t,v) * x(t,v)] = sum( sum( z(k,v,e) * z(k,v,e), e in the set of shocks ), k = 0 … infinity )

So the standard deviation of a variable in a model without bounds is the square-root of the sum of the squared IRF coefficients.
Since you don’t have linearity in the presence of bounds this formula no longer holds exactly, but it may still be reasonable.

Hi Michael,

Thanks for your reply. I was really asking whether the stochastic simulation paths of variables would be valid. If I understand correctly only the IRFs are strictly valid, but you are using an approximation to infer variances, shock decompositions etc. from the IRFs. May I ask what model are you working with? Will it pose any problems for the code if I use a much larger linear model or a nonlinear model that is approximated to second-order?

Best,
Michael

mch: I initially thought this method could not be used for stochastic simulation, but thinking further I see that it can. First, add a load of “shadow shocks” to the model as in the IRF method. Now suppose we’ve simulated up to period t. Then simulate one more period holding just the shadow shocks at zero. Then simulate a large number more periods holding all shocks at zero. Observe if the ZLB is ever hit (in t+1,t+2,…). If it isn’t, your simulation of t+1 is fine, and you can go to the next period. If it is, then agents should predict this and adjust expectations accordingly. As in the IRF case, the task is to find the vector of shadow shocks such that the bound is always satisfied, and shadow shocks are only positive when the bound is expected to bind in the relevant number of periods. Again, you can exploit linearity to turn this into a quadratic optimisation problem. (Effectively you’re adding the shadow shock IRF to the shock-less predicted future path.) Once you’ve found a solution to the quadratic optimisation problem you have a new valid value for t+1, and you can go to the next period.

So you just have to solve a quadratic optimsation problem for each period you simulate. This will be slower than standard simulation, but not prohibitively slow.

If any one wants to use this stochastic simulation method PLEASE CITE THIS URL, at least until I get a paper out of this. Sorry if that’s a rude request, but clearly I could (should?) have kept my mouth shut about this algorithm until it was published. (If it is indeed publishable anywhere decent…) If anyone feels like adding the code to Dynare to implement this (Michel, Stephane?) then perhaps we could co-author the paper.

In answer to your other question mch: yes it can be used in large models, but no it cannot be used with second order approximations (we require linearity to make adding IRFs valid).

Tom (Holden)

@Michael: You ask for the model, I am working with. At the moment I implement Tom’s algorithm to solve a model for Chinese monetary policy. Here, the lending and deposit rates are bouded, since the monetary authority has strict guidelines for the private banking sector. It is not finished yet, but as soon as there is a working paper version, I will post the link and the codes here (approx. march).

You do not have to worry about larger models. The model I am using is already quite large. And the additional computation time depends only on the number of periods the constraint holds.

Best
Michael

Finally, Tom and I have a working paper on the algortihm, used for simulations:

uni-hamburg.de/fachbereiche- … uality.pdf

We simulated a two-country NKM and the Smets & Wouters(2003) Model using the shadow price method.

I also attached the Code for a sinlge country NKM for IRFs and Simulations, so that everyone can use it. Although the files should be selfexplaining, do not hesitate to contact me, if you experience any problems.

If someone is interested, here are two Papers, using the method for applications apart from monetary policy:

suomenpankki.fi/bofit_en/tut … dp1112.pdf

suomenpankki.fi/bofit_en/tut … dp1612.pdf

Best
Michael
NKM_OneCountry.zip (9.17 KB)

Hi

Thank you Tom for sharing the file.

I am having problems with adding a shock to the LZB model. Whenever I run the dynare file I only get the graphs of the IRF from the shocks already in the model. Could you please explain how one could add shocks.

As in standard Dynare… I’m not sure I understand your problem.

To implement both an upper bound and a lower bound on a variable you must include an additional variable that is equal to the upper bound minus the variable of interest. This new variable is then given a lower bound.

Hi
I am trying to find the effects of government spending shock using when the ZLB binds.

I am using a model based on Gali (2008) basic NKM with added government spending. When running the NKM_ZLB I get the following error message:
I am new to Dynare (and DSGE) and cannot find what it is i am doing wrong.

(I have tried to decrease the number of periods the XLB binds, but then I get another error message saying try to increase the nomber of periods the ZLB binds.)

Warning: There is only a guaranteed solution to the linear programming problem when the ZLB binds
for at most 6 periods.

In INITIAL_CHECKS at 51
In NKM_ZLB at 1701
In dynare at 120

Computation time for set-up and initial feasibility checks:
Elapsed time is 1.023637 seconds.
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
1.260768e-21.

In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.028441e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.651111e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
8.088044e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.588730e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.790571e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
4.574485e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.991333e-25.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.140634e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.366691e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.028441e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.651111e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
8.088044e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.588730e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.790571e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
4.574485e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.991333e-25.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.140634e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.366691e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.028441e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.651111e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
8.088044e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.588730e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.790571e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
4.574485e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.991333e-25.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
9.140634e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
6.366691e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.028441e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND =
7.651111e-24.
In solve_quadprog at 51
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Exiting: One or more of the residuals, duality gap, or total relative error
has stalled:
the primal appears to be infeasible (and the dual unbounded).
(The dual residual < TolFun=1.49e-08.)
Warning: Failed to find initial feasible point.

In solve_quadprog at 64
In STEADYSTATE_IRF_CONS at 38
In NKM_ZLB at 1704
In dynare at 120
Error using solve_quadprog (line 72)
Failed to solve quadratic programming problem. Try increasing TShadow.
Error in STEADYSTATE_IRF_CONS (line 38)
alpha = solve_quadprog( M, V, AlphaStart, TShadow, Accuracy, Options, ZeroVec, OneVec );
Error in NKM_ZLB (line 1704)
IRF_, IRF_CONS_ ] = STEADYSTATE_IRF_CONS( ZLBData );
Error in dynare (line 120)
evalin(‘base’,fname) ;

I attach the mod file should anyone have the time to take a look at it. Grateful if anyone could help

NKM_ZLB.mod (6.14 KB)

I’ll have a look at this in the next few weeks. I’m extremely busy at the moment I’m afraid.

Hi ended up using a different model. But thank you for the reply.

Sorry.