Skip to main content

🇬🇧 English · 🇪🇸 Español

puremacro

A Pyodide-compatible empirical macroeconomics toolbox: pure-numpy + scipy + pandas + matplotlib at runtime, runs on iPad / juno.sh as well as a regular workstation.

What's in it

Core econometrics

  • VAR — reduced-form OLS, BVAR (Minnesota), VECM (Engle-Granger / Johansen), TVP-VAR, panel-VAR; IRF / FEVD / GFEVD; residual, block, moving-block, and wild bootstrap bands.
  • SVAR identification (var.identify.*) — Cholesky, Blanchard-Quah, sign restrictions (Rubio-Ramirez-Waggoner-Zha), sign + zero restrictions (Arias-Rubio Ramirez-Waggoner), sign-robust bands (Giacomini-Kitagawa), proxy / external instruments, max-share / news, heteroskedasticity (Rigobon), non-Gaussian (Lanne-Meitz-Saikkonen). All public estimators return frozen-dataclass …Result objects.
  • Local projections (lp.*) — single-country LP-HAC, LP-IV, lag-augmented LP (Plagborg-Møller-Wolf), panel LP with cluster / Driscoll-Kraay SE, state-dependent LP, smoothed LP (Barnichon- Brownlees B-splines), asymmetric LP (Tenreyro-Thwaites), LP-GARCH- state, LP-GARCH-in-mean, mean-group, CCE, quantile LP.
  • Inference (inference.*) — central HAC OLS, Newey-West, Kiefer- Vogelsang fixed-b, Driscoll-Kraay; weak-IV diagnostics (Cragg-Donald, Kleibergen-Paap, Anderson-Rubin, Montiel Olea-Pflueger); Hansen-J / Stock-Yogo over-id; Pesaran CD, Swamy slope-homogeneity, Quandt- Andrews structural breaks, specification curves.
  • Other estimators — Diebold-Yilmaz spillover index; Diebold-Mariano / Giacomini-White forecast comparison + density- forecast scoring (CRPS, log score); Bai-Perron breaks; unit-root tests (ADF, KPSS, PP, Zivot-Andrews); Klein QZ solver for linear DSGE (Blanchard-Kahn enforced).

Modern macro extensions

  • Staggered DiD (did.*) — Callaway-Sant'Anna, Sun-Abraham, Borusyak-Jaravel-Spiess, Synthetic-DiD; bootstrap SE throughout.
  • Dynamic-panel GMM (dynpanel.*) — Arellano-Bond, Blundell-Bond two-step Windmeijer + Hansen-J + AR(1)/AR(2) + Roodman collapse.
  • High-frequency monetary surprises (hfi.*) — Gertler-Karadi 2015, Nakamura-Steinsson 2018, Jarociński-Karadi 2020.
  • Volatility (volatility.*) — SigmaObject (1:1 port of the MAV MATLAB class with extended decomposition API), BEKK, CCC, HAR-RV, range-based, ARCH-LM / Ljung-Box diagnostics.
  • Nowcasting (nowcast.*) — Kalman-DFM (Doz-Giannone-Reichlin) with ragged-edge handling, Mariano-Murasawa MF-VAR, forecast combinations, probabilistic scoring rules.
  • Growth-at-risk (gar.*) — quantile AR, ABG 2019 skew-t fit, NFCI- style FCI.
  • Cycles / cointegration / factors — Hamilton 2018 trend-cycle filter (cycles), Phillips-Hansen FM-OLS / Stock-Watson DOLS / Phillips-Ouliaris (cointegration_modern), PCA factors + Bai-Ng IC (factor), MIDAS (midas), KORV (2000) system-GMM CES (korv_gmm), synthetic control + placebo inference (synthetic_control).
  • Spectral / wavelet (spectral, wavelet) — Welch PSD / cross- spectrum / coherence (numpy.fft only); MODWT-Haar wavelet variance decomposition.
  • Realized volatility (realized_vol) — realized variance, bipower variation, Corsi HAR-RV.
  • Heterogeneous-agent / VFI (vfi.*) — value-function iteration with EGM, finite-horizon life-cycle, OLG, Krusell-Smith aggregate shocks, Hopenhayn firm entry/exit, Epstein-Zin, permanent types, transition paths, and method-of-moments estimation; numpy reference backend with optional numba / mlx / cupy acceleration. See notebooks/ for a showcase suite.

