From f7ac22dd22865cc3adfdc7d20457ca40e3195450 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 12:40:46 -0400 Subject: [PATCH 1/6] Update corporate SDLT and business rates statistics and project them with OBR receipts Corporate SDLT (HMRC buyer-type tables) now runs to 2024-25 and business rates to 2025-26 (Wales 2024-25); both grow with OBR March 2026 receipts forecasts by property type / nation. NI business rates were total rates (domestic and non-domestic); they are now LPS non-domestic rates paid. Co-Authored-By: Claude Opus 5.5 --- ...ate-corporate-receipts-statistics.fixed.md | 1 + .../gov/economic_assumptions/yoy_growth.yaml | 117 ++++++++ .../gov/hmrc/business_rates/statistics.yaml | 94 +++++-- .../gov/hmrc/stamp_duty/statistics.yaml | 263 +++++++++++++++--- 4 files changed, 413 insertions(+), 62 deletions(-) create mode 100644 changelog.d/update-corporate-receipts-statistics.fixed.md diff --git a/changelog.d/update-corporate-receipts-statistics.fixed.md b/changelog.d/update-corporate-receipts-statistics.fixed.md new file mode 100644 index 0000000000..fc324ba56e --- /dev/null +++ b/changelog.d/update-corporate-receipts-statistics.fixed.md @@ -0,0 +1 @@ +Update the corporate SDLT and business rates statistics behind `corporate_sdlt` and `business_rates` to the latest official outturn (HMRC stamp tax statistics to 2024-25; England, Scotland and Northern Ireland non-domestic rates to 2025-26; Wales to 2024-25) and project them with the OBR's March 2026 receipts forecasts instead of holding 2018-2021 values flat. Northern Ireland business rates no longer include domestic rates. diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index 01fa695891..15ba6edb8a 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -646,6 +646,123 @@ obr: - title: OBR EFO March 2026 (detailed forecast tables, expenditure, Table 4.1) href: https://obr.uk/efo/economic-and-fiscal-outlook-march-2026/ + # Receipts used to project the statistics behind corporate incidence. + # Each is the OBR's growth in a receipts line: 2024 is outturn growth + # (2024-25 outturn in the March 2026 EFO over 2023-24 outturn in the March + # 2025 EFO), 2025-2030 the March 2026 EFO forecast, and 2031 onwards the + # average_earnings long-run path (the OBR forecasts receipts only to + # 2030-31). Values are ratios of the published levels, to six decimals. + stamp_duty_land_tax: + residential: + description: Growth in stamp duty land tax receipts from residential property (England and Northern Ireland). + values: + # Outturn (2024-25 over 2023-24), 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 + # 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 + 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) + 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), 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 + # 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 + 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) + 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), 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 + # 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 + 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) + 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). + values: + # Outturn (2024-25 over 2023-24), 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 + # 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 + 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) + 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. diff --git a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml index 36fb035a73..4df3cfb6f4 100644 --- a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml @@ -1,38 +1,88 @@ +description: Business rates (non-domestic rates) statistics. metadata: economy: false propagate_metadata_to_children: true +# Non-domestic rates in each nation, on the headline outturn measure each +# government publishes. For England, Scotland and Wales that is the amount +# councils collect after reliefs for the retention scheme or national pool; +# for Northern Ireland it is the non-domestic rates Land & Property Services +# received in the rating year. Dates are the first calendar year of each +# fiscal year (2025-01-01 = 2025-26). The latest year of each series is +# provisional where the source says so. +# +# After its latest outturn year each series is projected by uprating with the +# OBR's receipts forecast: England, Scotland and Wales with the OBR's +# "Business rates" line, and Northern Ireland with its "Northern Ireland +# business rates" line (gov.economic_assumptions.yoy_growth.obr.business_rates). revenue: + description: Total revenue raised by business rates. ENGLAND: + description: Non-domestic rating income from the business rates retention scheme, England. + values: + 2019-01-01: 25_344_250_093 + 2020-01-01: 12_967_918_437 + 2021-01-01: 20_447_905_400 + 2022-01-01: 22_923_982_400 + 2023-01-01: 25_079_394_900 + 2024-01-01: 26_397_345_600 + 2025-01-01: 27_591_022_700 metadata: + unit: currency-GBP + label: Business rates income, England + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain reference: - - href: https://www.gov.uk/government/collections/national-non-domestic-rates-collected-by-councils#2021-to-2022 - title: National non-domestic (non-residential) rates collected by councils - in England + - title: MHCLG, National non-domestic rates collected by councils in England 2025 to 2026, Table 1 "Non-domestic rating income from rates retention scheme" (2021-22 to 2025-26; 2025-26 provisional) + href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2025-to-2026 + - title: MHCLG, National non-domestic rates collected by councils in England 2023 to 2024, Table 1 (2019-20, 2020-21) + href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2023-to-2024 + SCOTLAND: + description: Non-domestic rates contributable amount, Scotland (audited outturn where published, otherwise provisional outturn). values: - 2019-01-01: 24967000000 - 2020-01-01: 16403000000 - 2021-01-01: 27222000000 - NORTHERN_IRELAND: + 2019-01-01: 2_752_830_731 + 2020-01-01: 1_816_120_309 + 2021-01-01: 2_108_180_163 + 2022-01-01: 2_791_962_750 + 2023-01-01: 3_033_471_284 + 2024-01-01: 3_146_317_233 + 2025-01-01: 3_079_138_735 metadata: + unit: currency-GBP + label: Business rates contributable amount, Scotland + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain reference: - - href: https://minutes.belfastcity.gov.uk/documents/s81213/Terms%20of%20Reference.pdf - title: 2019 Review of Business Rates + - title: Scottish Government, Non-domestic rates income statistics (August 2026 update), Table 1 "Contributable amount" (audited outturn 2019-20 to 2021-22; provisional outturn 2022-23 to 2025-26) + href: https://www.gov.scot/publications/non-domestic-rates-income-statistics/ + WALES: + description: Non-domestic rates contribution to the pool, Wales. values: - 2018-01-01: 1334000000 - SCOTLAND: + 2019-01-01: 990_231_844 + 2020-01-01: 952_827_214 + 2021-01-01: 991_820_618 + 2022-01-01: 986_435_966 + 2023-01-01: 893_667_788 + 2024-01-01: 980_085_115 metadata: + unit: currency-GBP + label: Business rates contribution to the pool, Wales + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain reference: - - href: https://www.gov.scot/publications/non-domestic-rates-income-statistics/ - title: Non-domestic (non-residential) rates income statistics + - title: StatsWales, Non-domestic rates actuals by local authority, "Contribution to the pool", Total Unitary Authorities (2019-20 to 2024-25) + href: https://stats.gov.wales/en-GB/a587b659-d5c7-4a53-a40d-382dbb851fdf/start + - title: Welsh Government, Non-domestic rates (actuals) April 2024 to March 2025 + href: https://www.gov.wales/node/76004 + NORTHERN_IRELAND: + description: Non-domestic rates paid against ratepayer accounts in the rating year, Northern Ireland. values: - 2020-01-01: 1912000000 - 2021-01-01: 2123000000 - WALES: + 2020-01-01: 380_876_615 + 2021-01-01: 446_688_825 + 2022-01-01: 609_651_544 + 2023-01-01: 702_804_905 + 2024-01-01: 741_337_437 + 2025-01-01: 766_153_718 metadata: + unit: currency-GBP + label: Business rates paid, Northern Ireland + uprating: gov.economic_assumptions.indices.obr.business_rates.northern_ireland reference: - - href: https://statswales.gov.wales/Catalogue/Local-Government/Finance/Non-Domestic-Rates/Estimates/nondomesticratesestimates-by-authority - title: "Non-domestic (non-residential) rates estimates by authority (\xA3\ - \ thousand) | StatsWales" - values: - 2020-01-01: 1053499000 - description: Total revenue raised by Business Rates + - title: Land & Property Services (OpenDataNI), Rates paid by District Council and Sector, "Non-Domestic Rates collected by District Council" (2020-21 to 2025-26) + href: https://admin.opendatani.gov.uk/dataset/rates-paid-by-district-council-and-sector diff --git a/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml b/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml index c138e6c4ef..62ff1b1eb2 100644 --- a/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml @@ -1,48 +1,244 @@ -description: Stamp Duty Land Tax statistics. +description: Stamp Duty Land Tax statistics (England and Northern Ireland). metadata: economy: false propagate_metadata_to_children: true - reference: - - href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics - title: UK Stamp Tax statistics - unit: currency-GBP +# HMRC's buyer-type tables split SDLT transactions at £40,000 or above between +# individuals (household) and other buyers (corporate): non-natural persons +# such as companies, partnerships and collective investment schemes. Receipts +# and values are in £ (published in £m, rounded to the nearest £5m); 2024-25 +# figures are from the edition published in December 2025 and corrected in +# March 2026 (the correction does not touch Tables 8a or 8b). Dates are the +# first calendar year of each fiscal year (2024-01-01 = 2024-25). +# +# Revenue after 2024-25 is projected by uprating: each revenue series grows +# with the OBR's receipts for its property type +# (gov.economic_assumptions.yoy_growth.obr.stamp_duty_land_tax), holding each +# buyer type's 2024-25 share of that property type's receipts. The OBR's +# 2024-25 outturn equals HMRC's all-buyer totals here (£10,380m residential, +# £3,505m non-residential), so the projection is that share times the OBR +# forecast. Transactions and values are outturn only. non_residential: corporate: revenue: - 2019-01-01: 2965000000 - 2020-01-01: 2425000000 + values: + 2019-01-01: 2_965_000_000 + 2020-01-01: 2_425_000_000 + 2021-01-01: 3_620_000_000 + 2022-01-01: 3_380_000_000 + 2023-01-01: 2_810_000_000 + 2024-01-01: 3_260_000_000 + metadata: + unit: currency-GBP + label: Non-residential SDLT receipts from non-natural persons + uprating: gov.economic_assumptions.indices.obr.stamp_duty_land_tax.non_residential + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transaction_values: - 2019-01-01: 103395000000 - 2020-01-01: 77080000000 + values: + 2019-01-01: 103_395_000_000 + 2020-01-01: 77_080_000_000 + 2021-01-01: 107_120_000_000 + 2022-01-01: 100_370_000_000 + 2023-01-01: 85_920_000_000 + 2024-01-01: 93_930_000_000 + metadata: + unit: currency-GBP + label: Non-residential SDLT transaction values for non-natural persons + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transactions: - 2019-01-01: 78800 - 2020-01-01: 65300 + values: + 2019-01-01: 78_800 + 2020-01-01: 65_300 + 2021-01-01: 83_100 + 2022-01-01: 81_500 + 2023-01-01: 80_300 + 2024-01-01: 87_300 + metadata: + label: Non-residential SDLT transactions by non-natural persons + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods household: revenue: - 2019-01-01: 210000000 - 2020-01-01: 230000000 + values: + 2019-01-01: 210_000_000 + 2020-01-01: 230_000_000 + 2021-01-01: 310_000_000 + 2022-01-01: 260_000_000 + 2023-01-01: 230_000_000 + 2024-01-01: 245_000_000 + metadata: + unit: currency-GBP + label: Non-residential SDLT receipts from individuals + uprating: gov.economic_assumptions.indices.obr.stamp_duty_land_tax.non_residential + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transaction_values: - 2019-01-01: 7025000000 - 2020-01-01: 7150000000 + values: + 2019-01-01: 7_025_000_000 + 2020-01-01: 7_150_000_000 + 2021-01-01: 9_025_000_000 + 2022-01-01: 7_985_000_000 + 2023-01-01: 6_955_000_000 + 2024-01-01: 7_640_000_000 + metadata: + unit: currency-GBP + label: Non-residential SDLT transaction values for individuals + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transactions: - 2019-01-01: 27800 - 2020-01-01: 24500 - metadata: - reference: - - href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics - title: UK Stamp Tax statistics (Table 6b) + values: + 2019-01-01: 27_800 + 2020-01-01: 24_500 + 2021-01-01: 28_800 + 2022-01-01: 26_200 + 2023-01-01: 24_800 + 2024-01-01: 25_000 + metadata: + label: Non-residential SDLT transactions by individuals + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8b (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6b (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6b (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods residential: corporate: revenue: - 2019-01-01: 885000000 - 2020-01-01: 705000000 + values: + 2019-01-01: 885_000_000 + 2020-01-01: 705_000_000 + 2021-01-01: 1_100_000_000 + 2022-01-01: 1_215_000_000 + 2023-01-01: 975_000_000 + 2024-01-01: 1_230_000_000 + metadata: + unit: currency-GBP + label: Residential SDLT receipts from non-natural persons + uprating: gov.economic_assumptions.indices.obr.stamp_duty_land_tax.residential + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transaction_values: - 2019-01-01: 31640000000 - 2020-01-01: 30460000000 + values: + 2019-01-01: 31_640_000_000 + 2020-01-01: 30_460_000_000 + 2021-01-01: 41_910_000_000 + 2022-01-01: 38_355_000_000 + 2023-01-01: 35_010_000_000 + 2024-01-01: 44_690_000_000 + metadata: + unit: currency-GBP + label: Residential SDLT transaction values for non-natural persons + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods transactions: - 2019-01-01: 104200 - 2020-01-01: 91600 + values: + 2019-01-01: 104_200 + 2020-01-01: 91_600 + 2021-01-01: 117_100 + 2022-01-01: 113_800 + 2023-01-01: 106_900 + 2024-01-01: 124_500 + metadata: + label: Residential SDLT transactions by non-natural persons + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods household: + revenue: + values: + 2019-01-01: 7_540_000_000 + 2020-01-01: 5_310_000_000 + 2021-01-01: 9_070_000_000 + 2022-01-01: 10_505_000_000 + 2023-01-01: 7_595_000_000 + 2024-01-01: 9_145_000_000 + metadata: + unit: currency-GBP + label: Residential SDLT receipts from individuals + uprating: gov.economic_assumptions.indices.obr.stamp_duty_land_tax.residential + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods + transaction_values: + values: + 2019-01-01: 269_690_000_000 + 2020-01-01: 310_380_000_000 + 2021-01-01: 374_495_000_000 + 2022-01-01: 341_420_000_000 + 2023-01-01: 270_220_000_000 + 2024-01-01: 335_515_000_000 + metadata: + unit: currency-GBP + label: Residential SDLT transaction values for individuals + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods + transactions: + values: + 2019-01-01: 918_600 + 2020-01-01: 933_700 + 2021-01-01: 1_091_300 + 2022-01-01: 951_800 + 2023-01-01: 764_800 + 2024-01-01: 925_100 + metadata: + label: Residential SDLT transactions by individuals + reference: + - title: HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected March 2026), Table 8a (2023-24, 2024-25) + href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics + - title: HMRC Annual Stamp Tax Statistics 2023 to 2024 (archived copy), Table 6a (2021-22, 2022-23) + href: https://web.archive.org/web/20250503054620/https://assets.publishing.service.gov.uk/media/674db4ec07045bdb881ee241/Annual_Stamps_2023_24.ods + - title: HMRC Annual Stamp Tax Statistics historic tables 2023 to 2024 (archived copy), Table 6a (2019-20, 2020-21) + href: https://web.archive.org/web/20250503051845/https://assets.publishing.service.gov.uk/media/674db6c42e91c6fb83fb51be/ASTP_Historic_Tables_2023_24.ods first_time_buyers_relief: brackets: - amount: @@ -106,15 +302,6 @@ residential: reference: - href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics title: UK Stamp Tax statistics (Table 6a) (Experimental) - revenue: - 2019-01-01: 7540000000 - 2020-01-01: 5310000000 - transaction_values: - 2019-01-01: 269690000000 - 2020-01-01: 310380000000 - transactions: - 2019-01-01: 918600 - 2020-01-01: 933700 transactions_by_age: brackets: - amount: @@ -178,7 +365,3 @@ residential: reference: - href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics title: UK Stamp Tax statistics (Table 6c) (Experimental) - metadata: - reference: - - href: https://www.gov.uk/government/statistics/uk-stamp-tax-statistics - title: UK Stamp Tax statistics (Table 6a) From 8ba8f280637ea69e0fe224a14a750b3b723992d8 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 13:09:30 -0400 Subject: [PATCH 2/6] Test the receipts statistics and their projection; record the interactions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test_corporate_receipts_statistics: outturn equals the published tables, growth equals ratios of the OBR's published receipts, projections track them, shares within each line are invariant (Hypothesis), and the microsimulation allocates each statistic once (and holds it at the latest outturn under no_economic_assumptions). - corporate_sdlt.yaml: expectations for the 2026-27 statistic (£5,982.55 per 1e-6 shareholding), derived from the HMRC and OBR cells. - programs.yaml: business rates verified to 2030. - fiscal_partition.yaml: data notes on the business rates head (includes NI, which the OBR records under other taxes) and the household SDLT head (calibrated to the OBR total; policyengine-uk-data#564). Co-Authored-By: Claude Opus 5.5 --- policyengine_uk/data/fiscal_partition.yaml | 14 + policyengine_uk/programs.yaml | 4 +- .../gov/hmrc/stamp_duty/corporate_sdlt.yaml | 65 +++-- .../test_corporate_receipts_statistics.py | 268 ++++++++++++++++++ 4 files changed, 320 insertions(+), 31 deletions(-) create mode 100644 policyengine_uk/tests/test_corporate_receipts_statistics.py diff --git a/policyengine_uk/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index 84da2e60fd..e320851778 100644 --- a/policyengine_uk/data/fiscal_partition.yaml +++ b/policyengine_uk/data/fiscal_partition.yaml @@ -337,6 +337,14 @@ tax_heads: payer: corporate incidence totals: [gov_tax, household_tax, pre_budget_change_household_tax] sign: nonnegative + data_note: >- + Allocates each nation's published non-domestic rates outturn, projected + with OBR receipts (gov.hmrc.business_rates.statistics). It includes + Northern Ireland, which the OBR records as "Northern Ireland business + rates" under other taxes (receipts Table 3.2), not on its Business + rates line. On policyengine-uk-data 1.58.0 it totals £35.61bn in + 2026-27 against £37.82bn for the OBR's two lines together, measured + 2026-10-11. - id: sdlt_household label: Stamp duty land tax on the household's own purchases variable: expected_sdlt @@ -347,6 +355,12 @@ tax_heads: payer: household totals: [gov_tax, household_tax, pre_budget_change_household_tax] sign: nonnegative + data_note: >- + policyengine-uk-data 1.58.0 calibrates stamp_duty_land_tax to the OBR's + total SDLT, which includes the companies' share that sdlt_corporate + allocates by shareholding (policyengine-uk-data issue 564). In 2026-27 + the two heads total £23.29bn against the OBR's £18.15bn, measured + 2026-10-11. - id: sdlt_corporate label: Stamp duty land tax paid by companies variable: corporate_sdlt diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index e8ba90376b..a290c936fa 100644 --- a/policyengine_uk/programs.yaml +++ b/policyengine_uk/programs.yaml @@ -167,8 +167,8 @@ programs: variable: business_rates parameter_prefix: gov.hmrc.business_rates verified_start_year: 2019 - verified_end_year: 2021 - notes: Parameters need updating beyond 2021 + verified_end_year: 2030 + notes: Receipts allocated to households by shareholding. Outturn to 2025-26 (Wales 2024-25), then OBR March 2026 receipts forecasts to 2030-31. - id: minimum_wage name: National Minimum Wage 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 15ad990f35..28d3eb9705 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,12 +1,19 @@ # Corporate SDLT is shareholding x (residential + non-residential corporate -# SDLT revenue) = shareholding x (£705m + £2,425m) = shareholding x £3,130m -# (gov.hmrc.stamp_duty.statistics, 2020 values held flat). A shareholding of -# 1e-6 gives £3,130 and 3e-6 gives £9,390. business_rates is set to 0 so the -# totals isolate SDLT. A £500,000 purchase that is not a first home pays -# £15,000 of SDLT (see expected_sdlt.yaml). +# 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 +# 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 +# purchase that is not a first home pays £15,000 of SDLT (see +# expected_sdlt.yaml). - name: Corporate SDLT enters household and government taxes once period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: region: LONDON shareholding: 0.000001 @@ -14,15 +21,15 @@ council_tax: 0 household_owns_tv: false output: - corporate_sdlt: 3_130 + corporate_sdlt: 5_982.55 expected_sdlt: 0 - corporate_tax_incidence: 3_130 - household_tax: 3_130 - gov_tax: 3_130 - pre_budget_change_household_tax: 3_130 + corporate_tax_incidence: 5_982.55 + household_tax: 5_982.55 + gov_tax: 5_982.55 + pre_budget_change_household_tax: 5_982.55 - name: Household and corporate SDLT each enter the totals once period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: region: LONDON main_residential_property_purchased: 500_000 @@ -33,13 +40,13 @@ household_owns_tv: false output: expected_sdlt: 15_000 - corporate_sdlt: 3_130 - household_tax: 18_130 - gov_tax: 18_130 - pre_budget_change_household_tax: 18_130 + corporate_sdlt: 5_982.55 + household_tax: 20_982.55 + gov_tax: 20_982.55 + pre_budget_change_household_tax: 20_982.55 - name: Abolishing SDLT removes household and corporate SDLT from the totals period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: gov.hmrc.stamp_duty.abolish: true region: LONDON @@ -59,7 +66,7 @@ pre_budget_change_household_tax: 0 - name: Two households, baseline - each household's SDLT counted once period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: people: buyer: @@ -90,12 +97,12 @@ household_owns_tv: false output: expected_sdlt: [15_000, 0] - corporate_sdlt: [3_130, 9_390] - household_tax: [18_130, 9_390] - gov_tax: [18_130, 9_390] + corporate_sdlt: [5_982.55, 17_947.64] + household_tax: [20_982.55, 17_947.64] + gov_tax: [20_982.55, 17_947.64] - name: Two households, SDLT abolished - no SDLT left in either household's totals period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: gov.hmrc.stamp_duty.abolish: true people: @@ -135,7 +142,7 @@ # shareholding, stays. - name: A Welsh shareholder bears corporate SDLT and business rates, each once period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: region: WALES shareholding: 0.000001 @@ -144,14 +151,14 @@ household_owns_tv: false output: expected_sdlt: 0 - corporate_sdlt: 3_130 - corporate_tax_incidence: 3_630 - household_tax: 3_630 - gov_tax: 3_630 - pre_budget_change_household_tax: 3_630 + 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 - name: Abolishing SDLT removes the Welsh shareholder's corporate SDLT and keeps business rates period: 2026 - absolute_error_margin: 0.01 + absolute_error_margin: 0.5 input: gov.hmrc.stamp_duty.abolish: true region: WALES diff --git a/policyengine_uk/tests/test_corporate_receipts_statistics.py b/policyengine_uk/tests/test_corporate_receipts_statistics.py new file mode 100644 index 0000000000..0383fc0dbd --- /dev/null +++ b/policyengine_uk/tests/test_corporate_receipts_statistics.py @@ -0,0 +1,268 @@ +"""Corporate SDLT and business rates statistics: published values and projection. + +corporate_sdlt and business_rates allocate these receipts to households by +shareholding. The outturn values are checked against the published figures, +and the projection against the OBR receipts levels it is built from. +""" + +import numpy as np +import pandas as pd +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from policyengine_uk import Microsimulation, parameters +from policyengine_uk.data import UKSingleYearDataset +from policyengine_uk.scenarios import no_economic_assumptions + +SDLT = parameters.gov.hmrc.stamp_duty.statistics +BUSINESS_RATES = parameters.gov.hmrc.business_rates.statistics.revenue +GROWTH = parameters.gov.economic_assumptions.yoy_growth.obr +INSTANT = "{}-01-01".format + +# HMRC Annual Stamp Tax Statistics, buyer-type tables, "All price bands" row, +# £m: receipts from individuals (household) and from other buyers (corporate). +# 2019-20 and 2020-21: historic tables 2023 to 2024, Tables 6a/6b; 2021-22 and +# 2022-23: 2023 to 2024 edition, Tables 6a/6b; 2023-24 and 2024-25: 2024 to +# 2025 edition (corrected March 2026), Tables 8a/8b. +SDLT_RECEIPTS_M = { + ("residential", "corporate"): (885, 705, 1_100, 1_215, 975, 1_230), + ("residential", "household"): (7_540, 5_310, 9_070, 10_505, 7_595, 9_145), + ("non_residential", "corporate"): (2_965, 2_425, 3_620, 3_380, 2_810, 3_260), + ("non_residential", "household"): (210, 230, 310, 260, 230, 245), +} +SDLT_FROM = 2019 + +# Non-domestic rates, £ (first year in brackets): MHCLG NNDR3 non-domestic +# rating income (2019; 2019-20 and 2020-21 from the 2023-24 release, later +# years from the 2025-26 release); Scottish Government NDRI contributable +# amount, latest outturn return (2019); StatsWales contribution to the pool, +# published in £ thousand (2019); LPS non-domestic rates paid (2020). +BUSINESS_RATES_OUTTURN = { + "ENGLAND": (2019, (25_344_250_093, 12_967_918_437, 20_447_905_400, + 22_923_982_400, 25_079_394_900, 26_397_345_600, + 27_591_022_700)), + "SCOTLAND": (2019, (2_752_830_731, 1_816_120_309, 2_108_180_163, + 2_791_962_750, 3_033_471_284, 3_146_317_233, + 3_079_138_735)), + "WALES": (2019, (990_231_844, 952_827_214, 991_820_618, 986_435_966, + 893_667_788, 980_085_115)), + "NORTHERN_IRELAND": (2020, (380_876_615, 446_688_825, 609_651_544, + 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_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, + ), + "stamp_duty_land_tax.non_residential": ( + 3.045, 3.505, 3.67504517435302, 4.72127759316189, 5.32882881047999, + 5.900913979881709, 6.53306953553104, 7.10465817727629, + ), + "business_rates.great_britain": ( + 29.599814327646055, 32.37681432764605, 34.05196393248926, + 37.41358657214458, 38.24093094782461, 39.111850954748434, + 42.4190677645469, 42.46319362251926, + ), + "business_rates.northern_ireland": ( + 0.3702940455770644, 0.3823335073068893, 0.39471664406441903, + 0.40263364127921164, 0.41045270712298504, 0.4181089461242919, + 0.42590403232705243, 0.4344900971429234, + ), +} # fmt: skip +OBR_LAST_YEAR = OBR_FROM + len(OBR_RECEIPTS_BN["business_rates.great_britain"]) - 1 + + +def _obr(series, year): + return OBR_RECEIPTS_BN[series][year - OBR_FROM] + + +def _growth(series): + node = GROWTH + for part in series.split("."): + node = getattr(node, part) + return node + + +# Each projected statistic, the OBR series it follows and its last outturn year. +PROJECTED = { + "residential.corporate": ("stamp_duty_land_tax.residential", 2024), + "residential.household": ("stamp_duty_land_tax.residential", 2024), + "non_residential.corporate": ("stamp_duty_land_tax.non_residential", 2024), + "non_residential.household": ("stamp_duty_land_tax.non_residential", 2024), + "ENGLAND": ("business_rates.great_britain", 2025), + "SCOTLAND": ("business_rates.great_britain", 2025), + "WALES": ("business_rates.great_britain", 2024), + "NORTHERN_IRELAND": ("business_rates.northern_ireland", 2025), +} + + +def _statistic(name): + if name in BUSINESS_RATES_OUTTURN: + return getattr(BUSINESS_RATES, name) + property_type, buyer = name.split(".") + return getattr(getattr(SDLT, property_type), buyer).revenue + + +@pytest.mark.parametrize("key", list(SDLT_RECEIPTS_M)) +def test_sdlt_receipts_match_hmrc_tables(key): + property_type, buyer = key + revenue = getattr(getattr(SDLT, property_type), buyer).revenue + for offset, receipts_m in enumerate(SDLT_RECEIPTS_M[key]): + assert revenue(INSTANT(SDLT_FROM + offset)) == receipts_m * 1e6 + + +@pytest.mark.parametrize("nation", list(BUSINESS_RATES_OUTTURN)) +def test_business_rates_match_published_outturn(nation): + first_year, values = BUSINESS_RATES_OUTTURN[nation] + for offset, value in enumerate(values): + assert getattr(BUSINESS_RATES, nation)(INSTANT(first_year + offset)) == value + + +def test_northern_ireland_business_rates_exclude_domestic_rates(): + # The previous value, £1,334m, was total NI rates (district £590m plus + # regional £744m, domestic and non-domestic). LPS records £1,631m of total + # rates paid in 2024-25, £889.5m of it domestic. + assert BUSINESS_RATES.NORTHERN_IRELAND(INSTANT(2024)) == 741_337_437 + + +@pytest.mark.parametrize("series", list(OBR_RECEIPTS_BN)) +@pytest.mark.parametrize("year", range(OBR_FROM + 1, OBR_LAST_YEAR + 1)) +def test_growth_is_the_ratio_of_published_obr_receipts(series, year): + published = _obr(series, year) / _obr(series, year - 1) - 1 + assert _growth(series)(INSTANT(year)) == pytest.approx(published, abs=5e-7) + + +@pytest.mark.parametrize("series", list(OBR_RECEIPTS_BN)) +@pytest.mark.parametrize("year", range(OBR_LAST_YEAR + 1, 2046)) +def test_growth_follows_average_earnings_after_the_obr_forecast(series, year): + assert _growth(series)(INSTANT(year)) == GROWTH.average_earnings(INSTANT(year)) + + +@pytest.mark.parametrize("name", list(PROJECTED)) +def test_projection_tracks_obr_receipts(name): + series, last_outturn = PROJECTED[name] + statistic = _statistic(name) + base = statistic(INSTANT(last_outturn)) + for year in range(last_outturn + 1, OBR_LAST_YEAR + 1): + expected = base * _obr(series, year) / _obr(series, last_outturn) + assert statistic(INSTANT(year)) == pytest.approx(expected, rel=2e-5) + + +@settings(max_examples=200, deadline=None, derandomize=True) +@given( + year=st.integers(2025, 2045), + other_year=st.integers(2025, 2045), +) +def test_projection_preserves_shares(year, other_year): + """Uprating scales a whole receipts line, so shares within it never move. + + Each buyer type keeps its 2024-25 share of its property type's SDLT, and + England, Scotland and Wales keep their shares of the three-nation total + from 2025-26 on (Wales's 2024-25 outturn is grown by the same index). + """ + + def shares(t): + out = [] + for property_type in ("residential", "non_residential"): + node = getattr(SDLT, property_type) + corporate = node.corporate.revenue(INSTANT(t)) + out.append(corporate / (corporate + node.household.revenue(INSTANT(t)))) + gb = [ + getattr(BUSINESS_RATES, n)(INSTANT(t)) + for n in ("ENGLAND", "SCOTLAND", "WALES") + ] + out += [value / sum(gb) for value in gb] + return np.array(out) + + np.testing.assert_allclose(shares(year), shares(other_year), rtol=1e-9) + np.testing.assert_allclose(shares(year)[:2], shares(2024)[:2], rtol=1e-9) + + +@pytest.mark.parametrize("name", list(PROJECTED)) +def test_projection_is_positive_and_finite(name): + statistic = _statistic(name) + values = np.array([statistic(INSTANT(year)) for year in range(2019, 2050)]) + assert np.isfinite(values).all() and (values > 0).all() + + +def _dataset(base_year=2023): + ids = np.arange(1, 4) + return UKSingleYearDataset( + person=pd.DataFrame( + { + "person_id": ids, + "person_benunit_id": ids, + "person_household_id": ids, + "age": 40, + } + ), + benunit=pd.DataFrame({"benunit_id": ids}), + household=pd.DataFrame( + { + "household_id": ids, + "household_weight": [1_000.0, 2_000.0, 500.0], + "region": ["LONDON", "WALES", "NORTHERN_IRELAND"], + "tenure_type": "OWNED_OUTRIGHT", + "rent": 0.0, + "council_tax": 0.0, + "domestic_rates": 0.0, + "corporate_wealth": [10_000.0, 0.0, 50_000.0], + "private_pension_wealth": [0.0, 20_000.0, 0.0], + } + ), + fiscal_year=base_year, + ) + + +def _sdlt_statistic(year): + return sum( + getattr(SDLT, property_type).corporate.revenue(INSTANT(year)) + for property_type in ("residential", "non_residential") + ) + + +def _business_rates_statistic(year): + return sum( + getattr(BUSINESS_RATES, nation)(INSTANT(year)) + for nation in BUSINESS_RATES_OUTTURN + ) + + +@pytest.mark.parametrize("year", [2025, 2026, 2030]) +def test_microsimulation_allocates_each_statistic_once(year): + # Variables are float32, so weighted totals match to about 1e-7. + sim = Microsimulation(dataset=_dataset()) + weights = sim.calculate("household_weight", year).values + + def weighted(variable): + return float((sim.calculate(variable, year).values * weights).sum()) + + sdlt = weighted("corporate_sdlt") + business_rates = weighted("business_rates") + assert sdlt == pytest.approx(_sdlt_statistic(year), rel=1e-6) + assert business_rates == pytest.approx(_business_rates_statistic(year), rel=1e-6) + assert weighted("baseline_business_rates") == pytest.approx(business_rates) + assert weighted("corporate_tax_incidence") == pytest.approx(sdlt + business_rates) + assert weighted("hbai_excluded_income") == pytest.approx(-(sdlt + business_rates)) + + +def test_no_economic_assumptions_holds_statistics_at_latest_outturn(): + sim = Microsimulation(dataset=_dataset(), scenario=no_economic_assumptions) + weights = sim.calculate("household_weight", 2030).values + + def weighted(variable): + return float((sim.calculate(variable, 2030).values * weights).sum()) + + latest_business_rates = sum( + getattr(BUSINESS_RATES, nation)(INSTANT(PROJECTED[nation][1])) + for nation in BUSINESS_RATES_OUTTURN + ) + assert weighted("corporate_sdlt") == pytest.approx(_sdlt_statistic(2024), rel=1e-6) + assert weighted("business_rates") == pytest.approx(latest_business_rates, rel=1e-6) From 1477c91372b945f4b86aac1e5354ada6ead00794 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 14:44:47 -0400 Subject: [PATCH 3/6] Add central rating lists and revised England outturn to business rates; address review - England central list (Main Non-Domestic Rating Accounts) and Wales central list (StatsWales), which councils' figures exclude; GB statistics now sum to within 1% of the OBR's Business rates line in 2024-25 and 2025-26. - England 2019-20 and 2020-21 from MHCLG's November 2025 revised data. - Document the Welsh Covid-year relief treatment, NI's 2020-21 start, the 2039 index horizon, the 2024 index anchor and the SDLT shares assumption. - Tests: central lists, NI = LPS total less domestic, GB coverage of the OBR line, flat after 2039, explicit no_economic_assumptions cutoff guard. Co-Authored-By: Claude Opus 5.5 --- .../gov/economic_assumptions/yoy_growth.yaml | 3 + .../gov/hmrc/business_rates/statistics.yaml | 97 +++++++++++++---- .../gov/hmrc/stamp_duty/statistics.yaml | 7 +- policyengine_uk/programs.yaml | 4 +- .../test_corporate_receipts_statistics.py | 102 ++++++++++++++---- .../gov/hmrc/baseline_business_rates.py | 10 +- 6 files changed, 176 insertions(+), 47 deletions(-) diff --git a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index 15ba6edb8a..4492945ab4 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -652,6 +652,9 @@ obr: # 2025 EFO), 2025-2030 the March 2026 EFO forecast, and 2031 onwards the # average_earnings long-run path (the OBR forecasts receipts only to # 2030-31). Values are ratios of the published levels, to six decimals. + # The 2024 value never enters a projection: indices start at 1.0 in a + # series' first year, so it only anchors the index at 2024, where the + # statistics with 2024-25 as their latest outturn are uprated from. stamp_duty_land_tax: residential: description: Growth in stamp duty land tax receipts from residential property (England and Northern Ireland). diff --git a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml index 4df3cfb6f4..240a3b805f 100644 --- a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml @@ -2,25 +2,34 @@ description: Business rates (non-domestic rates) statistics. metadata: economy: false propagate_metadata_to_children: true -# Non-domestic rates in each nation, on the headline outturn measure each -# government publishes. For England, Scotland and Wales that is the amount -# councils collect after reliefs for the retention scheme or national pool; -# for Northern Ireland it is the non-domestic rates Land & Property Services -# received in the rating year. Dates are the first calendar year of each -# fiscal year (2025-01-01 = 2025-26). The latest year of each series is -# provisional where the source says so. +# Non-domestic rates paid in each nation, on the headline outturn measure each +# government publishes: +# - England and Wales: the local rating lists, which councils bill and +# collect for the retention scheme or national pool (after reliefs), plus +# the central rating lists (mostly extensive holdings of industries that +# span several authorities), whose rates are paid to the Secretary of State +# or the Welsh Government instead. +# - Scotland: the contributable amount councils pay into the national pool. +# - Northern Ireland: non-domestic rates paid to Land & Property Services. +# Dates are the first calendar year of each fiscal year (2025-01-01 = +# 2025-26). The latest year of each series is provisional where the source +# says so. In 2024-25 the England, Scotland and Wales series sum to £32.69bn, +# against £32.38bn on the OBR's Business rates line (cash basis, March 2026 +# EFO, receipts Table 3.8). # # After its latest outturn year each series is projected by uprating with the # OBR's receipts forecast: England, Scotland and Wales with the OBR's -# "Business rates" line, and Northern Ireland with its "Northern Ireland -# business rates" line (gov.economic_assumptions.yoy_growth.obr.business_rates). +# "Business rates" line, Northern Ireland with its "Northern Ireland business +# rates" line (gov.economic_assumptions.yoy_growth.obr.business_rates). The +# economic-assumption indices run to 2039, so every series is flat in cash +# terms from 2039-40. revenue: description: Total revenue raised by business rates. ENGLAND: - description: Non-domestic rating income from the business rates retention scheme, England. + description: Non-domestic rating income from the business rates retention scheme (local rating lists), England. values: - 2019-01-01: 25_344_250_093 - 2020-01-01: 12_967_918_437 + 2019-01-01: 25_332_567_663 + 2020-01-01: 13_115_709_138 2021-01-01: 20_447_905_400 2022-01-01: 22_923_982_400 2023-01-01: 25_079_394_900 @@ -28,13 +37,34 @@ revenue: 2025-01-01: 27_591_022_700 metadata: unit: currency-GBP - label: Business rates income, England + label: Business rates income, England local lists uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain reference: - title: MHCLG, National non-domestic rates collected by councils in England 2025 to 2026, Table 1 "Non-domestic rating income from rates retention scheme" (2021-22 to 2025-26; 2025-26 provisional) href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2025-to-2026 - - title: MHCLG, National non-domestic rates collected by councils in England 2023 to 2024, Table 1 (2019-20, 2020-21) - href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2023-to-2024 + - title: MHCLG, NNDR3 2019 to 2020 local authority data, November 2025 update, Datasheet1 "nndrincome", England + href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2019-to-2020 + - title: MHCLG, NNDR3 2020 to 2021 consolidated data, November 2025 update, "nndrincome", England + href: https://www.gov.uk/government/statistics/national-non-domestic-rates-collected-by-councils-in-england-2020-to-2021 + ENGLAND_CENTRAL_LIST: + description: Rates received by the Secretary of State from ratepayers on the central non-domestic rating list, England. + values: + 2019-01-01: 1_764_413_000 + 2020-01-01: 1_822_745_000 + 2021-01-01: 1_776_808_000 + 2022-01-01: 1_770_409_000 + 2023-01-01: 1_954_686_000 + 2024-01-01: 2_064_205_000 + 2025-01-01: 2_102_772_000 + metadata: + unit: currency-GBP + label: Business rates received, England central list + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain + reference: + - title: MHCLG, Main Non-Domestic Rating Account 2025-26, "Amounts received from rate payers on the Central non domestic rating list" (2025-26) + href: https://www.gov.uk/government/publications/business-rate-retention-and-non-domestic-rates-2025-to-2026 + - title: MHCLG, Main Non-Domestic Rating Accounts 2019-20 to 2024-25 (same line, each year's account) + href: https://www.gov.uk/government/collections/business-rate-retention-and-non-domestic-rates-accounts SCOTLAND: description: Non-domestic rates contributable amount, Scotland (audited outturn where published, otherwise provisional outturn). values: @@ -53,7 +83,13 @@ revenue: - title: Scottish Government, Non-domestic rates income statistics (August 2026 update), Table 1 "Contributable amount" (audited outturn 2019-20 to 2021-22; provisional outturn 2022-23 to 2025-26) href: https://www.gov.scot/publications/non-domestic-rates-income-statistics/ WALES: - description: Non-domestic rates contribution to the pool, Wales. + description: >- + Non-domestic rates contribution to the pool (local rating lists), Wales. + In 2020-21 and 2021-22 it was 1.41 and 1.38 times the councils' + estimated in-year net collectable debit, against 0.96 to 1.02 in + 2018-19, 2019-20 and 2022-23 to 2024-25, so those two years appear to + include retail, leisure and hospitality relief that ratepayers did not + pay. values: 2019-01-01: 990_231_844 2020-01-01: 952_827_214 @@ -63,15 +99,34 @@ revenue: 2024-01-01: 980_085_115 metadata: unit: currency-GBP - label: Business rates contribution to the pool, Wales + label: Business rates contribution to the pool, Wales local lists uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain reference: - title: StatsWales, Non-domestic rates actuals by local authority, "Contribution to the pool", Total Unitary Authorities (2019-20 to 2024-25) href: https://stats.gov.wales/en-GB/a587b659-d5c7-4a53-a40d-382dbb851fdf/start - - title: Welsh Government, Non-domestic rates (actuals) April 2024 to March 2025 - href: https://www.gov.wales/node/76004 + - title: StatsWales, Collection of non-domestic rates by billing authority, "Estimated in-year NDR net collectable debit" + href: https://stats.gov.wales/en-GB/5eeb55b8-ba2b-44c6-8dca-282923028e1e/start + WALES_CENTRAL_LIST: + description: Rates received by the Welsh Government from ratepayers on the central non-domestic rating list, Wales. + values: + 2019-01-01: 100_671_014 + 2020-01-01: 102_668_488 + 2021-01-01: 100_212_013 + 2022-01-01: 101_438_110 + 2023-01-01: 96_926_991 + 2024-01-01: 104_685_854 + metadata: + unit: currency-GBP + label: Business rates received, Wales central list + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain + reference: + - title: StatsWales, Non-domestic rates central list, "Total Rates Received", Wales (2019-20 to 2024-25) + href: https://stats.gov.wales/en-GB/ddada8b1-60ac-4a9a-8a8e-4e04df23d2f8/start NORTHERN_IRELAND: - description: Non-domestic rates paid against ratepayer accounts in the rating year, Northern Ireland. + description: >- + Non-domestic rates paid against ratepayer accounts in the rating year, + Northern Ireland. The series starts in 2020-21 (a rates-holiday year), + and earlier years take that value. values: 2020-01-01: 380_876_615 2021-01-01: 446_688_825 @@ -85,4 +140,4 @@ revenue: uprating: gov.economic_assumptions.indices.obr.business_rates.northern_ireland reference: - title: Land & Property Services (OpenDataNI), Rates paid by District Council and Sector, "Non-Domestic Rates collected by District Council" (2020-21 to 2025-26) - href: https://admin.opendatani.gov.uk/dataset/rates-paid-by-district-council-and-sector + href: https://www.opendatani.gov.uk/dataset/rates-paid-by-district-council-and-sector diff --git a/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml b/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml index 62ff1b1eb2..4b121ee52e 100644 --- a/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml @@ -16,7 +16,12 @@ metadata: # buyer type's 2024-25 share of that property type's receipts. The OBR's # 2024-25 outturn equals HMRC's all-buyer totals here (£10,380m residential, # £3,505m non-residential), so the projection is that share times the OBR -# forecast. Transactions and values are outturn only. +# forecast. Holding the 2024-25 shares means the projection ignores later +# policy or market changes that fall unevenly on buyer types. Transactions +# and values are outturn only. corporate_sdlt allocates the corporate receipts +# to UK households by shareholding, a modelling convention: HMRC's "other +# buyers" are all non-natural persons, including partnerships and collective +# investment schemes as well as companies. non_residential: corporate: revenue: diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index a290c936fa..7a2651893a 100644 --- a/policyengine_uk/programs.yaml +++ b/policyengine_uk/programs.yaml @@ -166,9 +166,9 @@ programs: coverage: UK variable: business_rates parameter_prefix: gov.hmrc.business_rates - verified_start_year: 2019 + verified_start_year: 2020 verified_end_year: 2030 - notes: Receipts allocated to households by shareholding. Outturn to 2025-26 (Wales 2024-25), then OBR March 2026 receipts forecasts to 2030-31. + notes: Receipts allocated to households by shareholding. Local and central rating lists; outturn from 2020-21 (Northern Ireland's first year) to 2025-26 (Wales 2024-25), then OBR March 2026 receipts forecasts to 2030-31. - id: minimum_wage name: National Minimum Wage diff --git a/policyengine_uk/tests/test_corporate_receipts_statistics.py b/policyengine_uk/tests/test_corporate_receipts_statistics.py index 0383fc0dbd..ca6fbf909c 100644 --- a/policyengine_uk/tests/test_corporate_receipts_statistics.py +++ b/policyengine_uk/tests/test_corporate_receipts_statistics.py @@ -11,7 +11,7 @@ from hypothesis import given, settings from hypothesis import strategies as st -from policyengine_uk import Microsimulation, parameters +from policyengine_uk import Microsimulation, Simulation, parameters from policyengine_uk.data import UKSingleYearDataset from policyengine_uk.scenarios import no_economic_assumptions @@ -33,20 +33,32 @@ } SDLT_FROM = 2019 -# Non-domestic rates, £ (first year in brackets): MHCLG NNDR3 non-domestic -# rating income (2019; 2019-20 and 2020-21 from the 2023-24 release, later -# years from the 2025-26 release); Scottish Government NDRI contributable -# amount, latest outturn return (2019); StatsWales contribution to the pool, -# published in £ thousand (2019); LPS non-domestic rates paid (2020). +# Non-domestic rates, £ (first year in brackets): +# - England local lists: MHCLG NNDR3 non-domestic rating income (2019; +# 2019-20 and 2020-21 from the November 2025 revised data, later years +# from the 2025-26 release, published in £m to four decimals). +# - England central list: Main Non-Domestic Rating Accounts, amounts received +# from ratepayers on the central list, published in £ thousand (2019). +# - Scotland: NDRI contributable amount, latest outturn return (2019). +# - Wales local lists: StatsWales contribution to the pool, published in +# £ thousand (2019); central list: StatsWales total rates received (2019). +# Values published in pounds and pence are rounded to the pound (half to even). +# - Northern Ireland: LPS non-domestic rates paid (2020). BUSINESS_RATES_OUTTURN = { - "ENGLAND": (2019, (25_344_250_093, 12_967_918_437, 20_447_905_400, + "ENGLAND": (2019, (25_332_567_663, 13_115_709_138, 20_447_905_400, 22_923_982_400, 25_079_394_900, 26_397_345_600, 27_591_022_700)), + "ENGLAND_CENTRAL_LIST": (2019, (1_764_413_000, 1_822_745_000, + 1_776_808_000, 1_770_409_000, + 1_954_686_000, 2_064_205_000, + 2_102_772_000)), "SCOTLAND": (2019, (2_752_830_731, 1_816_120_309, 2_108_180_163, 2_791_962_750, 3_033_471_284, 3_146_317_233, 3_079_138_735)), "WALES": (2019, (990_231_844, 952_827_214, 991_820_618, 986_435_966, 893_667_788, 980_085_115)), + "WALES_CENTRAL_LIST": (2019, (100_671_014, 102_668_488, 100_212_013, + 101_438_110, 96_926_991, 104_685_854)), "NORTHERN_IRELAND": (2020, (380_876_615, 446_688_825, 609_651_544, 702_804_905, 741_337_437, 766_153_718)), } # fmt: skip @@ -97,8 +109,10 @@ def _growth(series): "non_residential.corporate": ("stamp_duty_land_tax.non_residential", 2024), "non_residential.household": ("stamp_duty_land_tax.non_residential", 2024), "ENGLAND": ("business_rates.great_britain", 2025), + "ENGLAND_CENTRAL_LIST": ("business_rates.great_britain", 2025), "SCOTLAND": ("business_rates.great_britain", 2025), "WALES": ("business_rates.great_britain", 2024), + "WALES_CENTRAL_LIST": ("business_rates.great_britain", 2024), "NORTHERN_IRELAND": ("business_rates.northern_ireland", 2025), } @@ -125,11 +139,45 @@ def test_business_rates_match_published_outturn(nation): assert getattr(BUSINESS_RATES, nation)(INSTANT(first_year + offset)) == value -def test_northern_ireland_business_rates_exclude_domestic_rates(): +# LPS rates paid, Northern Ireland, £: total and domestic ("Rates collected by +# District Council and Sector"), 2020-21 to 2025-26. +NI_TOTAL_RATES_PAID = (1_101_723_078, 1_195_019_197, 1_380_794_919, + 1_540_739_422, 1_630_880_597, 1_714_042_296) # fmt: skip +NI_DOMESTIC_RATES_PAID = (720_846_463, 748_330_372, 771_143_375, 837_934_517, + 889_543_160, 947_888_579) # fmt: skip + + +@pytest.mark.parametrize("offset", range(len(NI_TOTAL_RATES_PAID))) +def test_northern_ireland_business_rates_are_total_rates_less_domestic(offset): # The previous value, £1,334m, was total NI rates (district £590m plus - # regional £744m, domestic and non-domestic). LPS records £1,631m of total - # rates paid in 2024-25, £889.5m of it domestic. - assert BUSINESS_RATES.NORTHERN_IRELAND(INSTANT(2024)) == 741_337_437 + # regional £744m, domestic and non-domestic together), so business_rates + # repeated NI domestic rates, which domestic_rates already charges. + year = 2020 + offset + business_rates = BUSINESS_RATES.NORTHERN_IRELAND(INSTANT(year)) + # LPS publishes each column to the pound, so the difference can be £1 off. + assert business_rates == pytest.approx( + NI_TOTAL_RATES_PAID[offset] - NI_DOMESTIC_RATES_PAID[offset], abs=1 + ) + + +# 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. +GB_SERIES = ( + "ENGLAND", + "ENGLAND_CENTRAL_LIST", + "SCOTLAND", + "WALES", + "WALES_CENTRAL_LIST", +) + + +@pytest.mark.parametrize("year", [2024, 2025]) +def test_great_britain_statistics_cover_the_obr_business_rates_line(year): + total = sum(getattr(BUSINESS_RATES, n)(INSTANT(year)) for n in GB_SERIES) + assert total / 1e9 == pytest.approx( + _obr("business_rates.great_britain", year), rel=0.02 + ) @pytest.mark.parametrize("series", list(OBR_RECEIPTS_BN)) @@ -155,17 +203,22 @@ def test_projection_tracks_obr_receipts(name): assert statistic(INSTANT(year)) == pytest.approx(expected, rel=2e-5) +# The economic-assumption indices run to 2039, so the projections do too. +LAST_INDEXED_YEAR = 2039 + + @settings(max_examples=200, deadline=None, derandomize=True) @given( - year=st.integers(2025, 2045), - other_year=st.integers(2025, 2045), + year=st.integers(2025, LAST_INDEXED_YEAR), + other_year=st.integers(2025, LAST_INDEXED_YEAR), ) def test_projection_preserves_shares(year, other_year): """Uprating scales a whole receipts line, so shares within it never move. Each buyer type keeps its 2024-25 share of its property type's SDLT, and - England, Scotland and Wales keep their shares of the three-nation total - from 2025-26 on (Wales's 2024-25 outturn is grown by the same index). + the England, Scotland and Wales series (local and central lists) keep + their shares of the Great Britain total from 2025-26 on (the Welsh + series' 2024-25 outturn is grown by the same index). """ def shares(t): @@ -174,10 +227,7 @@ def shares(t): node = getattr(SDLT, property_type) corporate = node.corporate.revenue(INSTANT(t)) out.append(corporate / (corporate + node.household.revenue(INSTANT(t)))) - gb = [ - getattr(BUSINESS_RATES, n)(INSTANT(t)) - for n in ("ENGLAND", "SCOTLAND", "WALES") - ] + gb = [getattr(BUSINESS_RATES, n)(INSTANT(t)) for n in GB_SERIES] out += [value / sum(gb) for value in gb] return np.array(out) @@ -185,6 +235,15 @@ def shares(t): np.testing.assert_allclose(shares(year)[:2], shares(2024)[:2], rtol=1e-9) +@pytest.mark.parametrize("name", list(PROJECTED)) +def test_projection_is_flat_after_the_last_indexed_year(name): + statistic = _statistic(name) + last = statistic(INSTANT(LAST_INDEXED_YEAR)) + assert statistic(INSTANT(LAST_INDEXED_YEAR - 1)) < last + for year in range(LAST_INDEXED_YEAR + 1, 2050): + assert statistic(INSTANT(year)) == last + + @pytest.mark.parametrize("name", list(PROJECTED)) def test_projection_is_positive_and_finite(name): statistic = _statistic(name) @@ -254,6 +313,11 @@ def weighted(variable): def test_no_economic_assumptions_holds_statistics_at_latest_outturn(): + # The scenario runs before the dataset loads, so it zeroes growth from the + # class default input period, not the dataset's year. Every statistic's + # latest outturn is 2024-25 or 2025-26, so the projection holds at that + # outturn only while the cutoff is 2025 or earlier. + assert Simulation.default_input_period <= 2025 sim = Microsimulation(dataset=_dataset(), scenario=no_economic_assumptions) weights = sim.calculate("household_weight", 2030).values diff --git a/policyengine_uk/variables/gov/hmrc/baseline_business_rates.py b/policyengine_uk/variables/gov/hmrc/baseline_business_rates.py index c18efdc998..11b45ebff9 100644 --- a/policyengine_uk/variables/gov/hmrc/baseline_business_rates.py +++ b/policyengine_uk/variables/gov/hmrc/baseline_business_rates.py @@ -12,9 +12,11 @@ class baseline_business_rates(Variable): def formula(household, period, parameters): br = parameters(period).gov.hmrc.business_rates.statistics.revenue total_revenue = ( - br.ENGLAND # HMRC - + br.SCOTLAND # Revenue Scotland - + br.WALES # Welsh Revenue Authority - + br.NORTHERN_IRELAND # HMRC + br.ENGLAND # Local rating lists, collected by councils + + br.ENGLAND_CENTRAL_LIST # Paid to the Secretary of State + + br.SCOTLAND # Collected by councils + + br.WALES # Local rating lists, collected by councils + + br.WALES_CENTRAL_LIST # Paid to the Welsh Government + + br.NORTHERN_IRELAND # Collected by Land & Property Services ) return household("shareholding", period) * total_revenue From 5f08c244cfbfa2230d9e812315d04b9b7a4a6ca1 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 14:45:56 -0400 Subject: [PATCH 4/6] Let the partition file carry spending sections; note negative VAT The aggregate impact report (#2335) adds gov_spending, household_benefits and spending_heads to fiscal_partition.yaml. The tax tests now check the three tax totals only, require that spending heads borrow no tax head id or variable and that no spending head names a tax total, and apply dropped_when to the tax totals alone. Checked against #2335's file with these tax sections merged in: this file's tests and #2335's partition and guard tests pass. The vat head records that 76 households have negative VAT on policyengine-uk-data 1.58.0 (consumption or the full-rate expenditure share is negative in the data; policyengine-uk-data issue 565). Refs #2159 Co-Authored-By: Claude Opus 5.5 --- policyengine_uk/data/fiscal_partition.yaml | 7 +++++++ .../tests/test_fiscal_partition.py | 20 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/policyengine_uk/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index 84da2e60fd..21bc4b9928 100644 --- a/policyengine_uk/data/fiscal_partition.yaml +++ b/policyengine_uk/data/fiscal_partition.yaml @@ -183,6 +183,13 @@ tax_heads: payer: consumer incidence totals: [gov_tax] sign: nonnegative + data_note: >- + Negative for 76 households on policyengine-uk-data 1.58.0 + (enhanced_frs_2024_25) in every year from 2025 to 2030, -£72m weighted + in 2026: full_rate_vat_consumption is negative there because the + dataset's consumption (44 households) or full_rate_vat_expenditure_rate + (32 households, as low as -1.02) is negative. policyengine-uk-data + issue 565. Measured 2026-10-11. - id: vat_change label: Change in VAT from its baseline variable: vat_change diff --git a/policyengine_uk/tests/test_fiscal_partition.py b/policyengine_uk/tests/test_fiscal_partition.py index 8e7b0da100..2988b43371 100644 --- a/policyengine_uk/tests/test_fiscal_partition.py +++ b/policyengine_uk/tests/test_fiscal_partition.py @@ -114,16 +114,23 @@ def tolerance(*arrays) -> np.ndarray: def test_partition_schema(): p = partition() assert p["schema_version"] == 1 - totals = set(p["totals"]) - assert totals == set(MODEL_LISTS) + # The tax totals are this file's subject; the spending totals and + # spending_heads (the aggregate impact report's) share the file and must + # not borrow tax heads or variables. + assert set(MODEL_LISTS) <= set(p["totals"]) + spending_heads = p.get("spending_heads", []) + spending_totals = {t for head in spending_heads for t in head["totals"]} + assert not spending_totals & set(MODEL_LISTS) ids = [head["id"] for head in heads()] variables = [head["variable"] for head in heads()] assert len(ids) == len(set(ids)), "duplicate head id" assert len(variables) == len(set(variables)), "a variable is in two heads" + assert not set(variables) & {h["variable"] for h in spending_heads} + assert not set(ids) & {h["id"] for h in spending_heads} for head in heads(): variable = system.variables[head["variable"]] assert head["entity"] == variable.entity.key, head["id"] - assert set(head["totals"]) <= totals, head["id"] + assert set(head["totals"]) <= set(MODEL_LISTS), head["id"] assert head["sign"] in {"nonnegative", "any"}, head["id"] assert head.get("zero_at_baseline", "expected") == "expected", head["id"] assert head["obr_line"], head["id"] @@ -144,8 +151,8 @@ def test_partition_schema(): assert set(x["spans"]) <= set(ids), x else: assert x["head"] in ids, x - for total, spec in p["totals"].items(): - for switch, dropped in spec.get("dropped_when", {}).items(): + for total in MODEL_LISTS: + for switch, dropped in p["totals"][total].get("dropped_when", {}).items(): system.parameters.get_child(switch) assert set(dropped) <= {h["variable"] for h in heads_of(total)} for guard in p["overlap_guards"]: @@ -488,7 +495,8 @@ def test_each_total_is_the_sum_of_its_heads(drawn, year): for scenario, reform in SCENARIOS.items(): sim = Simulation(situation=random_situation(drawn, year), reform=reform) values = {h["id"]: household_values(sim, h["variable"], year) for h in heads()} - for total, spec in partition()["totals"].items(): + for total in MODEL_LISTS: + spec = partition()["totals"][total] dropped = set() for switch, names in spec.get("dropped_when", {}).items(): if reform and switch in reform: From cafd3f1dbf7a5f853f948881505c2f1278ac6220 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 14:48:44 -0400 Subject: [PATCH 5/6] Split the business rates partition note into GB and NI against the OBR lines Co-Authored-By: Claude Opus 5.5 --- policyengine_uk/data/fiscal_partition.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/policyengine_uk/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index e320851778..6f340ec191 100644 --- a/policyengine_uk/data/fiscal_partition.yaml +++ b/policyengine_uk/data/fiscal_partition.yaml @@ -338,13 +338,14 @@ tax_heads: totals: [gov_tax, household_tax, pre_budget_change_household_tax] sign: nonnegative data_note: >- - Allocates each nation's published non-domestic rates outturn, projected - with OBR receipts (gov.hmrc.business_rates.statistics). It includes - Northern Ireland, which the OBR records as "Northern Ireland business - rates" under other taxes (receipts Table 3.2), not on its Business - rates line. On policyengine-uk-data 1.58.0 it totals £35.61bn in - 2026-27 against £37.82bn for the OBR's two lines together, measured - 2026-10-11. + Allocates each nation's published non-domestic rates outturn (England + and Wales local and central rating lists, Scotland, Northern Ireland), + projected with OBR receipts (gov.hmrc.business_rates.statistics). In + 2026-27 the England, Scotland and Wales series total £37.26bn against + £37.41bn on the OBR's Business rates line (receipts Table 3.8). + Northern Ireland's £0.78bn (LPS non-domestic rates paid) compares with + £0.40bn on the OBR's "Northern Ireland business rates" line, which the + OBR records under other taxes (Table 3.2). Measured 2026-10-11. - id: sdlt_household label: Stamp duty land tax on the household's own purchases variable: expected_sdlt From 2f951f8ec4c5a4ac27b5f3a2ed74b87da1621626 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 15:16:50 -0400 Subject: [PATCH 6/6] Note the shareholding convention and 2023-24 coverage in the business rates statistics Comment-only (review round 2, findings 2 and 3). Co-Authored-By: Claude Opus 5.5 --- .../parameters/gov/hmrc/business_rates/statistics.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml index 240a3b805f..84cdf1b00c 100644 --- a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml @@ -11,11 +11,17 @@ metadata: # or the Welsh Government instead. # - Scotland: the contributable amount councils pay into the national pool. # - Northern Ireland: non-domestic rates paid to Land & Property Services. +# business_rates allocates all of it by shareholding, a modelling convention +# that applies to every ratepayer on the lists, including, on the Welsh +# central list in 2024-25, Network Rail (£10.5m) and Dwr Cymru (£17.0m) of +# £104.7m. # Dates are the first calendar year of each fiscal year (2025-01-01 = # 2025-26). The latest year of each series is provisional where the source -# says so. In 2024-25 the England, Scotland and Wales series sum to £32.69bn, +# says so. The England, Scotland and Wales series sum to £32.69bn in 2024-25, # against £32.38bn on the OBR's Business rates line (cash basis, March 2026 -# EFO, receipts Table 3.8). +# EFO, receipts Table 3.8), and to £31.06bn in 2023-24, against £29.60bn +# (March 2025 EFO): England's local-list income is an accounting measure, +# the OBR line cash. # # After its latest outturn year each series is projected by uprating with the # OBR's receipts forecast: England, Scotland and Wales with the OBR's