Estimation

Default or custom lags

Exogenous variables

Minnesota prior distributions

Flexible control of MCMC sampling

Multiple chains

Postestimation

MCMC diagnostics

Checks for parameter stability

One-step-ahead Bayesian predictions

Full Bayesian postestimation features support

Vector autoregressive (VAR) models study relationships between multiple time series, such as unemployment and inflation rates, by including lags of outcome variables as model predictors. That is, the current unemployment rate would be modeled using unemployment and inflation rates at previous times. And likewise for the current inflation rate.

VAR models are known to have many parameters: with K outcome variables and p lags, there are at least K(pK+1) parameters. Reliable estimation of the model parameters can be challenging, especially with small datasets.

You can use the **bayes: var** command to fit Bayesian VAR models that help overcome these challenges by incorporating prior information about model parameters. This often stabilizes parameter estimation. (Think of a prior as introducing a certain amount of shrinkage for model parameters.)

You can investigate the influence of a random-walk assumption on the results by varying the parameters of several supported variations of the original Minnesota prior distribution. You can check the assumption of a parameter stability by using the command **bayesvarstable**. Once satisfied, you can generate dynamic forecasts by using **bayesfcast** and perform impulse–response function (IRF) and forecast-error variance decomposition (FEVD) analysis by using **bayesirf**.

Consider Federal Reserve quarterly economic macrodata from the first quarter of 1954 to the fourth quarter of 2010. We would like to study the relationship between inflation, the output gap, and the federal funds rate. We wish to evaluate how each of these macroeconomic variables affects the others over time. In particular, we are interested in the effects of the federal fund rate controlled by policymakers. We are also interested in obtaining dynamic forecasts for the three outcome variables.

Let's take a look at our data first.

.webuse usmacro(Federal Reserve Economic Data - St. Louis Fed) .tssetTime variable: date, 1954q3 to 2010q4 Delta: 1 quarter .tsline inflation ogap fedfunds

We wish to fit a Bayesian VAR model to study the relationship between the three variables. If you are already familiar with Stata's **var** command, which fits classical VAR models, fitting Bayesian models will be particularly easy. We simply prefix the **var** command with **bayes:**. Below, we also specify a random-number seed for reproducibility.

The output from **bayes: var** is long, so we will describe it in pieces.

.bayes, rseed(17): var inflation ogap fedfundsBurn-in ... Simulation ...

Model summary |

Likelihood: |

inflation |

ogap |

fedfunds ~ mvnormal(3,xb_inflation,xb_ogap,xb_fedfunds,{Sigma,m}) |

Priors: |

{inflation:L(1 2).inflation} (1) |

{inflation:L(1 2).ogap} (1) |

{inflation:L(1 2).fedfunds} (1) |

{inflation:_cons} (1) |

{ogap:L(1 2).inflation} (2) |

{ogap:L(1 2).ogap} (2) |

{ogap:L(1 2).fedfunds} (2) |

{ogap:_cons} (2) |

{fedfunds:L(1 2).inflation} (3) |

{fedfunds:L(1 2).ogap} (3) |

{fedfunds:L(1 2).fedfunds} (3) |

{fedfunds:_cons} ~ varconjugate(3,2,1,_b0,{Sigma,m},_Phi0) (3) |

{Sigma,m} ~ iwishart(3,5,_Sigma0) |

As with a traditional VAR model, the likelihood is assumed to be multivariate (trivariate in our example) normal with the error covariance matrix **{Sigma,m}**. The error covariance is a model parameter, so it appears in curly braces, **{}**.

A Bayesian VAR model additionally requires priors for all model parameters. **bayes: var** provides default priors, but you can modify them to adjust to your analysis.

By default, VAR regression coefficients are assigned a so-called conjugate Minnesota prior, and the error covariance is assigned an inverse Wishart prior. The idea behind a Minnesota prior is to "shrink" coefficients toward some values (often zeros or ones for the first own-lag coefficients) while maintaining the underlying time-dependent relationships in the data. You can learn more about this prior in Explaining the Minnesota prior in **[BAYES] bayes: var**.

What follows next is a rather lengthy output of results. As we will see in IRF analysis, the results from a VAR model are usually interpreted by using IRFs and other functions. But we show the output below for completeness.

The header reports the standard information about the MCMC procedure: the number of burn-in iterations, the size of the MCMC sample, and so on. The defaults are 2,500 burn-in iterations and 10,000 for the MCMC sample size, but you may need fewer or more in your analysis. Because **bayes: var** uses Gibbs sampling for simulation, the MCMC results will typically have high efficiency (close to 1); see the output below under **Efficiency:**

