bvarSvForecast#
Purpose#
Generate density forecasts from a fitted SV-BVAR model with time-varying volatility propagation.
Format#
- dfc = bvarSvForecast(result, h)#
- dfc = bvarSvForecast(result, h, ctl)
- dfc = bvarSvForecast(result, h, ctl, xreg=X_future)
- Parameters:
result (struct) – an instance of a
bvarSvResultstructure returned bybvarSvFit().h (scalar) – forecast horizon (number of steps ahead).
ctl (struct) –
Optional input, an instance of an
svForecastControlstructure. An instance is initialized by callingsvForecastControlCreate()and the following members can be set:ctl.h
Scalar, forecast horizon. Default = 12.
ctl.mode
String, forecast mode.
"mean_path"Deterministic h-path using posterior mean innovations. Fast but underestimates forecast variance (Jensen’s inequality). (Default)
"simulate"Draw innovation paths from the SV-implied time-varying covariance. Gives proper predictive density.
ctl.n_paths
Scalar, number of simulation paths per posterior draw (
"simulate"mode only). Default = 100.ctl.quantile_levels
Vector, quantile levels to report. Default = 0.05|0.16|0.50|0.84|0.95.
ctl.h_init
String, log-volatility initialization for forecasting.
"stochastic"Draw h_T from the reservoir. Captures h_T uncertainty. (Default)
"posterior_mean"Use posterior mean h_T. Faster, underestimates tails.
ctl.store_draws
Scalar, 1 to store raw forecast draws in dfc.draws, 0 to discard. Default = 0.
ctl.seed
Scalar, RNG seed for simulation mode. Default = 42.
xreg (hxK matrix) – Optional keyword, future values of exogenous regressors. Required if the model was fit with xreg.
quiet (scalar) – Optional keyword, set to 1 to suppress printed output. Default = 0.
- Returns:
dfc (struct) –
An instance of a
densityForecastResultstructure containing:dfc.fc_mean
hxm matrix, mean forecast across posterior draws.
dfc.fc_median
hxm matrix, median forecast across posterior draws.
dfc.quantile_bands
Array of hxm matrices, one per quantile level. Access the i-th quantile band as
dfc.quantile_bands[i].dfc.quantile_levels
n_quantiles x 1 vector, quantile levels corresponding to each band (e.g., 0.05, 0.16, 0.50, 0.84, 0.95).
dfc.log_vol_mean
hxm matrix, mean forecast log-volatility per equation.
dfc.log_vol_median
hxm matrix, median forecast log-volatility per equation.
dfc.h
Scalar, forecast horizon.
dfc.m
Scalar, number of variables.
dfc.n_draws
Scalar, effective number of posterior draws used.
dfc.mode
String, forecast mode used:
"mean_path"or"simulate".dfc.var_names
Mx1 string array, variable names.
dfc.draws
(n_draws)x(h*m) matrix, raw forecast draws. Empty matrix unless
ctl.store_draws = 1. Row layout: each row is one draw, columns ordered as h1_v1, h1_v2, …, h1_vm, h2_v1, …
Examples#
Quick Mean-Path Forecast#
new;
library timeseries;
data = loadd(getGAUSSHome("pkgs/timeseries/examples/macro.dat"));
result = bvarSvFit(data, quiet=1);
struct densityForecastResult dfc;
dfc = bvarSvForecast(result, 12);
print "Mean forecast:";
print dfc.fc_mean;
print "Median forecast:";
print dfc.fc_median;
Full Density Forecast (Simulate Mode)#
new;
library timeseries;
data = loadd(getGAUSSHome("pkgs/timeseries/examples/macro.dat"));
result = bvarSvFit(data, quiet=1);
// Simulate mode for proper predictive density
fctl = svForecastControlCreate();
fctl.mode = "simulate";
fctl.n_paths = 500;
dfc = bvarSvForecast(result, 24, fctl);
Custom Quantiles for VaR#
new;
library timeseries;
data = loadd(getGAUSSHome("pkgs/timeseries/examples/macro.dat"));
result = bvarSvFit(data, quiet=1);
fctl = svForecastControlCreate();
fctl.mode = "simulate";
fctl.n_paths = 1000;
fctl.quantile_levels = 0.01|0.05|0.10|0.50|0.90|0.95|0.99;
dfc = bvarSvForecast(result, 12, fctl);
// 1% VaR forecast (first quantile band)
var_01 = dfc.quantile_bands[1];
print "1% quantile forecast (VaR):";
print var_01;
// 5% VaR forecast (second quantile band)
var_05 = dfc.quantile_bands[2];
Forecast Log-Volatility Path#
new;
library timeseries;
data = loadd(getGAUSSHome("pkgs/timeseries/examples/macro.dat"));
ctl = bvarSvControlCreate();
ctl.p = 4;
ctl.n_draws = 10000;
ctl.n_burn = 5000;
result = bvarSvFit(data, ctl, quiet=1);
dfc = bvarSvForecast(result, 24);
// Future volatility path
print "Forecast log-volatility (mean):";
print dfc.log_vol_mean;
// Convert to standard deviations
print "Forecast std dev:";
print exp(dfc.log_vol_mean / 2);
Store Raw Draws for Custom Analysis#
new;
library timeseries;
data = loadd(getGAUSSHome("pkgs/timeseries/examples/macro.dat"));
result = bvarSvFit(data, quiet=1);
fctl = svForecastControlCreate();
fctl.mode = "simulate";
fctl.store_draws = 1;
dfc = bvarSvForecast(result, 12, fctl);
// Raw draws: each row is one draw, columns are h1_v1, h1_v2, ..., h1_vm, h2_v1, ...
print "Draw matrix:" rows(dfc.draws) "x" cols(dfc.draws);
// Extract GDP (variable 1) draws at horizon 1
m = dfc.m;
gdp_h1_draws = dfc.draws[., 1]; // First column = h1, variable 1
Remarks#
Forecast modes:
"mean_path" (default) uses the posterior mean innovation variance at each
forecast horizon. This is fast but underestimates forecast uncertainty due to
Jensen’s inequality — the mean of convex functions exceeds the function of
the mean. Use this for quick point forecasts.
"simulate" draws n_paths innovation paths per posterior draw from the
SV-implied time-varying covariance. The log-volatility \(h_{i,t}\) is
propagated forward:
and innovations are drawn from \(N(0, \text{diag}(\exp(h_{T+s})))\). This gives a proper predictive density that captures volatility clustering and parameter uncertainty. Required for density forecast evaluation.
h_T initialization:
"stochastic" draws the initial log-volatility \(h_T\) from the reservoir
of posterior draws (when sv_keep = "online" or "full"). This captures
uncertainty about the current volatility state.
"posterior_mean" uses the posterior mean \(h_T\). Faster but
underestimates tail risk by ignoring \(h_T\) uncertainty.
Memory considerations:
Setting store_draws = 1 stores an (n_draws * n_paths) x (h * m) matrix.
For large systems or long horizons, this can be substantial. Default is off.
Model#
The SV-BVAR density forecast accounts for three sources of uncertainty:
Parameter uncertainty: different \((B^{(s)}, A^{(s)})\) draws.
Volatility uncertainty: the future path of log-volatilities \(h_{T+1}, \ldots, h_{T+h}\).
Innovation uncertainty: random \(\varepsilon_{T+s}\) with time-varying variance.
At each forecast horizon \(s = 1, \ldots, h\):
The resulting predictive density is non-Gaussian and potentially fat-tailed due to volatility clustering — a key advantage over constant-variance BVAR forecasts. Algorithm ———
Simulate mode:
For each posterior draw \((B^{(s)}, A^{(s)}, \mu^{(s)}, \phi^{(s)}, \sigma^{(s)}, h_T^{(s)})\):
For each of n_paths simulation paths: i. Propagate log-volatilities forward: \(h_{T+1}, \ldots, h_{T+h}\). ii. Draw innovations from the time-varying covariance. iii. Iterate the VAR forward.
Collect all forecast paths and compute quantiles.
Mean-path mode: Uses the posterior mean volatility at each horizon (no simulation of \(\eta\)), giving a single path per posterior draw. Faster but underestimates tail risk.
Complexity: Simulate mode: \(O(n\_draws \cdot n\_paths \cdot h \cdot m^2)\). Troubleshooting —————
Density forecasts are too narrow compared to realized outcomes:
Use mode = "simulate" instead of "mean_path". The mean-path mode
underestimates uncertainty by ignoring future volatility randomness.
Memory issues with large systems:
Use store_draws = 0 (default) and rely on the quantile summaries. For systems
with m > 10, use sv_keep = "online" in bvarSvFit().
Forecast volatility path seems unreasonable: If \(h_T\) is at an extreme value (e.g., a crisis period), forecasts may show elevated volatility for many periods. This is the model correctly reflecting persistent volatility. If the persistence \(\phi_i\) is near 1, volatility shocks take many periods to decay. Verification ————
SV-BVAR forecast density calibration verified via PIT (probability integral transform)
tests on out-of-sample evaluation windows. Forecast paths validated against
R bayesianVARs::predict() for structural consistency.
See the Verification and Cross-Validation page. References ———-
Clark, T.E. (2011). “Real-time density forecasts from Bayesian vector autoregressions with stochastic volatility.” Journal of Business & Economic Statistics, 29(3), 327-341.
Kastner, G. and S. Fruhwirth-Schnatter (2014). “Ancillarity-sufficiency interweaving strategy (ASIS) for boosting MCMC estimation of stochastic volatility models.” Computational Statistics & Data Analysis, 76, 408-423.
Library#
timeseries
Source#
forecast.src
See also
Functions bvarSvFit(), svForecastControlCreate(), bvarForecast(), condForecast(), pitTest()