From 93e241f8c0e75b8a3f1b744ea3abd31bf316be24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:02:17 +0000 Subject: [PATCH 01/10] Update the economic assumptions to the October 2026 EFO Run the importer on the October 2026 economy and receipts tables for 2025-2031, so the revised 2025 outturn and the new 2031 forecast are in, and re-derive the series it does not cover from the same tables: per-capita GDP and mixed income, non-labour and household interest income, council tax, social and private rents, the AHC deflator, Ofwat water bills, road fuel volumes and their litre proxies, the fuel duty RPI path and the private school VAT share. Join RPI, CPIH and earnings to their long-run rates in equal steps from 2032. Population stays on the March 2026 long-term determinants until the October edition is published. The October receipts workbook titles sheet 4.8 "43.8", so the importer now takes the table number from the sheet name when they disagree. A minimal fixture of that workbook reproduces the committed receipts series. Co-Authored-By: Claude Opus 5.5 --- .../obr-october-2026-efo-2711.changed.md | 1 + .../forecast_gap/awe_total_pay_may_july.yaml | 21 +- .../forecast_gap/cpi_september.yaml | 27 +- .../gov/economic_assumptions/yoy_growth.yaml | 821 ++++++++++-------- .../gov/hmrc/fuel_duty/petrol_and_diesel.yaml | 40 +- .../vat/private_school_share_of_receipts.yaml | 28 +- .../tests/fixtures/obr_receipts/README.md | 21 +- .../obr_efo_october_2026_receipts.xlsx | Bin 0 -> 44075 bytes .../gov/hmrc/stamp_duty/corporate_sdlt.yaml | 45 +- .../scottish_carer_supplement.yaml | 10 +- policyengine_uk/tests/test_ahc_deflator.py | 6 +- .../test_corporate_receipts_statistics.py | 38 +- .../tests/test_council_tax_uprating.py | 37 +- .../tests/test_import_obr_forecasts.py | 87 +- .../tests/test_population_vintage.py | 42 +- .../tests/test_private_school_vat_receipts.py | 16 +- policyengine_uk/tests/test_rent_uprating.py | 4 +- .../tests/test_september_cpi_uprating.py | 14 +- .../test_triple_lock_statutory_inputs.py | 68 +- .../tests/test_water_bills_growth.py | 4 +- policyengine_uk/utils/create_ahc_deflator.py | 2 +- policyengine_uk/utils/import_obr_forecasts.py | 6 + 22 files changed, 721 insertions(+), 617 deletions(-) create mode 100644 changelog.d/obr-october-2026-efo-2711.changed.md create mode 100644 policyengine_uk/tests/fixtures/obr_receipts/obr_efo_october_2026_receipts.xlsx diff --git a/changelog.d/obr-october-2026-efo-2711.changed.md b/changelog.d/obr-october-2026-efo-2711.changed.md new file mode 100644 index 0000000000..16a73c61b5 --- /dev/null +++ b/changelog.d/obr-october-2026-efo-2711.changed.md @@ -0,0 +1 @@ +Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. diff --git a/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/awe_total_pay_may_july.yaml b/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/awe_total_pay_may_july.yaml index 126d1ffcaf..5657069954 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/awe_total_pay_may_july.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/awe_total_pay_may_july.yaml @@ -2,15 +2,16 @@ description: Forecast difference between May-July earnings growth and calendar-y values: # No gap applies to published years. 2010-07-01: 0 - # OBR EFO March 2026: Q2 average earnings growth on a year earlier (economy Table 1.6) minus calendar-year growth in yoy_growth.yaml. - 2025-07-01: 0.00259 - 2026-07-01: 0.00274 - 2027-07-01: 0.00027 - 2028-07-01: -0.00021 - 2029-07-01: -0.00015 - 2030-07-01: -0.00011 + # OBR EFO October 2026: Q2 average earnings growth on a year earlier (economy Table 1.6) minus calendar-year growth in yoy_growth.yaml. + 2025-07-01: -0.00204 + 2026-07-01: 0.00439 + 2027-07-01: 0.00306 + 2028-07-01: -0.00025 + 2029-07-01: -0.00014 + 2030-07-01: -0.00031 + 2031-07-01: 0.00014 # After the EFO horizon: no gap, so the forecast is calendar-year growth. - 2031-07-01: 0 + 2032-07-01: 0 metadata: unit: /1 label: May-July earnings forecast gap to calendar-year earnings @@ -28,5 +29,5 @@ metadata: gap is zero after the EFO horizon, where the May-July forecast falls back to calendar-year growth. reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.6) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.6) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ diff --git a/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/cpi_september.yaml b/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/cpi_september.yaml index 37f30d0198..de12b3b71e 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/cpi_september.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/statutory_uprating_inputs/forecast_gap/cpi_september.yaml @@ -2,16 +2,17 @@ description: Forecast difference between September CPI inflation and calendar-ye values: # No gap applies to published years. 2010-09-01: 0 - # OBR EFO March 2026: September CPI (receipts Table 3.19) minus calendar-year CPI growth in yoy_growth.yaml. - 2025-09-01: 0.00411 - 2026-09-01: -0.00184 - 2027-09-01: 0.00072 - 2028-09-01: 0.0003 - 2029-09-01: 0.00048 - # OBR EFO March 2026: Q3 CPI 12-month rate (economy Table 1.7) minus calendar-year growth in yoy_growth.yaml. - 2030-09-01: 0 - # After the EFO horizon: no gap, so the forecast is calendar-year growth. + # OBR EFO October 2026: September CPI (receipts Table 4.19) minus calendar-year CPI growth in yoy_growth.yaml. + 2025-09-01: 0.00441 + 2026-09-01: 0.00001 + 2027-09-01: 0.0002 + 2028-09-01: -0.00058 + 2029-09-01: 0.00073 + 2030-09-01: 0.00005 + # OBR EFO October 2026: Q3 CPI 12-month rate (economy Table 1.7) minus calendar-year growth in yoy_growth.yaml. 2031-09-01: 0 + # After the EFO horizon: no gap, so the forecast is calendar-year growth. + 2032-09-01: 0 metadata: unit: /1 label: September CPI forecast gap to calendar-year CPI @@ -27,7 +28,7 @@ metadata: yoy_growth.yaml). The gap is zero after the EFO horizon, where the September forecast falls back to calendar-year CPI. reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.19) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.19) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index 85285ba2a9..f599d62fdb 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -1,15 +1,16 @@ # OBR Economic Projections # # Data sources by horizon: -# - 2009-2024: OBR outturn data from detailed forecast tables. -# - 2025-2030: OBR forecast from the latest Economic and Fiscal Outlook -# (EFO, March 2026). Values come from the EFO economy supplementary -# tables — RPI/CPI/CPIH from Table 1.7, average earnings from Table 1.6. +# - 2009-2025: OBR outturn data from detailed forecast tables. 2025 is the +# outturn in the latest Economic and Fiscal Outlook (EFO, October 2026). +# - 2026-2031: OBR forecast from the October 2026 EFO. Values come from the +# EFO economy supplementary tables — RPI/CPI/CPIH from Table 1.7, average +# earnings from Table 1.6. # Exceptions are documented on each series: mortgage_interest 2030 is # carried over from the November 2025 EFO, consumer_price_index_ahc is # derived rather than published by the OBR, and social_rent forecasts # apply the England social rent cap. -# - 2031-2073: OBR long-run equilibrium assumptions, taken from the OBR +# - 2032-2073: OBR long-run equilibrium assumptions, taken from the OBR # Fiscal Risks and Sustainability report and the long-run RPI-CPI wedge # methodology. Steady-state values: # * consumer_price_index: 2.00% (Bank of England target) @@ -19,11 +20,12 @@ # CPIH methodology from Feb 2030 per ONS) # * average_earnings: 3.83% (productivity growth + CPI) # -# How the 2031+ series are constructed: -# - CPI hits its 2% target on 2031-01-01 and is held flat. -# - RPI, CPIH and average earnings use the checked-in convergence rates; -# their annual steps are not uniform. RPI/CPIH reach steady state in 2035, -# earnings in 2036; the rates then hold flat through 2073-01-01. +# How the 2032+ series are constructed: +# - CPI is at its 2% target in the EFO's 2031 forecast and is held flat. +# - RPI and CPIH move in equal steps, rounded to 4 decimals, from the EFO's +# 2031 forecast (2.18%) to 2.39% in 2035. Average earnings move the same +# way from the EFO's 2031 forecast (2.60%) to 3.83% in 2036. The rates +# then hold flat through 2073-01-01. # - These intermediate rates are model assumptions beyond the EFO horizon. # Review them when a new EFO is released. The helper module below creates # cumulative indices from these rates, not the convergence paths themselves: @@ -47,7 +49,7 @@ obr: rpi: description: Retail price index year-on-year growth. values: - # Outturn (2009-2024) + # Outturn (2009-2025) 2009-01-01: 0.018 2010-01-01: 0.008 2011-01-01: 0.016 @@ -64,18 +66,18 @@ obr: 2022-01-01: 0.1158 2023-01-01: 0.0969 2024-01-01: 0.0359 - # Forecast (2025-2030) - 2025-01-01: 0.041 - 2026-01-01: 0.031 - 2027-01-01: 0.030 - 2028-01-01: 0.028 - 2029-01-01: 0.029 - 2030-01-01: 0.023 - # Long-run assumptions (2031+) - 2031-01-01: 0.0230 - 2032-01-01: 0.0237 - 2033-01-01: 0.0238 - 2034-01-01: 0.0238 + 2025-01-01: 0.0413 + # Forecast (2026-2031) + 2026-01-01: 0.0359 + 2027-01-01: 0.0432 + 2028-01-01: 0.0303 + 2029-01-01: 0.0298 + 2030-01-01: 0.0229 + 2031-01-01: 0.0218 + # Long-run assumptions (2032+) + 2032-01-01: 0.0223 + 2033-01-01: 0.0229 + 2034-01-01: 0.0234 2035-01-01: 0.0239 2036-01-01: 0.0239 2037-01-01: 0.0239 @@ -119,14 +121,14 @@ obr: unit: /1 label: Retail price index growth reference: - - title: OBR EFO March 2026 (Table A.1) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR long-run RPI-CPI wedge methodology (2031+ values derived from this) + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR long-run RPI-CPI wedge methodology (2032+ values derived from this) href: https://obr.uk/box/the-long-run-difference-between-rpi-and-cpi-inflation/ average_earnings: description: Average earnings year-on-year growth. values: - # Outturn (2009-2024) + # Outturn (2009-2025) 2009-01-01: 0.018 2010-01-01: 0.008 2011-01-01: 0.016 @@ -143,19 +145,19 @@ obr: 2022-01-01: 0.0614 2023-01-01: 0.0622 2024-01-01: 0.051 - # Forecast (2025-2030) - 2025-01-01: 0.053 - 2026-01-01: 0.034 - 2027-01-01: 0.024 - 2028-01-01: 0.021 - 2029-01-01: 0.022 - 2030-01-01: 0.024 - # Long-run assumptions (2031+) - 2031-01-01: 0.0332 - 2032-01-01: 0.0371 - 2033-01-01: 0.0374 - 2034-01-01: 0.0377 - 2035-01-01: 0.0380 + 2025-01-01: 0.0412 + # Forecast (2026-2031) + 2026-01-01: 0.0373 + 2027-01-01: 0.0299 + 2028-01-01: 0.0215 + 2029-01-01: 0.0227 + 2030-01-01: 0.0249 + 2031-01-01: 0.0260 + # Long-run assumptions (2032+) + 2032-01-01: 0.0285 + 2033-01-01: 0.0309 + 2034-01-01: 0.0334 + 2035-01-01: 0.0358 2036-01-01: 0.0383 2037-01-01: 0.0383 2038-01-01: 0.0383 @@ -198,15 +200,15 @@ obr: unit: /1 label: Average earnings growth reference: - - title: OBR EFO March 2026 (Table A.1) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR long-run economic methodology (2031+ values derived from this, unchanged from November 2025) + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.6) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR long-run economic methodology (the 3.83% rate from 2036, unchanged from November 2025) href: https://obr.uk/forecasts-in-depth/the-economy-forecast/potential-output-and-the-output-gap/ consumer_price_index: description: Consumer price index year-on-year growth. values: - # Outturn (2009-2024) + # Outturn (2009-2025) 2009-01-01: 0.022 2010-01-01: 0.035 2011-01-01: 0.043 @@ -223,15 +225,15 @@ obr: 2022-01-01: 0.0907 2023-01-01: 0.0730 2024-01-01: 0.025 - # Forecast (2025-2030) - 2025-01-01: 0.034 - 2026-01-01: 0.023 - 2027-01-01: 0.020 - 2028-01-01: 0.020 - 2029-01-01: 0.020 - 2030-01-01: 0.020 - # Long-run assumptions (2031+): Bank of England 2% target + 2025-01-01: 0.0337 + # Forecast (2026-2031) + 2026-01-01: 0.0311 + 2027-01-01: 0.0342 + 2028-01-01: 0.0210 + 2029-01-01: 0.0210 + 2030-01-01: 0.0201 2031-01-01: 0.0200 + # Long-run assumptions (2032+): Bank of England 2% target 2032-01-01: 0.0200 2033-01-01: 0.0200 2034-01-01: 0.0200 @@ -278,29 +280,38 @@ obr: unit: /1 label: Consumer price index growth reference: - - title: OBR EFO March 2026 (Table A.1) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: Bank of England inflation target (2031+ assumes 2% target) + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: Bank of England inflation target (2032+ assumes 2% target) href: https://www.bankofengland.co.uk/monetary-policy/inflation road_fuel_volume: description: UK road-fuel petrol and diesel clearances year-on-year growth. values: + # Fiscal year t-(t+1), stored at t-01-01. # HMRC Hydrocarbon Oils Bulletin Table 2a: petrol plus diesel clearances. + # 2025-26 is the provisional outturn in the June 2026 bulletin. 2021-01-01: 0.24418262350052777 2022-01-01: 0.06256523245735934 2023-01-01: -0.005727524527185501 2024-01-01: -0.0012858149728238732 - # OBR March 2026 fuel-duty receipts forecast, net of non-road fuel - # receipts, divided by fiscal-year average petrol/diesel duty rates. - 2025-01-01: -0.019907019324541197 - 2026-01-01: -0.01438967286340953 - 2027-01-01: -0.02416859220902523 - 2028-01-01: -0.02700230120226388 - 2029-01-01: -0.037280775640417985 - 2030-01-01: -0.052236910509542045 - # Hold the final OBR forecast volume flat after 2030-31. - 2031-01-01: 0.0 + 2025-01-01: -0.013032417508512473 + # OBR October 2026 fuel-duty receipts forecast (receipts Table 4.8), + # net of non-road fuel receipts (OBR April 2024 vehicle-type release, + # "Other fuels", held at GBP 0.3bn after 2028-29), divided by the + # fiscal-year average petrol/diesel duty rate on the Budget 2026 path + # behind that forecast: 52.95p to 30 June 2027, 60.59p from 1 July + # 2027, then raised each 1 April by Q1 RPI growth (OBR economy + # Table 1.7), the convention that gives 60.59p. That path is policy, + # not the current law in gov.hmrc.fuel_duty.petrol_and_diesel. The + # derivation is policyengine-uk-data's sources/road_fuel_volume.py. + 2026-01-01: -0.02315665811165113 + 2027-01-01: -0.030554808261277322 + 2028-01-01: -0.03089248062672023 + 2029-01-01: -0.03954082422617977 + 2030-01-01: -0.05402149170377035 + 2031-01-01: -0.06452057525352783 + # Hold the final OBR forecast volume flat after 2031-32. 2032-01-01: 0.0 2033-01-01: 0.0 2034-01-01: 0.0 @@ -349,8 +360,8 @@ obr: reference: - title: HMRC Hydrocarbon Oils Bulletin href: https://www.gov.uk/government/statistics/hydrocarbon-oils-bulletin - - title: OBR EFO March 2026 (fuel-duty receipts forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (fuel-duty receipts forecast, receipts Table 4.8; duty path, paragraph 4.29) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: OBR fuel-duty supplementary release, receipts by vehicle type href: https://obr.uk/docs/dlm_uploads/Fuel-duty-supplementary-release_receipts-by-vehicle-type.pdf @@ -361,13 +372,13 @@ obr: 2022-01-01: 0.32048914761975955 2023-01-01: -0.11986709923501582 2024-01-01: -0.05406513567003335 - 2025-01-01: -0.06707986156775403 - 2026-01-01: 0.09664209519298694 - 2027-01-01: -0.026990320280212532 - 2028-01-01: -0.030105962123468832 - 2029-01-01: -0.04054292967950757 - 2030-01-01: -0.055636618682285754 - 2031-01-01: -0.002394253790901746 + 2025-01-01: -0.06053614112047978 + 2026-01-01: 0.08688748446453687 + 2027-01-01: -0.033358069858687056 + 2028-01-01: -0.0339837326821375 + 2029-01-01: -0.04279532013771159 + 2030-01-01: -0.05741479842942443 + 2031-01-01: -0.0667603504125377 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 2034-01-01: -0.0018963968459926317 @@ -416,8 +427,8 @@ obr: reference: - title: HMRC Hydrocarbon Oils Bulletin href: https://www.gov.uk/government/statistics/hydrocarbon-oils-bulletin - - title: OBR EFO March 2026 (fuel-duty receipts forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (fuel-duty receipts forecast, receipts Table 4.8; duty path, paragraph 4.29) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: DESNZ annual average ULSP pump price (household.consumption.fuel.prices.petrol) href: https://www.gov.uk/government/statistical-data-sets/oil-and-petroleum-products-monthly-statistics @@ -428,13 +439,13 @@ obr: 2022-01-01: 0.38539703418341165 2023-01-01: -0.12622295394260497 2024-01-01: -0.07372422161516101 - 2025-01-01: -0.06091804825263625 - 2026-01-01: 0.17519490109106162 - 2027-01-01: -0.026990320280212532 - 2028-01-01: -0.030105962123468832 - 2029-01-01: -0.04054292967950768 - 2030-01-01: -0.055636618682285865 - 2031-01-01: -0.002394253790901746 + 2025-01-01: -0.0543311074029702 + 2026-01-01: 0.16474156463748946 + 2027-01-01: -0.033358069858687056 + 2028-01-01: -0.0339837326821375 + 2029-01-01: -0.04279532013771159 + 2030-01-01: -0.05741479842942432 + 2031-01-01: -0.0667603504125377 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 2034-01-01: -0.0018963968459926317 @@ -483,8 +494,8 @@ obr: reference: - title: HMRC Hydrocarbon Oils Bulletin href: https://www.gov.uk/government/statistics/hydrocarbon-oils-bulletin - - title: OBR EFO March 2026 (fuel-duty receipts forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (fuel-duty receipts forecast, receipts Table 4.8; duty path, paragraph 4.29) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: DESNZ annual average ULSD pump price (household.consumption.fuel.prices.diesel) href: https://www.gov.uk/government/statistical-data-sets/oil-and-petroleum-products-monthly-statistics @@ -497,13 +508,14 @@ obr: 2023-01-01: 0.0826 2024-01-01: 0.0327 2025-01-01: 0.0265 - # Forecast (2026-2030): derived by policyengine_uk/utils/create_ahc_deflator.py + # Forecast (2026-2031): derived by policyengine_uk/utils/create_ahc_deflator.py # from OBR CPI and rent forecasts and Ofwat water bills (see documentation). - 2026-01-01: 0.0217 - 2027-01-01: 0.0187 - 2028-01-01: 0.0194 - 2029-01-01: 0.0193 - 2030-01-01: 0.0191 + 2026-01-01: 0.0304 + 2027-01-01: 0.0341 + 2028-01-01: 0.0200 + 2029-01-01: 0.0202 + 2030-01-01: 0.0193 + 2031-01-01: 0.0189 metadata: unit: /1 label: After housing costs consumer price index growth @@ -523,30 +535,30 @@ obr: reference: - title: ONS ad hoc 3582, CPI series excluding rents, maintenance repairs and water charges, February 2007 to June 2026 href: https://www.ons.gov.uk/economy/inflationandpriceindices/adhocs/3582consumerpriceindicesseriesexcludingrentsmaintenancerepairsandwaterchargesfebruary2007tojune2026 - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7), CPI and actual rents inputs - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7), CPI and actual rents inputs + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: ONS CPI weights href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/consumerpriceinflationupdatingweightsannexatablesw1tow3 cpih: description: Consumer price index including owner occupiers' housing costs year-on-year growth. values: - # Outturn (2022-2024) + # Outturn (2022-2025) 2022-01-01: 0.0792 2023-01-01: 0.0679 2024-01-01: 0.0327 - # Forecast (2025-2030) 2025-01-01: 0.0388 - 2026-01-01: 0.0255 - 2027-01-01: 0.0211 - 2028-01-01: 0.0204 - 2029-01-01: 0.0209 - 2030-01-01: 0.0212 - # Long-run assumptions (2031+): CPI + 0.4pp wedge for housing costs - 2031-01-01: 0.0230 - 2032-01-01: 0.0237 - 2033-01-01: 0.0238 - 2034-01-01: 0.0238 + # Forecast (2026-2031) + 2026-01-01: 0.0324 + 2027-01-01: 0.0330 + 2028-01-01: 0.0214 + 2029-01-01: 0.0217 + 2030-01-01: 0.0214 + 2031-01-01: 0.0218 + # Long-run assumptions (2032+): the same steps as RPI + 2032-01-01: 0.0223 + 2033-01-01: 0.0229 + 2034-01-01: 0.0234 2035-01-01: 0.0239 2036-01-01: 0.0239 2037-01-01: 0.0239 @@ -590,32 +602,33 @@ obr: unit: /1 label: CPIH growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR long-run RPI-CPI wedge methodology (2031+ values derived from this) + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR long-run RPI-CPI wedge methodology (2032+ values derived from this) href: https://obr.uk/box/the-long-run-difference-between-rpi-and-cpi-inflation/ non_labour_income: description: Non-labour income year-on-year growth. values: - # Outturn (2021-2024) + # Outturn (2021-2025) 2021-01-01: 0.0870 2022-01-01: 0.0987 2023-01-01: 0.1215 - 2024-01-01: 0.0492 - # Forecast (2025-2030) from OBR EFO March 2026, Table 1.12 - 2025-01-01: 0.0349 - 2026-01-01: 0.0397 - 2027-01-01: 0.0513 - 2028-01-01: 0.0350 - 2029-01-01: 0.0301 - 2030-01-01: 0.0317 + 2024-01-01: 0.0477 + 2025-01-01: 0.0292 + # Forecast (2026-2031) from OBR EFO October 2026, Table 1.12 + 2026-01-01: 0.0302 + 2027-01-01: 0.0468 + 2028-01-01: 0.0419 + 2029-01-01: 0.0409 + 2030-01-01: 0.0382 + 2031-01-01: 0.0332 metadata: unit: /1 label: Non-labour income growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.12) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.12) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ # Growth in each country's council tax receipts, net of council tax # reduction. Receipts are the Band D level times the tax base (Band D @@ -625,7 +638,9 @@ obr: # (uprate_council_tax, #2067). The fiscal year starting in year t is stored # at t-01-01, as growth over the year before, rounded to 4 decimals. # - # 2025-2030 are OBR's receipts forecasts. 2023 and 2024 are outturns of the + # 2025 is the October 2026 EFO's 2025-26 receipts outturn over the March + # 2026 EFO's 2024-25 outturn, and 2026-2031 are its receipts forecasts + # (Expenditure Table 5.1). 2023 and 2024 are outturns of the # liability behind each country's OBR line, net of council tax reduction, # from the official statistics named below # (policyengine_uk/tests/test_council_tax_uprating.py recomputes them). They @@ -643,19 +658,22 @@ obr: # is £41.2225bn. 2023-01-01: 0.0662 2024-01-01: 0.0647 - # Forecast (2025-2030) from OBR EFO March 2026, Expenditure Table 4.1 + # 2025 (outturn) and 2026-2031 (forecast) from OBR EFO October 2026, Expenditure Table 5.1 2025-01-01: 0.0702 - 2026-01-01: 0.0545 - 2027-01-01: 0.0605 - 2028-01-01: 0.0615 - 2029-01-01: 0.0562 - 2030-01-01: 0.0550 + 2026-01-01: 0.0610 + 2027-01-01: 0.0524 + 2028-01-01: 0.0561 + 2029-01-01: 0.0555 + 2030-01-01: 0.0542 + 2031-01-01: 0.0531 metadata: unit: /1 reference: - title: MHCLG, Council Tax levels set by local authorities in England 2025 to 2026, Table 1 (2023 and 2024) href: https://www.gov.uk/government/statistics/council-tax-levels-set-by-local-authorities-in-england-2025-to-2026 - - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1) + - title: OBR EFO October 2026 (detailed forecast tables, expenditure, Table 5.1) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ scotland: description: Growth in council tax receipts in Scotland. @@ -668,19 +686,22 @@ obr: # year's bills received by 31 March 2025. 2023-01-01: 0.0638 2024-01-01: 0.0236 - # Forecast (2025-2030) from OBR EFO March 2026, Expenditure Table 4.1 - 2025-01-01: 0.0384 - 2026-01-01: 0.0384 - 2027-01-01: 0.0384 - 2028-01-01: 0.0384 - 2029-01-01: 0.0384 - 2030-01-01: 0.0384 + # 2025 (outturn) and 2026-2031 (forecast) from OBR EFO October 2026, Expenditure Table 5.1 + 2025-01-01: 0.0386 + 2026-01-01: 0.0386 + 2027-01-01: 0.0386 + 2028-01-01: 0.0386 + 2029-01-01: 0.0386 + 2030-01-01: 0.0386 + 2031-01-01: 0.0386 metadata: unit: /1 reference: - title: Scottish Government, Council Tax Collection Statistics 2024-25, Figure 1 (2023 and 2024) href: https://www.gov.scot/publications/council-tax-collection-statistics-2024-25/pages/3/ - - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1) + - title: OBR EFO October 2026 (detailed forecast tables, expenditure, Table 5.1) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ wales: description: Growth in council tax receipts in Wales. @@ -693,13 +714,14 @@ obr: # collected in the year. 2023-01-01: 0.0709 2024-01-01: 0.0987 - # Forecast (2025-2030) from OBR EFO March 2026, Expenditure Table 4.1 + # 2025 (outturn) and 2026-2031 (forecast) from OBR EFO October 2026, Expenditure Table 5.1 2025-01-01: 0.0773 - 2026-01-01: 0.0743 - 2027-01-01: 0.0743 - 2028-01-01: 0.0743 - 2029-01-01: 0.0743 - 2030-01-01: 0.0743 + 2026-01-01: 0.0740 + 2027-01-01: 0.0740 + 2028-01-01: 0.0740 + 2029-01-01: 0.0740 + 2030-01-01: 0.0740 + 2031-01-01: 0.0740 metadata: unit: /1 reference: @@ -709,7 +731,9 @@ obr: href: https://www.gov.wales/council-tax-collection-rates-april-2023-march-2024 - title: Welsh Government, Council tax collection rates April 2024 to March 2025 (2024) href: https://www.gov.wales/council-tax-collection-rates-april-2024-march-2025 - - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1) + - title: OBR EFO October 2026 (detailed forecast tables, expenditure, Table 5.1) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ # Receipts used to project the statistics behind corporate incidence. @@ -730,230 +754,240 @@ obr: values: # Outturn (2024-25 over 2023-24) from OBR EFO March 2026 over March 2025, receipts Table 3.7 "SDLT from residential property" 2024-01-01: 0.211202 - # Forecast (2025-2030) from OBR EFO March 2026, receipts Table 3.7 - 2025-01-01: 0.1302 - 2026-01-01: 0.144691 - 2027-01-01: 0.115872 - 2028-01-01: 0.112713 - 2029-01-01: 0.0774 - 2030-01-01: 0.06083 + # Outturn (2025-26 over 2024-25) from OBR EFO October 2026 over March 2026, receipts Table 4.7 (March 2026: Table 3.7) "SDLT from residential property" + 2025-01-01: 0.113145 + # Forecast (2026-2031) from OBR EFO October 2026, receipts Table 4.7 + 2026-01-01: 0.003813 + 2027-01-01: 0.104558 + 2028-01-01: 0.114288 + 2029-01-01: 0.087399 + 2030-01-01: 0.076349 + 2031-01-01: 0.075592 # Beyond the OBR forecast: the average_earnings long-run path above - 2031-01-01: 0.0332 - 2032-01-01: 0.0371 - 2033-01-01: 0.0374 - 2034-01-01: 0.0377 - 2035-01-01: 0.0380 + 2032-01-01: 0.0285 + 2033-01-01: 0.0309 + 2034-01-01: 0.0334 + 2035-01-01: 0.0358 2036-01-01: 0.0383 metadata: unit: /1 label: Residential SDLT receipts growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.7) + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.7; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR EFO March 2025 (detailed forecast tables, receipts, Table 3.7; 2023-24 outturn) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ non_residential: description: Growth in stamp duty land tax receipts from non-residential property (England and Northern Ireland). values: # Outturn (2024-25 over 2023-24) from OBR EFO March 2026 over March 2025, receipts Table 3.7 "SDLT from non-residential property" 2024-01-01: 0.151067 - # Forecast (2025-2030) from OBR EFO March 2026, receipts Table 3.7 - 2025-01-01: 0.048515 - 2026-01-01: 0.284686 - 2027-01-01: 0.128684 - 2028-01-01: 0.107357 - 2029-01-01: 0.107128 - 2030-01-01: 0.087492 + # Outturn (2025-26 over 2024-25) from OBR EFO October 2026 over March 2026, receipts Table 4.7 (March 2026: Table 3.7) "SDLT from non-residential property" + 2025-01-01: 0.028474 + # Forecast (2026-2031) from OBR EFO October 2026, receipts Table 4.7 + 2026-01-01: -0.045915 + 2027-01-01: 0.180481 + 2028-01-01: 0.15006 + 2029-01-01: 0.043996 + 2030-01-01: 0.088605 + 2031-01-01: 0.078972 # Beyond the OBR forecast: the average_earnings long-run path above - 2031-01-01: 0.0332 - 2032-01-01: 0.0371 - 2033-01-01: 0.0374 - 2034-01-01: 0.0377 - 2035-01-01: 0.0380 + 2032-01-01: 0.0285 + 2033-01-01: 0.0309 + 2034-01-01: 0.0334 + 2035-01-01: 0.0358 2036-01-01: 0.0383 metadata: unit: /1 label: Non-residential SDLT receipts growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.7) + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.7; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR EFO March 2025 (detailed forecast tables, receipts, Table 3.7; 2023-24 outturn) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ business_rates: great_britain: description: Growth in business rates receipts in England, Scotland and Wales (the OBR "Business rates" line, cash basis). values: # Outturn (2024-25 over 2023-24) from OBR EFO March 2026 over March 2025, receipts Table 3.8 (March 2025: Table 3.9) "Business rates" 2024-01-01: 0.093818 - # Forecast (2025-2030) from OBR EFO March 2026, receipts Table 3.8 - 2025-01-01: 0.051739 - 2026-01-01: 0.09872 - 2027-01-01: 0.022113 - 2028-01-01: 0.022775 - 2029-01-01: 0.084558 - 2030-01-01: 0.00104 + # Outturn (2025-26 over 2024-25) from OBR EFO October 2026 over March 2026, receipts Table 4.8 (March 2026: Table 3.8) "Business rates" + 2025-01-01: 0.047966 + # Forecast (2026-2031) from OBR EFO October 2026, receipts Table 4.8 + 2026-01-01: 0.044394 + 2027-01-01: 0.050267 + 2028-01-01: 0.0389 + 2029-01-01: 0.072362 + 2030-01-01: 0.02309 + 2031-01-01: 0.024211 # Beyond the OBR forecast: the average_earnings long-run path above - 2031-01-01: 0.0332 - 2032-01-01: 0.0371 - 2033-01-01: 0.0374 - 2034-01-01: 0.0377 - 2035-01-01: 0.0380 + 2032-01-01: 0.0285 + 2033-01-01: 0.0309 + 2034-01-01: 0.0334 + 2035-01-01: 0.0358 2036-01-01: 0.0383 metadata: unit: /1 label: Business rates receipts growth (Great Britain) reference: - - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.8) + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.8) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.8; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR EFO March 2025 (detailed forecast tables, receipts, Table 3.9; 2023-24 outturn) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ northern_ireland: description: Growth in Northern Ireland business rates receipts (the OBR "Northern Ireland business rates" line in other taxes, which appears to cover the regional rate only; also applied to district rates, for which we found no published forecast). values: # Outturn (2024-25 over 2023-24) from OBR EFO March 2026 over March 2025, receipts Table 3.2 "Northern Ireland business rates" 2024-01-01: 0.032513 - # Forecast (2025-2030) from OBR EFO March 2026, receipts Table 3.2 - 2025-01-01: 0.032388 - 2026-01-01: 0.020057 - 2027-01-01: 0.01942 - 2028-01-01: 0.018653 - 2029-01-01: 0.018644 - 2030-01-01: 0.02016 + # Outturn (2025-26 over 2024-25) from OBR EFO October 2026 over March 2026, receipts Table 4.2 (March 2026: Table 3.2) "Northern Ireland business rates" + 2025-01-01: 0.03454 + # Forecast (2026-2031) from OBR EFO October 2026, receipts Table 4.2 + 2026-01-01: 0.026328 + 2027-01-01: 0.021192 + 2028-01-01: 0.019597 + 2029-01-01: 0.019577 + 2030-01-01: 0.01971 + 2031-01-01: 0.019094 # Beyond the OBR forecast: the average_earnings long-run path above - 2031-01-01: 0.0332 - 2032-01-01: 0.0371 - 2033-01-01: 0.0374 - 2034-01-01: 0.0377 - 2035-01-01: 0.0380 + 2032-01-01: 0.0285 + 2033-01-01: 0.0309 + 2034-01-01: 0.0334 + 2035-01-01: 0.0358 2036-01-01: 0.0383 metadata: unit: /1 label: Northern Ireland business rates receipts growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.2) + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.2) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR EFO March 2026 (detailed forecast tables, receipts, Table 3.2; 2024-25 outturn) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - - title: OBR EFO March 2025 (detailed forecast tables, receipts, Table 3.2; 2023-24 outturn) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ per_capita: gdp: description: Per capita nominal GDP year-on-year growth. values: - # Calendar-year nominal GDP growth from the March 2026 EFO (Table 1.4 + # Calendar-year nominal GDP growth from the October 2026 EFO (Table 1.4 # annual totals, the same growth as Table A.1), divided by one plus # ons.population: (1 + nominal) / (1 + population) - 1, rounded to 4 - # decimals. 2021-2024 are outturn, 2025-2030 forecast. + # decimals. 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0892 2022-01-01: 0.1004 2023-01-01: 0.0524 - 2024-01-01: 0.0389 - 2025-01-01: 0.0474 - 2026-01-01: 0.0294 - 2027-01-01: 0.0326 - 2028-01-01: 0.0317 - 2029-01-01: 0.0306 - 2030-01-01: 0.0315 + 2024-01-01: 0.0387 + 2025-01-01: 0.0465 + 2026-01-01: 0.0384 + 2027-01-01: 0.0294 + 2028-01-01: 0.0328 + 2029-01-01: 0.0347 + 2030-01-01: 0.0331 + 2031-01-01: 0.0332 metadata: unit: /1 label: Per capita GDP growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.4), divided by ons.population growth - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.4), divided by ons.population growth + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ mixed_income: description: Per capita mixed income year-on-year growth. values: - # Calendar-year growth in mixed income from the March 2026 EFO (Table + # Calendar-year growth in mixed income from the October 2026 EFO (Table # 1.12 annual totals), divided by one plus ons.population: # (1 + growth) / (1 + population) - 1, rounded to 4 decimals. - # 2021-2024 are outturn, 2025-2030 forecast. + # 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0636 2022-01-01: 0.0288 2023-01-01: -0.0060 - 2024-01-01: 0.0269 - 2025-01-01: 0.0112 - 2026-01-01: 0.0309 - 2027-01-01: 0.0378 - 2028-01-01: 0.0371 - 2029-01-01: 0.0364 - 2030-01-01: 0.0370 + 2024-01-01: 0.0267 + 2025-01-01: 0.0049 + 2026-01-01: 0.0282 + 2027-01-01: 0.0307 + 2028-01-01: 0.0340 + 2029-01-01: 0.0367 + 2030-01-01: 0.0393 + 2031-01-01: 0.0400 metadata: unit: /1 label: Per capita mixed income growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.12) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.12) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ non_labour_income: description: Per capita non-labour income year-on-year growth. values: # obr.non_labour_income divided by one plus ons.population: # (1 + growth) / (1 + population) - 1, rounded to 4 decimals. - # 2021-2024 are outturn, 2025-2030 forecast. + # 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0831 2022-01-01: 0.0880 2023-01-01: 0.1069 - 2024-01-01: 0.0378 - 2025-01-01: 0.0318 - 2026-01-01: 0.0361 - 2027-01-01: 0.0483 - 2028-01-01: 0.0317 - 2029-01-01: 0.0266 - 2030-01-01: 0.0280 + 2024-01-01: 0.0363 + 2025-01-01: 0.0261 + 2026-01-01: 0.0266 + 2027-01-01: 0.0438 + 2028-01-01: 0.0386 + 2029-01-01: 0.0374 + 2030-01-01: 0.0345 + 2031-01-01: 0.0307 metadata: unit: /1 label: Per capita non-labour income growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.12) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.12) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ house_prices: description: House prices year-on-year growth. values: - # Outturn (2021-2024) + # Outturn (2021-2025) 2021-01-01: 0.082 2022-01-01: 0.0926 2023-01-01: 0.0036 2024-01-01: 0.007 - # Forecast (2025-2030) - 2025-01-01: 0.028 - 2026-01-01: 0.024 - 2027-01-01: 0.029 - 2028-01-01: 0.027 - 2029-01-01: 0.026 - 2030-01-01: 0.024 + 2025-01-01: 0.0264 + # Forecast (2026-2031) + 2026-01-01: 0.0209 + 2027-01-01: 0.0244 + 2028-01-01: 0.0278 + 2029-01-01: 0.0275 + 2030-01-01: 0.0275 + 2031-01-01: 0.0275 metadata: unit: /1 label: House prices growth reference: - - title: OBR EFO March 2026 (Table A.1) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.16) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ mortgage_interest: description: Mortgage interest year-on-year growth. values: - # Outturn (2021-2024) + # Outturn (2021-2025) 2021-01-01: -0.0226 2022-01-01: 0.1462 2023-01-01: 0.5224 2024-01-01: 0.2730 - # Forecast (2025-2030) 2025-01-01: 0.0952 - 2026-01-01: 0.0797 - 2027-01-01: 0.1040 - 2028-01-01: 0.0476 - 2029-01-01: 0.0468 + # Forecast (2026-2029) + 2026-01-01: 0.0623 + 2027-01-01: 0.1156 + 2028-01-01: 0.0668 + 2029-01-01: 0.0475 # 2030: the OBR November 2025 EFO calendar-2030 forecast (5.535%), - # carried over. The March 2026 EFO stops forecasting mortgage interest - # payments after 2030 Q1 (Table 1.7 note), so it has no calendar-2030 - # figure; its 2030 Q1 rate is 5.40% and its 2029-30 rate 5.05%. + # carried over. The October 2026 EFO stops forecasting mortgage + # interest payments after 2029 Q4, before the ONS changes RPI + # methodology in February 2030 (Table 1.7 note), so it has no 2030 or + # 2031 figure; its 2029 Q4 rate is 5.43% and its 2029-30 rate 5.11%. + # Later years hold the 2030 rate. 2030-01-01: 0.0553 metadata: unit: /1 label: Mortgage interest growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: OBR EFO November 2025 (detailed forecast tables, economy, Table 1.7), 2030 value only href: https://obr.uk/efo/economic-and-fiscal-outlook-november-2025/ @@ -972,19 +1006,19 @@ obr: 2023-01-01: 0.041 2024-01-01: 0.072 2025-01-01: 0.080 - # Forecast (2026-2030): policy cap with composition multiplier set to 1. + # Forecast (2026-2031): policy cap with composition multiplier set to 1. # 2026: ONS September 2025 CPI 3.8% + 1pp. 2026-01-01: 0.048 - # 2027: placeholder. The cap needs September 2026 CPI (ONS, due - # 21 October 2026) + 1pp; 3.3% is calendar-2026 CPI (2.3%) + 1pp. - # The OBR March 2026 forecast of September 2026 CPI is 2.1%, which - # would give 3.1%, but August 2026 CPI outturn was already 3.1%. - 2027-01-01: 0.033 - # 2028-2030: OBR March 2026 Q3 CPI forecasts for 2027-2029 (Table 1.7: - # 2.01%, 2.02%, 2.00%) + 1pp, to 0.1pp. - 2028-01-01: 0.030 + # 2027: ONS September 2026 CPI 3.5% (21 October 2026) + 1pp. + 2027-01-01: 0.045 + # 2028-2031: OBR October 2026 forecasts of September CPI in 2027-2030 + # (receipts Table 4.19, "CPI used to uprate thresholds": 3.44%, 2.04%, + # 2.17%, 2.01%) + 1pp, to 0.1pp. They are the September CPI forecasts + # in statutory_uprating_inputs. + 2028-01-01: 0.044 2029-01-01: 0.030 - 2030-01-01: 0.030 + 2030-01-01: 0.032 + 2031-01-01: 0.030 metadata: unit: /1 label: Social rent growth @@ -1001,28 +1035,31 @@ obr: href: https://www.gov.uk/government/publications/direction-on-the-rent-standard-2026/policy-statement-on-rents-for-social-housing - title: ONS D7G7, CPI annual rate, all items (September CPI input to the cap) href: https://www.ons.gov.uk/economy/inflationandpriceindices/timeseries/d7g7/mm23 + - title: OBR EFO October 2026 (detailed forecast tables, receipts, Table 4.19), September CPI forecasts + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ rent: description: Rent year-on-year growth, private and social (ONS series D7GQ). values: - # Outturn (2022-2024) + # Outturn (2022-2025) 2022-01-01: 0.0347 2023-01-01: 0.0575 2024-01-01: 0.0716 - # Forecast (2025-2030) 2025-01-01: 0.0542 - 2026-01-01: 0.0334 - 2027-01-01: 0.0302 - 2028-01-01: 0.0230 - 2029-01-01: 0.0238 - 2030-01-01: 0.0258 + # Forecast (2026-2031) + 2026-01-01: 0.0365 + 2027-01-01: 0.0316 + 2028-01-01: 0.0268 + 2029-01-01: 0.0261 + 2030-01-01: 0.0254 + 2031-01-01: 0.0275 metadata: unit: /1 label: Rent growth reference: - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ ons: population: @@ -1043,6 +1080,9 @@ ons: # exactly (policyengine_uk/tests/test_population_vintage.py). # The per_capita series under obr are derived from this series; re-derive # them, and the petrol and diesel spending proxies, whenever it changes. + # The long-term determinants for the October 2026 EFO are not yet + # published, so this stays on the March 2026 vintage until they are; the + # per_capita series meanwhile divide October 2026 aggregates by it. values: 2021-01-01: 0.0036 2022-01-01: 0.0098 @@ -1118,20 +1158,21 @@ ons: 2023-01-01: 0.987 # 86.0/43.3 - 1 2024-01-01: 0.142 # 98.2/86.0 - 1 # Forecast: use OBR non-labour income growth as proxy (Table 1.12) - 2025-01-01: 0.0349 - 2026-01-01: 0.0397 - 2027-01-01: 0.0513 - 2028-01-01: 0.0350 - 2029-01-01: 0.0301 - 2030-01-01: 0.0317 + 2025-01-01: 0.0292 + 2026-01-01: 0.0302 + 2027-01-01: 0.0468 + 2028-01-01: 0.0419 + 2029-01-01: 0.0409 + 2030-01-01: 0.0382 + 2031-01-01: 0.0332 metadata: unit: /1 label: Household interest income growth reference: - title: ONS National Accounts D.41g - Households interest received (HAXV series) href: https://www.ons.gov.uk/economy/grossdomesticproductgdp/timeseries/haxv/ukea - - title: OBR EFO March 2026 - Non-labour income growth used as proxy for 2025+ (Table 1.12) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 - Non-labour income growth used as proxy for 2025+ (Table 1.12) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ private_rental_prices: # Historical values are calendar-year averages from ONS PIPR. Forecast # values back out private-rent growth from the OBR aggregate rent forecast @@ -1144,19 +1185,20 @@ ons: 2023-01-01: 0.073824 2024-01-01: 0.087127 2025-01-01: 0.063279 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: United kingdom private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ ENGLAND: description: Private rental prices year-on-year growth in England. values: @@ -1164,19 +1206,20 @@ ons: 2023-01-01: 0.071723 2024-01-01: 0.087245 2025-01-01: 0.063996 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: England private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ WALES: description: Private rental prices year-on-year growth in Wales. values: @@ -1184,19 +1227,20 @@ ons: 2023-01-01: 0.083841 2024-01-01: 0.084642 2025-01-01: 0.077081 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: Wales private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ SCOTLAND: description: Private rental prices year-on-year growth in Scotland. values: @@ -1204,19 +1248,20 @@ ons: 2023-01-01: 0.100690 2024-01-01: 0.084690 2025-01-01: 0.042929 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: Scotland private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ NORTHERN_IRELAND: description: Private rental prices year-on-year growth in Northern Ireland. values: @@ -1224,19 +1269,20 @@ ons: 2023-01-01: 0.087019 2024-01-01: 0.092217 2025-01-01: 0.068702 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: Northern Ireland private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ NORTH_EAST: description: Private rental prices year-on-year growth in North East. values: @@ -1244,19 +1290,20 @@ ons: 2023-01-01: 0.054987 2024-01-01: 0.067069 2025-01-01: 0.090155 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: North east private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ NORTH_WEST: description: Private rental prices year-on-year growth in North West. values: @@ -1264,19 +1311,20 @@ ons: 2023-01-01: 0.075098 2024-01-01: 0.092231 2025-01-01: 0.077692 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: North west private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ YORKSHIRE: description: Private rental prices year-on-year growth in Yorkshire and The @@ -1286,19 +1334,20 @@ ons: 2023-01-01: 0.067502 2024-01-01: 0.069094 2025-01-01: 0.040862 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: Yorkshire and the humber private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ EAST_MIDLANDS: description: Private rental prices year-on-year growth in East Midlands. values: @@ -1306,19 +1355,20 @@ ons: 2023-01-01: 0.060960 2024-01-01: 0.086271 2025-01-01: 0.069478 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: East midlands private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ WEST_MIDLANDS: description: Private rental prices year-on-year growth in West Midlands. values: @@ -1326,19 +1376,20 @@ ons: 2023-01-01: 0.066340 2024-01-01: 0.087831 2025-01-01: 0.061272 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: West midlands private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ EAST_OF_ENGLAND: description: Private rental prices year-on-year growth in East of England. values: @@ -1346,19 +1397,20 @@ ons: 2023-01-01: 0.052949 2024-01-01: 0.073996 2025-01-01: 0.071305 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: East of England private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ LONDON: description: Private rental prices year-on-year growth in London. values: @@ -1366,19 +1418,20 @@ ons: 2023-01-01: 0.084473 2024-01-01: 0.103216 2025-01-01: 0.066484 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: London private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ SOUTH_EAST: description: Private rental prices year-on-year growth in South East. values: @@ -1386,19 +1439,20 @@ ons: 2023-01-01: 0.065655 2024-01-01: 0.079285 2025-01-01: 0.057820 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: South east private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ SOUTH_WEST: description: Private rental prices year-on-year growth in South West. values: @@ -1406,19 +1460,20 @@ ons: 2023-01-01: 0.067635 2024-01-01: 0.068267 2025-01-01: 0.053907 - 2026-01-01: 0.020663830 - 2027-01-01: 0.027757447 - 2028-01-01: 0.016893617 - 2029-01-01: 0.018391489 - 2030-01-01: 0.022136170 + 2026-01-01: 0.026468085 + 2027-01-01: 0.019910638 + 2028-01-01: 0.011795745 + 2029-01-01: 0.022697872 + 2030-01-01: 0.019642553 + 2031-01-01: 0.025319149 metadata: unit: /1 label: South west private rental prices growth reference: - title: "ONS Price Index of Private Rents, UK: monthly price statistics" href: https://www.ons.gov.uk/economy/inflationandpriceindices/datasets/priceindexofprivaterentsukmonthlypricestatistics - - title: OBR EFO March 2026 (detailed forecast tables, economy, Table 1.7) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ ofwat: water_bills: description: Water and sewerage bills year-on-year growth. @@ -1446,9 +1501,9 @@ ofwat: 2024-01-01: 0.044 2025-01-01: 0.27 2026-01-01: 0.054 - 2027-01-01: 0.055 - 2028-01-01: 0.05 - 2029-01-01: 0.049 + 2027-01-01: 0.062 + 2028-01-01: 0.062 + 2029-01-01: 0.050 metadata: unit: /1 label: Water bills growth diff --git a/policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml b/policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml index cf7d2a640f..267d1bce1d 100644 --- a/policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml +++ b/policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml @@ -105,60 +105,60 @@ values: # continues the same April cadence. # BEGIN RPI forecast generated by calculate_fuel_duty_rates.py 2027-04-01: - value: 0.5975 + value: 0.6003 metadata: - note: Forecast. 0.5795 uprated by 2026 RPI growth of 3.1%. + note: Forecast. 0.5795 uprated by 2026 RPI growth of 3.6%. reference: - title: Budget 2025 (fuel duty uprated by RPI from April 2027) href: https://www.gov.uk/government/publications/budget-2025-document/budget-2025-html - title: HM Treasury, Budget 2025 policy costings, page 14 (from 1 April 2027) href: https://assets.publishing.service.gov.uk/media/692872fd2a37784b16ecf676/Budget_2025-Policy_Costings.pdf#page=14 - - title: OBR EFO March 2026 (Table A.1) (RPI forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) (RPI forecast) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ 2028-04-01: - value: 0.6154 + value: 0.6262 metadata: - note: Forecast. 0.5975 uprated by 2027 RPI growth of 3.0%. + note: Forecast. 0.6003 uprated by 2027 RPI growth of 4.3%. reference: - title: Budget 2025 (fuel duty uprated by RPI from April 2027) href: https://www.gov.uk/government/publications/budget-2025-document/budget-2025-html - title: HM Treasury, Budget 2025 policy costings, page 14 (from 1 April 2027) href: https://assets.publishing.service.gov.uk/media/692872fd2a37784b16ecf676/Budget_2025-Policy_Costings.pdf#page=14 - - title: OBR EFO March 2026 (Table A.1) (RPI forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) (RPI forecast) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ 2029-04-01: - value: 0.6326 + value: 0.6452 metadata: - note: Forecast. 0.6154 uprated by 2028 RPI growth of 2.8%. + note: Forecast. 0.6262 uprated by 2028 RPI growth of 3.0%. reference: - title: Budget 2025 (fuel duty uprated by RPI from April 2027) href: https://www.gov.uk/government/publications/budget-2025-document/budget-2025-html - title: HM Treasury, Budget 2025 policy costings, page 14 (from 1 April 2027) href: https://assets.publishing.service.gov.uk/media/692872fd2a37784b16ecf676/Budget_2025-Policy_Costings.pdf#page=14 - - title: OBR EFO March 2026 (Table A.1) (RPI forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) (RPI forecast) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ 2030-04-01: - value: 0.6509 + value: 0.6644 metadata: - note: Forecast. 0.6326 uprated by 2029 RPI growth of 2.9%. + note: Forecast. 0.6452 uprated by 2029 RPI growth of 3.0%. reference: - title: Budget 2025 (fuel duty uprated by RPI from April 2027) href: https://www.gov.uk/government/publications/budget-2025-document/budget-2025-html - title: HM Treasury, Budget 2025 policy costings, page 14 (from 1 April 2027) href: https://assets.publishing.service.gov.uk/media/692872fd2a37784b16ecf676/Budget_2025-Policy_Costings.pdf#page=14 - - title: OBR EFO March 2026 (Table A.1) (RPI forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) (RPI forecast) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ 2031-04-01: - value: 0.6659 + value: 0.6796 metadata: - note: Forecast. 0.6509 uprated by 2030 RPI growth of 2.3%. + note: Forecast. 0.6644 uprated by 2030 RPI growth of 2.3%. reference: - title: Budget 2025 (fuel duty uprated by RPI from April 2027) href: https://www.gov.uk/government/publications/budget-2025-document/budget-2025-html - title: HM Treasury, Budget 2025 policy costings, page 14 (from 1 April 2027) href: https://assets.publishing.service.gov.uk/media/692872fd2a37784b16ecf676/Budget_2025-Policy_Costings.pdf#page=14 - - title: OBR EFO March 2026 (Table A.1) (RPI forecast) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.7) (RPI forecast) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ # END RPI forecast generated by calculate_fuel_duty_rates.py metadata: unit: currency-GBP diff --git a/policyengine_uk/parameters/gov/simulation/vat/private_school_share_of_receipts.yaml b/policyengine_uk/parameters/gov/simulation/vat/private_school_share_of_receipts.yaml index fe25c4c119..4e142d97f8 100644 --- a/policyengine_uk/parameters/gov/simulation/vat/private_school_share_of_receipts.yaml +++ b/policyengine_uk/parameters/gov/simulation/vat/private_school_share_of_receipts.yaml @@ -6,9 +6,9 @@ metadata: label: Private school fees' share of VAT receipts derivation: >- HMRC's OBR-certified costing of VAT on private school fees divided by OBR - cash-basis VAT receipts for the same fiscal year: 1,505 / 180,169 in - 2025-26, 1,560 / 187,704 in 2026-27, 1,610 / 195,923 in 2027-28, 1,665 / - 204,591 in 2028-29 and 1,725 / 213,118 in 2029-30 (£m). Each value starts on + cash-basis VAT receipts for the same fiscal year: 1,505 / 179,861 in + 2025-26 (outturn), 1,560 / 186,154 in 2026-27, 1,610 / 193,974 in 2027-28, + 1,665 / 203,284 in 2028-29 and 1,725 / 211,701 in 2029-30 (£m). Each value starts on 1 April, so a model year reads its fiscal year's share. The 2024-25 part-year receipt (£460m from 1 January 2025, 0.27% of £170,994m) is left in general VAT, as private_school_vat is zero in model year 2024. The survey @@ -20,19 +20,19 @@ metadata: Microcosm f9d1922c in 2025-26). vat and baseline_vat both read the share from the simulation's own parameters, so that the baseline reads each fiscal year's value; docs/engineering/vat-coverage.md sets out the allocation. - The receipts were read from the OBR workbook with SHA-256 - f65b6cb7f96931d4abd85940794eb60f6f65afca8bbf16c74a4548bf92766a28: - 180.16893868541794, 187.70436725810845, 195.922624491872, - 204.59126694885538 and 213.11818629804077 (£bn). + The receipts were read from the OBR October 2026 receipts workbook with + SHA-256 d115705716d77b11c190385d41cb1924f30080c9331a8a386c04d4e65a368e95: + 179.861, 186.15408153120995, 193.97359959830945, 203.2843806572163 and + 211.70087777364822 (£bn). reference: - title: HMRC, Applying VAT to private school fees (updated 15 November 2024), Exchequer impact (Autumn Budget 2024 Table 5.1, certified by the OBR) href: https://www.gov.uk/government/publications/vat-on-private-school-fees/applying-vat-to-private-school-fees - - title: OBR, Economic and fiscal outlook March 2026, detailed forecast tables, receipts (efo-march-2026-detailed-forecast-tables-receipts.xlsx), sheet 3.8, row 13 (Value added tax, cash basis), cells E13:I13 for 2025-26 to 2029-30 (£bn) - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + - title: OBR, Economic and fiscal outlook October 2026, detailed forecast tables, receipts (efo-october-2026-detailed-forecast-tables-receipts.xlsx), sheet 4.8, row 13 (Value added tax, cash basis), cells D13:H13 for 2025-26 to 2029-30 (£bn) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ values: 2010-01-01: 0 - 2025-04-01: 0.008353 - 2026-04-01: 0.008311 - 2027-04-01: 0.008218 - 2028-04-01: 0.008138 - 2029-04-01: 0.008094 + 2025-04-01: 0.008368 + 2026-04-01: 0.008380 + 2027-04-01: 0.008300 + 2028-04-01: 0.008190 + 2029-04-01: 0.008148 diff --git a/policyengine_uk/tests/fixtures/obr_receipts/README.md b/policyengine_uk/tests/fixtures/obr_receipts/README.md index 163912f1aa..825e379a3d 100644 --- a/policyengine_uk/tests/fixtures/obr_receipts/README.md +++ b/policyengine_uk/tests/fixtures/obr_receipts/README.md @@ -1,22 +1,29 @@ # Real OBR receipts table fixtures These parser fixtures retain the original worksheet XML for Contents, Other -taxes (3.2), Property transactions taxes: receipts by sector (3.7), and Current -receipts (on a cash basis: 3.9 in 2025, 3.8 in 2026), plus the original shared +taxes (3.2, or 4.2 in October 2026), Property transactions taxes: receipts by +sector (3.7, or 4.7), and Current receipts (on a cash basis: 3.9 in March +2025, 3.8 in March 2026, 4.8 in October 2026), plus the original shared strings. Only the workbook's sheet list and relationships were reduced to those entries. The published unit cells, fiscal-year headers, markers, row labels and numeric cells are unchanged. These are minimal archives for the importer's XLSX -reader, rather than complete Excel documents with styles and charts. +reader, rather than complete Excel documents with styles and charts. The +October 2026 workbook titles sheet 4.8 "43.8 Current receipts (on a cash +basis)"; the fixture keeps that misprint. -Sources: OBR [March 2025 EFO](https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/) -and [March 2026 EFO](https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/), +Sources: OBR [March 2025 EFO](https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/), +[March 2026 EFO](https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/) +and [October 2026 EFO](https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/), receipts detailed forecast tables. The original files used for extraction are -`obr_efo_march_2025_receipts.xlsx` and `obr_efo_march_2026_receipts.xlsx`. -Their SHA-256 hashes are: +`obr_efo_march_2025_receipts.xlsx`, `obr_efo_march_2026_receipts.xlsx` and +`efo-october-2026-detailed-forecast-tables-receipts.xlsx` (in the October 2026 +detailed forecast tables zip file). Their SHA-256 hashes are: - March 2025: `6b20e05e93c50e3ccae1d3111fd84b8fa326b75c38c8ab055fad694648c75905` - March 2026: `f65b6cb7f96931d4abd85940794eb60f6f65afca8bbf16c74a4548bf92766a28` +- October 2026: `d115705716d77b11c190385d41cb1924f30080c9331a8a386c04d4e65a368e95` +The committed YAML holds the October 2026 tables over the March 2026 ones. Tests mutate the unit cell and selected receipt levels inside these real tables; the unchanged control must reproduce the committed YAML byte for byte. No test downloads a workbook or depends on a developer's local source directory. diff --git a/policyengine_uk/tests/fixtures/obr_receipts/obr_efo_october_2026_receipts.xlsx b/policyengine_uk/tests/fixtures/obr_receipts/obr_efo_october_2026_receipts.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5a4c58ec6767d60783399980b6390f341885c4c7 GIT binary patch literal 44075 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