Narrative econometrics (narrative.*)

Fiscal- / labor- / uncertainty-narrative IV pipeline: canonical NarrativeEvent / NarrativeInstrument schemas, deduplication, keyword and manual scoring backends, panel construction, replication loaders for canonical datasets (Romer-Romer, Mertens-Ravn). LLM scoring backend (narrative.scoring.llm) and HTTP source modules (narrative.sources.*) live as out-of-Pyodide side-channels. Sources include:

  • Beige Book — Fed Beige Book corpus from federalreserve.gov modern
    • FOMC historical pages, with per-canonical-section + per-district parsing (puremacro.narrative.sources.iter_beige_book, puremacro.narrative.indices.bbui).
  • US executive narrative — Economic Report of the President (iter_erp), State of the Union (iter_sotu), and CBO reports (iter_cbo); three matching indices erpui, sotuui, cboui. CBO body fetches transparently fall back to the Wayback Machine when cbo.gov returns a DataDome challenge.
  • EU legislative narrative — EUR-Lex binding acts (iter_eurlex) and EU Parliament plenary verbatim (iter_ep_debates); two trilingual EN/DE/FR indices eurlex_ui and ep_ui. EUR-Lex enumeration via the public Cellar SPARQL endpoint (Wayback-routed per-act fetch due to AWS-WAF on the live site); EP via Wayback CDX with coverage back to Term 7 (2009-07-14).
  • Bluesky archive — central-bank governors + finance ministers via AT Protocol (iter_bluesky_posts, bluesky_ui). Hand-curated 29- handle seed list (BLUESKY_KNOWN_HANDLES); 12 resolved as of 2026-05-25. Multilingual via languages=... connector kwarg; the index defaults to monthly actor-level text aggregation (aggregate_to="actor_month") to mitigate LUI's short-text degradation.
  • Cross-source disagreementconsensus_disagreement computes the cross-sectional mean + std over any subset of narrative indices; CROSS_SOURCE_GROUPS documents thematic subsets.

Connectors hit by WAF / bot-protection (EUR-Lex, EU Parliament, CBO) fall back to the Wayback Machine via the shared puremacro.narrative.sources._wayback helper. Coverage is constrained by what Wayback has snapshotted.

Data pipelines (newly absorbed; see ARCHITECTURE.md)

  • Fetchers (fetch.*) — FRED / ALFRED (real-time vintages), SDMX-CSV (OECD, Eurostat, ECB, IMF SDMX-Central), EPU / GPR / WUI / JLN / Fernald, OECD-MEI / QNA / Energy / FX, ILOSTAT, Yahoo, WB pink sheet, plus per-state FRED loaders for the US subnational track.
  • Panel builders (build_panel, build_subnational_panel) — single entry points that materialise quarterly / monthly cross-country and US-state panels from the fetchers, with regime tagging, SA (X-13 / STL fallback), and a derived GARCH-σ pipeline.
  • Instruments (instruments.*) — instrument registry + composition + external loaders (FRED API key path); backbone of the LP-IV machinery.
  • Bartik / shift-share (bartik.*) — shares, sensitivities, Rotemberg weights, county-level EPU exposure.
  • Misc data utilities — EU-KLEMS 2023 loader (klems), BIS NEER aggregator (bis_neer), G9 homogeneous-vintage splice (long_panel), Gollin labor share (labor_share), real-time vintages (vintages), seasonal adjustment (sa).
  • Labor flows — 3-state E/U/N transitions from BLS CPS aggregates (labor_flows) and 4-state F/I/U/N transitions from ENOE microdata for Mexico (labor_flows_enoe).

