6. DSGE-VAR Modeling

(Also known in the literature as BVAR-DSGE; the modern factory is dsge_var_model.)

6.1. Description

The DSGE-VAR (also known as BVAR-DSGE) is a methodology that combines a BVAR and a DSGE model following Del Negro and Schorfheide (2004) and Del Negro, Schorfheide, Smets and Wouters (2007).

There are two possible interpretations: the DSGE is used as a prior for the BVAR, or the BVAR serves to relax the tight restrictions in the DSGE.

In the end you have four sub-models in one object:

  • the VAR model,

  • the VAR approximation of the DSGE model,

  • the DSGE model,

  • the BVAR model – the VAR with the (VAR approximation of the) DSGE as prior.

The DSGE can be a model with a simple instrument rule (e.g. a Taylor rule) or an optimal policy under commitment or under discretion. It can be stationary or non-stationary.

6.2. A quick-start example

6.2.1. A simple New Keynesian DSGE model

dsgemodel = {
    'model: New Keynesian model'
    '@endogenous X "Output gap" R "interest rate" P "Inflation" G U'
    '@exogenous EG "Demand shock" EU "Monetary Policy shock"'
    '@parameters beta "discount factor" kappa "Phillips curve slope" sigu sigg rhou rhog psi'
    '@observables P R'
    '@model'
    '   P = beta*P{+1} + kappa*X;'
    '   X = X{+1} - (R - P{+1} - G);'
    '   R = psi*P + U;'
    '   U = rhou*U{-1} + sigu*EU;'
    '   G = rhog*G{-1} + sigg*EG;'
    };

6.2.2. Setting up the BVAR-DSGE model

nlags    = 4;
constant = false;

mdl = dsge_var_model(dsgemodel, ...
    lag_length    = nlags, ...
    constant_term = constant);

6.2.3. Fixed parameters

mdl = set(mdl, parameters = {'beta', 0.96});

6.2.4. Priors

priors = struct();

% priors on the DSGE parameters
priors.kappa = {0.2, 0.5, 0.5, 'gamma'};
priors.psi   = {1.5, 2,   0.5, 'gamma'};
priors.rhou  = {0.75, 0.75, 0.1, 'beta'};
priors.rhog  = {0.75, 0.75, 0.1, 'beta'};
priors.sigu  = {0.01, 0.01, 4,   'sichisq'};
priors.sigg  = {0.01, 0.01, 4,   'sichisq'};

% prior on the DSGE-prior weight
priors.dsge_prior_weight = {3, 3, 1, 'gamma'};

plotOpts = struct();
plotOpts.prior_trunc = 2e-3;
rdist.plot(priors, plotOpts)

6.2.5. Collecting and transforming the data

d = fetch_fred({'CPALTT01USQ661S','BOGZ1FL072052006Q'});

db   = struct();
db.P = log(d(1).series / lag(d(1).series, 1));
db.R = d(2).series / 100;

6.2.6. Maximizing the posterior

mdlest = estimate(mdl, ...
    estim_priors      = priors, ...
    data              = db, ...
    data_demean       = true, ...
    estim_start_date  = date2serial('1960Q2'), ...
    estim_end_date    = date2serial('2022Q3'));

6.2.7. IRFs of the BVAR-DSGE at the maximized posterior

myirfs_bvar_dsge = irf(mdlest);

6.2.8. IRFs of the DSGE model at the maximized posterior

myirfs_dsge = irf(mdlest.dsge);

6.2.9. IRF comparison

myirfs = ts.concatenator(myirfs_bvar_dsge, myirfs_dsge);
quick_irfs(mdlest.dsge, myirfs, {'P','R'});

6.3. Choosing the VAR representation

A DSGE-VAR carries three reduced-form representations, and the analytics path (irf, variance and historical decompositions) draws from whichever you select with the which_var option:

  • 'var_dsge' (default) – the Bayesian DSGE-VAR combination: the data VAR shrunk toward the DSGE-implied restrictions with weight dsge_prior_weight. This is the BVAR-DSGE proper, and it is what irf(mdlest) returns above.

  • 'var' – the pure data VAR (OLS), the dsge_prior_weight -> 0 limit. Use it to see what the data say with no DSGE shrinkage.

  • 'var_approx' – the DSGE-implied VAR, the dsge_prior_weight -> inf limit. Use it to see the DSGE’s own finite-order VAR approximation.

Select a representation with set and run the analytics as usual:

myirfs_data_var = irf(set(mdlest, 'which_var', 'var'));
myirfs_dsge_var = irf(set(mdlest, 'which_var', 'var_approx'));

The two limits bracket the Bayesian combination: 'var' ignores the DSGE prior, 'var_approx' ignores the data, and the default 'var_dsge' interpolates between them according to dsge_prior_weight.