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 whatirf(mdlest)returns above.'var'– the pure data VAR (OLS), thedsge_prior_share = 0limit. Use it to see what the data say with no DSGE shrinkage.'var_approx'– the DSGE-implied VAR, thedsge_prior_share = 1limit. 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.