model 02 — OBR macroeconometric model · obr-macro · UK · hosted
UK fiscal reform, quarter by quarter.
Run selected UK tax and spending scenarios and trace GDP, consumption, and investment over 3–5 years against the March 2026 EFO baseline. Borrowing is not yet returned by the PolicyEngine Macro adapter.
How a reform reaches it, what it is, what it can answer.
Three things to know before you run it: how a PolicyEngine reform gets into the model, what the model actually is, and what it will and will not tell you. The panel alongside carries the figures each step refers to.
With the microsimulation
Microsimulation supplies the direct cost; this model returns the feedback.
The combination
score_reform(country="uk", reform=..., model="obr") runs PolicyEngine's static costing for each year of the window, then hands this model the bill — the OBR's own workflow: static costing in, second-round effects out.
The mechanism
Each year's costing enters as HHDI_ADDFACTOR: minus the annual £bn, spread flat across its four quarters (×1000 ÷ 4 → £m/qtr), held as an add-factor on household disposable income. The emulator then solves income → consumption → GDP quarter by quarter against the anchored March 2026 baseline.
pe-macro score --country uk \
--reform '{"gov.hmrc.income_tax.rates.uk[0].rate":0.21}' \
--model obrTCPRO lever converges only slowly (a 12-quarter run is ~40% of its plateau), so the bridge
refuses it rather than guessing. UK only: no US bridge exists, so a
US reform is scored statically.
Or drive it directly, without the microsimulation
The bridge is one way in, not the only one. You can shock the
model's own exogenous variables directly, in model units, with no
PolicyEngine reform involved — useful when what you have is a
macro assumption rather than a statutory change, or when the reform
is not household-borne. list_reform_variables returns
the levers and the caveat attached to each.
# £5bn/year more government consumption, 12 quarters
pe-macro obr-shock --var CGG --shock 1250 --periods 12
# or in Python, with no PolicyEngine dependency at all
from obr_macro import run_reform
df = run_reform(name="spending", var="CGG", shock=1250, periods=12)
Levers: CGG (government consumption, £m/qtr),
TCPRO (corporation tax rate), CGIPS
(public investment — dead, do not use),
HHDI_ADDFACTOR (a costing you produced yourself), and
the R / RX monetary and exchange-rate
assumptions. Read each one's caveat first: only two of them carry
behaviour, and two do not work at
all.
every join in the suite → this join on the landing page →
HHDI_ADDFACTOR — household disposable income, £m/qtrWhat it is
An open Python implementation of the OBR's published equations.
The published listing, made runnable
The OBR's model is a computational representation of the UK National Accounts — built by HM Treasury in 1970, jointly maintained by the OBR and the Treasury since 2010. The OBR publishes its full equation listing, but as EViews source few can run. This project transpiles it to Python and solves it: 372 published equations in 17 thematic groups over 636 variables — 383 solved by the model (roughly 29 econometrically estimated, 216 identities, 138 calibrated or technical) and 253 exogenous inputs, the judgements and assumptions you get to change.
Where it sits
It is a structural macroeconometric model in the HM Treasury / Cowles-Commission tradition: where the OLG model derives behaviour from optimising households and firms, this one reproduces the estimated relationships the official forecaster actually relies on.
What it can answer
Second-round effects on a static costing.
The half of the workflow it does
The emulator does the second half of the official workflow: microsimulation supplies the direct Exchequer effect, the macro model the economy-wide feedback. A static-costing bridge wires PolicyEngine's microsimulation into the emulator so a statutory reform can be scored end to end.
Worked example
1p on the basic rate of income tax from April 2026: direct yield £6.46bn in 2026, £7.38bn by 2030. The second round is a GDP fall that builds to roughly 0.35× the revenue raised by the end of the five-year window — close to the OBR's published 0.3 for income tax and NICs. Read the direction and the scale, not the individual quarters: no quarter of the solve converges to tolerance, and the first year flips sign under a shock that is flat across it. Full walkthrough → /score.
CGG) lands straight in the GDP
identity with no behavioural equation responding, giving a multiplier
of exactly 1.0000, flat, against the OBR's 0.6 —
and capital spending (CGIPS) is worse still: it does not
transmit at all. Total fixed investment moves exactly zero, and
business investment moves wrong-signed and
non-proportionally — quadrupling the shock
changes the response by under a factor of two, so there is no
multiplier to quote, against the OBR's published 1.0. The
validation page lists the
full set of known limits.