Shadow-rate VAR toolkit for Bayesian macroeconomic forecasting in pure Python.
Explore the docs »
Quick Start
·
Report Bug
·
Request Feature
Table of Contents
srvar-toolkit is a lightweight, testable implementation of Shadow-Rate Vector Autoregression (SRVAR) models for macroeconomic forecasting. It provides a complete Bayesian workflow for fitting VARs with:
- Effective Lower Bound (ELB) constraints — Model interest rates that are censored at the zero lower bound
- Stochastic volatility — Capture time-varying uncertainty in economic variables
- Minnesota-style shrinkage — Improve forecast accuracy with informative priors
- Variable selection (SSVS) — Identify which predictors matter most
The toolkit is designed for researchers and practitioners who need transparent, reproducible Bayesian VAR estimation without the overhead of large econometric frameworks.
|
|
| Component | Description | How to Enable | Status |
|---|---|---|---|
| Conjugate BVAR (NIW) | Closed-form posterior updates and fast sampling for VAR coefficients/covariance | PriorSpec.niw_default(...) |
Supported |
| Minnesota Shrinkage | Minnesota-style shrinkage via NIW prior construction | PriorSpec.niw_minnesota(...) |
Supported |
| Variable Selection (SSVS) | Spike-and-slab inclusion indicators for stochastic search | PriorSpec.from_ssvs(...) |
Supported |
| Bayesian LASSO (BLASSO) | Bayesian LASSO shrinkage prior for VAR coefficients (global or adaptive) | PriorSpec.from_blasso(...) |
Supported |
| Shadow-Rate / ELB | Latent shadow-rate sampling at the effective lower bound | ModelSpec(elb=ElbSpec(...)) |
Supported |
| Stochastic Volatility | Diagonal log-volatility random-walk (KSC mixture sampling) | ModelSpec(volatility=VolatilitySpec(...)) |
Supported |
| Combined ELB + SV | Joint shadow-rate and stochastic volatility model | ModelSpec(elb=..., volatility=...) |
Supported |
| Steady-State VAR (SSP) | Parameterize the VAR intercept via a steady-state mean mu (optional mu-SSVS) |
ModelSpec(steady_state=SteadyStateSpec(...)) |
Supported |
| Forecasting | Posterior predictive simulation with quantiles | srvar.api.forecast(...) |
Supported |
| Plotting | Shadow rate, volatility, and fan chart visualisations | srvar.plotting |
Supported |
| Backtesting | Rolling/expanding refit + forecast with evaluation plots + metrics export | srvar backtest config.yml |
Supported |
- ELB: effective lower bound (censoring constraint applied to selected observed series)
- NIW: Normal-Inverse-Wishart prior (conjugate Bayesian VAR)
- SSVS: stochastic search variable selection (spike-and-slab variable selection)
- SVRW: stochastic volatility random walk (diagonal log-variance random-walk model)
- KSC: Kim-Shephard-Chib mixture approximation for log-(\chi^2)
- SSP: steady-state parameterization (replace intercept with long-run mean
mu)
- Python 3.11 or higher
- pip package manager
If you're concerned about cross-platform differences (macOS/Windows/Linux), installing into a fresh virtual environment is the most reliable workflow.
python -m venv .venv
# Activate (macOS/Linux)
source .venv/bin/activate
# Activate (Windows PowerShell)
# .venv\Scripts\Activate.ps1
python -m pip install -U pip
# Install from this repo (CLI + FRED fetch)
python -m pip install -e ".[cli,fred]"For development (tests + docs + plotting):
python -m pip install -e ".[dev,cli,fred,docs,plot]"git clone https://github.com/shawcharles/srvar-toolkit.git
cd srvar-toolkit
pip install -e .# With plotting support
pip install -e '.[plot]'
# With FRED data fetching
pip install -e '.[fred]'
# With all development tools
pip install -e '.[dev]'
# All extras
pip install -e '.[dev,plot,fred,docs]'Note: srvar fetch-fred requires the optional fred extra (it depends on fredapi).
If you see a warning like srvar-toolkit ... does not provide the extra 'fred', you are likely installing a different distribution than this repository. From the repository root, prefer:
python -m pip install -e ".[fred]"You will also need a FRED API key (set FRED_API_KEY in your environment).
Fit a simple Bayesian VAR and generate forecasts:
import numpy as np
from srvar import Dataset
from srvar.api import fit, forecast
from srvar.spec import ModelSpec, PriorSpec, SamplerConfig
# Create a dataset
ds = Dataset.from_arrays(
values=np.random.standard_normal((80, 2)),
variables=["y1", "y2"]
)
# Configure the model
model = ModelSpec(p=2, include_intercept=True)
prior = PriorSpec.niw_default(k=1 + ds.N * model.p, n=ds.N)
sampler = SamplerConfig(draws=500, burn_in=100, thin=1)
# Fit and forecast
fit_res = fit(ds, model, prior, sampler)
fc = forecast(fit_res, horizons=[1, 4], draws=200)
print(fc.mean)SSP replaces the explicit intercept with a steady-state mean vector mu.
import numpy as np
from srvar.api import fit, forecast
from srvar.spec import ModelSpec, PriorSpec, SamplerConfig, SteadyStateSpec
model = ModelSpec(
p=2,
include_intercept=True,
steady_state=SteadyStateSpec(mu0=np.array([0.0, 0.0]), v0_mu=0.1),
)YAML (CLI) example:
model:
p: 2
include_intercept: true
steady_state:
mu0: [0.02, 0.03]
v0_mu: 0.01
ssvs:
enabled: false
spike_var: 0.0001
slab_var: 0.01
inclusion_prob: 0.5from srvar import Dataset, ElbSpec, VolatilitySpec
from srvar.api import fit, forecast
from srvar.spec import ModelSpec, PriorSpec, SamplerConfig
# Configure ELB + SV model
model = ModelSpec(
p=4,
include_intercept=True,
elb=ElbSpec(applies_to=["interest_rate"], bound=0.125),
volatility=VolatilitySpec(enabled=True)
)
# Fit with Minnesota prior
prior = PriorSpec.niw_minnesota(p=4, y=data_array, n=n_vars)
sampler = SamplerConfig(draws=2000, burn_in=500, thin=2)
fit_res = fit(dataset, model, prior, sampler)from srvar.plotting import plot_shadow_rate, plot_forecast_fanchart, plot_volatility
# Plot inferred shadow rate
fig, _ax = plot_shadow_rate(fit_res, var="interest_rate")
fig.savefig("shadow_rate.png", dpi=150, bbox_inches="tight")
# Plot forecast fan chart
fig, _ax = plot_forecast_fanchart(fc, var="gdp_growth")
fig.savefig("forecast.png", dpi=150, bbox_inches="tight")
# Plot volatility paths
fig, _ax = plot_volatility(fit_res, var="gdp_growth")
fig.savefig("volatility.png", dpi=150, bbox_inches="tight")For more examples, see the examples/README.md.
SSP example:
examples/ssp_fit_forecast.py
For production-style usage, you can run the toolkit from a YAML configuration file.
# Validate a config (checks schema, variable names, and basic compatibility)
srvar validate config/demo_config.yaml
# Run fit (+ optional forecast/plots depending on the config)
srvar run config/demo_config.yaml
# Override output directory
srvar run config/demo_config.yaml --out outputs/my_run
# Run a rolling/expanding backtest (refit + forecast over multiple origins)
srvar backtest config/backtest_demo_config.yaml
# Override output directory for backtest
srvar backtest config/backtest_demo_config.yaml --out outputs/my_backtest
# Fetch macro data directly from FRED into a cached CSV
srvar fetch-fred config/fetch_fred_demo_config.yaml
# Preview what would be fetched/written (no network calls)
srvar fetch-fred config/fetch_fred_demo_config.yaml --dry-run
# Preflight-check that series IDs exist (network call)
srvar fetch-fred config/fetch_fred_demo_config.yaml --validate-seriesSee:
config/demo_config.yaml(comment-rich template)config/minimal_config.yaml(minimal runnable)config/backtest_demo_config.yaml(comment-rich backtest template)config/fetch_fred_demo_config.yaml(comment-rich FRED fetch template)
In addition to the standard keys (data, model, prior, sampler, output), backtesting uses:
backtest: refit schedule and forecast horizonsmode:expandingorrollingmin_obs: minimum training sample size at first originstep: origin step sizehorizons: list of horizons to evaluatedraws,quantile_levels: forecast distribution settings
evaluation: which metrics/plots to generatecoverage: empirical interval coverage by horizonpit: PIT histograms for calibration checkscrps: CRPS-by-horizon plot + CRPS in metrics tablemetrics_table: writemetrics.csv
When you run srvar backtest, outputs are written into output.out_dir (or --out), for example:
config.ymlmetrics.csvcoverage_all.png,coverage_<var>.pngpit_<var>_h<h>.pngcrps_by_horizon.pngbacktest_summary.json
- Conjugate BVAR (NIW) with closed-form posteriors
- Minnesota-style shrinkage priors
- Stochastic Search Variable Selection (SSVS)
- Shadow-rate / ELB data augmentation
- Diagonal stochastic volatility (SVRW)
- Combined ELB + SV model
- Forecasting with fan charts
- Plotting utilities
- Bayesian LASSO prior
- Steady-state VAR parameterisation
- Dirichlet-Laplace prior
- Full-covariance stochastic volatility
- Replication: Carriero et al. (2025) "Forecasting with shadow rate VARs" baseline results
See the open issues for a full list of proposed features.
Contributions are welcome and appreciated. To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Run the test suite (
pytest) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For full contributor guidelines (including docs builds, style, and testing expectations), see CONTRIBUTING.md.
- This is currently an alpha research toolkit.
- SV is diagonal (no time-varying covariances).
- MCMC runtime depends heavily on
T,N, and sampler settings (draws/burn-in/thinning).
The documentation site contains more detailed guidance and caveats.
# Clone and install with dev dependencies
git clone https://github.com/shawcharles/srvar-toolkit.git
cd srvar-toolkit
pip install -e '.[dev]'
# Install pre-commit hooks
pre-commit install
# Run tests
pytest
# Run linting
ruff check srvar/
black --check srvar/Distributed under the MIT License. See LICENSE for more information.
If you use srvar-toolkit in your research, please cite both the software and the original methodology paper.
@software{shaw2025srvar,
author = {Shaw, Charles},
title = {srvar-toolkit: Shadow-Rate VAR Toolkit for Python},
year = {2025},
url = {https://github.com/shawcharles/srvar-toolkit},
version = {0.1.0}
}@article{grammatikopoulos2025forecasting,
author = {Grammatikopoulos, Michael},
title = {Forecasting With Machine Learning Shadow-Rate VARs},
journal = {Journal of Forecasting},
year = {2025},
pages = {1--17},
doi = {10.1002/for.70041}
}
@article{carriero2025forecasting,
title={Forecasting with shadow rate VARs},
author={Carriero, Andrea and Clark, Todd E and Marcellino, Massimiliano and Mertens, Elmar},
journal={Quantitative Economics},
volume={16},
number={3},
pages={795--822},
year={2025},
publisher={Wiley Online Library}
}This toolkit implements methods from:
Grammatikopoulos, M. 2025. "Forecasting With Machine Learning Shadow-Rate VARs." Journal of Forecasting 1–17. https://doi.org/10.1002/for.70041
Carriero, A., Clark, T. E., Marcellino, M., & Mertens, E. 2025. "Forecasting with shadow rate VARs." Quantitative Economics 16(3), 795–822.
For the original MATLAB replication code, see: MichaelGrammmatikopoulos/MLSRVARs
For an additional MATLAB replication toolbox with code written by Elmar Mertens, see: elmarmertens/CCMMshadowrateVAR-code
- Kim, S., Shephard, N., & Chib, S. (1998). "Stochastic Volatility: Likelihood Inference and Comparison with ARCH Models." Review of Economic Studies 65(3), 361–393.
- Carriero, A., Clark, T. E., & Marcellino, M. (2019). "Large Bayesian Vector Autoregressions with Stochastic Volatility and Non-Conjugate Priors." Journal of Econometrics 212(1), 137–154.