Teaching artefacts

teaching.* is a research / teaching side-channel that intentionally wraps statsmodels / linearmodels / arch so notebooks can compare puremacro's pure-numpy estimators against the canonical packages. Not covered by the Pyodide promise.

Installation

Local (development)

From the puremacro/ package directory (the one containing this README.md and pyproject.toml):

pip install -e .

To run the dev parity tests, install the optional dev deps too:

pip install -e '.[dev]'

To use the narrative.sources PDF body extractor:

pip install -e '.[narrative]'

Other optional extras: [backend] (numba + Apple-Silicon mlx), [cuda] (NVIDIA cupy), [data] (yfinance / fredapi / xlrd data fetchers), [llm] (Anthropic-backed narrative scoring), [embeddings] (sentence-transformers narrative scoring), [notebooks] (jupytext notebook build).

For connectors that want opt-in on-disk caching + per-host throttling, the variants safe_get_bytes_cached and safe_get_text_cached apply a SHA-256-keyed cache at ~/.cache/puremacro/http/. Set PUREMACRO_HTTP_NO_CACHE=1 to bypass.

juno.sh / iPad

Upload the puremacro/ directory to your juno.sh workspace, then in a notebook cell:

%pip install ./puremacro

Run the LLM features for free (local models)

The narrative LLM features (score_llm, llm_prob_kernel) run on a local model — no API key, no paid API, $0. Everything else in puremacro is already free; this closes the last paid gap.

Install an engine once (any one):

pip install "puremacro[local-llm]"     # MLX (Apple Silicon) + llama.cpp (any OS)
# or install Ollama (https://ollama.com) — no Python deps — then:  ollama pull qwen2.5:3b

Then swap in a local backend (same signatures as the paid backends):

from puremacro.narrative.scoring import score_llm, LocalBackend
events = score_llm(records, backend=LocalBackend("qwen2.5-3b-instruct", engine="auto"))

from puremacro.narrative.indices import llm_prob_kernel, LocalProvider
idx = llm_prob_kernel(records, provider=LocalProvider("qwen2.5-3b-instruct"),
                      category="economic uncertainty")

engine="auto" picks the best installed engine (Apple GPU via MLX → llama.cpp → a running Ollama server; for LM Studio / vLLM / any OpenAI-compatible server, pass engine="openai" with base_url=). Models: qwen2.5-3b-instruct (default), gemma2-2b (Google), llama3.2-3b (Meta), phi3.5 (Microsoft), or any raw engine model id. See puremacro/examples/narrative_local_llm.py and the local_llm_uncertainty notebook. (Local inference is desktop-only — it does not run inside the browser playground.)

Pyodide compatibility

The runtime promise is: only numpy + scipy + pandas + matplotlib ever get imported by code that ships in the wheel. statsmodels, linearmodels, arch, pypdf, and the network fetchers are all either dev-only / extras-only or lazy-imported behind a guard.

The regression test is tests/test_pyodide_compat.py — it walks every shippable submodule and asserts no forbidden module lands in sys.modules. If you add a new optional dependency, follow the existing lazy-import pattern (see narrative.scoring.llm or fetch._seasonal._x13_arima_analysis for the canonical examples).

Quickstart

First 5 minutes — offline, no data files, no API key. The quickest check that your install works (a sign-restricted SVAR on a synthetic 3-variable DGP; no network, no data, fixed seed):

python -m puremacro.examples.sign_restrictions_uhlig

Or, in Python, on a synthetic system you build in three lines:

import numpy as np
import pandas as pd
import puremacro as pm

# A small synthetic 3-variable system (no data files, no API key).
rng = np.random.default_rng(0)
T = 200
Y = rng.standard_normal((T, 3)).cumsum(0)          # ndarray, shape (T, 3)