Bayesian vector autoregression MCMC iterations = 12,500 Gibbs sampling Burn-in = 2,500 MCMC sample size = 10,000 Sample: 1956q1 thru 2010q4 Number of obs = 220 Acceptance rate = 1 Efficiency: min = .9621 avg = .9968 Log marginal-likelihood = -803.40081 max = 1

Equal-tailed | ||

Mean Std. dev. MCSE Median [95% cred. interval] | ||

inflation | ||

inflation | ||

L1. | 1.050509 .0406623 .000407 1.050519 .9709674 1.131497 | |

L2. | -.0983798 .038157 .000382 -.0982178 -.1732963 -.0242587 | |

ogap | ||

L1. | .0738608 .0326438 .000318 .0738179 .011719 .1383346 | |

L2. | -.0047669 .0299874 .000296 -.0044935 -.06365 .0537368 | |

fedfunds | ||

L1. | .0717713 .031543 .000315 .0715381 .0111944 .1340734 | |

L2. | -.054096 .0285518 .000286 -.0542693 -.1101743 .0019505 | |

_cons | .1360559 .0870247 .00087 .1357733 -.0358968 .3071866 | |

ogap | ||

inflation | ||

L1. | -.070946 .0504929 .000515 -.0713239 -.1695751 .0279189 | |

L2. | .0080639 .0471388 .000471 .0084353 -.0845188 .1001178 | |

ogap | ||

L1. | 1.034557 .040881 .000409 1.034394 .9533511 1.113827 | |

L2. | -.1038247 .0379861 .00038 -.103874 -.1776099 -.0288752 | |

fedfunds | ||

L1. | .0361347 .0388217 .000388 .0359872 -.0390069 .1130978 | |

L2. | -.0450505 .0351746 .000352 -.0447803 -.1138243 .0243874 | |

_cons | .2129268 .1080613 .001081 .2122609 -.0000164 .4277089 | |

fedfunds | ||

inflation | ||

L1. | .0259699 .0538047 .000527 .0256361 -.077736 .1331889 | |

L2. | .0468066 .0500692 .000501 .0470046 -.0512646 .1447051 | |

ogap | ||

L1. | .1545118 .0437399 .000437 .1542643 .0695918 .2404831 | |

L2. | -.0954632 .0401437 .000401 -.0949833 -.1751912 -.0169302 | |

fedfunds | ||

L1. | .998348 .0419964 .000425 .998391 .917987 1.080904 | |

L2. | -.0806434 .0380157 .00038 -.0804814 -.1541685 -.0075734 | |

_cons | .2036804 .1155176 .001155 .2048609 -.0246111 .4297876 | |

Sigma_1_1 | .4384999 .0416187 .000422 .435944 .3634841 .5272232 | |

Sigma_2_1 | .0569301 .0369788 .00037 .0569781 -.0143685 .1305416 | |

Sigma_3_1 | .1559746 .0407611 .000408 .1547395 .079231 .2400816 | |

Sigma_2_2 | .6777257 .0647212 .000647 .6736507 .5615162 .8158431 | |

Sigma_3_2 | .2506655 .0518798 .000519 .2481628 .1547145 .3596628 | |

Sigma_3_3 | .7746199 .0724508 .000725 .7701015 .6465796 .9287891 | |

By default, **bayes: var** includes two lags for each outcome variable, but you can specify other lags in the **lags()** option; see Selecting the number of lags.

After simulation, you may want to save your MCMC results for further postestimation analysis. With **bayes**, this can be done either during or after estimation.

.bayes, saving(bvarsim2)note: filebvarsim2.dtasaved.

We also store the current **bayes: var** estimation results for later model comparison.

.estimates store lag2

As with any MCMC method, we should check that MCMC converged before moving on to other analyses. We can use graphical checks,

.bayesgraph diagnostics {inflation:L1.ogap}

or we can compute the Gelman–Rubin convergence statistic using multiple chains. The trace plot does not exhibit any trend, and the autocorrelation is low. Our MCMC appears to have converged.

Inference from a VAR model relies on the assumption of parameter stability, which you can check after a Bayesian VAR model by using the command **bayesvarstable**.

.bayesvarstableEigenvalue stability condition Companion matrix size = 6 MCMC sample size = 10000

Eigenvalue | Equal-tailed | |

modulus | Mean Std. dev. MCSE Median [95% cred. interval] | |

1 | .9529782 .01603 .00016 .9533415 .920918 .9840033 | |

2 | .9486492 .0188851 .000189 .9504839 .9058018 .9807103 | |

3 | .8867184 .0361654 .000362 .8893334 .8093261 .9464411 | |

4 | .1746283 .0438198 .000438 .1709831 .0996019 .2688087 | |

5 | .1091889 .0400347 .0004 .1057698 .0401139 .1913403 | |

6 | .0519465 .0354457 .000354 .0472559 .0019949 .1240763 | |

