Jorge Jesus Alonso Ortiz

Jorge Jesus Alonso Ortiz

Research, teaching, coding… and dogs

puremacro

PYPI 6.3.0 · OPEN SOURCE · MIT LICENSE · PYTHON 3.11+

Macroeconometrics and structural modeling in Python.

Analyze macroeconomic data, simulate policy, and export results with NumPy, SciPy, pandas and Matplotlib. A local workstation is the supported target; browser and tablet workflows are best effort.

pip install puremacro

Analyze data · Simulate policy · Learn or teach

PyPI version Supported Python versions MIT license

CI

tests across three operating systems and Python 3.11–3.13

Examples

worked analyses, simulations and empirical replications

EN / ES

notebook learning paths in English and Spanish

0

compiled extensions of its own: pure Python on NumPy and SciPy

Releases and capabilities · Gallery · From Stata & Dynare · Run it anywhere · Documentation · Changelog

HOUSEHOLD MODELING · AVAILABLE SINCE 5.1

Heterogeneous-agent models, declared like a .mod file

The examples below were prepared for 5.1 and remain illustrations of the published household-modeling workflow. Their figures come from notebook 21, the dp guide and the SCF example. Use the documented package and course edition for each notebook; the numerical values in these figures belong to the examples shown.

DECLARATIVE DYNAMIC PROGRAMMING · NOTEBOOK 21

Declare the model, read its exact distribution, simulate a panel

puremacro.dp does for dynamic programs what a Dynare .mod file does for DSGE models: states, shocks, choices, the reward and the constraints are equations in Dynare expression syntax, parsed by the same parser, and Model.solve() writes the solver call. Inequality statistics come exactly from the stationary distribution. In the published 6.3.0 package, simulate supports VFI and EGM panels, continuous-time HJB and Krusell–Smith simulation within their documented model restrictions, with seeded reproducibility. See the simulation guide for the supported modes. dp is the supported interface for declaring these models.

dp.Model, DPSolution.gini, DPSolution.lorenz, DPSolution.simulate, dp.Panel
Open notebook 21 in your browser →

ONE DECLARATION, SEVERAL SOLVERS

Life cycles, discrete choices and aggregate risk in the same syntax

solve() compiles a declaration to discrete value function iteration, to the endogenous grid method (one step per age in a life cycle, an upper envelope over a discrete choice, logit choice probabilities with taste shocks), to the continuous-time HJB solver when the model has a drift, or to the Krusell–Smith forecast-rule loop under aggregate risk. Supported equilibrium configurations declare prices and market clearing in the same syntax; each solver has explicit model restrictions.

Model.horizon, Model.discrete, Model.taste_shocks, Model.aggregate_state, Model.solve("egm")
Read the dp guide →

SURVEY MICRODATA

Household surveys with design-based standard errors

fetch.micro reads ACS, CPS, SCF and ENIGH data into a MicroFrame that records the available survey design. Supported uncertainty estimates use ACS/SCF replicate weights or ENIGH strata and PSUs; the CPS basic reader carries weights only. Not every statistic has design-based uncertainty for every source. A worked SCF–Aiyagari example shows what a calibrated model explains and misses.

fetch.micro.fetch_scf, MicroFrame.gini, MicroFrame.top_share, fetch.registry
Read the microdata guide →

Also in 5.1: puremacro.llm, one entry point for local language models (MLX, llama.cpp, Ollama and OpenAI-compatible servers) with a completion cache that any engine can answer from; puremacro.text, a tokenizer and sparse document-term matrix for narrative corpora that are now stored and exportable; exact-diffuse Kalman filtering and smoothing that agree with the batch posterior; the full Stock–Yogo tables; and Galí’s (1999) difference specification in the benchmark example. Full changelog.

CROSS-COUNTRY DATA

Cross-country data in one call, with every seam recorded

