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/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index 84da2e60fd..c96ccffaec 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 @@ -337,6 +344,15 @@ 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 (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 @@ -347,6 +363,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/parameters/gov/economic_assumptions/yoy_growth.yaml b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml index 01fa695891..4492945ab4 100644 --- a/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +++ b/policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml @@ -646,6 +646,126 @@ 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. + # 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). + 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..84cdf1b00c 100644 --- a/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/business_rates/statistics.yaml @@ -1,38 +1,149 @@ +description: Business rates (non-domestic rates) statistics. metadata: economy: false propagate_metadata_to_children: true +# 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. +# 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. 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), 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 +# "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 (local rating lists), England. + values: + 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 + 2024-01-01: 26_397_345_600 + 2025-01-01: 27_591_022_700 metadata: + unit: currency-GBP + label: Business rates income, England local lists + 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, 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: 24967000000 - 2020-01-01: 16403000000 - 2021-01-01: 27222000000 - NORTHERN_IRELAND: + 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: - - href: https://minutes.belfastcity.gov.uk/documents/s81213/Terms%20of%20Reference.pdf - title: 2019 Review of Business Rates - values: - 2018-01-01: 1334000000 + - 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: + 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://www.gov.scot/publications/non-domestic-rates-income-statistics/ - title: Non-domestic (non-residential) rates income statistics - values: - 2020-01-01: 1912000000 - 2021-01-01: 2123000000 + - 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 (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 + 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 local lists + uprating: gov.economic_assumptions.indices.obr.business_rates.great_britain 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" + - 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: 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: - 2020-01-01: 1053499000 - description: Total revenue raised by Business Rates + 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. 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 + 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: + - 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://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 c138e6c4ef..4b121ee52e 100644 --- a/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml +++ b/policyengine_uk/parameters/gov/hmrc/stamp_duty/statistics.yaml @@ -1,48 +1,249 @@ -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. 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: - 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 +307,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 +370,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) diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index e8ba90376b..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_end_year: 2021 - notes: Parameters need updating beyond 2021 + verified_start_year: 2020 + verified_end_year: 2030 + 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/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..ca6fbf909c --- /dev/null +++ b/policyengine_uk/tests/test_corporate_receipts_statistics.py @@ -0,0 +1,332 @@ +"""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, Simulation, 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): +# - 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_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 + +# 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), + "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), +} + + +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 + + +# 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 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)) +@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) + + +# 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, 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 + 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): + 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 GB_SERIES] + 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_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) + 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(): + # 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 + + 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) 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: 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