model 03 — Federal Reserve macroeconomic model · frb-us · US · hosted

Test US monetary and fiscal shocks.

Trace how a funds-rate or fiscal shock affects US output, inflation, and unemployment quarter by quarter using the April 2026 baseline.

methodology

Parse, add-factor, solve by Newton.

The five stages of the frb-us pipeline, from the Board's published artefacts to an impulse response. Each step's formal structure follows its narrative; equations render locally (no CDN). The full derivations are in the working paper.

1

Parse the Board's model file

One source of truth: the Board's model.xml model.xml variables, equations, coefficients, endo/exo public domain parse normalise rewrite EViews lags, substitute coefficients, flip to residual form 284 equations behavioural + identity, each with aerr + trac VAR ("standard") set nothing re-typed or re-specified — the XML declares the model's semantics
click to expand

The published artefacts

The Federal Reserve Board publishes FRB/US whole: the equation system as model.xml, the LONGBASE historical and projection database, the documentation, and a reference Python solver, pyfrbus — all in the public domain.

One source of truth

The parse stage reads model.xml directly: variables, equations, per-equation coefficients, and the endogenous / exogenous classification for the VAR-expectations ("standard") equation set. Nothing is re-typed or re-specified — the XML file is the single source of truth for the model's semantics. That yields 284 endogenous variables and their equations, classified into behavioural and identity blocks exactly as the Board's file declares them.

Residual form

Each equation is normalised — EViews lag and difference notation rewritten, coefficient references substituted by their published values — flipped to residual form \(F_i(\cdot) = 0\), and augmented with its additive shock term (_aerr) and a tracking residual (_trac), so each equation solves \(F_i + \mathrm{aerr}_i + \mathrm{trac}_i = 0\).

2

Load LONGBASE, then add-factor

Add-factoring pins the baseline LONGBASE.TXT April 2026 vintage history + projection quarterly PeriodIndex init_trac set each equation's tracking residual, per quarter solve = LONGBASE reproduced to machine precision shocks are then imposed on top of the add-factored baseline
click to expand

The baseline database

The load stage brings LONGBASE.TXT — the April 2026 vintage — into a pandas frame on a quarterly PeriodIndex. This is the Board's own historical and projection database, and it conditions everything that follows: every simulation is read as a deviation from this baseline.

Tracking residuals (init_trac)

init_trac sets each equation's tracking residual so that solving the model reproduces the database exactly. This is the Fed's own device, used the Fed's own way — the direct analogue of the OBR emulator's anchoring. Shocks are then imposed on top of the add-factored baseline.

3

Solve by damped Newton

Simultaneous within the quarter, recursive across quarters one quarter: damped Newton analytic sparse Jacobian (sympy) sparse LU solve (SuperLU) damp: halve the step to stay in-domain check convergence, else iterate Newton iteration converged t t+1 t+2 each quarter starts from the previous solution
click to expand

Period by period

Under VAR expectations every expectations term depends only on current and lagged observables, so the model is simultaneous within each quarter but recursive across quarters. The solver therefore works period by period, starting each quarter from the previous quarter's solution.

Analytic sparse Jacobian

Each quarter, a damped Newton iteration solves the full simultaneous system with an analytic sparse Jacobian — differentiated symbolically with sympy, factorised with scipy.sparse.linalg.splu. Damping backtracks the step only to stay inside the domain of definition (no logs of non-positive arguments, no NaNs). Defaults are \(\mathrm{xtol} = 10^{-8}\), \(\mathrm{rtol} = 5\times 10^{-4}\).

One block, not many

The reference implementation decomposes each period into recursive and simultaneous blocks; this one solves the whole period at once. Both approaches solve the same \(F(x) = 0\), which is why the two agree to solver tolerance rather than to some negotiated threshold — see how far to trust it.

4

Policy rules

0/1 switches select which rule sets the funds rate inertial_taylor default, LONGBASE rule shock: rffintay_aerr taylor same bracket, no inertia shock: rfftay_aerr fixed_funds_rate baseline path held no monetary offset funds rate rff — one rule active per run each rule reads its own add-error; the wrong one is rejected, not zeroed
click to expand

A modular funds rate

Monetary policy is modular: exogenous 0/1 switches in the model file select which rule sets the funds rate. Three are exposed through frbus_shock: inertial_taylor (the default, the LONGBASE rule and the one the validation numbers use), taylor, and fixed_funds_rate, which holds the funds rate on its baseline path so there is no endogenous monetary offset.

The rule choice is the exercise

The choice is usually the economic point of the exercise. Run the same government-purchases shock (1% of GDP) under both settings and the multiplier moves from 0.72 in year one under the inertial Taylor rule to 0.99 in year two with the funds rate fixed — and the price-level response is larger still without the monetary offset. The overview places both inside the published cross-model ranges.

Each rule reads its own error term

Each policy rule reads its own add-error, so rffintay_aerr works only under inertial_taylor; asking for it under taylor is rejected with a pointer to rfftay_aerr rather than silently returning all-zero responses — one of the two traps the code page walks through before you shock anything.

5

Shock and compare

Impulse response = shocked path minus baseline path baseline solve add-factored LONGBASE shocked solve aerr += shock, same window difference sim − baseline 100bp IRF GDP −0.55% lur +0.26pp picxfe −0.034pp shock units are per-lever — pp for the policy-rate error, log points of growth for spending
click to expand

Shocks are error-term additions

A shock is an addition to an equation's error term — rffintay_aerr for the policy rule, for instance. Solve shocked and baseline paths over the same window and read the difference. Shock sizes are per-lever and not interchangeable — percentage points for the policy-rate error, log points of quarterly growth for the spending levers; the code page spells out the units trap.

What comes out

The headline 100bp tightening lands where the Board's documentation says it should: the funds rate up 1.000pp on impact, real GDP bottoming at −0.55% in 2027Q4, unemployment peaking +0.26pp, core inflation down 0.034pp at its trough. The same four numbers are the simulation-properties row of the validation tables.

What stays out of scope

The pipeline covers the VAR-expectations model only: the model-consistent-expectations variants, forward guidance, and the reference implementation's mcontrol trajectory-targeting routine are not implemented, and there is no bridge from a PolicyEngine reform to model variables — see the known limits.