The 95% credible intervals for individual eigenvalue moduli do not contain values greater or equal to one, which is a good sign. And the posterior probability that all eigenvalues lie in the unit circle is close to one. We have no reason to suspect a violation of the stability assumption.

You can read more about this assumption in **[BAYES] bayesvarstable**.

By default, the conjugate Minnesota prior of **bayes: var** shrinks the first own-lag coefficients toward one. (A first own-lag coefficient is a coefficient for the first lag of the outcome variable in its own equation. In our example, there are three such coefficients: **{inflation:L1.inflation}**, **{ogap:L1.ogap}**, and **{fedfunds:L1.fedfunds}**.)

The default prior favors the assumption of a random walk for the outcome variable. This assumption may or may not be what you want depending on the data type. For instance, with differenced data, you may want to shrink all of the coefficients toward zero.

We can do this by modifying the default specification of the **minnconjugate()** option, which specifies the conjugate Minnesota prior. The default prior assumes prior means of ones only for the first own-lag coefficients. Prior means of the other coefficients are already zeros. So we need to specify zero means only for the three first own-lag coefficients. We can do this by specifying a vector of length 3 of 0s in **minnconjprior()**'s suboption **mean()**.

.bayes, rseed(17) minnconjprior(mean(J(1,3,0))): var inflation ogap fedfundsBurn-in ... Simulation ...

Model summary |

Likelihood: |

inflation |

ogap |

fedfunds ~ mvnormal(3,xb_inflation,xb_ogap,xb_fedfunds,{Sigma,m}) |

Priors: |

{inflation:L(1 2).inflation} (1) |

{inflation:L(1 2).ogap} (1) |

{inflation:L(1 2).fedfunds} (1) |

{inflation:_cons} (1) |

{ogap:L(1 2).inflation} (2) |

{ogap:L(1 2).ogap} (2) |

{ogap:L(1 2).fedfunds} (2) |

{ogap:_cons} (2) |

{fedfunds:L(1 2).inflation} (3) |

{fedfunds:L(1 2).ogap} (3) |

{fedfunds:L(1 2).fedfunds} (3) |

{fedfunds:_cons} ~ varconjugate(3,2,1,(J(1,3,0)),{Sigma,m},_Phi0 ) (3) |

{Sigma,m} ~ iwishart(3,5,_Sigma0) |

Equal-tailed | ||

Mean Std. dev. MCSE Median [95% cred. interval] | ||

inflation | ||

inflation | ||

L1. | .8857357 .0485368 .000485 .885746 .790685 .9824396 | |

L2. | .0269907 .0455449 .000455 .0271839 -.0626737 .1155095 | |

ogap | ||

L1. | .0761181 .0389651 .00038 .0760672 .0019879 .1531618 | |

L2. | .001521 .0357946 .000354 .0018469 -.0686749 .0713939 | |

fedfunds | ||

L1. | .098638 .037651 .000377 .0983597 .0262863 .1730537 | |

L2. | -.055385 .0340805 .000341 -.0555918 -.1224443 .0115358 | |

_cons | .1544722 .1038773 .001039 .1541354 -.0510049 .3581968 | |

ogap | ||

inflation | ||

L1. | -.0675691 .0598816 .00061 -.0680522 -.1848906 .0498421 | |

L2. | -.0150082 .0559096 .000559 -.0145887 -.1250453 .0939403 | |

ogap | ||

L1. | .8719911 .0484592 .000485 .871777 .7757726 .966344 | |

L2. | .0249191 .0450373 .00045 .0248376 -.0625478 .1135304 | |

fedfunds | ||

L1. | .0631993 .0460222 .00046 .0629379 -.0258211 .1543138 | |

L2. | -.0643443 .0417046 .000417 -.0641588 -.1458078 .0178974 | |

_cons | .2199806 .128148 .001281 .2193497 -.0318993 .4743479 | |

fedfunds | ||

inflation | ||

L1. | .0734435 .0630289 .000617 .073388 -.0487301 .1981055 | |

L2. | .0493568 .0586613 .000587 .0494503 -.0655153 .1640052 | |

ogap | ||

L1. | .1859435 .0512156 .000512 .185431 .0871488 .2868869 | |

L2. | -.1102205 .0469907 .00047 -.1097752 -.203735 -.0180675 | |

fedfunds | ||

L1. | .8202078 .049201 .000497 .8202937 .7256878 .9166404 | |

L2. | .0450037 .0445312 .000445 .0450415 -.0415155 .1307499 | |

_cons | .308838 .1353585 .001354 .310172 .0415897 .5746537 | |

Sigma_1_1 | .6247714 .0593237 .000601 .6212457 .5183145 .7517009 | |

Sigma_2_1 | .0657255 .0522565 .000523 .0660805 -.034914 .1691783 | |

