OPEN SOURCE · MIT LICENSE · PYTHON 3.11+
Empirical macroeconomics in pure Python.
From SVARs and local projections to Bayesian DSGE and heterogeneous-agent models: one toolbox that runs on your laptop, in your browser and even on an iPad.
pip install puremacro
4,984
automated tests, run on three operating systems and three Python versions
91
worked examples and real-data replications
33
notebooks you can run in the browser, each with a Spanish twin
0
compiled extensions of its own: pure Python on NumPy and SciPy
Gallery · From Stata & Dynare · Run it anywhere · Documentation · Changelog
Why puremacro
Built at ITAM–CIE for research and teaching, and engineered like production software.
PURE PYTHON
No compiler, no licence
The estimator core imports only NumPy, SciPy, pandas and Matplotlib. Nothing to compile, no MATLAB or Stata licence, MIT-licensed.
RUNS ANYWHERE
Laptop, browser, iPad
The same code runs locally, in JupyterLite and under Pyodide. Heavy jobs offload to Google Colab; long bootstraps resume after the app is suspended.
SPEAKS DYNARE
Bring your .mod files
Load native Dynare models, solve to second order with pruning, handle the ZLB with OccBin and get oo_.dr-compatible decision rules.
PUBLICATION-READY
From estimate to LaTeX
Every estimator returns a result object with .summary(), .plot(), .to_latex(), .to_typst() and .to_markdown().
What it can do
Fifty-two subpackages covering the empirical and structural toolkit of modern macroeconomics.
A REAL EXAMPLE
From live data to an impulse response
Pull U.S. real GDP and the federal funds rate straight from FRED, with no API key, estimate a Jordà local projection with 90% Newey–West bands, and plot it.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from puremacro.fetch import fetch_fred
from puremacro.lp.jorda import lp_hac
gdp = fetch_fred("GDPC1").dropna().resample("QS").last()
ff = fetch_fred("FEDFUNDS").dropna().resample("QS").mean()
df = pd.concat([np.log(gdp).rename("log_gdp"),
ff.rename("ff")], axis=1).dropna()
irf = lp_hac(df, y="log_gdp", x="ff",
horizons=range(0, 17), n_lags=2, alpha=0.10)
plt.plot(irf["h"], irf["beta"])
plt.fill_between(irf["h"], irf["lo"], irf["hi"], alpha=0.15)
Classic results, reproduced
Real-data replications ship with the package on frozen data snapshots and run fully offline. A built-in scorecard checks puremacro against each paper’s published numbers.



from puremacro.replication import scorecard
df = scorecard() # puremacro vs each paper's published target
df["passed"].all()
Every case compares puremacro’s estimate with the number printed in the paper, so a regression shows up as a failed row, not a silently different figure.
Coming from Stata, MATLAB or Dynare?
The commands you know, and their puremacro equivalents.
| Task | Stata / MATLAB / Dynare | puremacro |
|---|---|---|
| Cholesky SVAR | var y1 y2, lags(1/4) + irf create | var.identify.cholesky_svar(Y, p=4, horizon=20) |
| Local Projections (HAC) | jorda / manual OLS | lp.lp_hac(df, y="y", x="shock", horizon=20, lags=4) |
| Staggered DiD | csdid y, ivar(id) time(t) gvar(g) | did.callaway_santanna(df, unit="id", time="t", outcome="y", treat_time="g") |
| DSGE from equations / .mod | Dynare .mod file | dsge.load_mod("rbc.mod") / dsge.build_dynare(eqs) |
| Bayesian DSGE (MCMC) | Dynare estimation(...) (Metropolis-Hastings) | dsge.estimate_dsge_bayesian(m, data, priors, n_draws=10000) |
ENGINEERED FOR CORRECTNESS
Numbers you can defend
Research code has to be right before it is fast. puremacro treats correctness as a feature.
- Every push runs the full test suite on three operating systems and three Python versions, plus mypy and a Pyodide-compatibility contract.
- A validation gallery cross-checks estimators against statsmodels, linearmodels and arch.
- A replication scorecard compares results with each paper’s published numbers.
- Clear diagnostic errors instead of silent garbage: singular matrices, non-positive-definite covariances and Blanchard–Kahn violations say what went wrong and where.
- Any released version that returned a wrong number is listed in a public correctness advisory.
Start in the browser, keep it on your laptop
Open the tour notebook in JupyterLite with nothing installed, then pip install puremacro when you are ready.
CITE PUREMACRO
@software{alonso_ortiz_puremacro,
author = {Alonso Ortiz, Jorge},
title = {puremacro: Production-grade Macroeconometric and
Heterogeneous-Agent Structural Modeling in Pure Python},
year = {2026},
url = {https://github.com/jalonso1979/puremacro}
}
Or use the repository’s CITATION.cff.