One-call panels from the World Bank, the OECD, Eurostat, the IMF, the BIS, ILOSTAT, the Penn World Table and the Maddison Project, each a (code, date) frame that carries its units, sources and what it could not obtain, and splice_sources to join them into long series with every seam recorded. These data tools remain available in the published 6.3.0 package.

See its figures in the gallery →

UPGRADING FROM 4.8

  • Trade and MRIO returned in 5.2.0. The legacy accounting, bundled table and named scenarios were removed; migrate 4.x applications using the 5.2 migration notes. Results can change under the corrected accounting. The course edition course-2026A-5.5.0 pins 5.5.0 and requires Python 3.12+; follow its setup instructions.
  • The research studies added since 4.4 left the package as well: the SW07 estimator studies, the household incidence application and the cross-country forecasting application. puremacro.structural and the Romer–Romer (2010) replication stay.
  • vfi.Model is deprecated and will be removed in 6.0; declare the model with puremacro.dp. vfi.simulate_panel now refuses a policy that is not an integer array of grid indices; use DPSolution.simulate.
  • kalman_filter and kalman_smoother with diffuse_states return the exact diffuse results, so loglik changes whenever a diffuse loading is not one.
  • PUREMACRO_LLM_CACHE now names the completion cache of puremacro.llm; the narrative score cache moved to PUREMACRO_LLM_SCORES_CACHE, and the local narrative backends default to qwen3-4b.

LATEST RELEASES · UPDATED AUTOMATICALLY

  • puremacro 6.4.0 adds reusable own-data quarterly fiscal policy briefs, bounded connector provenance and freshness reporting, local-projection chronological and specification contracts with two-way fixed-effects panel IV, and eleven numerical and data-provenance correctness fixes […]
  • puremacro 6.3.0 adds research APIs for solving equilibria, accounting for simulation uncertainty, and auditing policy models. It merges #232 and #233 while preserving existing entry points and their approximation orders. Equilibrium derivatives, […]
  • Fiscal rules & debt-sustainability analysis, state-dependent LP & weak-IV HAC diagnostics, sequence-space optimal policy, SVAR identification, GIV, and investment-research workflows. Added Experimental investment-research kernels in asset_pricing: lagged, self-financing long-only backtests with cash, […]

From the GitHub release feed. All releases · Changelog · PyPI history

Why puremacro

Built at ITAM–CIE for applied analysis, research and teaching, with explicit numerical diagnostics and reproducible examples.

PURE PYTHON

No compiler, no licence

The numerical core uses NumPy, SciPy, pandas and Matplotlib, with no compiled extension of its own. Data fetching also uses requests; optional workflows have additional dependencies. Frozen reference comparisons run in Python; regenerating external reference output can require the original software.

RUNS ANYWHERE

Laptop, browser, iPad

Local installation is supported. The numerical core is Pyodide-compatible, while browser and tablet execution depends on memory, file formats and network access. Colab helpers package heavier jobs; checkpointed workflows can resume supported computations.

SPEAKS DYNARE

Bring your .mod files

Compile the supported Dynare subset, choose local orders 1–3 or nonlinear perfect foresight, and inspect explicit compatibility and accuracy reports. Existing pruning, OccBin and oo_.dr interfaces remain available.

PUBLICATION-READY

From estimate to LaTeX

Estimators return result objects with .summary(), .plot() and .to_latex(), so the last step to a paper table is one line.

What it can do

The empirical and structural toolkit of modern macroeconomics, in one library.

VARs & identification

Cholesky, long-run, sign and zero, narrative, proxy-IV, heteroskedasticity and non-Gaussian identification, with bootstrap and Bayesian bands.

Open the notebook →

Local projections & inference

LP-HAC, LP-IV, lag-augmented, panel, state-dependent, smooth and quantile LPs, with HAC, fixed-b and weak-IV-robust inference.

Open the notebook →

DSGE & Bayesian estimation

Shared nonlinear equations, local perturbation and pruning, deterministic transitions, explicitly mapped global policies, OccBin and Bayesian estimation. Off-grid Euler/KKT audits and solver-specific diagnostics expose numerical limits; likelihood-score support depends on the estimation specification.

