| Title: | Bayesian Vector Autoregressions with Steady-State Priors |
|---|---|
| Description: | Provides estimation of Bayesian vector autoregression (BVAR) models with steady-state priors via 'Stan', along with functions for unconditional and conditional forecasting, as well as impulse response analysis. For details on the steady-state BVAR model see Villani (2009) <doi:10.1002/jae.1065>. |
| Authors: | Mark Becker [aut, cre, cph] |
| Maintainer: | Mark Becker <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.2.0.9000 |
| Built: | 2026-10-15 08:02:32 UTC |
| Source: | https://github.com/markjwbecker/steadystatebvar |
Initialises a steady-state bvar object. This is the starting point for all models in SteadyStateBVAR.
After creation, pass the object sequentially to setup, priors,
and fit to build and estimate the model.
bvar(data)bvar(data)
data |
A numeric matrix or time series of data where each column is a variable and each row is a time period. |
For a detailed theoretical introduction to the steady-state BVAR model, run the following
vignette("SteadyStateBVAR-intro")
The steady-state BVAR model takes the form
where is an -dimensional vector of endogenous variables at time , and is
a -dimensional vector of deterministic (exogenous) variables at time .
Here for is a matrix of autoregressive parameters,
and is a matrix of steady-state parameters. Now
is the unconditional mean, or the steady state of the process.
Note that the current version of this package only allows for to contain either a constant,
a constant and a dummy variable, or a constant and a time trend.
We may stack the (transposed) matrices in the matrix
Then the model can be rewritten as a nonlinear regression (Karlsson, 2013)
where is a -dimensional vector of lagged endogenous variables
and is a -dimensional vector of lagged deterministic (exogenous) variables,
is the identity matrix and denotes the Kronecker product.
The goal is to estimate the parameters , and as such priors are needed.
Please see priors for more details.
For the innovations to the model, in the case of the homoscedastic (the original) steady-state BVAR, they are .
However, with stochastic volatility, there is instead a time-varying covariance matrix .
The innovations then take the form
where is a lower triangular matrix with ones on the diagonal that describes
the contemporaneous interaction of the endogenous variables, and
contains the time-varying volatilities.
For the AR1 stochastic volatility specification, the log volatilities follow AR(1) processes
where the log volatility AR(1) processes are restricted to the stationary region, i.e. .
For the RW stochastic volatility specification, the log volatilities follow (driftless) Random Walk processes
The innovations to the log volatilities follow in the AR(1) case
where is not diagonal and as such the innovations to the log
volatilities are allowed to be correlated across variables. For the Random Walk case, is diagonal
with variances for .
Note that under both stochastic volatility specifications, the time-varying covariance matrix is
For details on the homoscedastic steady-state BVAR model, see Villani (2009). For details on the Random Walk stochastic volatility steady-state BVAR model, see Clark (2011). See Carriero, Clark, and Marcellino (2024) for the above-mentioned AR(1) stochastic volatility specification applied to a conventional BVAR.
To see examples for each type of steady-state BVAR model, simply run one of the following
vignette("Homoscedastic-steady-state-BVAR")
vignette("RW-stochastic-volatility-steady-state-BVAR")
vignette("AR1-stochastic-volatility-steady-state-BVAR")
A steady-state bvar object.
Carriero, A., Clark, T. E., and Marcellino, M. (2024). Capturing macro-economic tail risks with Bayesian vector autoregressions. Journal of Money, Credit and Banking, 56(5), pp. 1099–1127.
Clark, T. E. (2011). Real-time density forecasts from Bayesian vector autoregressions with stochastic volatility. Journal of Business & Economic Statistics, 29(3), pp. 327–341.
Karlsson, S. (2013). Forecasting with Bayesian vector autoregression. In: Elliott, G. and Timmermann, A. (eds), Handbook of Economic Forecasting. Elsevier B.V., Vol. 2, Part B, pp. 791–897.
Villani, M. (2009). Steady-state priors for vector autoregressions. Journal of Applied Econometrics, 24(4), pp. 630–650.
yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt)yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt)
Computes and plots conditional forecasts from a fitted steady-state bvar object.
Conditions are imposed on specific variables at specific horizons using Algorithm 3.3.1
from Dieppe, Legrand, and van Roye (2016). Both conditional and unconditional
forecasts are plotted for comparison. Please note that for the moment, conditional forecasting
is only enabled for the homoscedastic steady-state BVAR, i.e. when SV=FALSE in priors().
conditional_forecast( x, conditions, pi = 0.95, fcst_type = c("mean", "median"), growth_rate_idx = NULL, plot_idx = NULL )conditional_forecast( x, conditions, pi = 0.95, fcst_type = c("mean", "median"), growth_rate_idx = NULL, plot_idx = NULL )
x |
A steady-state |
conditions |
A data frame with three columns: |
pi |
Numeric. The prediction interval width. Default |
fcst_type |
Character. Whether to use |
growth_rate_idx |
Integer vector. Indices of variables of which to convert forecasts to
annual growth rates |
plot_idx |
Integer vector. Indices of variables to plot. If |
See Section 5.3 of Dieppe, Legrand, and van Roye (2016) for more details. Please note the limitations of this method, see the detailed discussion in Section 5.4 of Dieppe, Legrand, and van Roye (2016).
Invisibly returns a list with three matrices: forecast, lower, and
upper, each of dimension H x k.
Dieppe, A., Legrand, R., and van Roye, B. (2016). The BEAR toolbox. Working Paper Series, No. 1934. European Central Bank.
#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) conditions <- data.frame(var = rep(2,8), horizon = rep(1:8), value = rep(1,8)) (cond_fcst <- conditional_forecast(bvar_obj, conditions, pi=0.68, fcst_type = "mean"))#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) conditions <- data.frame(var = rep(2,8), horizon = rep(1:8), value = rep(1,8)) (cond_fcst <- conditional_forecast(bvar_obj, conditions, pi=0.68, fcst_type = "mean"))
Estimates the steady-state BVAR model using the No-U-Turn sampler (a variant of Hamiltonian Monte Carlo) via Stan.
Also generates draws from the joint predictive distribution.
Uses the data, setup, and priors stored in the steady-state bvar object.
fit(x, H = 1, d_pred = NULL, ...)fit(x, H = 1, d_pred = NULL, ...)
x |
A steady-state |
H |
Positive Integer. Forecast horizon.
Default is |
d_pred |
Matrix of size |
... |
Additional arguments passed directly to the |
The function selects the appropriate precompiled Stan model based on settings from priors:
steady_state_bvar_homoscedastic_jeffreys_prior
steady_state_bvar_homoscedastic_inverse_wishart_prior
steady_state_bvar_RW_stochastic_volatility
steady_state_bvar_AR1_stochastic_volatility
The function estimates the following parameter matrices/vectors (see bvar for details):
beta: VAR coefficient matrix
Psi: steady-state parameter matrix
Sigma_u: innovation covariance matrix ( for homoscedastic,
for stochastic volatility)
If Random Walk stochastic volatility:
A: lower triangular matrix with ones on the diagonal that describes
the contemporaneous interaction of the endogenous variables
phi: -dimensional vector of log volatility innovation variances
If AR1 stochastic volatility:
A: lower triangular matrix with ones on the diagonal that describes
the contemporaneous interaction of the endogenous variables
gamma_0: -dimensional vector of log volatility intercepts
gamma_1: -dimensional vector of log volatility slopes
Phi: log volatility innovation covariance matrix
A fitted steady-state bvar object with:
x$fit$stan: An object of class stanfit
x$fit$posterior_means: List of elementwise posterior mean estimates
x$fit$posterior_medians: List of elementwise posterior median estimates
#homoscedastic with Jeffreys prior, d_t = constant yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) #homoscedastic with inverse-Wishart prior, d_t = constant and dummy yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) dummy_variable <- c(rep(1,5), rep(0,5)) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant_and_dummy", dummy = dummy_variable) k <- bvar_obj$setup$k q <- bvar_obj$setup$q bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, k*q), Omega_Psi = diag(0.1, k*q, k*q), Jeffreys = FALSE) #inverse-Wishart bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) #RW stochastic volatility yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, control = list(max_treedepth = 12, adapt_delta = 0.85) ) #AR1 stochastic volatility yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_AR1 <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_gamma_0 = rep(0.1, k), Omega_gamma_0 = diag(1000, k), theta_gamma_1 = rep(0.9, k), Omega_gamma_1 = diag(10, k), theta_log_lambda_1 = rep(0.1, k)/(1-rep(0.9, k)), Omega_log_lambda_1 = diag(1000, k), V_Phi = (10 - k - 1) * diag(k), m_Phi = 10 ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "AR1", SV_priors = SV_priors_AR1) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, control = list(max_treedepth = 12, adapt_delta = 0.85) )#homoscedastic with Jeffreys prior, d_t = constant yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) #homoscedastic with inverse-Wishart prior, d_t = constant and dummy yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) dummy_variable <- c(rep(1,5), rep(0,5)) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant_and_dummy", dummy = dummy_variable) k <- bvar_obj$setup$k q <- bvar_obj$setup$q bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, k*q), Omega_Psi = diag(0.1, k*q, k*q), Jeffreys = FALSE) #inverse-Wishart bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) #RW stochastic volatility yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, control = list(max_treedepth = 12, adapt_delta = 0.85) ) #AR1 stochastic volatility yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_AR1 <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_gamma_0 = rep(0.1, k), Omega_gamma_0 = diag(1000, k), theta_gamma_1 = rep(0.9, k), Omega_gamma_1 = diag(10, k), theta_log_lambda_1 = rep(0.1, k)/(1-rep(0.9, k)), Omega_log_lambda_1 = diag(1000, k), V_Phi = (10 - k - 1) * diag(k), m_Phi = 10 ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "AR1", SV_priors = SV_priors_AR1) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, control = list(max_treedepth = 12, adapt_delta = 0.85) )
Computes and plots forecasts from a fitted steady-state bvar object. Draws from the
joint predictive distribution are used to construct point forecasts and
prediction intervals. Optionally converts monthly or quarterly growth rate forecasts to annual growth
rates for variables specified as 100*diff(log(x)). Optionally overlays the posterior steady
states.
forecast( x, pi = 0.95, fcst_type = c("mean", "median"), growth_rate_idx = NULL, plot_idx = NULL, show_all = TRUE, ss = TRUE, ss_type = c("mean", "median"), ss_ci = 0.95 )forecast( x, pi = 0.95, fcst_type = c("mean", "median"), growth_rate_idx = NULL, plot_idx = NULL, show_all = TRUE, ss = TRUE, ss_type = c("mean", "median"), ss_ci = 0.95 )
x |
A steady-state |
pi |
Numeric. The prediction interval width. Default |
fcst_type |
Character. Whether to use |
growth_rate_idx |
Integer vector. Indices of variables of which to convert forecasts to
annual growth rates |
plot_idx |
Integer vector. Indices of variables to plot. If |
show_all |
Logical. If |
ss |
Logical. If |
ss_type |
Character. Whether to use |
ss_ci |
Numeric. The posterior credible interval width for the steady state.
Default |
Invisibly returns a list with three matrices: forecast, lower, and
upper, each of dimension H x k where H is the
forecast horizon and k is the number of variables.
#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) forecast(bvar_obj, fcst_type = "mean", pi = 0.90, show_all = TRUE, ss = TRUE, ss_type = "mean", ss_ci = 0.95)#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) forecast(bvar_obj, fcst_type = "mean", pi = 0.90, show_all = TRUE, ss = TRUE, ss_type = "mean", ss_ci = 0.95)
Computes and plots impulse response functions (IRFs) from a fitted
steady-state bvar object. Supports both orthogonalized (OIRF) and generalized
(GIRF) impulse responses, with optional conversion to annual growth rates.
IRF( x, H = 20, response = NULL, impulse = NULL, type = c("median", "mean"), method = c("OIRF", "GIRF"), ci = 0.95, t = NULL, growth_rate_idx = NULL )IRF( x, H = 20, response = NULL, impulse = NULL, type = c("median", "mean"), method = c("OIRF", "GIRF"), ci = 0.95, t = NULL, growth_rate_idx = NULL )
x |
A steady-state |
H |
Integer. The forecast horizon for the IRF. Default |
response |
Integer vector. Indices of the response variables to plot. If
|
impulse |
Integer vector. Indices of the impulse variables to plot. If |
type |
Character. Whether to use |
method |
Character. The IRF method: |
ci |
Numeric. The credible interval width. Default |
t |
Integer. Time index for the covariance matrix when using stochastic
volatility models. If |
growth_rate_idx |
Integer vector. Indices of variables for which the impulse
response is converted from a quarterly or monthly log first difference to an
annual growth rate response, i.e. |
Invisibly returns a list with three arrays: the point estimate IRF, lower, and
upper credible bounds, each of dimension k x k x (H+1).
#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) IRF(bvar_obj)#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1) IRF(bvar_obj)
Quarterly US macroeconomic data (1953Q1-2006Q3) from Koop and Korobilis (2010)
KoopKorobilis2010KoopKorobilis2010
KoopKorobilis2010A multivariate time series object with 215 rows and 3 columns:
inflation rate (annual percentage change in a chain-weighted GDP price index)
unemployment rate (seasonally adjusted civilian unemployment rate, all civilian workers aged 16 years or older)
interest rate (yield on the three-month Treasury bill rate)
Koop, G. and Korobilis, D. (2010). Bayesian multivariate time series methods for empirical macroeconomics. Foundations and Trends in Econometrics, 3(4), pp. 267-358.
Calculates the mean and variance of a normal prior probability interval.
Given a lower and upper bound of a prior probability interval
this function recovers the implied normal prior parameters.
Useful for specifying informative priors
on the steady-state parameters (elements of ).
ppi(l, u, interval = 0.95, annualized_growthrate = FALSE, freq = NULL)ppi(l, u, interval = 0.95, annualized_growthrate = FALSE, freq = NULL)
l |
Numeric. The lower bound of the prior probability interval. |
u |
Numeric. The upper bound of the prior probability interval. |
interval |
Numeric. The prior probability mass within the interval.
Default |
annualized_growthrate |
Logical. If |
freq |
Integer. The data frequency (e.g. |
Consider a CPI variable CPI <- data$CPI, observed at quarterly frequency.
In the model, quarter-on-quarter inflation is used x <- 100*diff(log(CPI)).
Suppose the prior belief is that annualized steady-state inflation lies between 1.7 and 2.3
with 95% probability (mean 2). On the quarterly scale used by x, this corresponds to a
95% interval of 0.425 to 0.575 (mean 0.5). Since it is typically more natural to elicit a prior
on the annualized scale, the annualized_growthrate argument performs this conversion.
See vignette("Homoscedastic-steady-state-BVAR") for usage in practice.
A list with two elements: mean and var, giving the
mean and variance of the implied normal distribution.
ppi(l = 1.7, u = 2.3, interval = 0.95) ppi(l = 1.7, u = 2.3, interval = 0.95, annualized_growthrate = TRUE, freq = 4)ppi(l = 1.7, u = 2.3, interval = 0.95) ppi(l = 1.7, u = 2.3, interval = 0.95, annualized_growthrate = TRUE, freq = 4)
This function prepares the priors. The Minnesota prior is used for the autoregressive parameters, and is determined by the overall tightness, cross-equation tightness, and the lag decay rate. For the steady-state parameters, a normal prior is used. Regarding the covariance matrix of the reduced-form innovations, for the homoscedastic model, the user can choose between Jeffreys prior or an uninformative inverse-Wishart prior. The user may also choose a stochastic volatility specification for the innovations, where the covariance matrix varies over time.
priors( x, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = NULL, theta_Psi = NULL, Omega_Psi = NULL, Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL )priors( x, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = NULL, theta_Psi = NULL, Omega_Psi = NULL, Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL )
x |
A steady-state |
lambda_1 |
Numeric. Overall tightness of the Minnesota prior.
Default |
lambda_2 |
Numeric. Cross-equation tightness of the Minnesota prior. Default |
lambda_3 |
Numeric. Lag decay rate of the Minnesota prior. Default |
first_own_lag_prior_mean |
Numeric vector of length |
theta_Psi |
Numeric vector. Prior mean vector for |
Omega_Psi |
Numeric matrix. Prior covariance matrix for |
Jeffreys |
Logical. If |
SV |
Logical. If |
SV_type |
Character. Type of stochastic volatility model. Must be either |
SV_priors |
List. User-supplied stochastic volatility priors. Required when
|
The goal is to estimate the parameters ,
and as such priors are needed. Following Villani (2009), prior independence between and is assumed.
For , which contains the autoregressive parameters, the Minnesota prior is used
The prior means (the elements of ) are specified according to
Here, the autoregressive coefficient is element
of for . As such, the Minnesota prior sets all prior means
for the elements in to , except for the elements that relate to the first
own lags of the variables, which are set to . If variable is in levels
(e.g. nominal interest rate), then , and typical choices for
are or . Evaluating the equations at their prior means,
equation becomes a random walk if and a persistent stationary
AR(1) process if . Since the steady state only exists if the process
is stationary, is recommended for the steady-state BVAR. If variable is differenced
(e.g. GDP growth), then , and the most common choice for
is , i.e. equation becomes (when evaluating it at its prior means)
a random walk expressed in first differences (a white noise process). If a differenced variable still shows some degree
of persistence (can be examined with an ACF plot), a suitable value for can
be (for example) instead of . Moving on to the prior variances, is a
diagonal matrix containing the prior variances for the elements in . They are specified as
Here , , and are scalar hyperparameters known as
the overall tightness, the cross-equation tightness and the lag decay rate. Furthermore,
is the :th element of , which is unknown and therefore
needs to be replaced with an estimate. In this package, it is replaced by the least squares residual variance
from a univariate autoregression for variable with lags
(including the constant and dummy/trend variable if applicable). Moving on to , the steady-state parameter matrix, the
(steady-state) prior is
This is the core of the steady-state BVAR model.
In , one specifies the prior beliefs about the location of the steady state,
and in , which is assumed to be a diagonal matrix, one specifies the degree
of certainty in those prior beliefs. Too see how to specify steady-state priors in practice, please see the package vignettes.
The prior for is either the usual non-informative Jeffreys prior
or a proper uninformative inverse-Wishart prior
where is the scale matrix and is the number of degrees of freedom.
An uninformative prior is specified by setting
where is the least squares estimate
from the VAR() (including the constant and dummy/trend variable if applicable), and .
However, if we opt to use stochastic volatility, the innovation covariance matrix is time-varying ,
instead of constant . Therefore, stochastic volatility priors are needed.
See bvar for more details on the stochastic volatility specifications. Please note that
below (volatilities) has nothing to do with the from the Minnesota prior (hyperparameters).
Now, for the Random Walk ("RW") stochastic volatility specification, the following priors are available
Here is a -dimensional vector that collects the free parameters in in row-major order,
and is a -dimensional vector containing the time values (initial conditions) of .
We assume that and are diagonal matrices.
Furthermore, for are the log volatility innovation variances. For the AR(1) ("AR1") stochastic volatility specification, the following priors are available
Here is again the -dimensional vector that collects the free parameters in in row-major order,
and is a -dimensional vector containing the time values (initial conditions) of .
Furthermore, is a -dimensional vector of log volatility intercepts, is a -dimensional vector of log volatility
slopes, and is the log volatility innovation covariance matrix.
We assume that , , , and are diagonal matrices.
Note that the prior for is truncated normal.
For details on the homoscedastic steady-state BVAR model, see Villani (2009). For details on the Random Walk stochastic volatility steady-state BVAR model, see Clark (2011). See Carriero, Clark, and Marcellino (2024) for the AR(1) stochastic volatility specification applied to a conventional BVAR.
To see examples of how to specify the priors, simply view the relevant vignette
vignette("Homoscedastic-steady-state-BVAR")
vignette("RW-stochastic-volatility-steady-state-BVAR")
vignette("AR1-stochastic-volatility-steady-state-BVAR")
The steady-state bvar object with an appended priors list containing:
theta_beta |
Prior mean vector for |
Omega_beta |
Prior covariance matrix for |
theta_Psi |
Prior mean vector for |
Omega_Psi |
Prior covariance matrix for |
Jeffreys |
Indicator for Jeffreys prior usage |
Sigma_AR |
Residual variance estimates from univariate AR fits, which are used by the Minnesota prior |
m |
Inverse-Wishart prior degrees of freedom (if |
V |
Inverse-Wishart prior scale matrix (if |
SV |
Logical indicator for stochastic volatility specification |
SV_type |
Stochastic volatility specification type |
SV_priors |
User-supplied SV prior list (if |
Carriero, A., Clark, T. E., and Marcellino, M. (2024). Capturing macro-economic tail risks with Bayesian vector autoregressions. Journal of Money, Credit and Banking, 56(5), pp. 1099–1127.
Clark, T. E. (2011). Real-time density forecasts from Bayesian vector autoregressions with stochastic volatility. Journal of Business & Economic Statistics, 29(3), pp. 327–341.
Villani, M. (2009). Steady-state priors for vector autoregressions. Journal of Applied Econometrics, 24(4), pp. 630–650.
#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) #RW stochastic volatility yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) #AR1 stochastic volatility yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_AR1 <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_gamma_0 = rep(0.1, k), Omega_gamma_0 = diag(1000, k), theta_gamma_1 = rep(0.9, k), Omega_gamma_1 = diag(10, k), theta_log_lambda_1 = rep(0.1, k)/(1-rep(0.9, k)), Omega_log_lambda_1 = diag(1000, k), V_Phi = (10 - k - 1) * diag(k), m_Phi = 10 ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "AR1", SV_priors = SV_priors_AR1)#homoscedastic with Jeffreys prior yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE, SV = FALSE, SV_type = NULL, SV_priors = NULL) #RW stochastic volatility yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) #AR1 stochastic volatility yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=1) k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_AR1 <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_gamma_0 = rep(0.1, k), Omega_gamma_0 = diag(1000, k), theta_gamma_1 = rep(0.9, k), Omega_gamma_1 = diag(10, k), theta_log_lambda_1 = rep(0.1, k)/(1-rep(0.9, k)), Omega_log_lambda_1 = diag(1000, k), V_Phi = (10 - k - 1) * diag(k), m_Phi = 10 ) bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1,2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "AR1", SV_priors = SV_priors_AR1)
Applies zero restrictions to the VAR coefficient matrix by setting the
corresponding prior variances in Omega_beta to a value near zero (prior means are zero by default in the Minnesota prior).
restrict_beta(x, restriction_matrix)restrict_beta(x, restriction_matrix)
x |
A steady-state |
restriction_matrix |
A numeric matrix of dimension |
The steady-state BVAR model takes the form
where is an -dimensional vector of endogenous variables at time , and is
a -dimensional vector of deterministic (exogenous) variables at time .
Here for is a matrix of autoregressive parameters,
and is a matrix of steady-state parameters.
One can stack the (transposed) matrices in the matrix
This function puts zero restrictions on the autoregressive parameters/coefficients, i.e the elements of .
The steady-state bvar object with the restriction matrix stored in
setup and the prior covariance matrix Omega_beta updated accordingly.
yt <- matrix(rnorm(50), 25, 2) colnames(yt) <- c("y1", "y2") bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=2) bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2)) p <- bvar_obj$setup$p k <- bvar_obj$setup$k restriction_matrix <- matrix(1,k*p,k) #restrict beta so y2 does not granger-cause y1 restriction_matrix[2, 1] <- 0 restriction_matrix[4, 1] <- 0 bvar_obj <- restrict_beta(bvar_obj, restriction_matrix)yt <- matrix(rnorm(50), 25, 2) colnames(yt) <- c("y1", "y2") bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p=2) bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2)) p <- bvar_obj$setup$p k <- bvar_obj$setup$k restriction_matrix <- matrix(1,k*p,k) #restrict beta so y2 does not granger-cause y1 restriction_matrix[2, 1] <- 0 restriction_matrix[4, 1] <- 0 bvar_obj <- restrict_beta(bvar_obj, restriction_matrix)
Prepares the components needed for prior specification and estimation. Also computes OLS estimates.
setup( x, p = 1, deterministic = c("constant", "constant_and_dummy", "constant_and_trend"), dummy = NULL )setup( x, p = 1, deterministic = c("constant", "constant_and_dummy", "constant_and_trend"), dummy = NULL )
x |
A steady-state |
p |
Integer. The lag order of the VAR. Default |
deterministic |
Character. The deterministic components to include in |
dummy |
Numeric vector of a dummy variable. Only
used when |
The steady-state bvar object with a setup list containing the
required components for prior specification and estimation, and also the OLS estimates.
yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj)yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj)
Produces time series plots of the data along with the implied prior for
the steady state .
steady_state_priors_plot( x, interval = 0.95, growth_rate_idx = NULL, plot_idx = NULL )steady_state_priors_plot( x, interval = 0.95, growth_rate_idx = NULL, plot_idx = NULL )
x |
A steady-state |
interval |
Numeric. The prior interval width. Default |
growth_rate_idx |
Integer vector. Indices of variables specified
as |
plot_idx |
Integer vector. Indices of variables to plot. If
|
The implied prior for the steady state is based on the prior for
which is specified in priors. Note that it is assumed that is diagonal.
Invisibly returns a list with three matrices, lower,
mean, and upper, each of dimension T x k giving the
steady-state prior bounds and mean over the historical sample. For
growth_rate_idx columns, these are on the annualized scale.
yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1, 2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) steady_state_priors_plot(bvar_obj)yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, lambda_1 = 0.2, lambda_2 = 0.5, lambda_3 = 1, first_own_lag_prior_mean = rep(1, 2), theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), Jeffreys = TRUE) steady_state_priors_plot(bvar_obj)
Produces time series plots of posterior stochastic volatility estimates
over the estimation sample together with predictive paths over the forecast
horizon for a fitted steady-state bvar object with stochastic volatility.
stochastic_volatility_plot( x, ci = 0.95, vol = "log_lambda", stat = "mean", plot_idx = NULL, xlim = NULL, ylim = NULL )stochastic_volatility_plot( x, ci = 0.95, vol = "log_lambda", stat = "mean", plot_idx = NULL, xlim = NULL, ylim = NULL )
x |
A steady-state |
ci |
Numeric. Interval level. Default is |
vol |
Character. Volatility representation: |
stat |
Character. Posterior summary statistic to use as point estimate:
|
plot_idx |
Integer vector. Indices of variables to plot. If |
xlim |
Numeric vector of length 2. Optional x-axis limits. |
ylim |
Numeric vector of length 2. Optional y-axis limits. |
The function supports two volatility representations:
"log_lambda": log volatilities
"sd": implied standard deviations of the reduced-form innovations
For each selected variable, the function plots the posterior point estimate path and credible bands over the estimation sample, and the predictive point estimate path and prediction intervals over the forecast horizon.
An invisible list with:
estimated: List of posterior summaries for the estimation sample:
point: matrix of posterior point estimates
(mean or median depending on stat)
lower: matrix of lower credible bounds
upper: matrix of upper credible bounds
predicted: List of posterior summaries for the forecast horizon:
point: matrix of predictive point estimates
(mean or median depending on stat)
lower: matrix of lower bound of prediction interval
upper: matrix of upper bound of prediction interval
yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, verbose = FALSE) stochastic_volatility_plot(bvar_obj, ci = 0.95)yt <- matrix(rnorm(50), 25, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") k <- bvar_obj$setup$k n_free_params_A <- bvar_obj$setup$n_free_params_A SV_priors_RW <- list( theta_A = rep(0, n_free_params_A), Omega_A = diag(1000, n_free_params_A), theta_log_lambda_1 = rep(0, k), Omega_log_lambda_1 = diag(1000, k), alpha_phi = rep(5, k), beta_phi = (rep(5, k) - 1) * rep(0.1, k) ) bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2), SV = TRUE, SV_type = "RW", SV_priors = SV_priors_RW) bvar_obj <- fit(bvar_obj, H = 8, iter = 200, warmup = 50, chains = 1, cores = 1, verbose = FALSE) stochastic_volatility_plot(bvar_obj, ci = 0.95)
Computes and prints elementwise posterior summaries from a fitted steady-state bvar object.
The printed output depends on whether the model is homoscedastic or includes
stochastic volatility (RW or AR1 specification).
## S3 method for class 'bvar' summary(object, pars = NULL, stat = "mean", t = NULL, ...)## S3 method for class 'bvar' summary(object, pars = NULL, stat = "mean", t = NULL, ...)
object |
A steady-state |
pars |
Character vector of parameter names to include. If
|
stat |
Character. Posterior summary statistic to display:
|
t |
Integer. Time index for the innovation covariance matrix if stochastic volatility was estimated.
If |
... |
Additional arguments (currently unused). |
The function summarizes, by calculating elementwise posterior means/medians, the following estimated parameter matrices/vectors:
beta: VAR coefficient matrix
Psi: steady-state parameter matrix
Sigma_u: innovation covariance matrix ( for homoscedastic,
for stochastic volatility)
If Random Walk stochastic volatility:
A: lower triangular matrix with ones on the diagonal that describes
the contemporaneous interaction of the endogenous variables
phi: -dimensional vector of log volatility innovation variances
If AR1 stochastic volatility:
A: lower triangular matrix with ones on the diagonal that describes
the contemporaneous interaction of the endogenous variables
gamma_0: -dimensional vector of log volatility intercepts
gamma_1: -dimensional vector of log volatility slopes
Phi: log volatility innovation covariance matrix
Returns the input object invisibly.
yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2)) bvar_obj <- fit(bvar_obj, H = 1, iter = 100, warmup = 50, chains = 1, cores = 1) summary(bvar_obj)yt <- matrix(rnorm(20), 10, 2) bvar_obj <- bvar(data = yt) bvar_obj <- setup(bvar_obj, p = 1, deterministic = "constant") bvar_obj <- priors(bvar_obj, theta_Psi = rep(0, 2), Omega_Psi = diag(0.1, 2, 2)) bvar_obj <- fit(bvar_obj, H = 1, iter = 100, warmup = 50, chains = 1, cores = 1) summary(bvar_obj)
Swedish macroeconomic data (1980Q1–2005Q4) from Section 4.1 in Villani (2009)
Villani2009Villani2009
Villani2009A multivariate time series object with 104 rows and 7 columns:
foreign GDP growth
foreign CPI inflation
foreign 3-month interest rate
domestic GDP growth
domestic CPI inflation
domestic 3-month interest rate
level of the real exchange rate defined as , where and
are the foreign and domestic CPI levels in logs and is the log of the trade-weighted nominal exchange rate
Villani, M. (2009). Steady-state priors for vector autoregressions. Journal of Applied Econometrics, 24(4), pp. 630-650.