A general, YAML based DSGE solver and Bayesian estimation toolkit implemented in Python.
Symbolic equations → rational-expectations solution → Kalman likelihood → MAP/MCMC → posterior diagnostics and IRFs.
- Dynare parity
- Realistic DSGE showcases
- Bayesian diagnostics, not just estimates
- Why PyDSGEforge
- Installation
- Quick start
- YAML model specification
- Project structure
- Reproducibility and quality
- Contributing, security, and citation
- Roadmap
- References
The first benchmark is deliberately direct: the same three-equation New Keynesian model, 82 observations, priors, posterior mode, prefiltering, stationary Kalman initialization, and unit-shock convention are evaluated in Dynare/Octave and PyDSGEforge.
| Numerical check | Dynare | PyDSGEforge | Absolute difference |
|---|---|---|---|
| Log likelihood at Dynare mode | -555.4646535601 | -555.4646535592 | 9.14 × 10⁻¹⁰ |
| Log posterior at Dynare mode | -586.7712107416 | -586.7712107406 | 9.14 × 10⁻¹⁰ |
| Log posterior on 25 Dynare draws | — | — | 1.82 × 10⁻⁹ max |
| Unit-shock IRFs | — | — | 7.77 × 10⁻¹⁶ max |
The curves below compare 500 retained Dynare draws with 10,500 post-warmup PyDSGEforge draws. Finite-chain KDEs need not overlap pixel-for-pixel; the pointwise likelihood and posterior checks above establish numerical parity.
The compact, reviewable reference is in
dynare_comprobation/. It contains the .mod
file, readable CSV data, posterior mode, retained draws, metrics, and an
independent validator—not Dynare's generated matrices, bytecode, or plots.
python dynare_comprobation/validate.pyTwo larger YAML-only models demonstrate persistent states, forward and backward dynamics, measurement error, MAP estimation, adaptive Metropolis-Hastings, and posterior IRF bands.
| Model | Economic ingredients | Solved system | MCMC acceptance |
|---|---|---|---|
HybridNKMedium |
Habit, indexation, rate smoothing, three AR(1) shocks | 8 states, 3 shocks | 20.5% |
SmallOpenEconomyNK |
Hybrid IS/Phillips blocks, exchange rate, natural rate, open-economy Taylor rule | 9 states, 4 shocks | 23.8% |
The synthetic datasets use fixed seeds and each model's solved state space. Rebuild the CSVs, estimations, posterior draws, PNG/PDF figures, and metrics with:
python scripts/build_showcase.pyMachine-readable results live in
outputs/showcase_report.json. Notebook-ready
cells for both models are in
notebooks/showcase_more_models.ipynb.
PyDSGEforge goes beyond producing a posterior mode or a collection of MCMC draws. Its analysis layer turns the retained chain into a detailed assessment of posterior uncertainty and sampling quality, directly in the economic parameter space.
- Effective sample size (ESS): estimates how much independent information remains after accounting for serial correlation in the chain.
- Monte Carlo precision: reports integrated autocorrelation time and Monte Carlo standard error (MCSE) for each selected parameter.
- Credible regions: computes configurable highest posterior density intervals (HPDI), together with posterior mean, median, and standard deviation.
- Visual convergence checks: produces trace plots, running means, posterior densities, and HPDI overlays, complemented by the sampler acceptance rate and explicit burn-in accounting.
- Economic interpretation: compares prior and posterior distributions and propagates parameter uncertainty into posterior impulse-response bands.
The diagnostics are available from the same fitted model object:
diagnostics = model.analyze_posteriors(
subset=["beta", "kappa", "phi_pi"],
plot=True,
describe=True,
return_data=True,
)This makes estimation, uncertainty quantification, sampling diagnostics, and economic interpretation part of one reproducible workflow rather than separate post-processing steps.
- General equations: declare variables, leads, lags, shocks, measurement equations, and parameters instead of selecting a hard-coded macro model.
- YAML-first experiments: model structure, priors, bounds, data, solver, likelihood, MAP, MCMC, and IRF settings can live in one reviewable file.
- Explicit numerical conventions: parameter transformations, covariance construction, Kalman initialization, prefiltering, and shock scaling are configurable and documented.
- Composable Python API: use the high-level
DSGEfacade or the underlying builders, Gensys solver, inference, and analysis modules independently. - External validation: numerical comparisons are stored as fixtures and executable checks rather than screenshots alone.
Current capabilities include symbolic linearization with SymPy, Blanchard-Kahn checks, a Sims-style Gensys solution, Gaussian state-space likelihood, multiple prior families and constrained transformations, MAP optimization, adaptive Metropolis-Hastings, and posterior impulse-response summaries.
Python 3.10 or newer is required.
git clone https://github.com/pablo-reyes8/PyDSGEforge.git
cd PyDSGEforge
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -e .Development tools and optional Kalman-loop acceleration:
python -m pip install -e ".[dev]"
python -m pip install -e ".[speed]"Validate a configuration without estimating it:
python scripts/run_pipeline.py --config configs/nk_full_yaml.yaml --dry-runRun the configured estimation:
python scripts/run_pipeline.py --config configs/nk_full_yaml.yamlUse the same model from Jupyter:
from pathlib import Path
import pandas as pd
import yaml
from src.dsge import DSGE
config_path = Path("configs/hybrid_nk_medium.yaml")
cfg = yaml.safe_load(config_path.read_text(encoding="utf-8"))
model, registry, theta = DSGE.from_yaml(config_path)
data = pd.read_csv(cfg["data"]["path"])[cfg["data"]["columns"]].to_numpy()
result = model.compute(
registry=registry,
theta_struct=theta,
data=data,
compute_steady=False,
div=cfg["solver"]["div"],
map=cfg["map"]["enabled"],
map_bounds="auto",
map_kwargs={
"method": cfg["map"]["method"],
"hess_step": cfg["map"]["hess_step"],
"tau_scale": cfg["map"]["tau_scale"],
"hessian_strategy": cfg["map"]["hessian_strategy"],
"include_jacobian_prior": cfg["map"]["include_jacobian_prior"],
},
run_mcmc=cfg["mcmc"]["enabled"],
mcmc_draws=cfg["mcmc"]["draws"],
mcmc_kwargs=cfg["mcmc"],
)See docs/usage.md for the Python API and
docs/yaml_configuration.md for the full schema.
A model is expressed as economic equations—not precomputed matrices:
model:
name: BasicNK
variables:
states: [x_t, pi_t, i_t]
leads: [x_tp1, pi_tp1]
shocks: [eps_d, eps_s, eps_m]
equations:
- "x_t = x_tp1 - (1 / sigma) * (i_t - pi_tp1) + eps_d"
- "pi_t = beta * pi_tp1 + kappa * x_t + eps_s"
- "i_t = phi_pi * pi_t + phi_x * x_t + eps_m"
parameters:
specs:
beta:
transform: logistic
bounds: {lower: 0.90, upper: 0.999}
prior:
family: beta
params: {a: 391.05, b: 3.95, loc: 0.0, scale: 1.0}
theta_econ:
beta: 0.99
q:
diag_params: [sig_d, sig_s, sig_m]The complete benchmark is
configs/nk_full_yaml.yaml; the smallest smoke
test is configs/tiny_ar1.yaml.
PyDSGEforge/
├── src/ # Library: builders, solver, inference, analysis
├── configs/ # Reusable YAML model specifications
├── tests/ # Numerical and API regression tests
├── docs/ # Usage, schema, conventions, and testing notes
├── scripts/ # CLI, showcase, and reference export utilities
├── dynare_comprobation/ # Minimal external parity fixture
├── data/ # Example and fixed-seed synthetic datasets
├── outputs/ # Reproducible figures and machine-readable results
└── notebooks/ # Interactive demonstrations
The core path is:
equations + parameter registry
↓
linear-system builder
↓
Gensys / Blanchard-Kahn solution
↓
state-space + Kalman likelihood
↓
MAP / MCMC
↓
posterior diagnostics + IRFs
Detailed module notes are available in docs/api.md and
docs/numerical-conventions.md.
The repository provides one-command development gates:
make help # list commands
make test # unit and regression tests
make dynare-check # independent numerical parity check
make check # lint + tests + parity + package build
make docker-test # isolated container test stageCI tests Python 3.10–3.12, validates a configured model, checks the Dynare fixture, builds source/wheel distributions, installs the wheel, and executes the Docker test stage. The runtime container is multi-stage and runs as a non-root user.
- Read
CONTRIBUTING.mdbefore proposing code or numerical convention changes. - Follow
CODE_OF_CONDUCT.md. - Report vulnerabilities privately as described in
SECURITY.md. - Cite research use with the machine-readable
CITATION.cff. - Release notes are maintained in
CHANGELOG.md.
PyDSGEforge is released under the MIT License.
- Add more cross-implementation fixtures and period-by-period Kalman diagnostics.
- Extend nonlinear steady-state and higher-order approximation workflows.
- Expand diagnostics for convergence, identification, and posterior predictive checks.
- Sims, C. A. (2001). “Solving Linear Rational Expectations Models.” Computational Economics, 20, 1–20. doi:10.1023/A:1013825826056.
- Jacobo, J. (2025). Una introducción a los métodos de máxima entropía y de inferencia bayesiana en econometría. Universidad Externado de Colombia.
This project is licensed under the MIT License. You are free to use, modify, and distribute this code, provided that appropriate credit is given to the author.