# Cholesky-identified SVAR with 90% residual-bootstrap bands.
from puremacro.var.identify.cholesky import cholesky_svar
res = cholesky_svar(Y, p=2, horizon=20, n_boot=500, ci=0.9)
print("IRF array shape (H+1, n, n):", res.irf_point.shape)   # (21, 3, 3)
# also available: res.irf_lower, res.irf_upper, res.n_boot, res.n_fail

# Single-country LP-HAC: response of y to a synthetic shock.
panel = pd.DataFrame({"y": Y[:, 0], "shock": rng.standard_normal(T)})
from puremacro.lp.jorda import lp_hac
irf = lp_hac(panel, y="y", x="shock", horizons=range(0, 21), n_lags=2)
print(irf.head())                       # columns: h, beta, se, t, lo, hi

Optional API keys are resolved centrally (none are needed for the synthetic examples above):

from puremacro import credentials
credentials.status()                  # see what's configured (no values leaked)
# credentials.require("fred")         # raises with a signup URL if the key is missing

End-to-end replications of canonical papers live under puremacro/examples/ — Bloom 2009 (bloom2009.py), Mertens-Ravn narrative SVAR (svariv_mertens_ravn.py), Romer-Romer monetary narrative (romer_romer_*.py), and ~60 more. Most (like the Uhlig example above) are fully synthetic and need no data or keys; a few read bundled or fetched data.

Documentation

  • ARCHITECTURE.md — module map, stability tiers, Pyodide contract, result-object standard. Read this first if you're contributing or trying to find where something lives.
  • CHANGELOG.md — per-release diff, including internal-only refactors.
  • Per-function docstrings are the canonical reference; the module docstring of each subpackage explains its scope.

Conventions

  • Public API per subpackage is curated via __init__.py::__all__; the top-level puremacro package only re-exports __version__.
  • Frozen-dataclass result objects for any estimator returning 3+ fields or non-trivial diagnostics (see ARCHITECTURE.md § Result- object standard). DataFrames returning named columns are exempt.
  • Diagnostic errors over silent garbage — singular X'X, non-PD Σ, BK violations, and ill-conditioned bootstrap draws raise or warn with a message naming the calling function and the likely cause.

Status

Pre-1.0; APIs rename freely with consumers updated in the same commit. Single-author research package. CI workflows (tests, Pyodide gate, mypy, reference drift-guard, playground deploy, PyPI release) are defined in .github/workflows/ and activate once the package is split into its own repository; while it lives inside the monorepo they are inert, so run pytest (or python tools/release_check.py) locally before tagging a release.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

puremacro-0.93.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

puremacro-0.93.0-py3-none-any.whl (1.4 MB view details)

Uploaded Python 3

File details

Details for the file puremacro-0.93.0.tar.gz.

File metadata

  • Download URL: puremacro-0.93.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for puremacro-0.93.0.tar.gz
Algorithm Hash digest
SHA256 342fca881aacc784965f7390d9e55faf3857c2f7b2e71c84d9380469dc6cced7
MD5 a19e51b9c0dc0b46ee29c38747713815
BLAKE2b-256 672c7d2164d19f668d626224ab09cbed5deb39a68808e462b7f99d2d1a562fdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for puremacro-0.93.0.tar.gz:

Publisher: release.yml on jalonso1979/puremacro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file puremacro-0.93.0-py3-none-any.whl.

File metadata

  • Download URL: puremacro-0.93.0-py3-none-any.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for puremacro-0.93.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dda93b6a754e72eb7966de9adfd9b6f255d5f1132ff977e4851f51527cad9478
MD5 ad903e88dd70763208b7c303b5316e92
BLAKE2b-256 9ebdbd5ae5f950451db59b399d1bf391d929e1a9000a2ad5915e1fc1a51ff80e

See more details on using hashes here.

Provenance

The following attestation bundles were made for puremacro-0.93.0-py3-none-any.whl:

Publisher: release.yml on jalonso1979/puremacro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.3.1

2 files

2.2.0

2 files

2.1.0

2 files

2.0.1

2 files

2.0.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.0

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.95.0

2 files

0.94.0

2 files

This release

0.93.0 This release

2 files

0.92.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page