Open the notebook →

Heterogeneous agents

Models declared as equations with puremacro.dp and solved by VFI, EGM, continuous-time HJB or Krusell–Smith; sequence-space HANK with the Fake News algorithm; firm dynamics and neural-network solvers.

Open the notebook →

Microdata, space & climate

ACS, CPS, SCF and ENIGH readers with their available survey designs, spatial models and climate scenarios. Trade and MRIO returned in 5.2 with consistent accounting, rebuilt OECD data and household incidence conditional on supplied prices and incomes.

Open the notebook →

Data, nowcasting & forecasting

One-call cross-country panels from the World Bank, OECD, Eurostat, IMF, BIS, ILOSTAT, PWT and Maddison; FRED, ECB, Banxico and INEGI fetchers; real-time vintages, nowcasts, text-based uncertainty indices and BVAR fan charts.

Open the notebook →

See every figure in the gallery →

Replication examples and independent evidence

Bundled empirical examples use frozen data snapshots. The replication scorecard distinguishes internal regression references from published targets; a separate research-benchmark dossier records analytical and external-software comparisons and their limitations.

from puremacro.replication import scorecard

df = scorecard()   # inspect each row's reference and scope
df["passed"].all()

Read each case’s source, specification and tolerance before interpreting a pass. Internal regression checks are not published replications. The independent research dossier retains a known RR2010 published t-statistic rounding mismatch; matching software output does not make that comparison pass.

Coming from Stata, MATLAB or Dynare?

The commands you know, and their puremacro equivalents.

TaskStata / MATLAB / Dynarepuremacro
Cholesky SVARvar y1 y2, lags(1/4) + irf createvar.identify.cholesky_svar(Y, p=4, horizon=20)
Local Projections (HAC)jorda / manual OLSlp.lp_hac(df, y="y", x="shock", horizon=20, lags=4)
Staggered DiDcsdid y, ivar(id) time(t) gvar(g)did.callaway_santanna(df, unit="id", time="t", outcome="y", treat_time="g")
DSGE from equations / .modDynare .mod filedsge.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)
Spatial Gravity GEAllen-Arkolakis replicationspatial.AllenArkolakisModel.from_coordinates(...)

TABLET WORKFLOWS · BEST EFFORT

Macroeconomics on an iPad, with Juno

Tablet workflows depend on the app’s Python version, available packages, memory and file access. A local workstation remains the supported installation target. Use the runtime guide to check the numerical core in Juno or a Pyodide browser session.

  • Knows where it is. puremacro recognises Juno, both its built-in Python and its in-browser Pyodide kernel, and works inside the iPad’s sandboxed file system.
  • Brings its data. Pocket cartridges carry panels built on your workstation to the iPad, checked on arrival, even in airplane mode.
  • Survives interruptions. Supported checkpointed computations can resume from saved state. Checkpointing must be enabled, and it does not make every estimator or interrupted tablet session resumable.
  • Knows its limits. runtime.fit sizes bootstraps to the device, and heavy jobs offload to Google Colab as a single notebook.
# In Juno, with puremacro installed
from puremacro import runtime

# What can this iPad do?
print(runtime.report())

# Size the bootstrap to the device
print(runtime.fit(n_boot=2000))

Detection and budgets are opt-in: the same script gives the same numbers on your laptop.

ENGINEERED FOR CORRECTNESS

Numbers you can defend

Research code has to be right before it is fast. puremacro treats correctness as a feature.

  • CI runs the default suite on three operating systems and Python 3.11–3.13, plus the Pyodide import contract and documentation checks. PyPI publication waits for the release workflow’s required CI and opt-in tests.
  • The validation gallery distinguishes internal, analytical, package and published-reference evidence. Each comparison has a specific scope and tolerance.
  • The replication scorecard labels its reference types. A green test suite or converged solver does not certify every economic conclusion; inspect the independent research benchmarks and structural validation status.
  • 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.