q 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 z MdmTfb;=fY=4<4kyW&i*H literal 0 HcmV?d00001 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml index 245ab925f5..df89d7bb1f 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/stamp_duty/corporate_sdlt.yaml @@ -1,11 +1,12 @@ # Corporate SDLT is shareholding x (residential + non-residential corporate # SDLT revenue) (gov.hmrc.stamp_duty.statistics). For 2026-27 that revenue is # HMRC's 2024-25 receipts from non-natural persons uprated with the OBR's -# receipts for each property type (March 2026 EFO, Table 3.7): -# residential £1,230m x 13.4289 / 10.380 = £1,591.29m -# non-residential £3,260m x 4.7213 / 3.505 = £4,391.26m -# total = £5,982.55m -# so a shareholding of 1e-6 gives £5,982.55 and 3e-6 gives £17,947.64. The +# receipts for each property type (2024-25 outturn from the March 2026 EFO, +# Table 3.7; 2026-27 from the October 2026 EFO, Table 4.7): +# residential £1,230m x 11.5985 / 10.380 = £1,374.39m +# non-residential £3,260m x 3.4393 / 3.505 = £3,198.88m +# total = £4,573.27m +# so a shareholding of 1e-6 gives £4,573.27 and 3e-6 gives £13,719.80. The # model chains the OBR's year-on-year growth rates (six decimals) into an # index rounded to five, so it lands within £0.10 of these; the margins are # £0.50. business_rates is set to 0 so the totals isolate SDLT. A £500,000 @@ -21,12 +22,12 @@ council_tax: 0 household_owns_tv: false output: - corporate_sdlt: 5_982.55 + corporate_sdlt: 4_573.27 expected_sdlt: 0 - corporate_tax_incidence: 5_982.55 - household_tax: 5_982.55 - gov_tax: 5_982.55 - pre_budget_change_household_tax: 5_982.55 + corporate_tax_incidence: 4_573.27 + household_tax: 4_573.27 + gov_tax: 4_573.27 + pre_budget_change_household_tax: 4_573.27 - name: Household and corporate SDLT each enter the totals once period: 2026 absolute_error_margin: 0.5 @@ -40,10 +41,10 @@ household_owns_tv: false output: expected_sdlt: 15_000 - corporate_sdlt: 5_982.55 - household_tax: 20_982.55 - gov_tax: 20_982.55 - pre_budget_change_household_tax: 20_982.55 + corporate_sdlt: 4_573.27 + household_tax: 19_573.27 + gov_tax: 19_573.27 + pre_budget_change_household_tax: 19_573.27 - name: Abolishing SDLT removes household and corporate SDLT from the totals period: 2026 absolute_error_margin: 0.5 @@ -97,9 +98,9 @@ household_owns_tv: false output: expected_sdlt: [15_000, 0] - corporate_sdlt: [5_982.55, 17_947.64] - household_tax: [20_982.55, 17_947.64] - gov_tax: [20_982.55, 17_947.64] + corporate_sdlt: [4_573.27, 13_719.80] + household_tax: [19_573.27, 13_719.80] + gov_tax: [19_573.27, 13_719.80] - name: Two households, SDLT abolished - no SDLT left in either household's totals period: 2026 absolute_error_margin: 0.5 @@ -151,11 +152,11 @@ household_owns_tv: false output: expected_sdlt: 0 - corporate_sdlt: 5_982.55 - corporate_tax_incidence: 6_482.55 - household_tax: 6_482.55 - gov_tax: 6_482.55 - pre_budget_change_household_tax: 6_482.55 + corporate_sdlt: 4_573.27 + corporate_tax_incidence: 5_073.27 + household_tax: 5_073.27 + gov_tax: 5_073.27 + pre_budget_change_household_tax: 5_073.27 - name: Abolishing SDLT removes the Welsh shareholder's corporate SDLT and keeps business rates period: 2026 absolute_error_margin: 0.5 diff --git a/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_carer_supplement.yaml b/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_carer_supplement.yaml index ffb1748332..967e7ef79c 100644 --- a/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_carer_supplement.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_carer_supplement.yaml @@ -6,7 +6,7 @@ # in 2026-27, sections 2 and 3). From April 2027 the model raises both each # April by the previous September's CPI (gov.benefit_uprating_cpi) and rounds # to the nearest 5p: 3.5% for April 2027 (ONS, 21 October 2026) and the OBR -# March 2026 EFO forecast of 2.1% for April 2028. +# October 2026 EFO forecast of 3.4% for April 2028. - name: Scottish Carer Supplement is 11.70 a week in 2026 period: 2026 @@ -41,10 +41,10 @@ care_hours: 40 country: SCOTLAND output: - # 12.10 x 1.021 = 12.3541, to the nearest 5p 12.35; x 52 = 642.20. - scottish_carer_supplement: 12.35 * 52 - # 89.50 x 1.021 = 91.3795, to the nearest 5p 91.40. - carer_support_payment: 91.40 * 52 + # 12.10 x 1.034 = 12.5114, to the nearest 5p 12.50; x 52 = 650.00. + scottish_carer_supplement: 12.50 * 52 + # 89.50 x 1.034 = 92.543, to the nearest 5p 92.55. + carer_support_payment: 92.55 * 52 - name: Carer in England gets no Scottish Carer Supplement in 2027 period: 2027 diff --git a/policyengine_uk/tests/test_ahc_deflator.py b/policyengine_uk/tests/test_ahc_deflator.py index 29aad4562e..807e6458e3 100644 --- a/policyengine_uk/tests/test_ahc_deflator.py +++ b/policyengine_uk/tests/test_ahc_deflator.py @@ -25,7 +25,7 @@ def test_stored_ahc_cpi_growth_matches_the_documented_derivation(): # updating CPI, rent or water bill forecasts without rerunning the script # fails here. derived = _derived_growth() - assert sorted(derived) == list(range(2022, 2031)) + assert sorted(derived) == list(range(2022, 2032)) for year, growth in derived.items(): assert AHC_GROWTH(f"{year}-01-01") == pytest.approx( round(growth, 4), abs=1e-9 @@ -33,8 +33,8 @@ def test_stored_ahc_cpi_growth_matches_the_documented_derivation(): def test_ahc_cpi_growth_2026_removes_rents_from_cpi(): - # OBR March 2026: calendar-2026 CPI 2.30%, actual rents 3.34%. Rents grow + # OBR October 2026: calendar-2026 CPI 3.11%, actual rents 3.65%. Rents grow # faster than CPI, so removing them leaves lower growth than CPI. cpi_growth = parameters.gov.economic_assumptions.yoy_growth.obr.consumer_price_index - assert AHC_GROWTH("2026-01-01") == pytest.approx(0.0217, abs=1e-9) + assert AHC_GROWTH("2026-01-01") == pytest.approx(0.0304, abs=1e-9) assert AHC_GROWTH("2026-01-01") < cpi_growth("2026-01-01") diff --git a/policyengine_uk/tests/test_corporate_receipts_statistics.py b/policyengine_uk/tests/test_corporate_receipts_statistics.py index ca6fbf909c..fa74449607 100644 --- a/policyengine_uk/tests/test_corporate_receipts_statistics.py +++ b/policyengine_uk/tests/test_corporate_receipts_statistics.py @@ -63,29 +63,32 @@ 702_804_905, 741_337_437, 766_153_718)), } # fmt: skip -# OBR receipts, £bn, as published: 2023-24 outturn from the March 2025 EFO -# and 2024-25 outturn to 2030-31 from the March 2026 EFO (receipts Tables 3.7 -# for SDLT by property type, 3.8 (March 2025: 3.9) for business rates and 3.2 -# for Northern Ireland business rates). +# OBR receipts, £bn, as published: 2023-24 outturn from the March 2025 EFO, +# 2024-25 outturn from the March 2026 EFO, and 2025-26 outturn to 2031-32 +# from the October 2026 EFO (receipts Tables 4.7 for SDLT by property type, +# 4.8 for business rates and 4.2 for Northern Ireland business rates; March +# 2026: 3.7, 3.8 and 3.2; March 2025: 3.7, 3.9 and 3.2). OBR_FROM = 2023 OBR_RECEIPTS_BN = { "stamp_duty_land_tax.residential": ( - 8.57, 10.38, 11.731471524432562, 13.428906667032589, 14.984943814530874, - 16.673948133476184, 17.964513468126285, 19.057301113969185, + 8.57, 10.38, 11.55444496305409, 11.598497804863152, 12.81121827423391, + 14.275385542155488, 15.523034837312446, 16.708206755202507, + 17.97120998332108, ), "stamp_duty_land_tax.non_residential": ( - 3.045, 3.505, 3.67504517435302, 4.72127759316189, 5.32882881047999, - 5.900913979881709, 6.53306953553104, 7.10465817727629, + 3.045, 3.505, 3.6048001541859174, 3.4392848579522055, 4.060008995487192, + 4.6692547224804075, 4.8746831796154595, 5.306606478148783, + 5.725680069577546, ), "business_rates.great_britain": ( - 29.599814327646055, 32.37681432764605, 34.05196393248926, - 37.41358657214458, 38.24093094782461, 39.111850954748434, - 42.4190677645469, 42.46319362251926, + 29.599814327646055, 32.37681432764605, 33.929814327646056, + 35.43608032863263, 37.21735218338801, 38.66510919685915, + 41.462982206056644, 42.42035811098974, 43.447399285510656, ), "business_rates.northern_ireland": ( - 0.3702940455770644, 0.3823335073068893, 0.39471664406441903, - 0.40263364127921164, 0.41045270712298504, 0.4181089461242919, - 0.42590403232705243, 0.4344900971429234, + 0.3702940455770644, 0.3823335073068893, 0.3955394050104385, + 0.40595301023058955, 0.414556055466312, 0.4226801104356366, + 0.43095512116333085, 0.4394491849889923, 0.44783993918412923, ), } # fmt: skip OBR_LAST_YEAR = OBR_FROM + len(OBR_RECEIPTS_BN["business_rates.great_britain"]) - 1 @@ -160,9 +163,10 @@ def test_northern_ireland_business_rates_are_total_rates_less_domestic(offset): ) -# OBR's Business rates line (cash basis, receipts Table 3.8, £bn): 2024-25 -# outturn and 2025-26 forecast. England, Scotland and Wales, local and -# central lists together, should cover the same receipts. +# OBR's Business rates line (cash basis, £bn): the 2024-25 outturn (March 2026 +# EFO, receipts Table 3.8) and the 2025-26 outturn (October 2026 EFO, Table +# 4.8). England, Scotland and Wales, local and central lists together, should +# cover the same receipts. GB_SERIES = ( "ENGLAND", "ENGLAND_CENTRAL_LIST", diff --git a/policyengine_uk/tests/test_council_tax_uprating.py b/policyengine_uk/tests/test_council_tax_uprating.py index 14ca1a0d3e..d2679ec3e5 100644 --- a/policyengine_uk/tests/test_council_tax_uprating.py +++ b/policyengine_uk/tests/test_council_tax_uprating.py @@ -22,7 +22,7 @@ REGIONS = [region.name for region in Region] -UPRATED_YEARS = list(range(2023, 2031)) +UPRATED_YEARS = list(range(2023, 2032)) COUNCIL_TAX_GROWTH = parameters.gov.economic_assumptions.yoy_growth.obr.council_tax # Household weights grow by the series uprating_indices.yaml lists them under. # It is read from the file here, not from the code under test. @@ -34,13 +34,15 @@ ] WEIGHT_GROWTH = parameters.get_child(WEIGHT_GROWTH_PATH) -# OBR March 2026 EFO, detailed forecast tables, expenditure, Table 4.1: -# council tax receipts in £ billion, 2024-25 (outturn) to 2030-31. -OBR_RECEIPTS_YEARS = range(2024, 2031) +# OBR council tax receipts in £ billion: the 2024-25 outturn from the March +# 2026 EFO (detailed forecast tables, expenditure, Table 4.1), then the +# 2025-26 outturn and the forecast to 2031-32 from the October 2026 EFO +# (Table 5.1). +OBR_RECEIPTS_YEARS = range(2024, 2032) OBR_RECEIPTS = { - "england": [41.2225, 44.1172, 46.5197, 49.3324, 52.3663, 55.308, 58.3527], - "scotland": [2.9384, 3.0512, 3.1684, 3.2901, 3.4164, 3.5476, 3.6839], - "wales": [2.2284, 2.4008, 2.5793, 2.771, 2.9771, 3.1984, 3.4362], + "england": [41.2225, 44.117, 46.806, 49.2566, 52.0217, 54.9103, 57.8847, 60.9565], + "scotland": [2.9384, 3.0519, 3.1699, 3.2924, 3.4196, 3.5518, 3.6891, 3.8316], + "wales": [2.2284, 2.4008, 2.5784, 2.7691, 2.9739, 3.1939, 3.4301, 3.6839], } # The liability behind each country's OBR line, net of council tax reduction, @@ -136,11 +138,12 @@ def _uprated_council_tax(regions, council_tax, year): def test_uprate_council_tax_holds_northern_ireland_flat(): # In 2025-26 OBR's council tax receipts grow 7.02% in England, 7.73% in - # Wales and 3.84% in Scotland (March 2026 EFO, Table 4.1), and household - # weights grow 0.30%, with population. So a £1,000 bill becomes + # Wales and 3.86% in Scotland (October 2026 EFO, Table 5.1, over the March + # 2026 EFO's 2024-25 outturn), and household weights grow 0.30%, with + # population. So a £1,000 bill becomes # £1,000 x 1.0702 / 1.0030 = £1,067.00 in London, # £1,000 x 1.0773 / 1.0030 = £1,074.08 in Wales and - # £1,000 x 1.0384 / 1.0030 = £1,035.29 in Scotland. Northern Ireland has + # £1,000 x 1.0386 / 1.0030 = £1,035.49 in Scotland. Northern Ireland has # no council tax series and keeps £1,000; it used to fall through to # England's growth, because the code compared the region with # "NORTHERN IRELAND" (a space) while the dataset label is NORTHERN_IRELAND. @@ -149,7 +152,7 @@ def test_uprate_council_tax_holds_northern_ireland_flat(): ) assert council_tax == pytest.approx( - [1_067.00, 1_074.08, 1_035.29, 1_000.0], abs=0.005 + [1_067.00, 1_074.08, 1_035.49, 1_000.0], abs=0.005 ) @@ -296,11 +299,11 @@ def _weighted_totals(dataset): def test_country_totals_track_obr_receipts(): - """Project a dataset from 2024-25 to 2030-31 with unequal weights and + """Project a dataset from 2024-25 to 2031-32 with unequal weights and bills. Each country's weighted council tax total grows as OBR forecasts its receipts to grow. Each year's growth is within 0.0001 of OBR's: the - series rounds each year to 4 decimals, and holds Wales at 0.0743 from - 2026, where Table 4.1 implies 0.0743 to 0.0744. Before #2067 the totals + series rounds each year to 4 decimals, and holds Wales at 0.0740 from + 2026, where Table 5.1 implies 0.0739 to 0.0740. Before #2067 the totals also grew with the weights, by population, and were 2.8% too high by 2030-31. """ @@ -311,7 +314,7 @@ def test_country_totals_track_obr_receipts(): weights=[3_000.0, 1_000.0, 2_500.0, 1_200.0, 800.0, 1_500.0], fiscal_year=2024, ) - projected = extend_single_year_dataset(dataset, parameters, end_year=2030) + projected = extend_single_year_dataset(dataset, parameters, end_year=2031) totals = {year: _weighted_totals(projected[year]) for year in OBR_RECEIPTS_YEARS} for series, receipts in OBR_RECEIPTS.items(): @@ -320,8 +323,8 @@ def test_country_totals_track_obr_receipts(): growth = totals[year][series] / totals[year - 1][series] - 1 obr_growth = receipts[year] / receipts[year - 1] - 1 assert growth == pytest.approx(obr_growth, abs=1e-4), (series, year) - assert totals[2030][series] / totals[2024][series] == pytest.approx( - receipts[2030] / receipts[2024], rel=5e-4 + assert totals[2031][series] / totals[2024][series] == pytest.approx( + receipts[2031] / receipts[2024], rel=5e-4 ), series diff --git a/policyengine_uk/tests/test_import_obr_forecasts.py b/policyengine_uk/tests/test_import_obr_forecasts.py index 58db83d3f4..5e9d9ecb18 100644 --- a/policyengine_uk/tests/test_import_obr_forecasts.py +++ b/policyengine_uk/tests/test_import_obr_forecasts.py @@ -482,7 +482,10 @@ def make_receipts_xlsx( northern_ireland_label: str = "Northern Ireland business rates", outturn_years: int = 1, sdlt_rows: list[tuple[str, tuple]] | None = None, + chapter: int = 3, ) -> bytes: + """Receipts tables numbered in ``chapter``: 3 to March 2026, 4 from + October 2026.""" levels = levels or RECEIPTS_LEVELS sheet_318 = make_sheet({2: [make_inline_cell("B2", "Other table")]}) sheet_319 = make_sheet( @@ -515,11 +518,11 @@ def make_receipts_xlsx( ) ], # The contents list names tables but holds none of their rows. - 6: [make_inline_cell("B6", "3.2 Other taxes")], + 6: [make_inline_cell("B6", f"{chapter}.2 Other taxes")], } ) - sheets["3.2"] = receipts_table( - "3.2 Other taxes", + sheets[f"{chapter}.2"] = receipts_table( + f"{chapter}.2 Other taxes", first_year, [ ( @@ -531,8 +534,8 @@ def make_receipts_xlsx( ], outturn_years=outturn_years, ) - sheets["3.7"] = receipts_table( - "3.7 Property transactions taxes: Receipts by sector", + sheets[f"{chapter}.7"] = receipts_table( + f"{chapter}.7 Property transactions taxes: Receipts by sector", first_year, sdlt_rows if sdlt_rows is not None @@ -551,8 +554,8 @@ def make_receipts_xlsx( ) # An accrued table with a "Business rates" row of its own, which the # cash-basis series must not read. - sheets["3.5"] = receipts_table( - "3.5 Current receipts (on an accrued basis)", + sheets[f"{chapter}.5"] = receipts_table( + f"{chapter}.5 Current receipts (on an accrued basis)", first_year, [("Business rates", (99.0,) * len(levels["great_britain"]))], outturn_years=outturn_years, @@ -568,8 +571,8 @@ def make_receipts_xlsx( first_column=4, outturn_years=outturn_years, ) - sheets["3.18"] = sheet_318 - sheets["3.19"] = sheet_319 + sheets[f"{chapter}.18"] = sheet_318 + sheets[f"{chapter}.19"] = sheet_319 return make_workbook(sheets) @@ -1411,31 +1414,46 @@ def test_rendered_growth_compounds_the_published_levels(years, data): assert render(rendered, current=current, previous=previous) == rendered -# Published OBR receipts levels as the workbooks hold them (£bn): the March -# 2026 EFO from 2024-25 and the March 2025 EFO from 2023-24. +# Published OBR receipts levels as the workbooks hold them (£bn): the October +# 2026 EFO from 2025-26 and the March 2026 EFO from 2024-25. +OCTOBER_2026_RECEIPTS = { + "residential": ("11.55444496305409", "11.598497804863152", "12.81121827423391", "14.275385542155488", "15.523034837312446", "16.708206755202507", "17.97120998332108"), + "non_residential": ("3.6048001541859174", "3.4392848579522055", "4.060008995487192", "4.6692547224804075", "4.8746831796154595", "5.306606478148783", "5.725680069577546"), + "great_britain": ("33.929814327646056", "35.43608032863263", "37.21735218338801", "38.66510919685915", "41.462982206056644", "42.42035811098974", "43.447399285510656"), + "northern_ireland": ("0.3955394050104385", "0.40595301023058955", "0.414556055466312", "0.4226801104356366", "0.43095512116333085", "0.4394491849889923", "0.44783993918412923"), +} # fmt: skip MARCH_2026_RECEIPTS = { "residential": ("10.379999999999999", "11.731471524432562", "13.428906667032589", "14.984943814530874", "16.673948133476184", "17.964513468126285", "19.057301113969185"), "non_residential": ("3.5049999999999999", "3.6750451743530199", "4.72127759316189", "5.3288288104799904", "5.9009139798817092", "6.5330695355310402", "7.1046581772762902"), "great_britain": ("32.376814327646052", "34.051963932489258", "37.413586572144581", "38.240930947824609", "39.111850954748434", "42.419067764546902", "42.463193622519263"), "northern_ireland": ("0.38233350730688931", "0.39471664406441903", "0.40263364127921164", "0.41045270712298504", "0.41810894612429189", "0.42590403232705243", "0.43449009714292341"), } # fmt: skip -MARCH_2025_RECEIPTS = { - "residential": ("8.57", "10.067621905140079", "11.260655778417849", "13.448356441943533", "15.629462727222798", "17.837320625934193", "19.309303893346414"), - "non_residential": ("3.0449999999999999", "3.51897590165244", "2.8597545561212101", "3.7329253327014698", "4.2294622915006306", "4.6980571035732099", "5.2115072362568595"), - "great_britain": ("29.599814327646055", "32.080747417794186", "34.009749097370083", "37.622908483210999", "37.878733699384433", "38.522006059307493", "39.56809170547703"), - "northern_ireland": ("0.37029404557706441", "0.38436854999535813", "0.39453673994468591", "0.40107161940999719", "0.40924102844267779", "0.41720986951771938", "0.42505803014305893"), -} # fmt: skip -def test_march_2026_tables_reproduce_the_committed_series(): - """yoy_growth.yaml holds exactly what the importer writes from the March - 2026 receipts tables (Tables 3.7, 3.8 and 3.2) and the March 2025 ones - (3.7, 3.9 and 3.2): rerunning it on the committed file changes nothing.""" +def test_october_2026_tables_reproduce_the_committed_series(): + """yoy_growth.yaml holds exactly what the importer writes from the + October 2026 receipts tables (Tables 4.7, 4.8 and 4.2) and the March 2026 + ones (3.7, 3.8 and 3.2): rerunning it on the committed file changes + nothing.""" committed = get_yoy_growth_path().read_text() rendered = render( committed, - current=make_receipts_xlsx(levels=MARCH_2026_RECEIPTS), - previous=make_previous_receipts_xlsx(levels=MARCH_2025_RECEIPTS), + current=make_receipts_xlsx( + release="October 2026", + first_year=2025, + levels=OCTOBER_2026_RECEIPTS, + cash_table="4.8", + chapter=4, + ), + previous=make_previous_receipts_xlsx( + release="March 2026", + first_year=2024, + levels=MARCH_2026_RECEIPTS, + cash_table="3.8", + northern_ireland_label="Northern Ireland business rates", + ), + release=("October", 2026), + previous_release=("March", 2026), ) assert rendered == committed @@ -1445,6 +1463,10 @@ def test_march_2026_tables_reproduce_the_committed_series(): year: (REAL_RECEIPTS_DIR / f"obr_efo_march_{year}_receipts.xlsx").read_bytes() for year in (2025, 2026) } +REAL_OCTOBER_2026_RECEIPTS = ( + REAL_RECEIPTS_DIR / "obr_efo_october_2026_receipts.xlsx" +).read_bytes() +COMMITTED_RELEASES = {"release": ("October", 2026), "previous_release": ("March", 2026)} XLSX_MAIN = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" XLSX_NS = {"m": XLSX_MAIN} @@ -1462,7 +1484,7 @@ def mutate_real_receipts(workbook, table, unit, scale=1): for node in ET.fromstring(source.read("xl/sharedStrings.xml")) ] sheet = ET.fromstring(source.read(path)) - first_column = "D" if table in ("3.8", "3.9") else "C" + first_column = "D" if table in ("3.8", "3.9", "4.8") else "C" cell = sheet.find(f"m:sheetData/m:row/m:c[@r='{first_column}3']", XLSX_NS) cell.clear() cell.attrib.update(r=f"{first_column}3", t="inlineStr") @@ -1489,11 +1511,21 @@ def mutate_real_receipts(workbook, table, unit, scale=1): def test_real_receipts_workbooks_reproduce_committed_yaml_byte_for_byte(): committed = get_yoy_growth_path().read_bytes() rendered = render( - committed.decode(), current=REAL_RECEIPTS[2026], previous=REAL_RECEIPTS[2025] + committed.decode(), + current=REAL_OCTOBER_2026_RECEIPTS, + previous=REAL_RECEIPTS[2026], + **COMMITTED_RELEASES, ) assert rendered.encode() == committed +def test_october_2026_cash_receipts_cite_the_sheet_not_the_misprinted_title(): + # The October 2026 workbook titles sheet 4.8 "43.8 Current receipts (on a + # cash basis)"; its contents sheet and sheet name say 4.8. + growth = compute_receipts_growth(REAL_OCTOBER_2026_RECEIPTS, REAL_RECEIPTS[2026]) + assert growth[("business_rates", "great_britain")].line.table == "4.8" + + @pytest.mark.parametrize( "year, tables", [(2026, ("3.2", "3.7", "3.8")), (2025, ("3.2", "3.7", "3.9"))] ) @@ -1544,8 +1576,9 @@ def test_explicit_billion_unit_aliases_preserve_the_real_workbook_output(unit): assert ( render( get_yoy_growth_path().read_text(), - current=mutate_real_receipts(REAL_RECEIPTS[2026], "3.8", unit), - previous=mutate_real_receipts(REAL_RECEIPTS[2025], "3.9", unit), + current=mutate_real_receipts(REAL_OCTOBER_2026_RECEIPTS, "4.8", unit), + previous=mutate_real_receipts(REAL_RECEIPTS[2026], "3.8", unit), + **COMMITTED_RELEASES, ).encode() == get_yoy_growth_path().read_bytes() ) diff --git a/policyengine_uk/tests/test_population_vintage.py b/policyengine_uk/tests/test_population_vintage.py index 4e3b0ed6fc..7861146b57 100644 --- a/policyengine_uk/tests/test_population_vintage.py +++ b/policyengine_uk/tests/test_population_vintage.py @@ -13,7 +13,9 @@ 2025-26 values to 1e-9 per cent. per_capita.*: (1 + aggregate growth) / (1 + ons.population) - 1, rounded to 4 -decimals, with calendar-year aggregates from the same EFO tables. +decimals, with calendar-year aggregates from the October 2026 EFO tables. The +long-term determinants for the October 2026 EFO are not yet published, so +population stays on the March 2026 vintage until they are. """ import pytest @@ -98,20 +100,21 @@ 2025: 106.69186884652444, } -# March 2026 EFO calendar-year totals, GBP billion. +# October 2026 EFO calendar-year totals, GBP billion. # Table 1.4 nominal GDP (annual growth equals Table A.1 nominal GDP growth). NOMINAL_GDP = { 2020: 2124.72, 2021: 2322.652, 2022: 2580.949, 2023: 2752.164, - 2024: 2890.664, - 2025: 3036.746486, - 2026: 3136.973465, - 2027: 3248.777377, - 2028: 3362.463387, - 2029: 3477.144474, - 2030: 3599.757631, + 2024: 2890.254, + 2025: 3033.866, + 2026: 3161.458961, + 2027: 3263.816753, + 2028: 3381.78475, + 2029: 3510.878469, + 2030: 3640.284132, + 2031: 3770.105082, } # Table 1.12 mixed income. MIXED_INCOME = { @@ -119,13 +122,14 @@ 2021: 162.369, 2022: 168.687, 2023: 169.885, - 2024: 176.374, - 2025: 178.87647080000002, - 2026: 185.0544149, - 2027: 192.6154851, - 2028: 200.4094443, - 2029: 208.40325, - 2030: 216.8960756, + 2024: 176.333, + 2025: 177.725, + 2026: 183.374482, + 2027: 189.543244, + 2028: 196.611717, + 2029: 204.513402, + 2030: 213.30725, + 2031: 222.381054, } @@ -160,7 +164,7 @@ def _per_capita(aggregate_growth, year): return round((1 + aggregate_growth) / (1 + POPULATION(f"{year}-01-01")) - 1, 4) -@pytest.mark.parametrize("year", range(2021, 2031)) +@pytest.mark.parametrize("year", range(2021, 2032)) def test_per_capita_gdp_divides_nominal_gdp_by_population(year): growth = NOMINAL_GDP[year] / NOMINAL_GDP[year - 1] - 1 assert YOY.obr.per_capita.gdp(f"{year}-01-01") == pytest.approx( @@ -168,7 +172,7 @@ def test_per_capita_gdp_divides_nominal_gdp_by_population(year): ) -@pytest.mark.parametrize("year", range(2021, 2031)) +@pytest.mark.parametrize("year", range(2021, 2032)) def test_per_capita_mixed_income_divides_mixed_income_by_population(year): growth = MIXED_INCOME[year] / MIXED_INCOME[year - 1] - 1 assert YOY.obr.per_capita.mixed_income(f"{year}-01-01") == pytest.approx( @@ -176,7 +180,7 @@ def test_per_capita_mixed_income_divides_mixed_income_by_population(year): ) -@pytest.mark.parametrize("year", range(2021, 2031)) +@pytest.mark.parametrize("year", range(2021, 2032)) def test_per_capita_non_labour_income_divides_by_population(year): growth = YOY.obr.non_labour_income(f"{year}-01-01") assert YOY.obr.per_capita.non_labour_income(f"{year}-01-01") == pytest.approx( diff --git a/policyengine_uk/tests/test_private_school_vat_receipts.py b/policyengine_uk/tests/test_private_school_vat_receipts.py index c29f5b3d24..73fbee9b34 100644 --- a/policyengine_uk/tests/test_private_school_vat_receipts.py +++ b/policyengine_uk/tests/test_private_school_vat_receipts.py @@ -39,16 +39,16 @@ BASIS = "gov.simulation.private_school_vat.private_school_vat_basis" FACTOR = 0.67 * 0.7 # HMRC's OBR-certified costing of VAT on private school fees (Autumn Budget -# 2024 Table 5.1, £m) and OBR cash-basis VAT receipts (March 2026 EFO detailed -# forecast tables, receipts, sheet 3.8, row 13, cells E13:I13, £m), by the -# model year of each fiscal year. +# 2024 Table 5.1, £m) and OBR cash-basis VAT receipts (October 2026 EFO +# detailed forecast tables, receipts, sheet 4.8, row 13, cells D13:H13, £m), +# by the model year of each fiscal year. COSTING = {2025: 1_505, 2026: 1_560, 2027: 1_610, 2028: 1_665, 2029: 1_725} RECEIPTS = { - 2025: 180_168.94, - 2026: 187_704.37, - 2027: 195_922.62, - 2028: 204_591.27, - 2029: 213_118.19, + 2025: 179_861.00, + 2026: 186_154.08, + 2027: 193_973.60, + 2028: 203_284.38, + 2029: 211_700.88, } # The share is zero before the 2025-26 model year and the 2029-30 value is # held from then on. diff --git a/policyengine_uk/tests/test_rent_uprating.py b/policyengine_uk/tests/test_rent_uprating.py index ab8db6a109..71c54feed2 100644 --- a/policyengine_uk/tests/test_rent_uprating.py +++ b/policyengine_uk/tests/test_rent_uprating.py @@ -47,7 +47,7 @@ def test_uprate_rent_uses_tenure_specific_growth(): def test_forecast_private_rent_preserves_obr_aggregate_growth(): growth = parameters.gov.economic_assumptions.yoy_growth - for year in range(2026, 2031): + for year in range(2026, 2032): private_rent_growth = growth.ons.private_rental_prices(year)["UNITED_KINGDOM"] social_rent_growth = growth.obr.social_rent(year) aggregate_rent_growth = growth.obr.rent(year) @@ -61,7 +61,7 @@ def test_forecast_private_rent_preserves_obr_aggregate_growth(): REGIONS = [region.name for region in Region] TENURES = ["RENT_PRIVATELY", "RENT_FROM_COUNCIL", "RENT_FROM_HA", "OWNED_OUTRIGHT"] -UPRATED_YEARS = list(range(2022, 2031)) +UPRATED_YEARS = list(range(2022, 2032)) def _uprated_rent(regions, tenures, rents, year): diff --git a/policyengine_uk/tests/test_september_cpi_uprating.py b/policyengine_uk/tests/test_september_cpi_uprating.py index d55644835c..57c0b35f45 100644 --- a/policyengine_uk/tests/test_september_cpi_uprating.py +++ b/policyengine_uk/tests/test_september_cpi_uprating.py @@ -103,9 +103,9 @@ def test_published_september_rates_give_the_april_rises(): def test_april_2028_rise_is_the_obr_september_2027_forecast(): - """OBR March 2026 EFO: calendar-year 2027 CPI plus the receipts Table 3.19 - gap for September 2027 (2.0719%), applied as the published 2.1%.""" - assert rise(system.parameters, 2028) == 0.021 + """OBR October 2026 EFO: calendar-year 2027 CPI plus the receipts Table + 4.19 gap for September 2027 (3.4400%), applied as the published 3.4%.""" + assert rise(system.parameters, 2028) == 0.034 def test_the_index_rises_by_each_april_rise(): @@ -171,7 +171,7 @@ def test_uc_childcare_caps_rise_by_september_cpi_in_april_2027(children, expecte def test_every_parameter_on_the_index_rises_by_september_cpi_after_its_last_value(): """After its last published value, each parameter uprated by the index rises by the April rise: 0% in April 2016, 3.5% in April 2027, - and 2.1% in April 2028, with any configured benefit-specific rounding.""" + and 3.4% in April 2028, with any configured benefit-specific rounding.""" parameters = system.parameters # The processed tree, including its baseline copy, is uprated, so read # the YAML files for the last published dates. @@ -311,13 +311,13 @@ def test_scenario_setting_september_cpi_moves_the_next_april(): def test_scenario_on_calendar_cpi_moves_the_forecast_with_the_obr_gap(): """Calendar-year CPI for 2027 moves the September 2027 forecast one for - one (keeping the OBR's +0.072pp gap), and so the April 2028 rise.""" + one (keeping the OBR's +0.02pp gap), and so the April 2028 rise.""" parameters = parameters_under( {f"{OBR}.consumer_price_index": {"year:2027-01-01:1": 0.04}} ) - assert rise(parameters, 2028) == 0.041 + assert rise(parameters, 2028) == 0.040 assert carers_allowance(parameters, 2028) == pytest.approx( - carers_allowance(parameters, 2027) * 1.041, abs=PENNY_TENTH + carers_allowance(parameters, 2027) * 1.040, abs=PENNY_TENTH ) diff --git a/policyengine_uk/tests/test_triple_lock_statutory_inputs.py b/policyengine_uk/tests/test_triple_lock_statutory_inputs.py index 69a84d1a1f..4aa7545fb7 100644 --- a/policyengine_uk/tests/test_triple_lock_statutory_inputs.py +++ b/policyengine_uk/tests/test_triple_lock_statutory_inputs.py @@ -103,22 +103,29 @@ def test_forecasts_are_calendar_growth_plus_the_obr_gap( assert statutory(observed) == pytest.approx( calendar(f"{year}-01-01") + gap(observed), abs=1e-12 ), year - if year > 2030: + if year > 2031: # After the EFO horizon the forecast is calendar-year growth. assert gap(observed) == 0 assert statutory(f"{last_year + 1}-{month_day}") is None -# OBR March 2026 EFO: September CPI from receipts Table 3.19 ("CPI used to -# uprate thresholds"), Q3 CPI from economy Table 1.7 for 2030, and Q2 average +# OBR October 2026 EFO: September CPI from receipts Table 4.19 ("CPI used to +# uprate thresholds"), Q3 CPI from economy Table 1.7 for 2031, and Q2 average # earnings growth on a year earlier from economy Table 1.6. OBR_SEPTEMBER_CPI = { - 2027: 0.020719, - 2028: 0.020299, - 2029: 0.020480, - 2030: 0.019996, + 2027: 0.034400, + 2028: 0.020420, + 2029: 0.021727, + 2030: 0.020146, + 2031: 0.019997, +} +OBR_Q2_EARNINGS = { + 2027: 0.032961, + 2028: 0.021251, + 2029: 0.022559, + 2030: 0.024586, + 2031: 0.026141, } -OBR_Q2_EARNINGS = {2027: 0.024266, 2028: 0.020795, 2029: 0.021852, 2030: 0.023890} def test_baseline_forecasts_reproduce_the_obr_statutory_forecasts(): @@ -136,31 +143,12 @@ def test_baseline_forecasts_reproduce_the_obr_statutory_forecasts(): def test_rule_reproduces_the_obr_triple_lock_forecast_from_its_own_inputs(): - """OBR Long-term economic determinants (March 2026 EFO), 'Triple Lock' - row: 3.7% in April 2027 and 2.5% in April 2028-2031. With the published - May-July 2026 figure removed, so earnings follow the OBR forecast, the - rule gives the same rates.""" - - def drop_may_july_2026(simulation): - system_ = simulation.tax_benefit_system - system_.reset_parameters() - statutory_inputs(system_.parameters).awe_total_pay_may_july.update( - period="year:2026-07-01:1", value=None - ) - system_.process_parameters() - - simulation = Simulation( - situation=PENSIONER, - scenario=Scenario( - simulation_modifier=drop_may_july_2026, applied_before_data_load=True - ), - ) - parameters = simulation.tax_benefit_system.parameters - assert statutory_inputs(parameters).awe_total_pay_may_july( - "2026-07-01" - ) == pytest.approx(0.036736, abs=1e-5) - assert [uprating(parameters, year) for year in range(2027, 2032)] == ( - pytest.approx([0.037, 0.025, 0.025, 0.025, 0.025]) + """OBR October 2026 EFO, Table A.3, 'Triple-lock' guarantee: 3.9% in April + 2027 (May-July 2026 earnings, published before the forecast closed), + 3.4% in April 2028 (September 2027 CPI), 2.5% in April 2029-2031 and 2.6% + in April 2032 (May-July 2031 earnings). The rule gives the same rates.""" + assert [uprating(system.parameters, year) for year in range(2027, 2033)] == ( + pytest.approx([0.039, 0.034, 0.025, 0.025, 0.025, 0.026]) ) @@ -176,8 +164,8 @@ def test_horizon_runs_to_the_end_of_the_economic_assumptions(): def test_macro_scenario_on_calendar_growth_moves_the_uprating(): - """Raising 2027 earnings growth from 2.4% to 5% moves May-July 2027 - earnings with it (plus the OBR gap, 0.027pp) and so the April 2028 rise. + """Raising 2027 earnings growth from 2.99% to 5% moves May-July 2027 + earnings with it (plus the OBR gap, 0.306pp) and so the April 2028 rise. Calendar-year series are keyed to 1 January, so the change is keyed year:2027-01-01:1; a bare "2027" names the fiscal year from 6 April 2027 @@ -187,9 +175,9 @@ def test_macro_scenario_on_calendar_growth_moves_the_uprating(): ) assert statutory_inputs(parameters).awe_total_pay_may_july( "2027-07-01" - ) == pytest.approx(0.05 + 0.00027) - assert uprating(parameters, 2028) == pytest.approx(0.05) - assert uprating(system.parameters, 2028) == pytest.approx(0.025) + ) == pytest.approx(0.05 + 0.00306) + assert uprating(parameters, 2028) == pytest.approx(0.053) + assert uprating(system.parameters, 2028) == pytest.approx(0.034) assert new_state_pension_weekly(parameters, 2028) > new_state_pension_weekly( system.parameters, 2028 ) @@ -235,10 +223,10 @@ def test_macro_scenario_moves_the_state_pension_in_a_microsimulation(): full_rate_2027 = 241.30 * 1.039 # Uprating indices are stored to 5 decimal places. assert baseline_pension == pytest.approx( - full_rate_2027 * 1.025 * WEEKS_IN_YEAR, rel=1e-5 + full_rate_2027 * 1.034 * WEEKS_IN_YEAR, rel=1e-5 ) assert reformed_pension == pytest.approx( - full_rate_2027 * 1.05 * WEEKS_IN_YEAR, rel=1e-5 + full_rate_2027 * 1.053 * WEEKS_IN_YEAR, rel=1e-5 ) diff --git a/policyengine_uk/tests/test_water_bills_growth.py b/policyengine_uk/tests/test_water_bills_growth.py index eea30ba5c3..d0ae401aae 100644 --- a/policyengine_uk/tests/test_water_bills_growth.py +++ b/policyengine_uk/tests/test_water_bills_growth.py @@ -47,8 +47,8 @@ def test_stored_bills_reach_the_pr24_final_determination_in_real_terms(): @pytest.mark.parametrize( "year, growth", - # 1.02833 real growth times 1 + CPIH t-1 (2.55%, 2.11%, 2.04%). - [(2027, 0.055), (2028, 0.050), (2029, 0.049)], + # 1.02833 real growth times 1 + CPIH t-1 (3.24%, 3.30%, 2.14%). + [(2027, 0.062), (2028, 0.062), (2029, 0.050)], ) def test_projected_water_bill_growth(year, growth): assert WATER_BILLS(f"{year}-01-01") == pytest.approx(growth) diff --git a/policyengine_uk/utils/create_ahc_deflator.py b/policyengine_uk/utils/create_ahc_deflator.py index b23782fc4c..5e29edbcd6 100644 --- a/policyengine_uk/utils/create_ahc_deflator.py +++ b/policyengine_uk/utils/create_ahc_deflator.py @@ -62,7 +62,7 @@ def create_modified_cpi_forecast( historical_modified_cpi, initial_weights, forecast_start_year=2026, - forecast_end_year=2030, + forecast_end_year=2031, ): cpi_values = get_parameter_values( cpi_parameter, forecast_start_year, forecast_end_year diff --git a/policyengine_uk/utils/import_obr_forecasts.py b/policyengine_uk/utils/import_obr_forecasts.py index d950da7652..f6db9bebc6 100644 --- a/policyengine_uk/utils/import_obr_forecasts.py +++ b/policyengine_uk/utils/import_obr_forecasts.py @@ -586,6 +586,7 @@ def update_forecast_gap_yaml( TABLE_TITLE_RE = re.compile(r"^(\d+\.\d+)\s+(.+)$") +TABLE_NUMBER_RE = re.compile(r"\d+\.\d+") FOOTNOTE_RE = re.compile(r"(?<=[a-z])\d+$", re.IGNORECASE) VALUE_LINE_RE = re.compile(r"^\s*(\d{4})-\d{2}-\d{2}:") @@ -844,6 +845,11 @@ def find_receipts_line( ordered = sorted(levels) if ordered != list(range(ordered[0], ordered[-1] + 1)): raise ValueError(f"{where} skips a year: {ordered}") + # The sheet name and the contents sheet number each table too. Where the + # title cell disagrees, the title is the misprint: October 2026 titles + # sheet 4.8 "43.8 Current receipts (on a cash basis)". + if TABLE_NUMBER_RE.fullmatch(sheet): + table = sheet return ReceiptsLine( table=table, label=FOOTNOTE_RE.sub("", " ".join(str(label).split())), From 4d749fe26b11e2f70dc575f5e81a566aba881023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:02:17 +0000 Subject: [PATCH 02/10] Document the October 2026 EFO update Co-Authored-By: Claude Opus 5.5 --- docs/book/assumptions/growthfactors.md | 80 +++++++-------- docs/book/assumptions/water-bills.md | 2 +- docs/book/programs/gov/dwp/state-pension.md | 13 ++- docs/engineering/vat-coverage.md | 19 ++-- .../gov/economic_assumptions/README.md | 99 ++++++++++++------- 5 files changed, 125 insertions(+), 88 deletions(-) diff --git a/docs/book/assumptions/growthfactors.md b/docs/book/assumptions/growthfactors.md index b26c734edc..29112514f4 100644 --- a/docs/book/assumptions/growthfactors.md +++ b/docs/book/assumptions/growthfactors.md @@ -1,7 +1,7 @@ # Economic assumptions ```{note} -We project economic variables using year-over-year growth rates stored in `parameters/gov/economic_assumptions/yoy_growth.yaml`. We generate index values from these rates to update household variables. We source all values from the OBR's long-term economic determinants and Economic and Fiscal Outlook ([March 2025](https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/)) unless we specify otherwise. The long-term determinants provide extended forecasts beyond the standard forecast horizon. +We project economic variables using year-over-year growth rates stored in `parameters/gov/economic_assumptions/yoy_growth.yaml`. We generate index values from these rates to update household variables. We source all values from the OBR's long-term economic determinants and Economic and Fiscal Outlook ([October 2026](https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/)) unless we specify otherwise. The long-term determinants provide extended forecasts beyond the standard forecast horizon. ``` ## Consumer price index @@ -10,9 +10,9 @@ We project economic variables using year-over-year growth rates stored in `param We use the OBR's CPI projections to drive most benefit and consumption variables. ``` -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 10.0% | 5.7% | 2.3% | 3.2% | 1.9% | 2.0% | 2.0% | 2.0% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 9.1% | 7.3% | 2.5% | 3.4% | 3.1% | 3.4% | 2.1% | 2.1% | 2.0% | 2.0% | We apply CPI to these variables: - All reported benefits– `carers_allowance_reported`, `child_benefit_reported`, `child_tax_credit_reported`, `esa_contrib_reported`, `esa_income_reported`, `housing_benefit_reported`, `iidb_reported`, `incapacity_benefit_reported`, `income_support_reported`, `jsa_contrib_reported`, `jsa_income_reported`, `maternity_allowance_reported`, `pension_credit_reported`, `sda_reported`, `state_pension_reported`, `universal_credit_reported`, `winter_fuel_allowance_reported`, `working_tax_credit_reported` @@ -32,9 +32,9 @@ column missing and household situations retain CPI uprating. See the We use HMRC road-fuel clearances and OBR-implied forecast volumes for petrol and diesel spending, because PolicyEngine converts these spending fields into litres by dividing by pump prices. -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 6.3% | -0.6% | -0.1% | -2.0% | -1.4% | -2.4% | -2.7% | -3.7% | +| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 6.3% | -0.6% | -0.1% | -1.3% | -2.3% | -3.1% | -3.1% | -4.0% | -5.4% | -6.5% | We apply this to: `diesel_spending`, `petrol_spending` @@ -58,9 +58,9 @@ rates after their last published value. We apply the OBR's wage growth forecasts to employment-related variables. ``` -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 6.4% | 6.9% | 4.7% | 3.7% | 2.2% | 2.1% | 2.3% | 2.5% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 6.1% | 6.2% | 5.1% | 4.1% | 3.7% | 3.0% | 2.1% | 2.3% | 2.5% | 2.6% | We use average earnings for these variables: `employee_pension_contributions`, `employer_pension_contributions`, `employment_income`, `employment_income_before_lsr`, `personal_pension_contributions`, `student_loan_repayments` @@ -91,29 +91,29 @@ write-off approximations are unchanged. We lag earnings growth by one year and use that to uprate housing service charges (including ground rent). -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 5.9% | 6.4% | 6.9% | 4.7% | 3.7% | 2.2% | 2.1% | 2.3% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 5.9% | 6.1% | 6.2% | 5.1% | 4.1% | 3.7% | 3.0% | 2.1% | 2.3% | 2.5% | ## Per capita GDP -We derive these rates as calendar-year nominal GDP growth from the OBR's March 2026 EFO divided by population growth: (1 + GDP growth) / (1 + population growth) − 1. +We derive these rates as calendar-year nominal GDP growth from the OBR's October 2026 EFO divided by population growth: (1 + GDP growth) / (1 + population growth) − 1. -| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 10.0% | 5.2% | 3.9% | 4.7% | 2.9% | 3.3% | 3.2% | 3.1% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 10.0% | 5.2% | 3.9% | 4.7% | 3.8% | 2.9% | 3.3% | 3.5% | 3.3% | 3.3% | We use per capita GDP for these variables: `benunit_reported_capital`, `capital_gains`, `capital_gains_badr`, `capital_gains_before_response`, `capital_gains_carried_interest`, `capital_gains_residential_property`, `cash_isa`, `corporate_wealth`, `directly_held_shares`, `dividend_income`, `gross_financial_wealth`, `household_lifetime_isa_balance`, `lifetime_isa_balance`, `lump_sum_income`, `main_residence_value`, `maintenance_income`, `miscellaneous_income`, `mortgage_capital_repayment`, `net_financial_wealth`, `non_residential_property_value`, `other_investment_income`, `other_residential_property_value`, `owned_land`, `pension_credit_reported_capital`, `pension_income`, `private_pension_wealth`, `private_transfer_income`, `property_income`, `property_rental_income`, `savings`, `savings_interest_income`, `spousal_maintenance_income`, `stocks_and_shares_isa`, `sublet_income`, `uc_reported_capital`, `unit_and_investment_trusts` ## Council tax -We project each country's council tax receipts, net of council tax reduction, with the OBR's forecasts (March 2026 EFO, Expenditure Table 4.1) from 2025-26, and official outturns before then: MHCLG's council tax requirement for England, the Scottish Government's net amount billed and the Welsh Government's net collectable debit. +We project each country's council tax receipts, net of council tax reduction, with the OBR's figures (October 2026 EFO, Expenditure Table 5.1) from 2025-26, and official outturns before then: MHCLG's council tax requirement for England, the Scottish Government's net amount billed and the Welsh Government's net collectable debit. -| Fiscal year | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | -|-------------|------|------|------|------|------|------|------|------| -| England | 6.6% | 6.5% | 7.0% | 5.5% | 6.1% | 6.2% | 5.6% | 5.5% | -| Scotland | 6.4% | 2.4% | 3.8% | 3.8% | 3.8% | 3.8% | 3.8% | 3.8% | -| Wales | 7.1% | 9.9% | 7.7% | 7.4% | 7.4% | 7.4% | 7.4% | 7.4% | +| Fiscal year | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------| +| England | 6.6% | 6.5% | 7.0% | 6.1% | 5.2% | 5.6% | 5.5% | 5.4% | 5.3% | +| Scotland | 6.4% | 2.4% | 3.9% | 3.9% | 3.9% | 3.9% | 3.9% | 3.9% | 3.9% | +| Wales | 7.1% | 9.9% | 7.7% | 7.4% | 7.4% | 7.4% | 7.4% | 7.4% | 7.4% | Receipts are the Band D level times the tax base, the number of Band D equivalent dwellings, so they grow with the number of homes as well as with bills. Household weights grow with population, so each household's `council_tax` grows by its country's receipts growth divided by population growth: (1 + receipts growth) / (1 + population growth) − 1. Each country's weighted total then grows with its receipts. Northern Ireland has no council tax (it has domestic rates), so any `council_tax` a dataset gives its households is held flat. @@ -121,9 +121,9 @@ Receipts are the Band D level times the tax base, the number of Band D equivalen We use the OBR's mortgage interest rate index growth rates. -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 26.2% | 48.5% | 22.1% | 13.6% | 12.6% | 8.2% | 4.2% | 4.7% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 14.6% | 52.2% | 27.3% | 9.5% | 6.2% | 11.6% | 6.7% | 4.8% | 5.5% | 5.5% | We apply this to: `mortgage_interest_repayment`, `property_finance_costs`, `property_finance_costs_brought_forward` @@ -131,9 +131,9 @@ We apply this to: `mortgage_interest_repayment`, `property_finance_costs`, `prop We use RPI year-on-year change from the previous year, capped at 5%. -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 5.0% | 5.0% | 5.0% | 4.7% | 3.7% | 2.2% | 2.1% | 2.3% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 5.0% | 5.0% | 5.0% | 3.6% | 4.1% | 3.6% | 4.3% | 3.0% | 3.0% | 2.3% | We apply this to: `private_pension_income` @@ -141,28 +141,28 @@ We apply this to: `private_pension_income` We use the OBR's rental growth projections. -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 4.0% | 6.3% | 7.4% | 5.7% | 3.6% | 2.7% | 2.3% | 2.4% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 3.5% | 5.8% | 7.2% | 5.4% | 3.6% | 3.2% | 2.7% | 2.6% | 2.5% | 2.8% | We apply this to: `rent` ## Per capita mixed income -We derive these rates as calendar-year mixed income growth from the OBR's March 2026 EFO (Table 1.12) divided by population growth, in the same way. +We derive these rates as calendar-year mixed income growth from the OBR's October 2026 EFO (Table 1.12) divided by population growth, in the same way. -| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 2.9% | -0.6% | 2.7% | 1.1% | 3.1% | 3.8% | 3.7% | 3.6% | +| Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 2.9% | -0.6% | 2.7% | 0.5% | 2.8% | 3.1% | 3.4% | 3.7% | 3.9% | 4.0% | We apply this to: `self_employment_income` ## Population -We use the population growth in the OBR's [long-term economic determinants for the March 2026 EFO](https://obr.uk/supplementary-forecast-information-release-long-term-economic-determinants-march-2026/): the OBR's forecast to 2030-31, then the principal projection of the [ONS 2024-based national population projections](https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/bulletins/nationalpopulationprojections/2024based). 2021-22 and 2022-23 are the same OBR series, read from the March 2026 EFO economy tables. +We use the population growth in the OBR's [long-term economic determinants for the March 2026 EFO](https://obr.uk/supplementary-forecast-information-release-long-term-economic-determinants-march-2026/): the OBR's forecast to 2030-31, then the principal projection of the [ONS 2024-based national population projections](https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/bulletins/nationalpopulationprojections/2024based). 2021-22 and 2022-23 are the same OBR series, read from the March 2026 EFO economy tables. The determinants for the October 2026 EFO are not yet published, so population stays on the March 2026 vintage until they are. -| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | -|-------------|------|------|------|------|------|------|------|------| -| Growth rate | 1.0% | 1.3% | 1.1% | 0.3% | 0.4% | 0.3% | 0.3% | 0.3% | +| Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | +|-------------|------|------|------|------|------|------|------|------|------|------| +| Growth rate | 1.0% | 1.3% | 1.1% | 0.3% | 0.4% | 0.3% | 0.3% | 0.3% | 0.4% | 0.2% | We apply this to: `household_weight` diff --git a/docs/book/assumptions/water-bills.md b/docs/book/assumptions/water-bills.md index 0aa9e88b85..6c764be137 100644 --- a/docs/book/assumptions/water-bills.md +++ b/docs/book/assumptions/water-bills.md @@ -25,7 +25,7 @@ Ofwat's [PR24 final determinations](https://www.ofwat.gov.uk/wp-content/uploads/ 1. Real growth already realised: the published 2025-26 and 2026-27 nominal increases less CPIH, 1.27 / 1.0327 × 1.054 / 1.0388 = 1.2478. 2. Real growth left: 1.3568 / 1.2478 = 1.0874, spread evenly over three years, 2.83% a year. -3. Inflation added back from `yoy_growth.obr.cpih`. Ofwat indexes bills to CPIH in the November before the charging year, so charging year t takes calendar year t-1: 1.0283 × 1.0255 = 5.5% for 2027-28, × 1.0211 = 5.0% for 2028-29, × 1.0204 = 4.9% for 2029-30. +3. Inflation added back from `yoy_growth.obr.cpih` (the OBR's October 2026 forecast). Ofwat indexes bills to CPIH in the November before the charging year, so charging year t takes calendar year t-1: 1.0283 × 1.0324 = 6.2% for 2027-28, × 1.0330 = 6.2% for 2028-29, × 1.0214 = 5.0% for 2029-30. ```{note} Open assumptions: diff --git a/docs/book/programs/gov/dwp/state-pension.md b/docs/book/programs/gov/dwp/state-pension.md index 0430650f94..8c5f1f6e74 100644 --- a/docs/book/programs/gov/dwp/state-pension.md +++ b/docs/book/programs/gov/dwp/state-pension.md @@ -250,15 +250,18 @@ growth in the matching OBR series (`yoy_growth.obr.consumer_price_index` or statutory-basis forecast minus the calendar-year growth stored in `yoy_growth.yaml`, so that in the baseline the input equals the OBR's figure: -- September CPI: the OBR's September CPI forecast (receipts Table 3.19, the - CPI used to uprate tax thresholds), or Q3 CPI (economy Table 1.7) in years - that table does not cover; +- September CPI: the OBR's September CPI forecast (receipts Table 4.19 in + the October 2026 EFO, the CPI used to uprate tax thresholds), or Q3 CPI + (economy Table 1.7) in years that table does not cover; - May-July earnings: Q2 average earnings growth (economy Table 1.6). The OBR does not forecast the ONS AWE series; its measure is wages and salaries per employee, and Q2 is the quarter nearest May to July. -After the EFO horizon the gap is zero, so the inputs follow calendar-year -growth. Smooth forecasts pay the higher of earnings, CPI and 2.5% each year, +With the October 2026 EFO the baseline rises are 3.9% in April 2027 (the +published May-July 2026 earnings), 3.4% in April 2028 (September 2027 CPI), +2.5% in April 2029 to 2031 and 2.6% in April 2032, as in the OBR's triple +lock row (EFO Table A.3). After the EFO horizon the gap is zero, so the +inputs follow calendar-year growth. Smooth forecasts pay the higher of earnings, CPI and 2.5% each year, so the baseline has none of the extra cost the triple lock builds up when September CPI and May-July earnings take turns to spike; the OBR's long-run projections add 0.56 percentage points a year over earnings for it (Fiscal diff --git a/docs/engineering/vat-coverage.md b/docs/engineering/vat-coverage.md index bf7b935777..2fa766c5fe 100644 --- a/docs/engineering/vat-coverage.md +++ b/docs/engineering/vat-coverage.md @@ -245,15 +245,20 @@ is not grossed up, so a reform to the VAT on energy bills changes `vat` by exactly the change in `E`. `s` is the costing divided by OBR cash-basis VAT receipts for the same -fiscal year (March 2026 EFO, table 3.8): +fiscal year (October 2026 EFO, table 4.8; 2025-26 is outturn): | Fiscal year | School-fee VAT (£m) | VAT receipts (£m) | Share | |---|---:|---:|---:| -| 2025-26 | 1,505 | 180,169 | 0.8353% | -| 2026-27 | 1,560 | 187,704 | 0.8311% | -| 2027-28 | 1,610 | 195,923 | 0.8218% | -| 2028-29 | 1,665 | 204,591 | 0.8138% | -| 2029-30 | 1,725 | 213,118 | 0.8094% | +| 2025-26 | 1,505 | 179,861 | 0.8368% | +| 2026-27 | 1,560 | 186,154 | 0.8380% | +| 2027-28 | 1,610 | 193,974 | 0.8300% | +| 2028-29 | 1,665 | 203,284 | 0.8190% | +| 2029-30 | 1,725 | 211,701 | 0.8148% | + +Before the October 2026 EFO the shares used the March 2026 EFO's receipts +(table 3.8), 0.8353% in 2025-26 to 0.8094% in 2029-30. The coverage +calibration above still uses the March 2026 EFO's 2024-25 outturn, which the +October 2026 EFO does not revise. The 2029-30 share is held after it. Each value starts on 1 April, so a model year reads its fiscal year's share. `vat` and `baseline_vat` both read it @@ -281,7 +286,7 @@ Properties of the split: - `s` is a share of total receipts, but `G` is calibrated to receipts net of energy-bill VAT. Where `G` matches receipts net of energy-bill VAT exactly, `s * sum(w * G)` falls short of the costing by `s` times energy-bill VAT: - on `f9d1922c`'s 2025-26 energy-bill VAT, 0.8353% of £2.01bn, about £17m + on `f9d1922c`'s 2025-26 energy-bill VAT, 0.8368% of £2.01bn, about £17m (arithmetic on the energy table above, not a run). The earlier design subtracted each household's own school charge from its diff --git a/policyengine_uk/parameters/gov/economic_assumptions/README.md b/policyengine_uk/parameters/gov/economic_assumptions/README.md index a7ef5d5f4f..cdea3637b0 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/README.md +++ b/policyengine_uk/parameters/gov/economic_assumptions/README.md @@ -30,10 +30,10 @@ GDP and population assumptions remain supported. | `petrol_spending_litre_proxy` | Spending growth that preserves road-fuel litres | HMRC + OBR | | `diesel_spending_litre_proxy` | Same, for diesel | HMRC + OBR | | `finance_ni.domestic_rates` | Average Northern Ireland domestic rates bill (regional plus district poundage) | DoF rate poundages, LPS rates paid, NI draft Budget 2026-29 | -| `stamp_duty_land_tax.residential` | SDLT receipts from residential property | EFO receipts Table 3.7 | -| `stamp_duty_land_tax.non_residential` | SDLT receipts from non-residential property | EFO receipts Table 3.7 | -| `business_rates.great_britain` | Business rates receipts, England, Scotland and Wales (cash) | EFO receipts, current receipts (cash basis): Table 3.8 in March 2026 | -| `business_rates.northern_ireland` | Northern Ireland business rates receipts | EFO receipts Table 3.2 | +| `stamp_duty_land_tax.residential` | SDLT receipts from residential property | EFO receipts, property transactions taxes by sector: Table 4.7 in October 2026 | +| `stamp_duty_land_tax.non_residential` | SDLT receipts from non-residential property | EFO receipts, property transactions taxes by sector: Table 4.7 in October 2026 | +| `business_rates.great_britain` | Business rates receipts, England, Scotland and Wales (cash) | EFO receipts, current receipts (cash basis): Table 4.8 in October 2026 | +| `business_rates.northern_ireland` | Northern Ireland business rates receipts | EFO receipts, other taxes: Table 4.2 in October 2026 | The four receipts series project the corporate SDLT and business rates statistics (`gov.hmrc.stamp_duty.statistics`, @@ -49,12 +49,12 @@ index keeps its base year. Three horizons are stitched together for each OBR and ONS series (not `finance_ni.domestic_rates`, which has its own method, below): -1. **Outturn** (history through 2024): ONS published data, copied from OBR +1. **Outturn** (history through 2025): ONS published data, copied from OBR detailed forecast tables. -2. **EFO forecast** (2025-2030): latest OBR Economic and Fiscal Outlook - supplementary tables. The version currently checked in is **March 2026**; - refresh after each new EFO. -3. **Long-run equilibrium** (2031-2073): constructed from OBR's long-run +2. **EFO forecast** (2026-2031): latest OBR Economic and Fiscal Outlook + supplementary tables. The version currently checked in is **October + 2026**; refresh after each new EFO. +3. **Long-run equilibrium** (2032-2073): constructed from OBR's long-run assumptions (Fiscal Risks and Sustainability report) and the long-run RPI-CPI wedge methodology. @@ -78,12 +78,15 @@ general horizon therefore does not extrapolate the experimental EOT series, whose published determinant ends in FY2030–31. CPI, CPIH, RPI, average earnings, road fuel and population run to 2073, but -several series end in 2030. Of those the projection uses, per-capita GDP and -mixed income, mortgage interest, council tax, social and private rents and -Northern Ireland domestic rates end in 2030. A parameter returns its latest -value after its last date, so in 2031 and 2032 these hold their 2030 growth -rate. That is an extrapolation, not an OBR forecast; replace it with the next -EFO's values once one covers those years. +several series end with the EFO. Of those the projection uses, per-capita GDP +and mixed income, council tax, house prices and social and private rents end +in 2031, the October 2026 EFO's last year. Mortgage interest and Northern +Ireland domestic rates end in 2030: the OBR stops forecasting RPI mortgage +interest payments after 2029, before RPI changes method in February 2030. +A parameter returns its latest value after its last date, so in 2032 the +first group holds its 2031 growth rate, and in 2031 and 2032 the second holds +its 2030 rate. That is an extrapolation, not an OBR forecast; replace it with +the next EFO's values once one covers those years. After `PROJECTION_END_YEAR`, policyengine-core checks for a formula result first, then an `uprating` attribute, then carries the last stored input forward. @@ -159,7 +162,7 @@ The additional indices have their own source limits: | Stored input | Variable index | Source coverage and terminal behavior | |---|---|---| | Salary-sacrifice pension contributions | `indices.obr.average_earnings` | Earnings growth has source values through 2073; its cumulative index compounds through 2039. | -| Water and sewerage charges | `indices.ofwat.water_bills` | Raw growth ends in 2029 at 4.5%; that rate carries into later years when the cumulative index is generated, through 2039. | +| Water and sewerage charges | `indices.ofwat.water_bills` | Raw growth ends in 2029 at 5.0%; that rate carries into later years when the cumulative index is generated, through 2039. | | Housing service charges | `indices.obr.lagged_average_earnings` | Lagged growth is generated through 2074 from the preceding year's earnings; its cumulative index compounds through 2039. | | Rail usage | `gov.dft.rail.ridership_index` | The source cumulative index ends in 2029 at 1.044. Its terminal level stays flat, so the projection ratio is one in 2031 and 2032. | @@ -168,28 +171,31 @@ The `indices.*` paths in this table are relative to added by fiscal-year conversion. -## How the 2031+ values were constructed +## How the 2032+ values were constructed Issue [#1379](https://github.com/PolicyEngine/policyengine-uk/issues/1379) -flagged that the year-by-year 2031+ values weren't documented. They are -constructed as follows: - -- **CPI** is pinned to the Bank of England's 2.0% target from 2031-01-01 - onwards. -- **RPI** and **CPIH** use the stored convergence assumptions: 2.30% in - 2031 and 2.37% in 2032, reaching 2.39% in 2035 and then holding that rate - through 2073. Their annual steps are not uniform. The 0.39 pp gap above - CPI is the OBR's published - long-run wedge to account for housing-cost growth ([long-run difference - between RPI and CPI inflation][rpi-cpi]). -- **Average earnings** use 3.32% in 2031 and 3.71% in 2032, reaching 3.83% - in 2036 and then holding that rate through 2073. These are existing model - convergence assumptions beyond the EFO forecast horizon. +flagged that the year-by-year long-run values weren't documented. Since the +October 2026 EFO they start in 2032 and are constructed as follows: + +- **CPI** is at the Bank of England's 2.0% target in the EFO's 2031 + forecast and is held there from 2032-01-01 onwards. +- **RPI** and **CPIH** move in equal steps, rounded to four decimals, from + the EFO's 2031 forecast of 2.18% to 2.39% in 2035: 2.23% in 2032, 2.29% in + 2033 and 2.34% in 2034. They then hold 2.39% through 2073. The 0.39 pp gap + above CPI is the OBR's published long-run wedge to account for + housing-cost growth ([long-run difference between RPI and CPI + inflation][rpi-cpi]). +- **Average earnings** move the same way from the EFO's 2031 forecast of + 2.60% to 3.83% in 2036: 2.85% in 2032, 3.09% in 2033, 3.34% in 2034 and + 3.58% in 2035. They then hold 3.83% through 2073. The 3.83% rate is an + existing model assumption, unchanged since the November 2025 EFO. - **`road_fuel_volume`** is held flat at 0% after the OBR forecast ends — i.e. the final EFO forecast volume is held constant in real terms. -Review these stored assumptions when refreshing the EFO or long-run sources. -They are not annual EFO forecasts for 2031 onwards. The 2031–2032 rates +The equal steps replace the stored convergence rates that followed the March +2026 EFO, which would have taken earnings from 2.60% in 2031 to 3.71% in +2032. Review these assumptions when refreshing the EFO or the OBR's long-term +economic determinants. They are not annual EFO forecasts. The 2032 rates directly affect projections through the dataset horizon. ## Statutory uprating inputs @@ -293,8 +299,13 @@ threshold by the same rises, up to the last year of ## Refreshing after a new EFO -1. Replace the 2025-2030 block in each series with values from the new EFO +1. Replace the forecast block in each series with values from the new EFO detailed forecast tables (note the EFO release month in the header comment). + An autumn EFO also revises the calendar year before its release, now + outturn (October 2026 revised 2025), and forecasts six years after it; the + importer's defaults cover only six years from the release year, so pass + `--forecast-start-year` and `--forecast-years` (2025 and 7 for October + 2026). The importer converts annual economy growth percentages to decimal rates and rounds them to four decimal places. Review the economy-series diff deliberately when running a full CLI import: with the real March 2026 @@ -303,7 +314,7 @@ threshold by the same rises, up to the last year of earnings −0.0585% and house prices +0.0194%. Receipts-only rendering can reproduce the committed YAML byte for byte; a full import also refreshes these economy series. -2. Recompute the 2031-2073 convergence path so the first long-run year +2. Recompute the long-run convergence path so the first long-run year continues smoothly from the new last forecast year (no jump). If the new EFO forecasts a year that a series has no entry for, add that entry first: the importer only replaces existing entries, and stops naming the series @@ -347,6 +358,24 @@ uv run python -m policyengine_uk.utils.import_obr_forecasts \ --previous-receipts-file receipts_tables_march_2025.xlsx ``` +and for October 2026, whose receipts tables are numbered 4.x: + +```bash +uv run python -m policyengine_uk.utils.import_obr_forecasts \ + --file efo-october-2026-detailed-forecast-tables-economy.xlsx \ + --receipts-file efo-october-2026-detailed-forecast-tables-receipts.xlsx \ + --previous-receipts-file policyengine_uk/tests/fixtures/obr_receipts/obr_efo_march_2026_receipts.xlsx \ + --forecast-start-year 2025 --forecast-years 7 +``` + +The October 2026 import also needed, by hand: 2031 entries added to +`house_prices` and `rent` before the run, the 2032+ joins above, and the +series the importer does not cover (per-capita GDP, mixed and non-labour +income, household interest income, council tax, social and private rents, +the AHC deflator, Ofwat water bills, road fuel volumes and the litre proxies, +and the fuel duty RPI path in `gov.hmrc.fuel_duty`). Each series' comments +name its source and method. + The EFO refresh does not touch `finance_ni.domestic_rates`; OBR does not publish a Northern Ireland domestic rates bill series (see below). From 6a4aad391c3252d8faee9316812f3385a4a47ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:07:27 +0000 Subject: [PATCH 03/10] Move the fuel duty, macro scenario and Scottish uprating tests to October 2026 The fuel duty rates and 2027 earnings growth they pin follow the October 2026 RPI and earnings forecasts. On the new CPI path a Scottish amount lands exactly halfway between two 5p steps in 2035, where the index's five-decimal levels decide the rounding, so the independent check accepts either step there. Co-Authored-By: Claude Opus 5.5 --- .../tests/test_fuel_duty_schedule.py | 17 +++++++++-------- .../tests/test_scottish_benefit_uprating.py | 15 ++++++++++----- .../tests/test_uprating_inputs_reach_data.py | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/policyengine_uk/tests/test_fuel_duty_schedule.py b/policyengine_uk/tests/test_fuel_duty_schedule.py index 743381e783..62611509cd 100644 --- a/policyengine_uk/tests/test_fuel_duty_schedule.py +++ b/policyengine_uk/tests/test_fuel_duty_schedule.py @@ -72,17 +72,18 @@ def test_statutory_rate_on_each_date(date, rate): assert schedule(date) == pytest.approx(rate, abs=1e-12) -# Model year Y runs from 6 April Y to 5 April Y+1. Rates from 1 April 2027: -# 59.75p, then 61.54p (2028), 63.26p (2029), 65.09p (2030), 66.59p (2031). +# Model year Y runs from 6 April Y to 5 April Y+1. Rates from 1 April 2027, +# on the OBR's October 2026 RPI forecast: 60.03p, then 62.62p (2028), +# 64.52p (2029), 66.44p (2030), 67.96p (2031). HAND_COMPUTED = { 2025: 0.5295, # 6 Apr to 31 Dec 2026, Jan to Feb 2027, Mar 2027, 1 to 5 Apr 2027. - 2026: (0.5295 * 270 + 0.5595 * 59 + 0.5795 * 31 + 0.5975 * 5) / 365, + 2026: (0.5295 * 270 + 0.5595 * 59 + 0.5795 * 31 + 0.6003 * 5) / 365, # 2028 is a leap year: 361 days to 31 March, then 5 days. - 2027: (0.5975 * 361 + 0.6154 * 5) / 366, - 2028: (0.6154 * 360 + 0.6326 * 5) / 365, - 2029: (0.6326 * 360 + 0.6509 * 5) / 365, - 2030: (0.6509 * 360 + 0.6659 * 5) / 365, + 2027: (0.6003 * 361 + 0.6262 * 5) / 366, + 2028: (0.6262 * 360 + 0.6452 * 5) / 365, + 2029: (0.6452 * 360 + 0.6644 * 5) / 365, + 2030: (0.6644 * 360 + 0.6796 * 5) / 365, } @@ -165,7 +166,7 @@ def fuel_duty_simulation(parameter_changes=None): def test_holding_55_95p_for_2027_removes_the_full_2027_28_rate_rise(): """Regression: calendar-year averaging cut this effect to 3.30p a litre. - The 2027-28 baseline is 59.77p, so holding 55.95p saves 3.82p a litre. + The 2027-28 baseline is 60.07p, so holding 55.95p saves 4.12p a litre. """ baseline = fuel_duty_simulation() reformed = fuel_duty_simulation({PATH: {"2027": 0.5595}}) diff --git a/policyengine_uk/tests/test_scottish_benefit_uprating.py b/policyengine_uk/tests/test_scottish_benefit_uprating.py index 4d65577835..8cf6dfe721 100644 --- a/policyengine_uk/tests/test_scottish_benefit_uprating.py +++ b/policyengine_uk/tests/test_scottish_benefit_uprating.py @@ -80,7 +80,10 @@ def test_later_scottish_projections_compound_the_previous_rounded_amount(name, a """Check every projected year, including beyond the former 2030 anchor. The independent calculation reads annual CPI growth, rather than the - cumulative index ratio, and rounds after each year's increase. + cumulative index ratio, and rounds after each year's increase. Where the + increase lands exactly halfway between two 5p steps (191.25 x 1.02 = + 195.075 in 2035), the index's five-decimal levels decide the tie, so + either step passes and the next year compounds from the model's amount. """ parameters = system.parameters parameter = parameters.get_child(name) @@ -94,10 +97,12 @@ def test_later_scottish_projections_compound_the_previous_rounded_amount(name, a expected = (unrounded / increment).quantize( Decimal("1"), rounding=ROUND_HALF_UP ) * increment - assert parameter(f"{year}-04-30") == pytest.approx(float(expected), abs=1e-9), ( - name, - year, - ) + actual = parameter(f"{year}-04-30") + if unrounded % increment == increment / 2: + assert round(actual, 2) in (float(expected - increment), float(expected)) + previous = Decimal(str(round(actual, 2))) + continue + assert actual == pytest.approx(float(expected), abs=1e-9), (name, year) previous = expected diff --git a/policyengine_uk/tests/test_uprating_inputs_reach_data.py b/policyengine_uk/tests/test_uprating_inputs_reach_data.py index 5a1ab4abe4..4956f94aad 100644 --- a/policyengine_uk/tests/test_uprating_inputs_reach_data.py +++ b/policyengine_uk/tests/test_uprating_inputs_reach_data.py @@ -52,7 +52,7 @@ PERSONAL_ALLOWANCE = "gov.hmrc.income_tax.allowances.personal_allowance.amount" HF_URL = "hf://policyengine/policyengine-uk-data-private/mock_frs_2025_26.h5" GCS_URL = "gs://policyengine-uk-data-private/mock_frs_2025_26.h5" -CURRENT_LAW_2027 = 0.024 # yoy_growth.obr.average_earnings for 2027 +CURRENT_LAW_2027 = 0.0299 # yoy_growth.obr.average_earnings for 2027 PROPERTY_SETTINGS = settings( max_examples=8, From 0525f80f29d42ca3198ab83a3da3ead81ba604ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:43:38 +0000 Subject: [PATCH 04/10] Recompute the YAML expectations that follow the October 2026 forecasts Fuel duty rates, the high value council tax surcharge, bus fares, Scottish income tax thresholds, the unused pension allowance deflators, the Plan 2 threshold, the private school VAT share and the Scottish Child Payment all take their projected values from the OBR's CPI, RPI, earnings and receipts forecasts. Each expectation is recomputed by hand from the October 2026 values, as its comment shows. Co-Authored-By: Claude Opus 5.5 --- .../income_tax/scottish_threshold_freeze.yaml | 18 ++++----- .../policy/baseline/gov/dft/bus_journeys.yaml | 20 +++++----- .../high_value_council_tax_surcharge.yaml | 14 ++++--- .../fuel_duty/petrol_and_diesel_schedule.yaml | 37 ++++++++++--------- ...used_pension_annual_allowance_default.yaml | 28 +++++++------- .../student_loans/student_loan_repayment.yaml | 7 ++-- .../baseline/gov/hmrc/vat/vat_grossing.yaml | 18 ++++----- .../scottish_child_payment.yaml | 7 ++-- .../scottish_child_payment_baby_bonus.yaml | 8 ++-- 9 files changed, 81 insertions(+), 76 deletions(-) diff --git a/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/scottish_threshold_freeze.yaml b/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/scottish_threshold_freeze.yaml index d836647644..65411bae13 100644 --- a/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/scottish_threshold_freeze.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/scottish_threshold_freeze.yaml @@ -6,7 +6,7 @@ # 2029-30 onward resumes the existing CPI projection from2028, without catch-up. # Neither future rate continuity nor post-freeze CPI is a multi-year enacted rule. # Oracles independently sum band widths x rates, with PA12570 below100k and0at150k. -# Current CPI index levels2026..2030: {2026: 1.64763, 2027: 1.68058, 2028: 1.71419, 2029: 1.74847, 2030: 1.78344} +# Current CPI index levels2026..2030 (OBR October 2026): {2026: 1.66019, 2027: 1.71697, 2028: 1.75303, 2029: 1.78984, 2030: 1.82582} - name: Scottish 2027 higher advanced and top thresholds stay frozen period: 2027 @@ -17,8 +17,8 @@ employment_income: [45000, 80000, 150000] output: earned_taxable_income: [32430, 67430, 150000] - earned_income_tax: [6877.87, 21727.87, 59630.17] - income_tax: [6877.87, 21727.87, 59630.17] + earned_income_tax: [6874.89, 21724.89, 59627.19] + income_tax: [6874.89, 21724.89, 59627.19] - name: Scottish 2028 higher advanced and top thresholds stay frozen period: 2028 @@ -29,8 +29,8 @@ employment_income: [45000, 80000, 150000] output: earned_taxable_income: [32430, 67430, 150000] - earned_income_tax: [6873.6, 21723.6, 59625.9] - income_tax: [6873.6, 21723.6, 59625.9] + earned_income_tax: [6870.35, 21720.35, 59622.65] + income_tax: [6870.35, 21720.35, 59622.65] - name: Scottish 2029 higher advanced and top thresholds project from the frozen base period: 2029 @@ -41,8 +41,8 @@ employment_income: [45000, 80000, 150000] output: earned_taxable_income: [32430, 67430, 150000] - earned_income_tax: [6738.67, 21551.22, 59378.44] - income_tax: [6738.67, 21551.22, 59378.44] + earned_income_tax: [6728.61, 21539.28, 59362.75] + income_tax: [6728.61, 21539.28, 59362.75] - name: Scottish 2030 higher advanced and top thresholds project from the frozen base period: 2030 @@ -53,8 +53,8 @@ employment_income: [45000, 80000, 150000] output: earned_taxable_income: [32430, 67430, 150000] - earned_income_tax: [6601.03, 21375.37, 59126.01] - income_tax: [6601.03, 21375.37, 59126.01] + earned_income_tax: [6590.06, 21362.3, 59108.71] + income_tax: [6590.06, 21362.3, 59108.71] - name: Scottish threshold freeze leaves the rest of UK unchanged period: 2028 diff --git a/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml b/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml index ad1f35619d..bdeb31d8fc 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml @@ -191,14 +191,14 @@ other_local_bus_trips: 100 bus_pass_eligible: false output: - # 100 * 1.252853758464 * GBP 2.550929922065 * 1.034 (OBR CPI, 2025 over - # 2024, as the engine's index rounds it: 1.61059 / 1.55763). - person_bus_fare_spending: 330.46 + # 100 * 1.252853758464 * GBP 2.550929922065 * 1.0337 (OBR CPI, 2025 over + # 2024, as the engine's index rounds it: 1.61012 / 1.55763). + person_bus_fare_spending: 330.36 # Cap changes use the table of uncapped single fares in # gov.dft.bus.uncapped_single_fares: 56% of singles at GBP 1.70, 31% at # GBP 2.21 and 13% at GBP 3.96 at FY2024-25 prices, uprated with OBR CPI -# (FY2025-26 x 1.61059 / 1.55763 = 1.0340). Case 10's passenger has 100 trips +# (FY2025-26 x 1.61012 / 1.55763 = 1.0337). Case 10's passenger has 100 trips # * 1.12466920264 boardings * 0.7 single share = 78.7268 single boardings, at # a GBP 181.06 baseline. - name: Case 14, without a cap in 2025-26 the singles above GBP 3 pay in full. @@ -211,9 +211,9 @@ local_bus_single_fare_share: 0.7 gov.dft.bus.fares.cap: .inf output: - # Only the high band (3.96 * 1.0340 = 4.0946) is above GBP 3: - # 181.0594 + 78.7268 * 0.13 * 1.0946. - person_bus_fare_spending: 192.26 + # Only the high band (3.96 * 1.0337 = 4.0934) is above GBP 3: + # 181.0594 + 78.7268 * 0.13 * 1.0934. + person_bus_fare_spending: 192.25 - name: Case 15, a GBP 2 cap in 2025-26 saves the middle and high bands. period: 2025 @@ -225,9 +225,9 @@ local_bus_single_fare_share: 0.7 gov.dft.bus.fares.cap: 2 output: - # Middle band 2.21 * 1.0340 = 2.2851 falls to 2; the high band falls - # from 3 to 2: 181.0594 - 78.7268 * (0.31 * 0.2851 + 0.13 * 1). - person_bus_fare_spending: 163.87 + # Middle band 2.21 * 1.0337 = 2.2845 falls to 2; the high band falls + # from 3 to 2: 181.0594 - 78.7268 * (0.31 * 0.2845 + 0.13 * 1). + person_bus_fare_spending: 163.88 - name: Case 16, paying youth journeys remain priced and free-pass journeys cost nothing. period: 2024 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml index af1f64e85f..497cf821d4 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/council_tax/high_value_council_tax_surcharge.yaml @@ -15,9 +15,10 @@ age: 40 region: LONDON tenure_type: OWNED_OUTRIGHT - # £2.01m in 2026 prices, grown by 2027 HPI 2.9% and 2028 HPI 2.7%. - # This annual index is a proxy for the published 2026 valuation basis. - main_residence_value: 2_124_133.83 + # £2.01m in 2026 prices, grown by 2027 HPI 2.44% and 2028 HPI 2.78% + # (OBR October 2026). This annual index is a proxy for the published + # 2026 valuation basis. + main_residence_value: 2_116_285.42 output: high_value_council_tax_surcharge: 2_500 - name: High value council tax surcharge applies in England and flows into aggregates @@ -44,9 +45,10 @@ council_tax: 0 household_owns_tv: false output: - high_value_council_tax_surcharge: 2_550 - household_tax: 2_550 - gov_tax: 2_550 + # £2,500 x (1 + 2028 CPI growth of 2.10%, OBR October 2026). + high_value_council_tax_surcharge: 2_552.5 + household_tax: 2_552.5 + gov_tax: 2_552.5 - name: High value council tax surcharge only applies in England period: 2028 input: diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/fuel_duty/petrol_and_diesel_schedule.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/fuel_duty/petrol_and_diesel_schedule.yaml index 4dfe920b38..ac3b8e31c0 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/fuel_duty/petrol_and_diesel_schedule.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/fuel_duty/petrol_and_diesel_schedule.yaml @@ -2,12 +2,13 @@ # 6 April to 5 April, and the dated rates are day-weighted across it: # 2025-26: 365 days at 52.95p. # 2026-27: 270 days at 52.95p (6 Apr to 31 Dec 2026), 59 at 55.95p -# (Jan to Feb 2027), 31 at 57.95p (Mar 2027) and 5 at 59.75p. -# 2027-28 (366 days): 361 at 59.75p and 5 at 61.54p. -# 2028-29: 360 at 61.54p and 5 at 63.26p. -# 2029-30: 360 at 63.26p and 5 at 65.09p. -# 2030-31: 360 at 65.09p and 5 at 66.59p. -# Rates from 1 April 2027 are the RPI forecast in petrol_and_diesel.yaml. +# (Jan to Feb 2027), 31 at 57.95p (Mar 2027) and 5 at 60.03p. +# 2027-28 (366 days): 361 at 60.03p and 5 at 62.62p. +# 2028-29: 360 at 62.62p and 5 at 64.52p. +# 2029-30: 360 at 64.52p and 5 at 66.44p. +# 2030-31: 360 at 66.44p and 5 at 67.96p. +# Rates from 1 April 2027 are the RPI forecast in petrol_and_diesel.yaml, on +# the OBR's October 2026 RPI forecast. - name: Fuel duty for 2025-26 is 52.95p a litre all year period: 2025 absolute_error_margin: 0.01 @@ -23,8 +24,8 @@ petrol_litres: 1_000 diesel_litres: 0 output: - # 1000 * (0.5295 * 270 + 0.5595 * 59 + 0.5795 * 31 + 0.5975 * 5) / 365 - fuel_duty: 539.5273972602739 + # 1000 * (0.5295 * 270 + 0.5595 * 59 + 0.5795 * 31 + 0.6003 * 5) / 365 + fuel_duty: 539.5657534246575 - name: Fuel duty for 2027-28 is the April 2027 RPI-uprated rate period: 2027 absolute_error_margin: 0.01 @@ -32,8 +33,8 @@ petrol_litres: 600 diesel_litres: 400 output: - # 1000 * (0.5975 * 361 + 0.6154 * 5) / 366 - fuel_duty: 597.7445355191257 + # 1000 * (0.6003 * 361 + 0.6262 * 5) / 366 + fuel_duty: 600.653825136612 - name: Fuel duty for 2028-29 period: 2028 absolute_error_margin: 0.01 @@ -41,8 +42,8 @@ petrol_litres: 1_000 diesel_litres: 0 output: - # 1000 * (0.6154 * 360 + 0.6326 * 5) / 365 - fuel_duty: 615.6356164383562 + # 1000 * (0.6262 * 360 + 0.6452 * 5) / 365 + fuel_duty: 626.4602739726027 - name: Fuel duty for 2029-30 period: 2029 absolute_error_margin: 0.01 @@ -50,8 +51,8 @@ petrol_litres: 1_000 diesel_litres: 0 output: - # 1000 * (0.6326 * 360 + 0.6509 * 5) / 365 - fuel_duty: 632.8506849315068 + # 1000 * (0.6452 * 360 + 0.6644 * 5) / 365 + fuel_duty: 645.4630136986301 - name: Fuel duty for 2030-31 period: 2030 absolute_error_margin: 0.01 @@ -59,8 +60,8 @@ petrol_litres: 1_000 diesel_litres: 0 output: - # 1000 * (0.6509 * 360 + 0.6659 * 5) / 365 - fuel_duty: 651.1054794520548 + # 1000 * (0.6644 * 360 + 0.6796 * 5) / 365 + fuel_duty: 664.6082191780822 - name: Rural relief takes 5p a litre off the 2027-28 rate period: 2027 absolute_error_margin: 0.01 @@ -69,5 +70,5 @@ diesel_litres: 0 in_rural_fuel_duty_relief_area: true output: - # 597.7445355191257 - 1000 * 0.05 - fuel_duty: 547.7445355191257 + # 600.653825136612 - 1000 * 0.05 + fuel_duty: 550.653825136612 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/pensions/unused_pension_annual_allowance_default.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/pensions/unused_pension_annual_allowance_default.yaml index bc5ff5b182..8271d6271d 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/pensions/unused_pension_annual_allowance_default.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/pensions/unused_pension_annual_allowance_default.yaml @@ -7,10 +7,10 @@ # first (s. 228A(7)), and the unused allowance of the three years before this # one is carried forward. # -# For 2026 the deflators are average earnings growth of 3.4% (2026), 5.3% -# (2025), 5.1% (2024), 6.22% (2023) and 6.14% (2022): 0.967118 for 2025, -# 0.918441 for 2024, 0.873873 for 2023, 0.822701 for 2022 and 0.775109 for -# 2021. The standard allowance is 40,000 to 2022-23 and 60,000 from 2023-24. +# For 2026 the deflators are average earnings growth of 3.73% (2026), 4.12% +# (2025), 5.1% (2024), 6.22% (2023) and 6.14% (2022), from the OBR's October +# 2026 EFO and earlier outturn: 0.964041 for 2025, 0.925894 for 2024, +# 0.880965 for 2023, 0.829378 for 2022 and 0.781400 for 2021. The standard allowance is 40,000 to 2022-23 and 60,000 from 2023-24. # Every case is a person aged 45 in London with employment income of 100,000. # Sources: https://www.legislation.gov.uk/ukpga/2004/12/section/228A # https://www.gov.uk/hmrc-internal-manuals/pensions-tax-manual/ptm055100 @@ -23,9 +23,9 @@ employment_income: 100_000 employer_pension_contributions: 50_000 output: - # Inputs of 43,693.66 (2023), 45,922.03 (2024) and 48,355.90 (2025) - # leave 16,306.34 + 14,077.97 + 11,644.10 of their 60,000 allowances. - unused_pension_annual_allowance: 42_028.41 + # Inputs of 44,048.26 (2023), 46,294.72 (2024) and 48,202.06 (2025) + # leave 15,951.74 + 13,705.28 + 11,797.94 of their 60,000 allowances. + unused_pension_annual_allowance: 41_454.96 pension_annual_allowance_chargeable_amount: 0 - name: An excess in a later year uses the earliest unused allowance first @@ -36,12 +36,12 @@ employment_income: 100_000 employer_pension_contributions: 63_000 output: - # 2023 input 55,054.01 leaves 4,945.99 unused and 2024 input 57,861.76 - # leaves 2,138.24. 2025 input 60,928.43 exceeds 60,000 by 928.43, which - # uses 2023's unused allowance (2021 and 2022 have none). 4,017.56 + - # 2,138.24 = 6,155.80, against 7,084.23 without that ordering. - unused_pension_annual_allowance: 6_155.80 - # 63,000 - 60,000 is within the 6,155.80 carried forward. + # 2023 input 55,500.81 leaves 4,499.19 unused and 2024 input 58,331.35 + # leaves 1,668.65. 2025 input 60,734.60 exceeds 60,000 by 734.60, which + # uses 2023's unused allowance (2021 and 2022 have none). 3,764.59 + + # 1,668.65 = 5,433.25, against 6,167.85 without that ordering. + unused_pension_annual_allowance: 5_433.25 + # 63,000 - 60,000 is within the 5,433.25 carried forward. pension_annual_allowance_chargeable_amount: 0 - name: Saving above the allowance every year leaves nothing to carry forward @@ -52,7 +52,7 @@ employment_income: 100_000 employer_pension_contributions: 70_000 output: - # Deflated inputs of 54,258 to 67,698 exceed each year's allowance. + # Deflated inputs of 54,698 to 67,483 exceed each year's allowance. unused_pension_annual_allowance: 0 pension_annual_allowance_chargeable_amount: 10_000 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml index 510ddfc2e0..4e0704aefa 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml @@ -115,9 +115,10 @@ employment_income: 40_000 student_loan_plan: PLAN_2 output: - # Threshold resumes RPI uprating from 2030 - # 9% of (40,000 - ~30,061) = 9% of ~9,939 = ~894.52 - student_loan_repayment: 894.522 + # Threshold resumes RPI uprating from 2030: 29,385 x 2.01921 / 1.97401 + # (OBR October 2026 RPI index) = 30,057.84. + # 9% of (40,000 - 30,057.84) = 9% of 9,942.16 = 894.79 + student_loan_repayment: 894.794 - name: Plan 2 - Income just below 2027 threshold period: 2027 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/vat/vat_grossing.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/vat/vat_grossing.yaml index 4ba456d1f6..fcb5a62706 100644 --- a/policyengine_uk/tests/policy/baseline/gov/hmrc/vat/vat_grossing.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/vat/vat_grossing.yaml @@ -7,9 +7,9 @@ output: # (10,000 x 20% + 1,000 x 5%) / (0.67 x 0.7) = 2,050 / 0.469 = 4,371.00, # less private school fees' official share of 2025-26 VAT receipts - # (0.008353), which private_school_vat counts separately. - vat: 4_334.49 - baseline_vat: 4_334.49 + # (0.008368), which private_school_vat counts separately. + vat: 4_334.43 + baseline_vat: 4_334.43 - name: With both factors at one, VAT is the statutory liability on recorded consumption period: 2025 @@ -20,8 +20,8 @@ full_rate_vat_consumption: 10_000 reduced_rate_vat_consumption: 1_000 output: - # 2,050 x (1 - 0.008353) - vat: 2_032.88 + # 2,050 x (1 - 0.008368) + vat: 2_032.85 - name: The household share alone grosses survey-complete VAT up to receipts period: 2025 @@ -31,8 +31,8 @@ full_rate_vat_consumption: 7_000 reduced_rate_vat_consumption: 0 output: - # 7,000 x 20% / 0.7 x (1 - 0.008353) - vat: 1_983.29 + # 7,000 x 20% / 0.7 x (1 - 0.008368) + vat: 1_983.26 - name: A reform to the deprecated combined factor still takes effect period: 2025 @@ -42,5 +42,5 @@ full_rate_vat_consumption: 10_000 reduced_rate_vat_consumption: 1_000 output: - # 2,050 / 0.5 x (1 - 0.008353) - vat: 4_065.75 + # 2,050 / 0.5 x (1 - 0.008368) + vat: 4_065.69 diff --git a/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_child_payment.yaml b/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_child_payment.yaml index 1e605c1822..3619f86217 100644 --- a/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_child_payment.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/social_security_scotland/scottish_child_payment.yaml @@ -299,7 +299,7 @@ # [parent, child_1] scottish_child_payment: [0, 1518.40] -- name: SCP with 2028 September CPI projection (£29.80/week) +- name: SCP with 2028 September CPI projection (£30.20/week) period: 2028 absolute_error_margin: 10 input: @@ -317,9 +317,10 @@ members: [parent, child_1] region: SCOTLAND output: - # £29.20 * 1.021 rounded to 5p = £29.80/week; annualised over 52 weeks = £1,549.60 + # £29.20 * 1.034 (OBR October 2026 September 2027 CPI) rounded to 5p = £30.20/week; + # annualised over 52 weeks = £1,570.40 # [parent, child_1] - scottish_child_payment: [0, 1549.60] + scottish_child_payment: [0, 1570.40] - name: CTC no longer qualifies from 2025 (after April 2024) period: 2025 diff --git a/policyengine_uk/tests/policy/reforms/scp_baby_bonus/scottish_child_payment_baby_bonus.yaml b/policyengine_uk/tests/policy/reforms/scp_baby_bonus/scottish_child_payment_baby_bonus.yaml index 48dcbca7be..9b0c04735a 100644 --- a/policyengine_uk/tests/policy/reforms/scp_baby_bonus/scottish_child_payment_baby_bonus.yaml +++ b/policyengine_uk/tests/policy/reforms/scp_baby_bonus/scottish_child_payment_baby_bonus.yaml @@ -51,9 +51,9 @@ members: [parent, toddler] region: SCOTLAND output: - # Standard rate only: £29.80/week * 52 = £1,549.60 + # Standard rate only: £30.20/week * 52 = £1,570.40 # [parent, toddler] - scottish_child_payment: [0, 1549.60] + scottish_child_payment: [0, 1570.40] - name: SCP baby bonus - mixed ages (2028) period: 2028 @@ -79,9 +79,9 @@ region: SCOTLAND output: # Baby (age 0): £40.80/week total * 52 = £2,121.60 - # Older child (age 5): £29.80/week * 52 = £1,549.60 + # Older child (age 5): £30.20/week * 52 = £1,570.40 # [parent, baby, older_child] - scottish_child_payment: [0, 2122, 1549.60] + scottish_child_payment: [0, 2122, 1570.40] - name: SCP baby bonus - not in Scotland (2028) period: 2028 From 5301207054674308caeff994f61ad193ef625401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:52:40 +0000 Subject: [PATCH 05/10] Address review round 1 on the October 2026 EFO update - Household interest income takes its 2020-2025 outturn from ONS HAXV (30 September 2026 release), so 2025 is -2.76%, not the proxy's +2.92%; the non-labour income proxy stays for 2026-2031. - Private rents follow the OBR's UK private rents forecast ("Private rentals for housing", Table 1.7) in every region, instead of being backed out of the aggregate rent forecast. - A test pins the equal-step joins to the long-run rates from 2032. - The road fuel comment says how the current-law fuel duty schedule's RPI convention differs from the OBR path; the NI domestic rates comment adds October's Table 5.1 line; the README and importer comments match what the code does; the changelog names the population vintage. Co-Authored-By: Claude Opus 5.5 --- .../obr-october-2026-efo-2711.changed.md | 2 +- .../gov/economic_assumptions/README.md | 7 +- .../gov/economic_assumptions/yoy_growth.yaml | 213 +++++++++--------- policyengine_uk/tests/test_long_run_joins.py | 62 +++++ policyengine_uk/tests/test_rent_uprating.py | 44 ++-- policyengine_uk/utils/import_obr_forecasts.py | 7 +- 6 files changed, 205 insertions(+), 130 deletions(-) create mode 100644 policyengine_uk/tests/test_long_run_joins.py diff --git a/changelog.d/obr-october-2026-efo-2711.changed.md b/changelog.d/obr-october-2026-efo-2711.changed.md index 16a73c61b5..e8efacfd5a 100644 --- a/changelog.d/obr-october-2026-efo-2711.changed.md +++ b/changelog.d/obr-october-2026-efo-2711.changed.md @@ -1 +1 @@ -Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. +Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population stays on the March 2026 long-term determinants until the October edition is published. diff --git a/policyengine_uk/parameters/gov/economic_assumptions/README.md b/policyengine_uk/parameters/gov/economic_assumptions/README.md index cdea3637b0..2ad1f9247f 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/README.md +++ b/policyengine_uk/parameters/gov/economic_assumptions/README.md @@ -80,9 +80,10 @@ whose published determinant ends in FY2030–31. CPI, CPIH, RPI, average earnings, road fuel and population run to 2073, but several series end with the EFO. Of those the projection uses, per-capita GDP and mixed income, council tax, house prices and social and private rents end -in 2031, the October 2026 EFO's last year. Mortgage interest and Northern -Ireland domestic rates end in 2030: the OBR stops forecasting RPI mortgage -interest payments after 2029, before RPI changes method in February 2030. +in 2031, the October 2026 EFO's last year. Mortgage interest ends in 2030: +the OBR stops forecasting RPI mortgage interest payments after 2029, before +RPI changes method in February 2030. Northern Ireland domestic rates, which +have their own method (below), also end in 2030. A parameter returns its latest value after its last date, so in 2032 the first group holds its 2031 growth rate, and in 2031 and 2032 the second holds its 2030 rate. That is an extrapolation, not an OBR forecast; replace it with diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index f599d62fdb..f0ff9dd74a 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -303,8 +303,13 @@ obr: # behind that forecast: 52.95p to 30 June 2027, 60.59p from 1 July # 2027, then raised each 1 April by Q1 RPI growth (OBR economy # Table 1.7), the convention that gives 60.59p. That path is policy, - # not the current law in gov.hmrc.fuel_duty.petrol_and_diesel. The - # derivation is policyengine-uk-data's sources/road_fuel_volume.py. + # not the current law in gov.hmrc.fuel_duty.petrol_and_diesel, which + # also uses another RPI convention: calculate_fuel_duty_rates.py applies + # the previous calendar year's RPI growth (60.03p from April 2027), so + # the model's rates differ from this path by up to 0.6p a litre in + # 2027-28 and by 0.3p or less from 2028-29. Aligning the two belongs + # with the current-law schedule (#2715). The derivation is + # policyengine-uk-data's sources/road_fuel_volume.py. 2026-01-01: -0.02315665811165113 2027-01-01: -0.030554808261277322 2028-01-01: -0.03089248062672023 @@ -1150,15 +1155,16 @@ ons: household_interest_income: description: Household interest income year-on-year growth from ONS National Accounts D.41g. values: - # Outturn from ONS HAXV - Total household interest received (D.41) - # https://www.ons.gov.uk/economy/grossdomesticproductgdp/timeseries/haxv/ukea - 2020-01-01: 0.000 - 2021-01-01: 0.225 # 19.6/16.0 - 1 - 2022-01-01: 1.210 # 43.3/19.6 - 1 - 2023-01-01: 0.987 # 86.0/43.3 - 1 - 2024-01-01: 0.142 # 98.2/86.0 - 1 - # Forecast: use OBR non-labour income growth as proxy (Table 1.12) - 2025-01-01: 0.0292 + # Outturn (2020-2025), ONS HAXV, total household interest received + # (D.41), £m, 30 September 2026 release + 2020-01-01: -0.3025 # 15,988 / 22,923 - 1 + 2021-01-01: 0.2238 # 19,566 / 15,988 - 1 + 2022-01-01: 1.2121 # 43,282 / 19,566 - 1 + 2023-01-01: 0.9891 # 86,092 / 43,282 - 1 + 2024-01-01: 0.1405 # 98,189 / 86,092 - 1 + 2025-01-01: -0.0276 # 95,477 / 98,189 - 1 + # Forecast (2026-2031): OBR non-labour income growth as a proxy + # (October 2026 EFO, Table 1.12) 2026-01-01: 0.0302 2027-01-01: 0.0468 2028-01-01: 0.0419 @@ -1169,15 +1175,16 @@ ons: unit: /1 label: Household interest income growth reference: - - title: ONS National Accounts D.41g - Households interest received (HAXV series) + - title: ONS, Households (S.14) interest (D.41) resources, current prices, £m, NSA (HAXV), UK Economic Accounts, 30 September 2026 href: https://www.ons.gov.uk/economy/grossdomesticproductgdp/timeseries/haxv/ukea - - title: OBR EFO October 2026 - Non-labour income growth used as proxy for 2025+ (Table 1.12) + - title: OBR EFO October 2026 - Non-labour income growth used as proxy for 2026+ (Table 1.12) href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ private_rental_prices: # Historical values are calendar-year averages from ONS PIPR. Forecast - # values back out private-rent growth from the OBR aggregate rent forecast - # after applying social-rent growth, because no public region-specific - # private-rent forecast is available. + # values (2026-2031) are the OBR's UK private rents forecast, "Private + # rentals for housing" (ONS KYHJ) in October 2026 economy Table 1.7, + # rounded to 4 decimals. No public region-specific private-rent forecast + # is available, so every region takes the UK growth. UNITED_KINGDOM: description: Private rental prices year-on-year growth in United Kingdom. values: @@ -1185,12 +1192,12 @@ ons: 2023-01-01: 0.073824 2024-01-01: 0.087127 2025-01-01: 0.063279 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: United kingdom private rental prices growth @@ -1206,12 +1213,12 @@ ons: 2023-01-01: 0.071723 2024-01-01: 0.087245 2025-01-01: 0.063996 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: England private rental prices growth @@ -1227,12 +1234,12 @@ ons: 2023-01-01: 0.083841 2024-01-01: 0.084642 2025-01-01: 0.077081 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: Wales private rental prices growth @@ -1248,12 +1255,12 @@ ons: 2023-01-01: 0.100690 2024-01-01: 0.084690 2025-01-01: 0.042929 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: Scotland private rental prices growth @@ -1269,12 +1276,12 @@ ons: 2023-01-01: 0.087019 2024-01-01: 0.092217 2025-01-01: 0.068702 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: Northern Ireland private rental prices growth @@ -1290,12 +1297,12 @@ ons: 2023-01-01: 0.054987 2024-01-01: 0.067069 2025-01-01: 0.090155 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: North east private rental prices growth @@ -1311,12 +1318,12 @@ ons: 2023-01-01: 0.075098 2024-01-01: 0.092231 2025-01-01: 0.077692 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: North west private rental prices growth @@ -1334,12 +1341,12 @@ ons: 2023-01-01: 0.067502 2024-01-01: 0.069094 2025-01-01: 0.040862 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: Yorkshire and the humber private rental prices growth @@ -1355,12 +1362,12 @@ ons: 2023-01-01: 0.060960 2024-01-01: 0.086271 2025-01-01: 0.069478 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: East midlands private rental prices growth @@ -1376,12 +1383,12 @@ ons: 2023-01-01: 0.066340 2024-01-01: 0.087831 2025-01-01: 0.061272 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: West midlands private rental prices growth @@ -1397,12 +1404,12 @@ ons: 2023-01-01: 0.052949 2024-01-01: 0.073996 2025-01-01: 0.071305 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: East of England private rental prices growth @@ -1418,12 +1425,12 @@ ons: 2023-01-01: 0.084473 2024-01-01: 0.103216 2025-01-01: 0.066484 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: London private rental prices growth @@ -1439,12 +1446,12 @@ ons: 2023-01-01: 0.065655 2024-01-01: 0.079285 2025-01-01: 0.057820 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: South east private rental prices growth @@ -1460,12 +1467,12 @@ ons: 2023-01-01: 0.067635 2024-01-01: 0.068267 2025-01-01: 0.053907 - 2026-01-01: 0.026468085 - 2027-01-01: 0.019910638 - 2028-01-01: 0.011795745 - 2029-01-01: 0.022697872 - 2030-01-01: 0.019642553 - 2031-01-01: 0.025319149 + 2026-01-01: 0.0341 + 2027-01-01: 0.0265 + 2028-01-01: 0.0198 + 2029-01-01: 0.0208 + 2030-01-01: 0.0235 + 2031-01-01: 0.0260 metadata: unit: /1 label: South west private rental prices growth @@ -1578,8 +1585,10 @@ finance_ni: # Neither OBR March 2026 line is large enough to cover the whole bill # (each is about half of LPS's £889.5m paid in 2024-25), and OBR labels # neither as regional or district; the attribution here is inferred. - # Expenditure Table 4.1 holds "NI domestic rates" at £0.494bn in every - # year to 2030-31 inside its council tax total, and ONS classes district + # March 2026 Expenditure Table 4.1 holds "NI domestic rates" at £0.494bn + # in every year to 2030-31 inside its council tax total (October 2026 + # Table 5.1 grows it from £0.515bn in 2025-26 to £0.662bn in 2031-32, + # about 4.3% a year), and ONS classes district # domestic rates with council tax, so it appears to be the district # rates. Receipts Table 3.2 "Northern Ireland domestic rates" (in "Other # taxes") appears to be the regional rate: ONS classes the regional diff --git a/policyengine_uk/tests/test_long_run_joins.py b/policyengine_uk/tests/test_long_run_joins.py new file mode 100644 index 0000000000..48f58f9fb3 --- /dev/null +++ b/policyengine_uk/tests/test_long_run_joins.py @@ -0,0 +1,62 @@ +"""The long-run paths join the last EFO year in equal steps. + +The October 2026 EFO forecasts to 2031. From 2032, RPI and CPIH step from +its 2031 forecast to 2.39% in 2035, and average earnings to 3.83% in 2036, +each step rounded to 4 decimals; the rates then hold. The receipts series +follow average earnings after their own forecast. Before this, the March +2026 path jumped earnings from 3.32% in 2031 to 3.71% in 2032, and no test +noticed. +""" + +import pytest + +from policyengine_uk.system import system + +OBR = system.parameters.gov.economic_assumptions.yoy_growth.obr +LAST_EFO_YEAR = 2031 + + +def rate(series, year): + return series(f"{year}-01-01") + + +def equal_steps(start, end, steps): + return [round(start + (end - start) * k / steps, 4) for k in range(steps + 1)] + + +@pytest.mark.parametrize( + "name, steady_state, steady_year", + [("rpi", 0.0239, 2035), ("cpih", 0.0239, 2035), ("average_earnings", 0.0383, 2036)], +) +def test_long_run_path_steps_evenly_to_its_steady_state( + name, steady_state, steady_year +): + series = getattr(OBR, name) + start = rate(series, LAST_EFO_YEAR) + years = range(LAST_EFO_YEAR, steady_year + 1) + expected = equal_steps(start, steady_state, steady_year - LAST_EFO_YEAR) + assert [rate(series, year) for year in years] == pytest.approx(expected, abs=1e-12) + for year in range(steady_year, 2074): + assert rate(series, year) == steady_state, (name, year) + + +def test_cpi_holds_its_target_after_the_efo(): + for year in range(LAST_EFO_YEAR + 1, 2074): + assert rate(OBR.consumer_price_index, year) == 0.02, year + + +@pytest.mark.parametrize( + "path", + [ + ("stamp_duty_land_tax", "residential"), + ("stamp_duty_land_tax", "non_residential"), + ("business_rates", "great_britain"), + ("business_rates", "northern_ireland"), + ], +) +def test_receipts_series_follow_earnings_after_the_efo(path): + series = OBR + for key in path: + series = getattr(series, key) + for year in range(LAST_EFO_YEAR + 1, 2074): + assert rate(series, year) == rate(OBR.average_earnings, year), (path, year) diff --git a/policyengine_uk/tests/test_rent_uprating.py b/policyengine_uk/tests/test_rent_uprating.py index 71c54feed2..d07b8912d1 100644 --- a/policyengine_uk/tests/test_rent_uprating.py +++ b/policyengine_uk/tests/test_rent_uprating.py @@ -13,14 +13,16 @@ from policyengine_uk.variables.household.demographic.geography import Region -PRIVATE_RENTAL_HOUSEHOLDS = 0.188 -SOCIAL_RENTAL_HOUSEHOLDS = 0.164 -PRIVATE_RENT_WEIGHT = PRIVATE_RENTAL_HOUSEHOLDS / ( - PRIVATE_RENTAL_HOUSEHOLDS + SOCIAL_RENTAL_HOUSEHOLDS -) -SOCIAL_RENT_WEIGHT = SOCIAL_RENTAL_HOUSEHOLDS / ( - PRIVATE_RENTAL_HOUSEHOLDS + SOCIAL_RENTAL_HOUSEHOLDS -) +# OBR October 2026 EFO, economy Table 1.7, "Private rentals for housing" +# (ONS KYHJ), calendar-year growth, per cent. +OBR_PRIVATE_RENTS = { + 2026: 3.41321, + 2027: 2.65158, + 2028: 1.98206, + 2029: 2.08464, + 2030: 2.34856, + 2031: 2.59541, +} def test_uprate_rent_uses_tenure_specific_growth(): @@ -44,19 +46,19 @@ def test_uprate_rent_uses_tenure_specific_growth(): assert current_year.household["rent"][1] == pytest.approx(1_080.0) -def test_forecast_private_rent_preserves_obr_aggregate_growth(): - growth = parameters.gov.economic_assumptions.yoy_growth - - for year in range(2026, 2032): - private_rent_growth = growth.ons.private_rental_prices(year)["UNITED_KINGDOM"] - social_rent_growth = growth.obr.social_rent(year) - aggregate_rent_growth = growth.obr.rent(year) - - weighted_growth = ( - PRIVATE_RENT_WEIGHT * private_rent_growth - + SOCIAL_RENT_WEIGHT * social_rent_growth - ) - assert weighted_growth == pytest.approx(aggregate_rent_growth) +def test_forecast_private_rent_is_the_obr_private_rents_forecast(): + """Every region's forecast is the OBR's UK private rents growth, to 4 + decimals: there is no regional forecast.""" + growth = parameters.gov.economic_assumptions.yoy_growth.ons.private_rental_prices + regions = list(growth.children) + assert len(regions) == 14 + for year, percent in OBR_PRIVATE_RENTS.items(): + values = growth(f"{year}-01-01") + for region in regions: + assert values[region] == pytest.approx(round(percent / 100, 4)), ( + region, + year, + ) REGIONS = [region.name for region in Region] diff --git a/policyengine_uk/utils/import_obr_forecasts.py b/policyengine_uk/utils/import_obr_forecasts.py index f6db9bebc6..fe271e864f 100644 --- a/policyengine_uk/utils/import_obr_forecasts.py +++ b/policyengine_uk/utils/import_obr_forecasts.py @@ -845,9 +845,10 @@ def find_receipts_line( ordered = sorted(levels) if ordered != list(range(ordered[0], ordered[-1] + 1)): raise ValueError(f"{where} skips a year: {ordered}") - # The sheet name and the contents sheet number each table too. Where the - # title cell disagrees, the title is the misprint: October 2026 titles - # sheet 4.8 "43.8 Current receipts (on a cash basis)". + # The sheet name and the contents sheet number each table too, so a sheet + # named as a table number gives the table's number, whatever its title + # cell says: October 2026 titles sheet 4.8 "43.8 Current receipts (on a + # cash basis)". if TABLE_NUMBER_RE.fullmatch(sheet): table = sheet return ReceiptsLine( From 8dc456ecfb6001a1c90d974d14c25cbf1a15859e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 17:05:46 +0000 Subject: [PATCH 06/10] Refit the bus fare table and move the remaining Python tests to October 2026 The uncapped single fare table is fitted on the OBR CPI path. On the October 2026 path the fit moves the high band's mean fare from GBP 3.96 to GBP 3.95; the shares and the other fares are unchanged. The bus fare, process-time, scenario-timing and legacy VAT tests pin 2027 earnings growth, 2025 CPI and the private school VAT share at their October values. Co-Authored-By: Claude Opus 5.5 --- docs/engineering/bus-fares.md | 20 ++++++++++--------- .../dft/bus/uncapped_single_fares/fare.yaml | 2 +- .../policy/baseline/gov/dft/bus_journeys.yaml | 8 ++++---- .../tests/test_bus_fare_reforms.py | 18 ++++++++--------- .../tests/test_process_time_reforms.py | 5 ++++- .../tests/test_scenario_sum_timing.py | 2 +- .../tests/test_vat_grossing_legacy.py | 2 +- scripts/fit_bus_cap_savings.py | 2 +- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/docs/engineering/bus-fares.md b/docs/engineering/bus-fares.md index 68f81df4fa..0c546c14fd 100644 --- a/docs/engineering/bus-fares.md +++ b/docs/engineering/bus-fares.md @@ -202,7 +202,7 @@ share of single tickets and its mean uncapped fare at FY2024–25 prices: |---|---:|---:| | `LOW`, at or below £2 | 0.56 | £1.70 | | `MIDDLE`, above £2 and up to £3 | 0.31 | £2.21 | -| `HIGH`, above £3 | 0.13 | £3.96 | +| `HIGH`, above £3 | 0.13 | £3.95 | The fares rise with the OBR CPI after FY2024–25 and the shares stay, so a fixed cap saves more as fares rise. The model caps each band's mean fare under both @@ -214,22 +214,24 @@ mean needs more bands. `scripts/fit_bus_cap_savings.py` fits the table by least squares to the facts below, each scaled by its tolerance. It searches shares in steps of one point and fares in steps of one penny, keeps each band's mean at least 10% above its -lower edge, and sets the low band's fare so all singles average £2.15: +lower edge, and sets the low band's fare so all singles average £2.15. The +last column is each fact under the fitted table, on the OBR's October 2026 CPI +path: | Fact | Source | Target | Table gives | |---|---|---:|---:| -| A full year at £2, 2023–24 | Fare cap support, DfT BUS05bi | £278.95m ± 10% | £282.8m | +| A full year at £2, 2023–24 | Fare cap support, DfT BUS05bi | £278.95m ± 10% | £281.5m | | Part of the December 2024 to March 2025 index step outside London due to the £3 cap | BUS0415a: +11.0%; neighbouring quarters 0.1% to 2.3% | 10% ± 1 point of the yield | 9.8% | -| The £3 cap in 2025 | ["over £150 million"](https://www.gov.uk/government/speeches/national-bus-fare-cap) | £150m ± 20% | £144.2m | -| The £2 cap in 2027, against no cap | ["£400 million"](https://www.gov.uk/government/speeches/2-bus-fares-from-january-2027) | £400m ± 20% | £420.2m | +| The £3 cap in 2025 | ["over £150 million"](https://www.gov.uk/government/speeches/national-bus-fare-cap) | £150m ± 20% | £142.7m | +| The £2 cap in 2027, against no cap | ["£400 million"](https://www.gov.uk/government/speeches/2-bus-fares-from-january-2027) | £400m ± 20% | £447.1m | | Mean pre-cap price of single tickets | [DfT evaluation](https://www.gov.uk/government/publications/evaluation-of-the-2-bus-fare-cap), Table 6 | £2.15 ± £0.10 | £2.15 | | Share of single tickets above £2 | Table 6: £0.32 / (£2.73 − £2.00) | 0.44 ± 0.05 | 0.44 | -| Their mean pre-cap price | Table 6 | £2.73 ± £0.10 | £2.73 | -| 2024–25: £2 for 270 days, then £3 | Fare cap support, DfT BUS05bi | £515.69m, not fitted | £272.7m | +| Their mean pre-cap price | Table 6 | £2.73 ± £0.10 | £2.72 | +| 2024–25: £2 for 270 days, then £3 | Fare cap support, DfT BUS05bi | £515.69m, not fitted | £271.4m | The £400 million is read as £2 against no cap: the £3 scheme is funded only to December 2026, and the £2 scheme replaces it. Read as £2 against a continued -£3 cap, the table gives £252.5m, 37% below. The script prints both. +£3 cap, the table gives £268.7m, 33% below. The script prints both. The 2024–25 grant, for the benchmark year itself, is reported and not fitted; the table puts it at about half. Grant per priced boarding rose 77.5% on @@ -253,7 +255,7 @@ cap's first ten months paid £210m against £245m planned. The table is a fitted central estimate, not an observed fare distribution. At FY2025–26 prices the table saves £0.36 per single ticket for a full year at -£2 against no cap, and £0.14 at £3: about £0.37bn and £0.14bn a year at +£2 against no cap, and £0.14 at £3: about £0.36bn and £0.14bn a year at 2024–25 boardings. A dataset or calculator can supply `local_bus_uncapped_single_fare` for each diff --git a/policyengine_uk/parameters/gov/dft/bus/uncapped_single_fares/fare.yaml b/policyengine_uk/parameters/gov/dft/bus/uncapped_single_fares/fare.yaml index 2bd7dce827..6704b33692 100644 --- a/policyengine_uk/parameters/gov/dft/bus/uncapped_single_fares/fare.yaml +++ b/policyengine_uk/parameters/gov/dft/bus/uncapped_single_fares/fare.yaml @@ -26,4 +26,4 @@ LOW: MIDDLE: '2024-01-01': 2.21 HIGH: - '2024-01-01': 3.96 + '2024-01-01': 3.95 diff --git a/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml b/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml index bdeb31d8fc..edaaae63eb 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dft/bus_journeys.yaml @@ -197,7 +197,7 @@ # Cap changes use the table of uncapped single fares in # gov.dft.bus.uncapped_single_fares: 56% of singles at GBP 1.70, 31% at -# GBP 2.21 and 13% at GBP 3.96 at FY2024-25 prices, uprated with OBR CPI +# GBP 2.21 and 13% at GBP 3.95 at FY2024-25 prices, uprated with OBR CPI # (FY2025-26 x 1.61012 / 1.55763 = 1.0337). Case 10's passenger has 100 trips # * 1.12466920264 boardings * 0.7 single share = 78.7268 single boardings, at # a GBP 181.06 baseline. @@ -211,9 +211,9 @@ local_bus_single_fare_share: 0.7 gov.dft.bus.fares.cap: .inf output: - # Only the high band (3.96 * 1.0337 = 4.0934) is above GBP 3: - # 181.0594 + 78.7268 * 0.13 * 1.0934. - person_bus_fare_spending: 192.25 + # Only the high band (3.95 * 1.0337 = 4.0831) is above GBP 3: + # 181.0594 + 78.7268 * 0.13 * 1.0831. + person_bus_fare_spending: 192.14 - name: Case 15, a GBP 2 cap in 2025-26 saves the middle and high bands. period: 2025 diff --git a/policyengine_uk/tests/test_bus_fare_reforms.py b/policyengine_uk/tests/test_bus_fare_reforms.py index 8baff05763..9eb3d93f68 100644 --- a/policyengine_uk/tests/test_bus_fare_reforms.py +++ b/policyengine_uk/tests/test_bus_fare_reforms.py @@ -131,14 +131,14 @@ def test_a_three_pound_cap_binds_and_cap_reforms_follow_the_table(): uncapped = spending_2025(**{cap: np.inf}) two_pounds = spending_2025(**{cap: 2}) assert uncapped > baseline > two_pounds - # FY2025-26 fares are the FY2024-25 table times CPI (1.034). Only the 13% - # at GBP 3.96 is above GBP 3; a GBP 2 cap also takes the 31% at GBP 2.21 + # FY2025-26 fares are the FY2024-25 table times CPI (1.0337). Only the 13% + # at GBP 3.95 is above GBP 3; a GBP 2 cap also takes the 31% at GBP 2.21 # down to GBP 2. assert uncapped - baseline == pytest.approx( - SINGLES * 0.13 * (3.96 * 1.034 - 3), rel=1e-3 + SINGLES * 0.13 * (3.95 * 1.0337 - 3), rel=1e-3 ) assert baseline - two_pounds == pytest.approx( - SINGLES * (0.31 * (2.21 * 1.034 - 2) + 0.13 * 1), rel=1e-3 + SINGLES * (0.31 * (2.21 * 1.0337 - 2) + 0.13 * 1), rel=1e-3 ) @@ -186,11 +186,11 @@ def test_a_supplied_uncapped_fare_replaces_the_table(): dataset=projected_dataset(other_trips=(100, 0), fares=(4, 4)), scenario=Scenario(parameter_changes={"gov.dft.bus.fares.cap": {2025: 2}}), ) - # The dataset's fare rises with CPI like other prices (2025: +3.4%). + # The dataset's fare rises with CPI like other prices (2025: +3.37%). assert simulation.calculate("local_bus_uncapped_single_fare", 2025)[ 0 - ] == pytest.approx(4 * 1.034) - # Every single ticket costs GBP 4.14, so a GBP 2 cap in place of GBP 3 + ] == pytest.approx(4 * 1.0337) + # Every single ticket costs GBP 4.13, so a GBP 2 cap in place of GBP 3 # saves GBP 1 on each, against GBP 0.22 on average with the table. reformed = simulation.calculate("person_bus_fare_spending", 2025)[0] baseline = simulation.baseline.calculate("person_bus_fare_spending", 2025)[0] @@ -213,8 +213,8 @@ def test_loaded_total_does_not_mask_journeys_or_cap_reforms(): priced_boardings = 1_850_509_887.26131 - 402_846_350.14539 benchmark = 2_069_953_713.42079 / priced_boardings # In 2024-25 the cap was GBP 2 for 270 days and GBP 3 for 95. Without it, - # the 31% of singles at GBP 2.21 and the 13% at GBP 3.96 pay in full. - saving = 0.31 * 0.21 * 270 / 365 + 0.13 * (1.96 * 270 / 365 + 0.96 * 95 / 365) + # the 31% of singles at GBP 2.21 and the 13% at GBP 3.95 pay in full. + saving = 0.31 * 0.21 * 270 / 365 + 0.13 * (1.95 * 270 / 365 + 0.95 * 95 / 365) uncapped_yield = benchmark + 0.7 * saving baseline_people = np.array([100, 20]) * k * benchmark reformed_people = np.array([100, 20]) * k * uncapped_yield diff --git a/policyengine_uk/tests/test_process_time_reforms.py b/policyengine_uk/tests/test_process_time_reforms.py index 732e58f2ab..5569b6981a 100644 --- a/policyengine_uk/tests/test_process_time_reforms.py +++ b/policyengine_uk/tests/test_process_time_reforms.py @@ -250,7 +250,10 @@ def test_the_growth_shown_for_a_year_is_the_growth_used_for_it(baseline): gap = value(baseline, AWE_GAP, "2027-07-01") assert value(reformed, AWE, "2027-07-01") == pytest.approx(0.2 + gap) assert value(reformed, AWE, "2028-07-01") == value(baseline, AWE, "2028-07-01") - assert value(reformed, TRIPLE_LOCK, "2028-01-01") == pytest.approx(0.2) + # The triple lock rounds May-July earnings, 20% plus the OBR gap, to 0.1pp. + assert value(reformed, TRIPLE_LOCK, "2028-01-01") == pytest.approx( + round(0.2 + gap, 3) + ) assert value(reformed, TRIPLE_LOCK, "2029-01-01") == value( baseline, TRIPLE_LOCK, "2029-01-01" ) diff --git a/policyengine_uk/tests/test_scenario_sum_timing.py b/policyengine_uk/tests/test_scenario_sum_timing.py index 78386ded3d..66d273aa8f 100644 --- a/policyengine_uk/tests/test_scenario_sum_timing.py +++ b/policyengine_uk/tests/test_scenario_sum_timing.py @@ -64,7 +64,7 @@ BASIC_RATE = "gov.hmrc.income_tax.rates.uk[0].rate" REFORM = {PERSONAL_ALLOWANCE: {"2025.2099": 20_000}} CURRENT_LAW_ALLOWANCE = 12_570 -CURRENT_LAW_GROWTH_2027 = 0.024 # yoy_growth.obr.average_earnings for 2027 +CURRENT_LAW_GROWTH_2027 = 0.0299 # yoy_growth.obr.average_earnings for 2027 MACRO_GROWTH_2027 = 0.2 # Calendar-year growth series are keyed to 1 January. MACRO = Scenario( diff --git a/policyengine_uk/tests/test_vat_grossing_legacy.py b/policyengine_uk/tests/test_vat_grossing_legacy.py index 1863aa2f5c..b7d29a86d9 100644 --- a/policyengine_uk/tests/test_vat_grossing_legacy.py +++ b/policyengine_uk/tests/test_vat_grossing_legacy.py @@ -21,7 +21,7 @@ RAW_VAT = 10_000 * 0.2 + 1_000 * 0.05 # A situation's VAT excludes private school fees' official share of 2025-26 # VAT receipts (gov.simulation.vat.private_school_share_of_receipts). -KEEP = 1 - 0.008353 +KEEP = 1 - 0.008368 def test_legacy_default_is_the_product_of_the_two_factors(): diff --git a/scripts/fit_bus_cap_savings.py b/scripts/fit_bus_cap_savings.py index 381dd4acfe..cef4d43df1 100644 --- a/scripts/fit_bus_cap_savings.py +++ b/scripts/fit_bus_cap_savings.py @@ -41,7 +41,7 @@ # GBP 400 million backing the GBP 2 cap in 2027 (GBP m), read as GBP 2 # against no cap: the GBP 3 scheme is funded only to December 2026 and the # GBP 2 scheme replaces it. Read as GBP 2 against a continued GBP 3 cap, the - # fitted table gives about GBP 253m, 37% below (see UNFITTED below). + # fitted table gives about GBP 269m, 33% below (see UNFITTED below). "cap_2_in_2027": (400, 0.20, "relative"), # Frontier Economics and SYSTRA for DfT, Table 6: all single tickets # averaged GBP 2.15 before the cap; those above GBP 2 averaged GBP 2.73, From 9251c19d398bf60aa5d2cb5821a8366689190759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 20:21:36 +0000 Subject: [PATCH 07/10] Back road fuel volumes out at #2719's April rule, and state the population gap From 1 April 2028 the volumes now use the duty rates PolicyEngine/policyengine-uk#2719 puts into current law, each April raised by the previous calendar year's RPI (63.21p to 68.61p for 2028 to 2031) rather than by Q1 RPI. Once #2719 is law, the model's duty on these volumes reproduces the OBR's road fuel receipts. 2025 to 2027 and the July 2027 step (60.59p) are unchanged; the litre proxies are re-derived. The population comment and changelog give how far the March 2026 path sits above the population the October 2026 economy tables imply: about 0.7% by 2030-31. Co-Authored-By: Claude Opus 5.5 --- .../obr-october-2026-efo-2711.changed.md | 2 +- .../gov/economic_assumptions/yoy_growth.yaml | 51 ++++++++++--------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/changelog.d/obr-october-2026-efo-2711.changed.md b/changelog.d/obr-october-2026-efo-2711.changed.md index e8efacfd5a..eb59892ff3 100644 --- a/changelog.d/obr-october-2026-efo-2711.changed.md +++ b/changelog.d/obr-october-2026-efo-2711.changed.md @@ -1 +1 @@ -Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population stays on the March 2026 long-term determinants until the October edition is published. +Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population stays on the March 2026 long-term determinants until the October edition is published; the October economy tables imply population, and so household weights, about 0.7% lower by 2030-31. diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index f0ff9dd74a..9d408fba29 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -300,22 +300,22 @@ obr: # net of non-road fuel receipts (OBR April 2024 vehicle-type release, # "Other fuels", held at GBP 0.3bn after 2028-29), divided by the # fiscal-year average petrol/diesel duty rate on the Budget 2026 path - # behind that forecast: 52.95p to 30 June 2027, 60.59p from 1 July - # 2027, then raised each 1 April by Q1 RPI growth (OBR economy - # Table 1.7), the convention that gives 60.59p. That path is policy, - # not the current law in gov.hmrc.fuel_duty.petrol_and_diesel, which - # also uses another RPI convention: calculate_fuel_duty_rates.py applies - # the previous calendar year's RPI growth (60.03p from April 2027), so - # the model's rates differ from this path by up to 0.6p a litre in - # 2027-28 and by 0.3p or less from 2028-29. Aligning the two belongs - # with the current-law schedule (#2715). The derivation is - # policyengine-uk-data's sources/road_fuel_volume.py. + # behind that forecast: 52.95p to 30 June 2027 and 60.59p from 1 July + # 2027 (57.95p raised by Q1 2027 RPI growth, OBR economy Table 1.7), + # then 63.21p, 65.13p, 67.07p and 68.61p from 1 April 2028 to 2031, + # each raised by the previous calendar year's RPI growth in obr.rpi. + # That is the schedule PolicyEngine/policyengine-uk#2719 puts into + # gov.hmrc.fuel_duty.petrol_and_diesel, so once it is law the model's + # duty on these volumes reproduces the OBR's road fuel receipts. Until + # then current law there is the Budget 2025 schedule (60.03p from April + # 2027). The derivation is policyengine-uk-data's + # sources/road_fuel_volume.py. 2026-01-01: -0.02315665811165113 2027-01-01: -0.030554808261277322 - 2028-01-01: -0.03089248062672023 - 2029-01-01: -0.03954082422617977 - 2030-01-01: -0.05402149170377035 - 2031-01-01: -0.06452057525352783 + 2028-01-01: -0.0397847818644439 + 2029-01-01: -0.041064621128607315 + 2030-01-01: -0.05572027407818414 + 2031-01-01: -0.06577310603942343 # Hold the final OBR forecast volume flat after 2031-32. 2032-01-01: 0.0 2033-01-01: 0.0 @@ -380,10 +380,10 @@ obr: 2025-01-01: -0.06053614112047978 2026-01-01: 0.08688748446453687 2027-01-01: -0.033358069858687056 - 2028-01-01: -0.0339837326821375 - 2029-01-01: -0.04279532013771159 - 2030-01-01: -0.05741479842942443 - 2031-01-01: -0.0667603504125377 + 2028-01-01: -0.04284766932261164 + 2029-01-01: -0.044313953686074714 + 2030-01-01: -0.05910748712453573 + 2031-01-01: -0.06800988232185101 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 2034-01-01: -0.0018963968459926317 @@ -447,10 +447,10 @@ obr: 2025-01-01: -0.0543311074029702 2026-01-01: 0.16474156463748946 2027-01-01: -0.033358069858687056 - 2028-01-01: -0.0339837326821375 - 2029-01-01: -0.04279532013771159 - 2030-01-01: -0.05741479842942432 - 2031-01-01: -0.0667603504125377 + 2028-01-01: -0.04284766932261175 + 2029-01-01: -0.044313953686074714 + 2030-01-01: -0.05910748712453584 + 2031-01-01: -0.0680098823218509 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 2034-01-01: -0.0018963968459926317 @@ -1087,7 +1087,12 @@ ons: # them, and the petrol and diesel spending proxies, whenever it changes. # The long-term determinants for the October 2026 EFO are not yet # published, so this stays on the March 2026 vintage until they are; the - # per_capita series meanwhile divide October 2026 aggregates by it. + # per_capita series meanwhile divide October 2026 aggregates by it. The + # October 2026 economy tables, read the same way, put growth at 0.33%, + # 0.20%, 0.13%, 0.17%, 0.21%, 0.25% and 0.24% for 2025-26 to 2031-32, + # against 0.30%, 0.35%, 0.29%, 0.32%, 0.34%, 0.36% and 0.24% here. So + # this path, and the household weights it grows, run about 0.7% above + # the October forecast by 2030-31. values: 2021-01-01: 0.0036 2022-01-01: 0.0098 From d73c849083eae19a3357e5c0b9debe71a9ba52ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 20:33:35 +0000 Subject: [PATCH 08/10] Take population to 2031-32 from the October 2026 EFO tables Population growth for 2021-22 to 2031-32 is now the OBR's October 2026 series, read from its economy tables as Q2 real GDP (Table 1.1) over Q2 real GDP per person (Table 1.5). On the March 2026 EFO that reading reproduces the long-term determinants for every forecast year, so it is the OBR's forecast without waiting for the October determinants; 2032 onwards stays on the ONS 2024-based principal projection. 2026-27 to 2030-31 growth falls from 0.29% to 0.36% a year to 0.13% to 0.25%, so household weights are about 0.7% lower by 2030-31. The per-capita GDP, mixed income and non-labour income series, rail journeys per person and the litre proxies are re-derived on it. Also re-base the Pension Credit boundary test from main on the October 2026 forecasts, with the threshold and allowance derived in its docstring. Co-Authored-By: Claude Opus 5.5 --- .../obr-october-2026-efo-2711.changed.md | 2 +- docs/book/assumptions/growthfactors.md | 8 +- .../gov/economic_assumptions/README.md | 9 +- .../gov/economic_assumptions/yoy_growth.yaml | 177 +++++++++--------- .../tests/test_council_tax_uprating.py | 20 +- ...ion_credit_guarantee_reform_projections.py | 9 +- .../tests/test_population_vintage.py | 141 +++++++++----- .../tests/test_rail_usage_uprating.py | 8 +- 8 files changed, 215 insertions(+), 159 deletions(-) diff --git a/changelog.d/obr-october-2026-efo-2711.changed.md b/changelog.d/obr-october-2026-efo-2711.changed.md index eb59892ff3..624ebcf16f 100644 --- a/changelog.d/obr-october-2026-efo-2711.changed.md +++ b/changelog.d/obr-october-2026-efo-2711.changed.md @@ -1 +1 @@ -Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population stays on the March 2026 long-term determinants until the October edition is published; the October economy tables imply population, and so household weights, about 0.7% lower by 2030-31. +Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population to 2031-32 is the OBR's October forecast, read from its economy tables; it grows more slowly than the March forecast, so household weights are about 0.7% lower by 2030-31. diff --git a/docs/book/assumptions/growthfactors.md b/docs/book/assumptions/growthfactors.md index 29112514f4..07c4ce5007 100644 --- a/docs/book/assumptions/growthfactors.md +++ b/docs/book/assumptions/growthfactors.md @@ -101,7 +101,7 @@ We derive these rates as calendar-year nominal GDP growth from the OBR's October | Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | |-------------|------|------|------|------|------|------|------|------|------|------| -| Growth rate | 10.0% | 5.2% | 3.9% | 4.7% | 3.8% | 2.9% | 3.3% | 3.5% | 3.3% | 3.3% | +| Growth rate | 10.0% | 5.2% | 4.0% | 4.6% | 4.0% | 3.1% | 3.4% | 3.6% | 3.4% | 3.3% | We use per capita GDP for these variables: `benunit_reported_capital`, `capital_gains`, `capital_gains_badr`, `capital_gains_before_response`, `capital_gains_carried_interest`, `capital_gains_residential_property`, `cash_isa`, `corporate_wealth`, `directly_held_shares`, `dividend_income`, `gross_financial_wealth`, `household_lifetime_isa_balance`, `lifetime_isa_balance`, `lump_sum_income`, `main_residence_value`, `maintenance_income`, `miscellaneous_income`, `mortgage_capital_repayment`, `net_financial_wealth`, `non_residential_property_value`, `other_investment_income`, `other_residential_property_value`, `owned_land`, `pension_credit_reported_capital`, `pension_income`, `private_pension_wealth`, `private_transfer_income`, `property_income`, `property_rental_income`, `savings`, `savings_interest_income`, `spousal_maintenance_income`, `stocks_and_shares_isa`, `sublet_income`, `uc_reported_capital`, `unit_and_investment_trusts` @@ -153,16 +153,16 @@ We derive these rates as calendar-year mixed income growth from the OBR's Octobe | Year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | |-------------|------|------|------|------|------|------|------|------|------|------| -| Growth rate | 2.9% | -0.6% | 2.7% | 0.5% | 2.8% | 3.1% | 3.4% | 3.7% | 3.9% | 4.0% | +| Growth rate | 2.8% | -0.6% | 2.8% | 0.5% | 3.0% | 3.2% | 3.5% | 3.8% | 4.0% | 4.0% | We apply this to: `self_employment_income` ## Population -We use the population growth in the OBR's [long-term economic determinants for the March 2026 EFO](https://obr.uk/supplementary-forecast-information-release-long-term-economic-determinants-march-2026/): the OBR's forecast to 2030-31, then the principal projection of the [ONS 2024-based national population projections](https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/bulletins/nationalpopulationprojections/2024based). 2021-22 and 2022-23 are the same OBR series, read from the March 2026 EFO economy tables. The determinants for the October 2026 EFO are not yet published, so population stays on the March 2026 vintage until they are. +We use the OBR's October 2026 population forecast to 2031-32, read from its economy tables (Table 1.1 real GDP over Table 1.5 real GDP per person, at Q2), and after that the population growth in the OBR's [long-term economic determinants for the March 2026 EFO](https://obr.uk/supplementary-forecast-information-release-long-term-economic-determinants-march-2026/), which follows the principal projection of the [ONS 2024-based national population projections](https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/bulletins/nationalpopulationprojections/2024based). On the March 2026 EFO the same reading of the tables reproduces the determinants' forecast years, so the October determinants, once published, should change only the later years. | Fiscal year | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | |-------------|------|------|------|------|------|------|------|------|------|------| -| Growth rate | 1.0% | 1.3% | 1.1% | 0.3% | 0.4% | 0.3% | 0.3% | 0.3% | 0.4% | 0.2% | +| Growth rate | 1.1% | 1.3% | 1.0% | 0.3% | 0.2% | 0.1% | 0.2% | 0.2% | 0.2% | 0.2% | We apply this to: `household_weight` diff --git a/policyengine_uk/parameters/gov/economic_assumptions/README.md b/policyengine_uk/parameters/gov/economic_assumptions/README.md index 2ad1f9247f..d3c2a37c62 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/README.md +++ b/policyengine_uk/parameters/gov/economic_assumptions/README.md @@ -371,10 +371,11 @@ uv run python -m policyengine_uk.utils.import_obr_forecasts \ The October 2026 import also needed, by hand: 2031 entries added to `house_prices` and `rent` before the run, the 2032+ joins above, and the -series the importer does not cover (per-capita GDP, mixed and non-labour -income, household interest income, council tax, social and private rents, -the AHC deflator, Ofwat water bills, road fuel volumes and the litre proxies, -and the fuel duty RPI path in `gov.hmrc.fuel_duty`). Each series' comments +series the importer does not cover (population, per-capita GDP, mixed and +non-labour income, household interest income, rail journeys per person, +council tax, social and private rents, the AHC deflator, Ofwat water bills, +road fuel volumes and the litre proxies, and the fuel duty RPI path in +`gov.hmrc.fuel_duty`). Each series' comments name its source and method. The EFO refresh does not touch `finance_ni.domestic_rates`; OBR does not diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index 9d408fba29..f654017784 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -374,15 +374,15 @@ obr: description: Unleaded-petrol spending proxy growth that preserves weighted road-fuel litres after dividing by model pump prices. Derived as (1 + road_fuel_volume) x (price_t / price_t-1) / (1 + population) - 1, using household.consumption.fuel.prices; re-derive whenever those prices change. values: 2021-01-01: 0.42818201287701263 - 2022-01-01: 0.32048914761975955 - 2023-01-01: -0.11986709923501582 - 2024-01-01: -0.05406513567003335 - 2025-01-01: -0.06053614112047978 - 2026-01-01: 0.08688748446453687 - 2027-01-01: -0.033358069858687056 - 2028-01-01: -0.04284766932261164 - 2029-01-01: -0.044313953686074714 - 2030-01-01: -0.05910748712453573 + 2022-01-01: 0.31957440996183406 + 2023-01-01: -0.12004079824838954 + 2024-01-01: -0.05284723399267499 + 2025-01-01: -0.060817053268056864 + 2026-01-01: 0.08851456153708859 + 2027-01-01: -0.031813450775269536 + 2028-01-01: -0.041414377422825166 + 2029-01-01: -0.043074165381306595 + 2030-01-01: -0.058075086362278316 2031-01-01: -0.06800988232185101 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 @@ -441,15 +441,15 @@ obr: description: Diesel spending proxy growth that preserves weighted road-fuel litres after dividing by model pump prices. Derived as (1 + road_fuel_volume) x (price_t / price_t-1) / (1 + population) - 1, using household.consumption.fuel.prices; re-derive whenever those prices change. values: 2021-01-01: 0.4041527984732878 - 2022-01-01: 0.38539703418341165 - 2023-01-01: -0.12622295394260497 - 2024-01-01: -0.07372422161516101 - 2025-01-01: -0.0543311074029702 - 2026-01-01: 0.16474156463748946 - 2027-01-01: -0.033358069858687056 - 2028-01-01: -0.04284766932261175 - 2029-01-01: -0.044313953686074714 - 2030-01-01: -0.05910748712453584 + 2022-01-01: 0.3844373331206423 + 2023-01-01: -0.12639539859349447 + 2024-01-01: -0.07253163122999695 + 2025-01-01: -0.05461387493788428 + 2026-01-01: 0.16648518973425208 + 2027-01-01: -0.031813450775269536 + 2028-01-01: -0.04141437742282528 + 2029-01-01: -0.043074165381306595 + 2030-01-01: -0.05807508636227843 2031-01-01: -0.0680098823218509 2032-01-01: -0.0021951706246258196 2033-01-01: -0.0020955992415926383 @@ -877,15 +877,15 @@ obr: # ons.population: (1 + nominal) / (1 + population) - 1, rounded to 4 # decimals. 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0892 - 2022-01-01: 0.1004 - 2023-01-01: 0.0524 - 2024-01-01: 0.0387 - 2025-01-01: 0.0465 - 2026-01-01: 0.0384 - 2027-01-01: 0.0294 - 2028-01-01: 0.0328 - 2029-01-01: 0.0347 - 2030-01-01: 0.0331 + 2022-01-01: 0.0997 + 2023-01-01: 0.0522 + 2024-01-01: 0.0401 + 2025-01-01: 0.0462 + 2026-01-01: 0.0400 + 2027-01-01: 0.0310 + 2028-01-01: 0.0344 + 2029-01-01: 0.0360 + 2030-01-01: 0.0343 2031-01-01: 0.0332 metadata: unit: /1 @@ -902,15 +902,15 @@ obr: # (1 + growth) / (1 + population) - 1, rounded to 4 decimals. # 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0636 - 2022-01-01: 0.0288 - 2023-01-01: -0.0060 - 2024-01-01: 0.0267 - 2025-01-01: 0.0049 - 2026-01-01: 0.0282 - 2027-01-01: 0.0307 - 2028-01-01: 0.0340 - 2029-01-01: 0.0367 - 2030-01-01: 0.0393 + 2022-01-01: 0.0281 + 2023-01-01: -0.0062 + 2024-01-01: 0.0280 + 2025-01-01: 0.0046 + 2026-01-01: 0.0297 + 2027-01-01: 0.0323 + 2028-01-01: 0.0355 + 2029-01-01: 0.0380 + 2030-01-01: 0.0404 2031-01-01: 0.0400 metadata: unit: /1 @@ -926,15 +926,15 @@ obr: # (1 + growth) / (1 + population) - 1, rounded to 4 decimals. # 2021-2025 are outturn, 2026-2031 forecast. 2021-01-01: 0.0831 - 2022-01-01: 0.0880 - 2023-01-01: 0.1069 - 2024-01-01: 0.0363 - 2025-01-01: 0.0261 - 2026-01-01: 0.0266 - 2027-01-01: 0.0438 - 2028-01-01: 0.0386 - 2029-01-01: 0.0374 - 2030-01-01: 0.0345 + 2022-01-01: 0.0873 + 2023-01-01: 0.1067 + 2024-01-01: 0.0376 + 2025-01-01: 0.0258 + 2026-01-01: 0.0281 + 2027-01-01: 0.0454 + 2028-01-01: 0.0401 + 2029-01-01: 0.0387 + 2030-01-01: 0.0356 2031-01-01: 0.0307 metadata: unit: /1 @@ -1069,41 +1069,38 @@ obr: ons: population: description: Population year-on-year growth. - # One vintage, consistent with the OBR's March 2026 EFO. The fiscal year - # starting in year t is stored at t-01-01, as growth over the year before, - # rounded to four decimals (2025-26's 0.2973% is 2025-01-01: 0.0030). The - # OBR reads population at the start of the fiscal year (Q2). - # - 2023-2073: the population growth row of the OBR's long-term economic - # determinants for the March 2026 EFO (28 May 2026). To 2030-31 it is - # the OBR's March 2026 forecast; after that it is the principal - # projection of the ONS 2024-based national population projections. - # - 2021-2022: that release starts at 2023-24, so these two years are - # the same OBR population series read from the March 2026 EFO economy - # tables: Q2 real GDP (Table 1.1) over Q2 real GDP per person, total - # population (Table 1.5), against the Q2 a year earlier. The same - # calculation gives the release's 2023-24, 2024-25 and 2025-26 values - # exactly (policyengine_uk/tests/test_population_vintage.py). - # The per_capita series under obr are derived from this series; re-derive - # them, and the petrol and diesel spending proxies, whenever it changes. - # The long-term determinants for the October 2026 EFO are not yet - # published, so this stays on the March 2026 vintage until they are; the - # per_capita series meanwhile divide October 2026 aggregates by it. The - # October 2026 economy tables, read the same way, put growth at 0.33%, - # 0.20%, 0.13%, 0.17%, 0.21%, 0.25% and 0.24% for 2025-26 to 2031-32, - # against 0.30%, 0.35%, 0.29%, 0.32%, 0.34%, 0.36% and 0.24% here. So - # this path, and the household weights it grows, run about 0.7% above - # the October forecast by 2030-31. + # The OBR's October 2026 population, then the ONS principal projection. + # The fiscal year starting in year t is stored at t-01-01, as growth over + # the year before, rounded to four decimals (2025-26's 0.3335% is + # 2025-01-01: 0.0033). The OBR reads population at the start of the + # fiscal year (Q2). + # - 2021-2031: the OBR's population series read from the October 2026 + # EFO economy tables: Q2 real GDP (Table 1.1) over Q2 real GDP per + # person, total population (Table 1.5), against the Q2 a year earlier. + # The long-term economic determinants for the October 2026 EFO are not + # yet published; for the March 2026 EFO the same calculation gave the + # determinants' 2023-24 to 2030-31 values to 1e-6 per cent + # (policyengine_uk/tests/test_population_vintage.py). + # - 2032-2073: the population growth row of the OBR's long-term economic + # determinants for the March 2026 EFO (28 May 2026), which from 2031-32 + # is the principal projection of the ONS 2024-based national population + # projections. The October 2026 EFO follows the same projection + # (paragraph 2.37). Replace it with the October determinants' row once + # published. + # The per_capita series under obr and orr are derived from this series; + # re-derive them, and the petrol and diesel spending proxies, whenever it + # changes. values: 2021-01-01: 0.0036 - 2022-01-01: 0.0098 - 2023-01-01: 0.0132 - 2024-01-01: 0.0110 - 2025-01-01: 0.0030 - 2026-01-01: 0.0035 - 2027-01-01: 0.0029 - 2028-01-01: 0.0032 - 2029-01-01: 0.0034 - 2030-01-01: 0.0036 + 2022-01-01: 0.0105 + 2023-01-01: 0.0134 + 2024-01-01: 0.0097 + 2025-01-01: 0.0033 + 2026-01-01: 0.0020 + 2027-01-01: 0.0013 + 2028-01-01: 0.0017 + 2029-01-01: 0.0021 + 2030-01-01: 0.0025 2031-01-01: 0.0024 2032-01-01: 0.0022 2033-01-01: 0.0021 @@ -1151,10 +1148,10 @@ ons: unit: /1 label: Population growth reference: - - title: OBR, "Long-term economic determinants - March 2026 Economic and fiscal outlook" (28 May 2026), population growth row + - title: OBR EFO October 2026 (detailed forecast tables, economy, Tables 1.1 and 1.5), 2021-22 to 2031-32 + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ + - title: OBR, "Long-term economic determinants - March 2026 Economic and fiscal outlook" (28 May 2026), population growth row, 2032-33 onwards href: https://obr.uk/supplementary-forecast-information-release-long-term-economic-determinants-march-2026/ - - title: OBR EFO March 2026 (detailed forecast tables, economy, Tables 1.1 and 1.5), for 2021-22 and 2022-23 - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ - title: ONS, "National population projections - 2024-based" (28 April 2026; principal projection, used by the OBR from 2031-32) href: https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationprojections/bulletins/nationalpopulationprojections/2024based household_interest_income: @@ -1670,15 +1667,15 @@ orr: # changes (policyengine_uk/tests/test_rail_usage_uprating.py checks). values: 2021-01-01: 1.5433 # 2.5525 / 1.0036 - 1 - 2022-01-01: 0.3851 # (3.5700 / 2.5525) / 1.0098 - 1 - 2023-01-01: 0.1490 # (4.1559 / 3.5700) / 1.0132 - 1 - 2024-01-01: 0.0607 # (4.4567 / 4.1559) / 1.0110 - 1 - 2025-01-01: 0.0551 # (4.7165 / 4.4567) / 1.0030 - 1 - 2026-01-01: -0.0035 # 1 / 1.0035 - 1 - 2027-01-01: -0.0029 # 1 / 1.0029 - 1 - 2028-01-01: -0.0032 # 1 / 1.0032 - 1 - 2029-01-01: -0.0034 # 1 / 1.0034 - 1 - 2030-01-01: -0.0036 # 1 / 1.0036 - 1 + 2022-01-01: 0.3841 # (3.5700 / 2.5525) / 1.0105 - 1 + 2023-01-01: 0.1487 # (4.1559 / 3.5700) / 1.0134 - 1 + 2024-01-01: 0.0621 # (4.4567 / 4.1559) / 1.0097 - 1 + 2025-01-01: 0.0548 # (4.7165 / 4.4567) / 1.0033 - 1 + 2026-01-01: -0.0020 # 1 / 1.0020 - 1 + 2027-01-01: -0.0013 # 1 / 1.0013 - 1 + 2028-01-01: -0.0017 # 1 / 1.0017 - 1 + 2029-01-01: -0.0021 # 1 / 1.0021 - 1 + 2030-01-01: -0.0025 # 1 / 1.0025 - 1 2031-01-01: -0.0024 # 1 / 1.0024 - 1 2032-01-01: -0.0022 # 1 / 1.0022 - 1 2033-01-01: -0.0021 # 1 / 1.0021 - 1 diff --git a/policyengine_uk/tests/test_council_tax_uprating.py b/policyengine_uk/tests/test_council_tax_uprating.py index d2679ec3e5..4a9eabeed7 100644 --- a/policyengine_uk/tests/test_council_tax_uprating.py +++ b/policyengine_uk/tests/test_council_tax_uprating.py @@ -139,11 +139,11 @@ def _uprated_council_tax(regions, council_tax, year): def test_uprate_council_tax_holds_northern_ireland_flat(): # In 2025-26 OBR's council tax receipts grow 7.02% in England, 7.73% in # Wales and 3.86% in Scotland (October 2026 EFO, Table 5.1, over the March - # 2026 EFO's 2024-25 outturn), and household weights grow 0.30%, with + # 2026 EFO's 2024-25 outturn), and household weights grow 0.33%, with # population. So a £1,000 bill becomes - # £1,000 x 1.0702 / 1.0030 = £1,067.00 in London, - # £1,000 x 1.0773 / 1.0030 = £1,074.08 in Wales and - # £1,000 x 1.0386 / 1.0030 = £1,035.49 in Scotland. Northern Ireland has + # £1,000 x 1.0702 / 1.0033 = £1,066.68 in London, + # £1,000 x 1.0773 / 1.0033 = £1,073.76 in Wales and + # £1,000 x 1.0386 / 1.0033 = £1,035.18 in Scotland. Northern Ireland has # no council tax series and keeps £1,000; it used to fall through to # England's growth, because the code compared the region with # "NORTHERN IRELAND" (a space) while the dataset label is NORTHERN_IRELAND. @@ -152,27 +152,27 @@ def test_uprate_council_tax_holds_northern_ireland_flat(): ) assert council_tax == pytest.approx( - [1_067.00, 1_074.08, 1_035.49, 1_000.0], abs=0.005 + [1_066.68, 1_073.76, 1_035.18, 1_000.0], abs=0.005 ) def test_uprate_council_tax_gives_unknown_region_england_growth(): council_tax = _uprated_council_tax(["UNKNOWN"], [1_000.0], 2025) - assert council_tax == pytest.approx([1_067.00], abs=0.005) + assert council_tax == pytest.approx([1_066.68], abs=0.005) def test_scottish_bills_grow_with_the_amount_billed_in_2024_25(): # Scotland's average Band D rose 0.1% in 2024-25, from £1,416.50 to # £1,418.11 (Scottish Government, Band D Council Tax 1996-97 to 2026-27), # but the net amount billed rose 2.36%, from £3,005.8m to £3,076.8m, and - # household weights grow 1.10%. So a £1,000 bill becomes - # £1,000 x 1.0236 / 1.0110 = £1,012.46. Dividing the Band D growth the + # household weights grow 0.97%. So a £1,000 bill becomes + # £1,000 x 1.0236 / 1.0097 = £1,013.77. Dividing the Band D growth the # series used to hold for 2024 (0.001) by the weights' growth would have - # cut it to £990.11, and Scotland's total would have grown 0.1%, not 2.36%. + # cut it to £991.38, and Scotland's total would have grown 0.1%, not 2.36%. council_tax = _uprated_council_tax(["SCOTLAND"], [1_000.0], 2024) - assert council_tax == pytest.approx([1_012.46], abs=0.005) + assert council_tax == pytest.approx([1_013.77], abs=0.005) @pytest.mark.parametrize("region", ["NORTHERN IRELAND", "ATLANTIS", ""]) diff --git a/policyengine_uk/tests/test_pension_credit_guarantee_reform_projections.py b/policyengine_uk/tests/test_pension_credit_guarantee_reform_projections.py index dbc2a04920..f9d3bf1557 100644 --- a/policyengine_uk/tests/test_pension_credit_guarantee_reform_projections.py +++ b/policyengine_uk/tests/test_pension_credit_guarantee_reform_projections.py @@ -641,12 +641,17 @@ def test_zero_phase_in_modifier_preserves_a_reformed_own_threshold(): @pytest.mark.parametrize( "weekly_guarantee,expected_threshold,expected_allowance,expected_step", - [(None, 221.585186, 272.195717, 1.01), (300, 268.368418, 318.978949, 1.38)], + [(None, 223.407952, 274.662918, 0.87), (300, 267.965646, 319.220612, 1.38)], ) def test_guarantee_credit_boundary_matches_main( weekly_guarantee, expected_threshold, expected_allowance, expected_step ): - """Frozen origin/main (6030cbc0b) cliff-probe values, including current law.""" + """Frozen origin/main (6030cbc0b) cliff-probe values, including current law, + re-based on the October 2026 EFO. Current law: a 2028-29 standard minimum + guarantee of 238 x 1.039 x 1.033 = 255.4423 (May-July 2026 and 2027 + earnings) less a maximum Savings Credit of 17.96 x 1.035 x 1.034 = + 19.2207 (September 2026 and 2027 CPI) over 0.6 gives the threshold; the + Housing Benefit allowance is the sum of the two.""" year = 2028 situation = { "people": {"claimant": {"age": {year: 85}}}, diff --git a/policyengine_uk/tests/test_population_vintage.py b/policyengine_uk/tests/test_population_vintage.py index 7861146b57..62307a4679 100644 --- a/policyengine_uk/tests/test_population_vintage.py +++ b/policyengine_uk/tests/test_population_vintage.py @@ -1,21 +1,21 @@ """Population growth and the per-capita series come from one OBR vintage. -ons.population, 2023-2073: the population growth row of the OBR's +ons.population, 2021-2031: the OBR's October 2026 population, read from the +October 2026 EFO detailed forecast tables (economy): population at Q2 = Table +1.1 real GDP / Table 1.5 real GDP per person (total population, index +2008Q1=100), fiscal year t-(t+1) stored at t-01-01. The long-term economic +determinants for the October 2026 EFO are not yet published. For the March +2026 EFO the same ratio on its own tables reproduces the determinants' +2023-24 to 2030-31 values to 1e-9 per cent, so the tables give the OBR's +population forecast. + +ons.population, 2032-2073: the population growth row of the OBR's "Long-term economic determinants - March 2026 Economic and fiscal outlook" -(28 May 2026), per cent, fiscal year t-(t+1) stored at t-01-01. To 2030-31 it -is the OBR's March 2026 forecast; after that, the principal projection of the -ONS 2024-based national population projections. - -ons.population, 2021-2022: the release starts at 2023-24, so the same OBR -series is read from the March 2026 EFO detailed forecast tables (economy): -population at Q2 = Table 1.1 real GDP / Table 1.5 real GDP per person (total -population, index 2008Q1=100). That ratio reproduces the release's 2023-24 to -2025-26 values to 1e-9 per cent. +(28 May 2026), which from 2031-32 is the principal projection of the ONS +2024-based national population projections. per_capita.*: (1 + aggregate growth) / (1 + ons.population) - 1, rounded to 4 -decimals, with calendar-year aggregates from the October 2026 EFO tables. The -long-term determinants for the October 2026 EFO are not yet published, so -population stays on the March 2026 vintage until they are. +decimals, with calendar-year aggregates from the October 2026 EFO tables. """ import pytest @@ -80,24 +80,66 @@ 2073: -0.10361433924080954, } -# March 2026 EFO economy tables, Q2 of each year. -# Table 1.1 real GDP, GBP billion chain-linked volumes. -REAL_GDP_Q2 = { - 2020: 522.356, - 2021: 655.443, - 2022: 686.335, - 2023: 689.491, - 2024: 695.28, - 2025: 704.973, +# EFO economy tables, Q2 of each year: Table 1.1 real GDP (GBP billion +# chain-linked volumes) and Table 1.5 real GDP per person (total population, +# index 2008Q1=100). +MARCH_2026_Q2 = { + "real_gdp": { + 2020: 522.356, + 2021: 655.443, + 2022: 686.335, + 2023: 689.491, + 2024: 695.28, + 2025: 704.973, + 2026: 711.4752108974202, + 2027: 722.8696711355229, + 2028: 734.3003452895008, + 2029: 745.6888920481834, + 2030: 756.9312657071862, + }, + "per_person": { + 2020: 82.30813961942992, + 2021: 102.91179537890864, + 2022: 106.71381138411466, + 2023: 105.81216977918598, + 2024: 105.53778853635153, + 2025: 106.69186884652444, + 2026: 107.29895022122213, + 2027: 108.70379905059379, + 2028: 110.06817103615971, + 2029: 111.39939151779004, + 2030: 112.66949934985858, + }, } -# Table 1.5 real GDP per person (total population), index 2008Q1=100. -REAL_GDP_PER_PERSON_Q2 = { - 2020: 82.30813961942992, - 2021: 102.91179537890864, - 2022: 106.71381138411466, - 2023: 105.81216977918598, - 2024: 105.53778853635153, - 2025: 106.69186884652444, +OCTOBER_2026_Q2 = { + "real_gdp": { + 2020: 522.356, + 2021: 655.443, + 2022: 686.335, + 2023: 689.491, + 2024: 694.91, + 2025: 704.274, + 2026: 712.545, + 2027: 719.317942019668, + 2028: 730.6639315269857, + 2029: 743.9492331304032, + 2030: 756.6079210550221, + 2031: 768.8776481950802, + }, + "per_person": { + 2020: 82.30813961942992, + 2021: 102.91179537890864, + 2022: 106.64443479278931, + 2023: 105.71652105745173, + 2024: 105.51970228805975, + 2025: 106.58608094213133, + 2026: 107.61945209228196, + 2027: 108.49781352227016, + 2028: 110.01755336744607, + 2029: 111.78317881384578, + 2030: 113.40385957086, + 2031: 114.96729664409621, + }, } # October 2026 EFO calendar-year totals, GBP billion. @@ -133,30 +175,41 @@ } -def q2_population_growth_percent(year): +def q2_population_growth_percent(tables, year): population = { - y: REAL_GDP_Q2[y] / REAL_GDP_PER_PERSON_Q2[y] for y in (year - 1, year) + y: tables["real_gdp"][y] / tables["per_person"][y] for y in (year - 1, year) } return (population[year] / population[year - 1] - 1) * 100 -@pytest.mark.parametrize("year", sorted(LTED_MARCH_2026_POPULATION_GROWTH)) -def test_population_is_the_march_2026_long_term_determinants_row(year): - expected = round(LTED_MARCH_2026_POPULATION_GROWTH[year] / 100, 4) +@pytest.mark.parametrize("year", range(2023, 2031)) +def test_efo_tables_reproduce_the_long_term_determinants(year): + """On the March 2026 EFO, the tables give the determinants' forecast.""" + assert q2_population_growth_percent(MARCH_2026_Q2, year) == pytest.approx( + LTED_MARCH_2026_POPULATION_GROWTH[year], abs=1e-9 + ) + + +@pytest.mark.parametrize("year", range(2021, 2032)) +def test_population_to_2031_is_the_october_2026_efo_tables(year): + expected = round(q2_population_growth_percent(OCTOBER_2026_Q2, year) / 100, 4) assert POPULATION(f"{year}-01-01") == pytest.approx(expected, abs=1e-12) -@pytest.mark.parametrize("year", [2023, 2024, 2025]) -def test_efo_tables_reproduce_the_release(year): - assert q2_population_growth_percent(year) == pytest.approx( - LTED_MARCH_2026_POPULATION_GROWTH[year], abs=1e-9 - ) +def test_october_population_grows_more_slowly_than_march(): + # 2026-27 to 2030-31: 0.13% to 0.25% a year, against 0.29% to 0.36% in + # the March 2026 forecast, about 0.7% lower by 2030-31. + level = 1.0 + for year in range(2026, 2031): + level *= (1 + POPULATION(f"{year}-01-01")) / ( + 1 + LTED_MARCH_2026_POPULATION_GROWTH[year] / 100 + ) + assert level == pytest.approx(1 - 0.0069, abs=0.0005) -@pytest.mark.parametrize("year, expected", [(2021, 0.0036), (2022, 0.0098)]) -def test_population_before_the_release_comes_from_the_efo_tables(year, expected): - # 2021: 0.3566% and 2022: 0.9824%, rounded to 4 decimals. - assert round(q2_population_growth_percent(year) / 100, 4) == expected +@pytest.mark.parametrize("year", range(2032, 2074)) +def test_population_after_2031_is_the_march_2026_determinants_row(year): + expected = round(LTED_MARCH_2026_POPULATION_GROWTH[year] / 100, 4) assert POPULATION(f"{year}-01-01") == pytest.approx(expected, abs=1e-12) diff --git a/policyengine_uk/tests/test_rail_usage_uprating.py b/policyengine_uk/tests/test_rail_usage_uprating.py index 4c8e83ec03..baa63c96b9 100644 --- a/policyengine_uk/tests/test_rail_usage_uprating.py +++ b/policyengine_uk/tests/test_rail_usage_uprating.py @@ -64,7 +64,7 @@ def test_journeys_are_held_flat_after_2025_26(year): @pytest.mark.parametrize("year", POPULATION_YEARS) def test_per_person_growth_is_journeys_growth_net_of_population_growth(year): - # 2025-26: (1,829.468 / 1,728.704) / 1.0030 - 1 = 0.0551. Fails if either + # 2025-26: (1,829.468 / 1,728.704) / 1.0033 - 1 = 0.0548. Fails if either # input series changes without re-deriving this one. instant, previous = f"{year}-01-01", f"{year - 1}-01-01" expected = RIDERSHIP(instant) / RIDERSHIP(previous) / (1 + POPULATION(instant)) - 1 @@ -106,8 +106,8 @@ def _total(dataset): def test_projected_rail_usage_tracks_orr_journeys(): - # Each household's usage grows by 1.0583 / 1.0030 = 1.0551 into 2025-26 - # and the weights by 1.0030, so the weighted total grows by ORR's 5.83%. + # Each household's usage grows by 1.0583 / 1.0033 = 1.0548 into 2025-26 + # and the weights by 1.0033, so the weighted total grows by ORR's 5.83%. # From 2026-27 the total stays flat in every projected year, past the end # of the OBR forecast too. Before #1862 rail_usage was not projected at # all. @@ -116,7 +116,7 @@ def test_projected_rail_usage_tracks_orr_journeys(): ) datasets = projected.datasets assert datasets[2025].household["rail_usage"].tolist() == pytest.approx( - [105.51, 42.204], rel=1e-4 + [105.48, 42.192], rel=1e-4 ) assert _total(datasets[2025]) / _total(datasets[2024]) == pytest.approx( JOURNEYS[2025] / JOURNEYS[2024], abs=1e-4 From a75c74ae83956af383716b98c30a38ad31676d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 20:50:00 +0000 Subject: [PATCH 09/10] Bring the rail fare indices, Bank Rate and financial assets to October 2026 - The current-law and prior-law regulated rail fare indices rise by the published July 2026 RPI (3.2%) plus 1 point in 2027, then by the previous calendar year's RPI forecast plus 1 point to 2031, in place of March 2025 RPI. test_rail_fare_index.py ties each step to obr.rpi. - Bank Rate for 2026-2031 is the calendar-year average of the OBR's market-derived path (October 2026 economy Table 1.9), in place of the November 2025 path. - Households' financial assets are October 2026 Table 1.11 to 2031, in place of the March 2024 series that ended in 2028. - The PROJECTION_END_YEAR comment names the October forecast, and the README says the national living wage forecast (Table 1.13) is not read here. Co-Authored-By: Claude Opus 5.5 --- policyengine_uk/data/economic_assumptions.py | 7 ++-- .../parameters/gov/boe/base_rate.yaml | 27 ++++++++------ .../parameters/gov/dft/rail/fare_index.yaml | 23 ++++++++---- .../gov/dft/rail/prior_law_fare_index.yaml | 23 ++++++++---- .../gov/economic_assumptions/README.md | 14 ++++++- .../household/wealth/financial_assets.yaml | 28 ++++++++------ policyengine_uk/tests/test_rail_fare_index.py | 37 +++++++++++++++++++ 7 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 policyengine_uk/tests/test_rail_fare_index.py diff --git a/policyengine_uk/data/economic_assumptions.py b/policyengine_uk/data/economic_assumptions.py index 9b94fe1c65..6db07617f5 100644 --- a/policyengine_uk/data/economic_assumptions.py +++ b/policyengine_uk/data/economic_assumptions.py @@ -105,12 +105,13 @@ # The last year a single-year dataset is projected to: 2032, fiscal year # 2032-33. An OBR forecast runs five years past the fiscal year it is made in, # so one made in 2026-27 ends in 2031-32 (year 2031). yoy_growth.yaml holds the -# March 2026 forecast, which ends in 2030-31. Move this on as forecasts move. +# October 2026 forecast, which ends in 2031-32. Move this on as forecasts move. # # Every year up to here is a dataset year, grown from the year before by # apply_single_year_uprating. A growth series with no value for a year grows -# at its latest rate, so a series that the March 2026 forecast ends in 2030 -# holds its 2030-31 rate in 2031-32 and 2032-33. +# at its latest rate, so a series that the October 2026 forecast ends in 2031 +# holds its 2031-32 rate in 2032-33, and one that ends in 2030 (mortgage +# interest) holds its 2030-31 rate in 2031-32 and 2032-33. # # Past this year policyengine-core serves each stored input from the last # projected year. An input whose variable has a formula is calculated by it diff --git a/policyengine_uk/parameters/gov/boe/base_rate.yaml b/policyengine_uk/parameters/gov/boe/base_rate.yaml index 300dba19b0..5ffb14b79e 100644 --- a/policyengine_uk/parameters/gov/boe/base_rate.yaml +++ b/policyengine_uk/parameters/gov/boe/base_rate.yaml @@ -6,20 +6,22 @@ metadata: reference: - title: Bank of England - Bank Rate history href: https://www.bankofengland.co.uk/boeapps/database/Bank-Rate.asp - - title: OBR EFO November 2025 - Market expectations for Bank Rate - href: https://obr.uk/efo/economic-and-fiscal-outlook-november-2025/ + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.9), market-derived Bank Rate, calendar-year averages + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ documentation: | The Bank of England base rate (Bank Rate). Used in student loan interest calculations for Plans 1 and 4, which charge the lower of RPI or (BoE base rate + 1%). - Historical values are from Bank of England data. - Forecast values (2025+) are based on OBR November 2025 EFO market - expectations: Bank Rate expected to fall from 4% to 3.6% by end-2026, - then gradually return to 4% by end-2030. + Historical values (to 2025) are from Bank of England data. + Forecast values (2026-2031) are the calendar-year averages of the + market-derived Bank Rate path in the OBR October 2026 EFO (economy Table + 1.9), rounded to 4 decimals: 3.78% in 2026, then 4.23% to 4.48%. Later + years hold the 2031 rate. # Historical: Bank of England outturn -# Forecast: OBR November 2025 EFO market expectations +# Forecast: OBR October 2026 EFO market-derived path (Table 1.9), +# calendar-year averages values: 2020-01-01: 0.001 # 0.1% from March 2020 2021-01-01: 0.001 # 0.1% throughout @@ -27,8 +29,9 @@ values: 2023-01-01: 0.0425 # Rising from 3.5% to 5.25% 2024-01-01: 0.0525 # 5.25% until August, then 5% 2025-01-01: 0.04 # 4% as of Nov 2025 - 2026-01-01: 0.036 # OBR: falls to 3.6% by end-2026 - 2027-01-01: 0.037 # OBR: gradual rise back - 2028-01-01: 0.038 # OBR: average ~3.8% 2025-2029 - 2029-01-01: 0.039 # OBR: rising toward 4% - 2030-01-01: 0.04 # OBR: returns to 4% by end-2030 + 2026-01-01: 0.0378 + 2027-01-01: 0.0423 + 2028-01-01: 0.0434 + 2029-01-01: 0.0430 + 2030-01-01: 0.0436 + 2031-01-01: 0.0448 diff --git a/policyengine_uk/parameters/gov/dft/rail/fare_index.yaml b/policyengine_uk/parameters/gov/dft/rail/fare_index.yaml index 6c3f3182fe..d7f1c7edc0 100644 --- a/policyengine_uk/parameters/gov/dft/rail/fare_index.yaml +++ b/policyengine_uk/parameters/gov/dft/rail/fare_index.yaml @@ -14,19 +14,28 @@ values: 2025-01-01: 1.217 # 2026: FROZEN (Autumn Budget 2025 policy) 2026-01-01: 1.217 - # 2027: +4.2% (projected - OBR RPI ~3.2% + 1%, from frozen base) + # 2027: +4.2% (July 2026 RPI outturn 3.2% + 1%, ONS CZBH) 2027-01-01: 1.268 - # 2028: +3.9% (projected - OBR RPI ~2.9% + 1%) - 2028-01-01: 1.318 - # 2029: +3.9% (projected - OBR RPI ~2.9% + 1%) - 2029-01-01: 1.369 + # Regulated fares rise by July RPI of the year before plus 1 point. From + # 2028 that July is not yet published, so the projection uses the + # previous calendar year's growth in gov.economic_assumptions.yoy_growth + # .obr.rpi, rounded to 0.1 points; the index is rounded to 3 decimals. + # policyengine_uk/tests/test_rail_fare_index.py checks each step. + # 2028: +5.3% (projected: 2027 RPI growth 4.32%, OBR October 2026, + 1%) + 2028-01-01: 1.335 + # 2029: +4.0% (projected: 2028 RPI growth 3.03%, OBR October 2026, + 1%) + 2029-01-01: 1.388 + # 2030: +4.0% (projected: 2029 RPI growth 2.98%, OBR October 2026, + 1%) + 2030-01-01: 1.444 + # 2031: +3.3% (projected: 2030 RPI growth 2.29%, OBR October 2026, + 1%) + 2031-01-01: 1.492 metadata: unit: /1 label: Regulated rail fare index (current law) reference: - title: GOV.UK Rail Fares Freeze Announcement - Autumn Budget 2025 href: https://www.gov.uk/government/news/rail-fares-freeze-autumn-budget-2025 - - title: OBR Economic and Fiscal Outlook March 2025 - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ + - title: OBR Economic and Fiscal Outlook October 2026 (RPI forecast, gov.economic_assumptions.yoy_growth.obr.rpi) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: Network Rail - How train fares are set href: https://www.networkrail.co.uk/stories/how-train-fares-set/ diff --git a/policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml b/policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml index 057ec22447..09a962aabb 100644 --- a/policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml +++ b/policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml @@ -14,19 +14,28 @@ values: 2025-01-01: 1.217 # 2026: +5.8% (counterfactual - July 2025 RPI 4.8% + 1%) 2026-01-01: 1.288 - # 2027: +4.2% (projected - OBR RPI ~3.2% + 1%) + # 2027: +4.2% (July 2026 RPI outturn 3.2% + 1%, ONS CZBH) 2027-01-01: 1.342 - # 2028: +3.9% (projected - OBR RPI ~2.9% + 1%) - 2028-01-01: 1.394 - # 2029: +3.9% (projected - OBR RPI ~2.9% + 1%) - 2029-01-01: 1.449 + # Regulated fares rise by July RPI of the year before plus 1 point. From + # 2028 that July is not yet published, so the projection uses the + # previous calendar year's growth in gov.economic_assumptions.yoy_growth + # .obr.rpi, rounded to 0.1 points; the index is rounded to 3 decimals. + # policyengine_uk/tests/test_rail_fare_index.py checks each step. + # 2028: +5.3% (projected: 2027 RPI growth 4.32%, OBR October 2026, + 1%) + 2028-01-01: 1.413 + # 2029: +4.0% (projected: 2028 RPI growth 3.03%, OBR October 2026, + 1%) + 2029-01-01: 1.470 + # 2030: +4.0% (projected: 2029 RPI growth 2.98%, OBR October 2026, + 1%) + 2030-01-01: 1.529 + # 2031: +3.3% (projected: 2030 RPI growth 2.29%, OBR October 2026, + 1%) + 2031-01-01: 1.579 metadata: unit: /1 label: Regulated rail fare index (prior law, no freeze) reference: - title: GOV.UK Rail Fares Freeze - Passenger Savings Estimate href: https://www.gov.uk/government/publications/rail-fares-freeze-passenger-savings-estimate - - title: OBR Economic and Fiscal Outlook March 2025 - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2025/ + - title: OBR Economic and Fiscal Outlook October 2026 (RPI forecast, gov.economic_assumptions.yoy_growth.obr.rpi) + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ - title: Network Rail - How train fares are set href: https://www.networkrail.co.uk/stories/how-train-fares-set/ diff --git a/policyengine_uk/parameters/gov/economic_assumptions/README.md b/policyengine_uk/parameters/gov/economic_assumptions/README.md index d3c2a37c62..b4e58b8cfc 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/README.md +++ b/policyengine_uk/parameters/gov/economic_assumptions/README.md @@ -375,8 +375,18 @@ series the importer does not cover (population, per-capita GDP, mixed and non-labour income, household interest income, rail journeys per person, council tax, social and private rents, the AHC deflator, Ofwat water bills, road fuel volumes and the litre proxies, and the fuel duty RPI path in -`gov.hmrc.fuel_duty`). Each series' comments -name its source and method. +`gov.hmrc.fuel_duty`). Each series' comments name its source and method. +The rail fare indices (`gov.dft.rail.fare_index` and `prior_law_fare_index`), +Bank Rate (`gov.boe.base_rate`, economy Table 1.9) and households' financial +assets (`household.wealth.financial_assets`, Table 1.11) also take October +2026 values. + +The national living wage forecast (economy Table 1.13) is not read here. Until +PolicyEngine/policyengine-uk#2700 adds it as `obr.national_living_wage`, the +minimum wage rates, and the rules built on them, stay at their April 2026 +levels; #2721 tracks teaching the importer to read the table. Whichever of +#2700 and the October 2026 update merges second copies the 2032+ earnings path +into that series. The EFO refresh does not touch `finance_ni.domestic_rates`; OBR does not publish a Northern Ireland domestic rates bill series (see below). diff --git a/policyengine_uk/parameters/household/wealth/financial_assets.yaml b/policyengine_uk/parameters/household/wealth/financial_assets.yaml index 3e344924ba..4eee5857ac 100644 --- a/policyengine_uk/parameters/household/wealth/financial_assets.yaml +++ b/policyengine_uk/parameters/household/wealth/financial_assets.yaml @@ -1,6 +1,9 @@ description: Financial assets of households. values: + # OBR October 2026 EFO, detailed forecast tables, economy, Table 1.11, + # households' financial assets, £bn, rounded to £1bn: outturn to 2025, + # forecast 2026-2031. 2012-01-01: 5_360_000_000_000 2013-01-01: 5_434_000_000_000 2014-01-01: 6_030_000_000_000 @@ -9,19 +12,22 @@ values: 2017-01-01: 6_901_000_000_000 2018-01-01: 6_669_000_000_000 2019-01-01: 7_113_000_000_000 - 2020-01-01: 7_566_000_000_000 - 2021-01-01: 7_673_000_000_000 - 2022-01-01: 6_838_000_000_000 - 2023-01-01: 6_870_000_000_000 - 2024-01-01: 7_071_000_000_000 - 2025-01-01: 7_300_000_000_000 - 2026-01-01: 7_549_000_000_000 - 2027-01-01: 7_810_000_000_000 - 2028-01-01: 8_090_000_000_000 + 2020-01-01: 7_563_000_000_000 + 2021-01-01: 7_662_000_000_000 + 2022-01-01: 6_581_000_000_000 + 2023-01-01: 6_582_000_000_000 + 2024-01-01: 6_567_000_000_000 + 2025-01-01: 6_748_000_000_000 + 2026-01-01: 6_805_000_000_000 + 2027-01-01: 6_916_000_000_000 + 2028-01-01: 7_048_000_000_000 + 2029-01-01: 7_164_000_000_000 + 2030-01-01: 7_279_000_000_000 + 2031-01-01: 7_390_000_000_000 metadata: unit: currency-GBP label: Financial assets reference: - - title: OBR March 2024 EFO - href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2024/ \ No newline at end of file + - title: OBR EFO October 2026 (detailed forecast tables, economy, Table 1.11), households' financial assets + href: https://obr.uk/efo/economic-and-fiscal-outlook-october-2026/ \ No newline at end of file diff --git a/policyengine_uk/tests/test_rail_fare_index.py b/policyengine_uk/tests/test_rail_fare_index.py new file mode 100644 index 0000000000..68f186917b --- /dev/null +++ b/policyengine_uk/tests/test_rail_fare_index.py @@ -0,0 +1,37 @@ +"""The projected regulated rail fare rises follow the RPI forecast. + +Regulated fares rise each January by July RPI of the year before plus 1 +point (2026 was frozen under current law). The 2027 rise uses the published +July 2026 RPI (3.2%). From 2028 the projection uses the previous calendar +year's growth in yoy_growth.obr.rpi plus 1 point, rounded to 0.1 points, so a +refreshed RPI forecast that leaves these indices stale fails here. +""" + +import pytest + +from policyengine_uk import parameters + +RAIL = parameters.gov.dft.rail +RPI = parameters.gov.economic_assumptions.yoy_growth.obr.rpi + + +def rise(index, year): + return index(f"{year}-01-01") / index(f"{year - 1}-01-01") - 1 + + +@pytest.mark.parametrize("name", ["fare_index", "prior_law_fare_index"]) +def test_2027_rise_is_july_2026_rpi_plus_one_point(name): + assert rise(getattr(RAIL, name), 2027) == pytest.approx(0.042, abs=5e-4) + + +@pytest.mark.parametrize("name", ["fare_index", "prior_law_fare_index"]) +@pytest.mark.parametrize("year", range(2028, 2032)) +def test_projected_rise_is_previous_year_rpi_plus_one_point(name, year): + expected = round(RPI(f"{year - 1}-01-01") + 0.01, 3) + # Each index level is rounded to 3 decimals, which moves a rise by at + # most about 0.05 points. + assert rise(getattr(RAIL, name), year) == pytest.approx(expected, abs=5e-4) + + +def test_current_law_holds_the_2026_freeze(): + assert rise(RAIL.fare_index, 2026) == 0 From 50665fb51db58b979abcd939d34cb045b1ffdd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:15:01 +0000 Subject: [PATCH 10/10] Put Bank Rate on one convention and name the October changes in the changelog Every Bank Rate value is now a calendar-year average from the October 2026 economy Table 1.9: Bank of England outturn to 2025, then the OBR's market-derived path. Before, 2020-2025 were point values. The changelog fragment also names the Bank Rate, rail fare index and household financial assets changes and what they move. Co-Authored-By: Claude Opus 5.5 --- .../obr-october-2026-efo-2711.changed.md | 2 +- .../parameters/gov/boe/base_rate.yaml | 27 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/changelog.d/obr-october-2026-efo-2711.changed.md b/changelog.d/obr-october-2026-efo-2711.changed.md index 624ebcf16f..005c296c37 100644 --- a/changelog.d/obr-october-2026-efo-2711.changed.md +++ b/changelog.d/obr-october-2026-efo-2711.changed.md @@ -1 +1 @@ -Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population to 2031-32 is the OBR's October forecast, read from its economy tables; it grows more slowly than the March forecast, so household weights are about 0.7% lower by 2030-31. +Update the economic assumptions to the OBR's October 2026 Economic and fiscal outlook, including its revised 2025 outturn and its new 2031 forecast, with a smooth join to the long-run paths from 2032. Population to 2031-32 is the OBR's October forecast, read from its economy tables; it grows more slowly than the March forecast, so household weights are about 0.7% lower by 2030-31. Bank Rate, which caps Plan 1 and Plan 4 student loan interest, is the calendar-year average from the October economy Table 1.9 in every year, so 2026-2031 follow the OBR's market path. The regulated rail fare indices rise by July 2026 RPI plus 1 point in 2027 and by the October RPI forecast plus 1 point to 2031, which raises rail_subsidy_spending from 2028. Households' financial assets follow October Table 1.11 to 2031; the October tables revise 2020 onwards down, so the property wealth, corporate wealth and land value totals they grow are about 10% lower in 2026, which moves land value tax and wealth tax reform results. diff --git a/policyengine_uk/parameters/gov/boe/base_rate.yaml b/policyengine_uk/parameters/gov/boe/base_rate.yaml index 5ffb14b79e..bfd748e42a 100644 --- a/policyengine_uk/parameters/gov/boe/base_rate.yaml +++ b/policyengine_uk/parameters/gov/boe/base_rate.yaml @@ -13,22 +13,21 @@ metadata: Used in student loan interest calculations for Plans 1 and 4, which charge the lower of RPI or (BoE base rate + 1%). - Historical values (to 2025) are from Bank of England data. - Forecast values (2026-2031) are the calendar-year averages of the - market-derived Bank Rate path in the OBR October 2026 EFO (economy Table - 1.9), rounded to 4 decimals: 3.78% in 2026, then 4.23% to 4.48%. Later - years hold the 2031 rate. + Every value is a calendar-year average of Bank Rate from the OBR October + 2026 EFO (economy Table 1.9), rounded to 4 decimals: Bank of England + outturn (Bankstats IUQABEDR) to 2025, then the OBR's market-derived path, + 3.78% in 2026 and 4.23% to 4.48% from 2027 to 2031. Later years hold the + 2031 rate. -# Historical: Bank of England outturn -# Forecast: OBR October 2026 EFO market-derived path (Table 1.9), -# calendar-year averages +# Calendar-year averages, OBR October 2026 EFO Table 1.9: Bank of England +# outturn to 2025, then the market-derived path. values: - 2020-01-01: 0.001 # 0.1% from March 2020 - 2021-01-01: 0.001 # 0.1% throughout - 2022-01-01: 0.01 # Rising from 0.25% to 3.5% - 2023-01-01: 0.0425 # Rising from 3.5% to 5.25% - 2024-01-01: 0.0525 # 5.25% until August, then 5% - 2025-01-01: 0.04 # 4% as of Nov 2025 + 2020-01-01: 0.0023 + 2021-01-01: 0.0011 + 2022-01-01: 0.0146 + 2023-01-01: 0.0468 + 2024-01-01: 0.0511 + 2025-01-01: 0.0426 2026-01-01: 0.0378 2027-01-01: 0.0423 2028-01-01: 0.0434