Sigma_3_1 | .1959076 .0566382 .000566 .1943097 .0884963 .3126778 | |

Sigma_2_2 | .9525887 .0909202 .000909 .9473281 .7902117 1.146957 | |

Sigma_3_2 | .3194013 .0714681 .000715 .3163695 .1868128 .468176 | |

Sigma_3_3 | 1.062408 .0993678 .000994 1.056211 .8867977 1.273854 | |

The new prior specification did not appear to change the results much. This means that the information contained in the observed data about the model parameters dominates our prior information.

A lag selection is an important consideration for VAR models. Traditional methods, such as those using the AIC criterion, often overestimate the number of lags. Bayesian analysis allows you to compute an actual probability of each model given the observed data—model posterior probability.

To compute model posterior probabilities, we must first fit all the models of interest. Let's consider one, two, and three lags here, but you can specify as many models as you would like in your own analysis.

We already stored the results from the model with two lags as **lag2**. We now fit models with one and three lags and save the corresponding results. We run the models quietly.

.quietly bayes, rseed(17) saving(bvarsim1): var inflation ogap fedfunds, lags(1/1).estimates store lag1.quietly bayes, rseed(17) saving(bvarsim3): var inflation ogap fedfunds, lags(1/3).estimates store lag3

We now use **bayestest model** to compute model posterior probabilities. We assume that each model is equally likely a priori (the default).

.bayestest model lag1 lag2 lag3Bayesian model tests

log(ML) P(M) P(M|y) | ||

lag1 | -814.4808 0.3333 0.0000 | |

lag2 | -803.4008 0.3333 0.0047 | |

lag3 | -798.0420 0.3333 0.9953 | |

The model with three lags has the highest posterior probability of the three considered models.

VAR models contain many regression coefficients, which makes it difficult to interpret the results from these models. Instead of individual coefficients, IRFs are used to summarize the results. IRFs measure the effect of a shock in one variable, an impulse variable, on a given response variable at a specific time period.

In our example, we are interested in the impact of the federal funds rate on the other outcomes in the model. Let's use IRFs to evaluate the effect of this variable.

Here we use the model with three lags that we selected in the previous section.

.estimates restore lag3(resultslag3are active now)

As with a standard IRF analysis in Stata, we first create IRF results and save them in an IRF dataset for later analysis. For IRF analysis after **bayes: var**, we use the **bayesirf** command instead of the existing **irf** command.

The command is needed because of the differences between classical and Bayesian IRFs. For a given pair of impulse and response variables, a frequentist IRF is a single function, whereas Bayesian IRFs correspond to a posterior MCMC sample of functions. This sample is summarized to produce a single function. The posterior mean IRF is reported by default, but you can compute the posterior median IRF instead.

First, we use **bayesirf create** to create IRF results named **birf** and save them in the IRF file **birfex.irf**.

.bayesirf create birf, set(birfex)(filebirfex.irfcreated) (filebirfex.irfnow active) (filebirfex.irfupdated)

We plot IRFs with **fedfunds** as the impulse variable.

.bayesirf graph irf, impulse(fedfunds)

This IRF graph shows that a shock to the federal funds rate has a positive effect on itself that decreases over time but is still positive after 8 quarters. The federal funds rate shock has little effect on the output gap and a small positive effect on inflation that dissipates after 2 quarters.

Also see Bayesian IRF and FEVD analysis.

VAR models are commonly used for forecasting. Here we show how to compute Bayesian dynamic forecasts after fitting a Bayesian VAR model.

We create forecasts after **bayes: var** just as we do after **var**, except we use **bayesfcast** instead of **fcast**.

Similarly to Bayesian IRFs, Bayesian forecasts correspond to the posterior MCMC sample of forecasts for each time period. The posterior mean forecast is reported by default, but you can compute the posterior median forecast instead.

Let's compute a Bayesian dynamic forecast at 10 time periods.

.bayesfcast compute f_, step(10)

The posterior mean forecasts, together with other forecast variables, are saved in the dataset in variables with outcome names prefixed with **f_**.

We can use **bayesfcast graph** to plot the computed forecasts.

.bayesfcast graph f_inflation f_ogap f_fedfunds

From this graph, our inflation forecast is small for the first quarter but is not statistically significant after that. (The 95% credible bands include zero.) The forecasted output gap is negative for the first year and is close to zero after that. The federal funds rate is forecasted to be small and close to zero for all periods.

Also see Bayesian dynamic forecasting.

After your analysis, remember to remove the datasets generated by **bayes: var** and **bayesirf**, which you no longer need.

.erase bvarsim1.dta.erase bvarsim2.dta.erase bvarsim3.dta.erase birfex.irf

Learn more in the *Stata Bayesian Analysis Reference Manual*.

Learn more about Bayesian econometrics features.