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. Its parameters must be constant: a DSGE with regime switching is refused (error dsge_var_model:switchingDsge).

6.2. The weight of the DSGE prior

The DSGE enters as a prior on the VAR, and the weight of that prior is a parameter of the model, which you can calibrate or estimate like any other. It comes in two forms; use either:

  • dsge_prior_share, \(\gamma \in [0,1]\): the share of the DSGE in the moments the VAR is estimated from. The posterior mode of the VAR coefficients is

    \[\Phi = \left[\gamma\,\Gamma_{XX}(\theta) + (1-\gamma)\,\tfrac{X'X}{T}\right]^{-1} \left[\gamma\,\Gamma_{XY}(\theta) + (1-\gamma)\,\tfrac{X'Y}{T}\right]\]

    where \(\Gamma(\theta)\) are the DSGE’s population moments of the observables and \(X'X/T\), \(X'Y/T\) those of the data. A share of 0 is the data VAR, a share of 1 the DSGE’s VAR approximation. Being bounded, the share takes a Beta prior.

  • dsge_prior_weight, \(\lambda = \gamma/(1-\gamma) \in [0,\infty)\): the number of artificial DSGE observations per actual observation, the parameterization of Del Negro and Schorfheide (2004).

Set or estimate one of the two; the other follows (a share of 1 is an infinite weight). Setting both in the same call, or giving both a prior, is an error (dsge_var_model:twoPriorWeights):

mdl = set(mdl, parameters = {'dsge_prior_share', 0.75});  % dsge_prior_weight is now 3
mdl = set(mdl, parameters = {'dsge_prior_weight', 1});    % dsge_prior_share is now 0.5

The prior is proper when \(\lambda T > k\), with \(T\) the number of observations and \(k\) the number of coefficients in each VAR equation, that is when \(\gamma > k/(T+k)\). Below that bound the likelihood is not evaluated and the draw is rejected.

The likelihood that estimate maximizes is the marginal likelihood of the DSGE-VAR, \(p(Y \mid \theta, \gamma)\), in closed form (Del Negro and Schorfheide, 2004); its profile over the share measures how well the DSGE fits the data. pull_objective returns minus the log posterior, which with a flat prior on the share is minus that likelihood. filter reports a different number: the likelihood of the data at the posterior mode of the VAR, the in-sample fit of a point estimate, which favors the data VAR whatever the DSGE.

6.3. A quick-start example

6.3.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.3.2. Setting up the BVAR-DSGE model

nlags    = 4;
constant = false;

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

6.3.3. Fixed parameters

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

6.3.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 weight of the DSGE prior, as a share in [0,1]
% (equivalently, a prior on dsge_prior_weight, never on both)
priors.dsge_prior_share = {0.75, 0.75, 0.1, 'beta'};

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

6.3.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.3.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.3.7. IRFs of the BVAR-DSGE at the maximized posterior

myirfs_bvar_dsge = irf(mdlest);

6.3.8. IRFs of the DSGE model at the maximized posterior

myirfs_dsge = irf(mdlest.dsge);

6.3.9. IRF comparison

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

6.4. 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 the weight of the DSGE prior (dsge_prior_share). This is the BVAR-DSGE proper, and it is what irf(mdlest) returns above.

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

  • 'var_approx' – the DSGE-implied VAR, the dsge_prior_share = 1 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_share.