[ANN] MacroModelling.jl: developing and solving DSGE models

I am happy to announce MacroModelling.jl - a package for developing and solving dynamic stochastic general equilibrium (DSGE) models.

The goal of this package is to reduce coding time and speed up model development by providing functions for working with discrete-time DSGE models.

The target audience for the package includes central bankers, regulators, graduate students, and others working in academia with an interest in DSGE modelling.

As of now the package can:

  • parse a model written with user friendly syntax (variables are followed by time indices …[2], [1], [0], [-1], [-2]…, or [x] for shocks)
  • (tries to) solve the model only knowing the model equations and parameter values - no steady state file needed
  • calculate first, second, and third order (pruned) perturbation solutions (see Villemot (2011), Andreasen et al. (2017) and Levintal (2017)) using (forward or reverse-mode) automatic differentiation (AD)
  • handle occasionally binding constraints
  • calculate (generalised) impulse response functions, simulate the model, or do conditional forecasts
  • calibrate parameters using (non stochastic) steady state relationships
  • match model moments (also for pruned higher order solutions)
  • estimate the model on data (Kalman filter using first order perturbation; see Durbin and Koopman (2012)) with gradient based samplers (e.g. NUTS, HMC)
  • differentiate (forward AD) the model solution, Kalman filter loglikelihood (reverse-mode AD), model moments, steady state, with respect to the parameters

The model has 17 models already implemented, among them Smets and Wouters (2003, 2007), Gerali et al. (2010), QUEST3 (2009), and the New Area-Wide Model (2008).

Writing a model and plotting the impulse response functions is as easy as this:

using MacroModelling
import StatsPlots

@model RBC begin
    1  /  c[0] = (β  /  c[1]) * (α * exp(z[1]) * k[0]^(α - 1) + (1 - δ))
    c[0] + k[0] = (1 - δ) * k[-1] + q[0]
    q[0] = exp(z[0]) * k[-1]^α
    z[0] = ρ * z[-1] + std_z * eps_z[x]

@parameters RBC begin
    std_z = 0.01
    ρ = 0.2
    δ = 0.02
    α = 0.5
    β = 0.95


Note the absence of variable declarations, parameter declarations, or any code related to the non stochastic steady state.

The package provides a range of convenience functions which are explained in the documentation.

I am looking forward to reading your feedback, issues, or pull requests.


Can you give a brief description of how this relates to the methods in https://www.nber.org/papers/w30573 ?

The package DifferentiableStateSpaceModels.jl related to the mentioned paper provides tools to solve, simulate, and estimate models using gradient based samplers. The focus is on the differentiability of the model solution even up to higher order pruned solutions.

Both DifferentiableStateSpaceModels.jl and MacroModelling.jl provide tools to estimate models using gradient based samplers but with DifferentiableStateSpaceModels.jl the use is limited to models with an analytical solution of the non stochastic steady state (NSSS). Larger models tend to not have an analytical solution of the NSSS and MacroModelling.jl can also use gradient based sampler in this case. Have a look at the estimation tutorial using gradient based samplers.

I did not take the time yet to write up a how-to guide for estimating models using filter-free methods with higher order pruned perturbation solutions (a use case highlighted by DifferentiableStateSpaceModels.jl) but this can be achieved with MacroModelling.jl (up to 3rd order even) in combination with Turing.jl. I implemented it already, and it works, but am looking to make it more user-friendly before adding it to the documentation.

In general, MacroModelling.jl has a broader focus and provides all of the functionality that DifferentiableStateSpaceModels.jl has but the former has many more convenience functions when it comes to model writing, calibrating, estimating, changing parameters, or plotting. For a comparison between these two and many more packages see the table at the end of the github page.