diff --git a/changelog.d/uk-pension-wealth-disregard-452.added.md b/changelog.d/uk-pension-wealth-disregard-452.added.md new file mode 100644 index 0000000000..cf5a58c116 --- /dev/null +++ b/changelog.d/uk-pension-wealth-disregard-452.added.md @@ -0,0 +1 @@ +Added `private_pension_wealth` (Household, imputed from the Wealth and Assets Survey) as an explicit capital disregard: it is not a capital source in any means test, `corporate_wealth` no longer describes private pensions, `total_wealth` includes it, and a new `corporate_sector_wealth` (corporate plus private pension wealth) is the allocation key for shareholding, corporate land value and the employer NI capital response so those keys do not move when the data splits pension wealth out of corporate wealth (policyengine-uk-data#452). diff --git a/docs/book/assumptions/growthfactors.md b/docs/book/assumptions/growthfactors.md index 746f3a1daa..6a0441da78 100644 --- a/docs/book/assumptions/growthfactors.md +++ b/docs/book/assumptions/growthfactors.md @@ -57,7 +57,7 @@ We derive these rates from OBR GDP growth and ONS population projections. |-------------|------|------|------|------|------|------|------|------| | Growth rate | 9.2% | 5.0% | 3.8% | 2.8% | 2.8% | 3.1% | 3.3% | 3.3% | -We use per capita GDP for these variables: `capital_gains`, `capital_gains_before_response`, `corporate_wealth`, `dividend_income`, `gross_financial_wealth`, `lump_sum_income`, `main_residence_value`, `maintenance_income`, `miscellaneous_income`, `mortgage_capital_repayment`, `net_financial_wealth`, `non_residential_property_value`, `other_investment_income`, `other_residential_property_value`, `owned_land`, `pension_income`, `private_transfer_income`, `property_income`, `savings`, `savings_interest_income`, `sublet_income` +We use per capita GDP for these variables: `capital_gains`, `capital_gains_before_response`, `corporate_wealth`, `dividend_income`, `gross_financial_wealth`, `lump_sum_income`, `main_residence_value`, `maintenance_income`, `miscellaneous_income`, `mortgage_capital_repayment`, `net_financial_wealth`, `non_residential_property_value`, `other_investment_income`, `other_residential_property_value`, `owned_land`, `pension_income`, `private_pension_wealth`, `private_transfer_income`, `property_income`, `savings`, `savings_interest_income`, `sublet_income` ## Council tax diff --git a/policyengine_uk/data/uprating_indices.yaml b/policyengine_uk/data/uprating_indices.yaml index b8a0ad7b96..b2c39d35cf 100644 --- a/policyengine_uk/data/uprating_indices.yaml +++ b/policyengine_uk/data/uprating_indices.yaml @@ -72,6 +72,7 @@ gov.economic_assumptions.yoy_growth.obr.per_capita.gdp: - other_residential_property_value - owned_land - pension_income +- private_pension_wealth - private_transfer_income - property_income - savings diff --git a/policyengine_uk/parameters/gov/dwp/ESA/income/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/ESA/income/capital/sources.yaml index 9d682d768e..3eb35b83ef 100644 --- a/policyengine_uk/parameters/gov/dwp/ESA/income/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/ESA/income/capital/sources.yaml @@ -7,7 +7,10 @@ description: > financial assets, `other_residential_property_value` for residential property other than the home, and `non_residential_property_value` for other land and premises. `main_residence_value` is excluded because Schedule 9 - paragraph 1 disregards premises occupied as the claimant's home. Other + paragraph 1 disregards premises occupied as the claimant's home. + `private_pension_wealth` is excluded because Schedule 9 paragraphs 28 and 29 + disregard the value of the right to receive an occupational or personal + pension and the value of funds held under a personal pension scheme. Other Schedule 9 disregards and the higher residential-care capital disregard are not yet modeled because the current dataset does not isolate those states or asset holdings. Because the dataset only provides household-level capital @@ -24,6 +27,8 @@ metadata: href: https://www.legislation.gov.uk/uksi/2008/794/regulation/111 - title: Employment and Support Allowance Regulations 2008 Schedule 9 para. 1 href: https://www.legislation.gov.uk/uksi/2008/794/schedule/9/paragraph/1 + - title: Employment and Support Allowance Regulations 2008 Schedule 9 paras. 28-29 + href: https://www.legislation.gov.uk/uksi/2008/794/schedule/9/paragraph/28 values: 2008-10-27: - savings diff --git a/policyengine_uk/parameters/gov/dwp/JSA/income/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/JSA/income/capital/sources.yaml index 715862ca1e..6484484ab8 100644 --- a/policyengine_uk/parameters/gov/dwp/JSA/income/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/JSA/income/capital/sources.yaml @@ -7,7 +7,10 @@ description: > financial assets, `other_residential_property_value` for residential property other than the home, and `non_residential_property_value` for other land and premises. `main_residence_value` is excluded because Schedule 8 - paragraph 1 disregards premises occupied as the claimant's home. Other + paragraph 1 disregards premises occupied as the claimant's home. + `private_pension_wealth` is excluded because Schedule 8 paragraphs 28 and 29 + disregard the value of the right to receive an occupational or personal + pension and the value of funds held under a personal pension scheme. Other Schedule 8 disregards, the higher residential-care capital disregard, and the separate child-capital disregard are not yet modeled because the current dataset does not isolate those states or asset holdings. Because the dataset @@ -25,6 +28,8 @@ metadata: href: https://www.legislation.gov.uk/uksi/1996/207/regulation/108 - title: Jobseeker's Allowance Regulations 1996 Schedule 8 para. 1 href: https://www.legislation.gov.uk/uksi/1996/207/schedule/8/paragraph/1 + - title: Jobseeker's Allowance Regulations 1996 Schedule 8 paras. 28-29 + href: https://www.legislation.gov.uk/uksi/1996/207/schedule/8/paragraph/28 values: 1996-10-07: - savings diff --git a/policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/capital/sources.yaml index cc94e50fe5..e313576158 100644 --- a/policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/capital/sources.yaml @@ -8,12 +8,15 @@ description: > `other_residential_property_value` for residential property other than the home, and `non_residential_property_value` for other land and premises. `main_residence_value` is excluded because Schedule 6 paragraph 1 disregards - premises occupied as the claimant's home. The current dataset definition for - `corporate_wealth` also bundles private pension wealth together with those - countable assets; the model currently includes that mixed bucket rather than - omitting share-like financial wealth entirely, so pension-capital treatment - remains an unresolved data limitation. Other Schedule 6 disregards within - these broad asset classes are not yet split out separately. Because the + premises occupied as the claimant's home. `private_pension_wealth` is + excluded because Schedule 6 paragraphs 31 and 32 disregard the value of the + right to receive an occupational or personal pension and the value of funds + held under a personal pension scheme (paragraph 24 of Schedule 6 to the + pension-age regulations and paragraphs 32 and 33 of Schedule 7 to the + Northern Ireland regulations make the same disregard). Datasets built before + private pension wealth was split out of `corporate_wealth` still carry it + inside that countable bucket. Other Schedule 6 disregards within these broad + asset classes are not yet split out separately. Because the dataset only provides household-level capital stocks, the model allocates them across benunits using an adult-share proxy. metadata: @@ -25,10 +28,16 @@ metadata: href: https://www.legislation.gov.uk/uksi/2006/213/regulation/44 - title: The Housing Benefit Regulations 2006 Schedule 6 para. 1 href: https://www.legislation.gov.uk/uksi/2006/213/schedule/6/paragraph/1 + - title: The Housing Benefit Regulations 2006 Schedule 6 paras. 31-32 + href: https://www.legislation.gov.uk/uksi/2006/213/schedule/6/paragraph/31 + - title: The Housing Benefit Regulations (Northern Ireland) 2006 Schedule 7 paras. 32-33 + href: https://www.legislation.gov.uk/nisr/2006/405/schedule/7/paragraph/32 - title: The Housing Benefit (Persons who have attained the qualifying age for state pension credit) Regulations 2006 reg. 44(1) href: https://www.legislation.gov.uk/uksi/2006/214/regulation/44 - title: The Housing Benefit (Persons who have attained the qualifying age for state pension credit) Regulations 2006 Schedule 6 para. 1 href: https://www.legislation.gov.uk/uksi/2006/214/schedule/6/paragraph/1 + - title: The Housing Benefit (Persons who have attained the qualifying age for state pension credit) Regulations 2006 Schedule 6 para. 24 + href: https://www.legislation.gov.uk/uksi/2006/214/schedule/6/paragraph/24 values: 2006-04-10: - savings diff --git a/policyengine_uk/parameters/gov/dwp/income_support/means_test/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/income_support/means_test/capital/sources.yaml index b3055cfc3a..5b28814633 100644 --- a/policyengine_uk/parameters/gov/dwp/income_support/means_test/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/income_support/means_test/capital/sources.yaml @@ -1,4 +1,8 @@ -description: Capital sources included in the Income Support capital test. +description: > + Capital sources included in the Income Support capital test. + `private_pension_wealth` is excluded because Schedule 10 paragraphs 23 and + 23A disregard the value of the right to receive an occupational or personal + pension and the value of funds held under a personal pension scheme. metadata: label: Income Support capital sources period: year @@ -10,6 +14,8 @@ metadata: href: https://www.legislation.gov.uk/uksi/1987/1967/data.pdf#page=70 - title: Income Support (General) Regulations 1987 Sch. 10 href: https://www.legislation.gov.uk/uksi/1987/1967/data.pdf#page=188 + - title: Income Support (General) Regulations 1987 Sch. 10 paras. 23-23A + href: https://www.legislation.gov.uk/uksi/1987/1967/schedule/10/paragraph/23 unit: list values: diff --git a/policyengine_uk/parameters/gov/dwp/pension_credit/income/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/pension_credit/income/capital/sources.yaml index cb82eed3c4..0761c1b0f3 100644 --- a/policyengine_uk/parameters/gov/dwp/pension_credit/income/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/pension_credit/income/capital/sources.yaml @@ -1,6 +1,11 @@ description: > PolicyEngine approximation of Pension Credit capital sources that count toward deemed income from capital, excluding the claimant's main home. + `private_pension_wealth` is excluded because Schedule V paragraphs 22 and 23 + (Part I) disregard the value of the right to receive income from an + occupational or personal pension scheme or under a retirement annuity + contract; the notional income rule for undrawn money purchase pots + (regulation 18) is not modelled. metadata: label: Pension Credit capital sources unit: list @@ -9,6 +14,8 @@ metadata: title: State Pension Credit Regulations 2002 reg. 15 - href: https://www.legislation.gov.uk/uksi/2002/1792/schedule/5 title: State Pension Credit Regulations 2002 Sch. 5 + - href: https://www.legislation.gov.uk/uksi/2002/1792/schedule/V/paragraph/22 + title: State Pension Credit Regulations 2002 Sch. 5 paras. 22-23 - href: https://www.gov.uk/government/publications/pension-credit-technical-guidance/a-detailed-guide-to-pension-credit-for-advisers-and-others title: Pension Credit technical guidance propagate_metadata_to_children: true diff --git a/policyengine_uk/parameters/gov/dwp/universal_credit/means_test/capital/sources.yaml b/policyengine_uk/parameters/gov/dwp/universal_credit/means_test/capital/sources.yaml index c535250583..f64474cebb 100644 --- a/policyengine_uk/parameters/gov/dwp/universal_credit/means_test/capital/sources.yaml +++ b/policyengine_uk/parameters/gov/dwp/universal_credit/means_test/capital/sources.yaml @@ -7,7 +7,12 @@ description: > home, `non_residential_property_value` for other land and premises, and `corporate_wealth` for shares and similar investment assets. `main_residence_value` is excluded because Schedule 10 paragraph 1 disregards premises occupied as - the person's home. Other Schedule 10 disregards within these broad asset + the person's home. `private_pension_wealth` is excluded because Schedule 10 + paragraph 10 disregards the value of any right to receive a pension under an + occupational or personal pension scheme (or any other scheme registered under + section 153 of the Finance Act 2004; paragraph 10 of Schedule 10 to the + Northern Ireland regulations makes the same disregard); pension income + actually drawn counts as unearned income instead. Other Schedule 10 disregards within these broad asset classes are not yet split out separately. Where only household-level capital is available for a multi-benunit household, the model uses a household-wide adult-share proxy for residual capital because the dataset does not identify @@ -31,6 +36,10 @@ metadata: href: https://www.legislation.gov.uk/uksi/2013/376/regulation/48/1 - title: The Universal Credit Regulations 2013 Schedule 10 para. 1 href: https://www.legislation.gov.uk/uksi/2013/376/schedule/10/paragraph/1 + - title: The Universal Credit Regulations 2013 Schedule 10 para. 10 + href: https://www.legislation.gov.uk/uksi/2013/376/schedule/10/paragraph/10 + - title: The Universal Credit Regulations (Northern Ireland) 2016 Schedule 10 para. 10 + href: https://www.legislation.gov.uk/nisr/2016/216/schedule/10/paragraph/10 values: 2013-04-29: - savings diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/esa_income/esa_income_capital.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/esa_income/esa_income_capital.yaml index 743653116f..bdbbef68e0 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/esa_income/esa_income_capital.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/esa_income/esa_income_capital.yaml @@ -191,3 +191,23 @@ esa_income: 0 income_support_eligible: true income_support: 5_252.0073 + +- name: Income-related ESA capital test disregards private pension wealth + period: 2026 + absolute_error_margin: 0 + input: + people: + claimant: + age: 40 + esa_income_reported: 1_000 + benunits: + benunit: + members: claimant + households: + household: + members: claimant + savings: 1_000 + corporate_wealth: 2_000 + private_pension_wealth: 150_000 + output: + esa_income_assessable_capital: 3_000 diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_capital.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_capital.yaml index 840f3245b9..e9a0cd47c3 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_capital.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/housing_benefit/housing_benefit_capital.yaml @@ -247,3 +247,25 @@ housing_benefit_tariff_income: 0 housing_benefit_applicable_income: 0 housing_benefit_eligible: true + +- name: Private pension wealth is disregarded from Housing Benefit capital + period: 2025 + absolute_error_margin: 0 + input: + people: + person: + age: 30 + in_social_housing: true + housing_benefit_reported: 1 + benunits: + benunit: + members: person + would_claim_uc: false + households: + household: + members: person + savings: 5_000 + private_pension_wealth: 150_000 + output: + housing_benefit_assessable_capital: 5_000 + housing_benefit_eligible: true diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support/income_support_capital.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support/income_support_capital.yaml index 9a54ef6617..585884ea9c 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support/income_support_capital.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support/income_support_capital.yaml @@ -210,3 +210,27 @@ savings: 18_000 output: income_support_assessable_capital: [18_000, 18_000] + +- name: Income Support capital test disregards private pension wealth + period: 2021 + absolute_error_margin: 1 + input: + people: + p1: + age: 26 + income_support_reported: true + c1: + age: 4 + is_child: true + benunits: + b1: + members: [p1, c1] + would_claim_IS: true + households: + household: + members: [p1, c1] + savings: 1000 + corporate_wealth: 2000 + private_pension_wealth: 150000 + output: + income_support_assessable_capital: 3000 diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/jsa_income/jsa_income_capital.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/jsa_income/jsa_income_capital.yaml index d727362549..13ecc3d659 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/jsa_income/jsa_income_capital.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/jsa_income/jsa_income_capital.yaml @@ -165,3 +165,23 @@ savings: 18_000 output: jsa_income_assessable_capital: [18_000, 18_000] + +- name: Income-based JSA capital test disregards private pension wealth + period: 2026 + absolute_error_margin: 0 + input: + people: + claimant: + age: 30 + jsa_income_reported: 1_000 + benunits: + benunit: + members: claimant + households: + household: + members: claimant + savings: 1_000 + corporate_wealth: 2_000 + private_pension_wealth: 150_000 + output: + jsa_income_assessable_capital: 3_000 diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/uc_unearned_income.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/uc_unearned_income.yaml index 8f35bf8e4b..b1db7dcd72 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/uc_unearned_income.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/income/uc_unearned_income.yaml @@ -227,3 +227,27 @@ output: uc_tariff_income: 52.2 uc_unearned_income: 52.2 + +- name: Dividend income stays unearned when only disregarded pension wealth is held + period: 2025 + absolute_error_margin: 0.01 + input: + people: + person: + age: 30 + dividend_income: 120 + benunits: + benunit: + members: person + households: + household: + members: person + savings: 6_001 + private_pension_wealth: 150_000 + output: + # Pension wealth is disregarded capital (UC Regs 2013 Sch 10 para 10), so + # the dividend gate keys on corporate_wealth alone: with no share-like + # holdings the dividends are not folded into capital and stay unearned. + uc_assessable_capital: 6_001 + uc_tariff_income: 4.35 * 12 + uc_unearned_income: 4.35 * 12 + 120 diff --git a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/is_UC_eligible.yaml b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/is_UC_eligible.yaml index 342cfc52b0..fa145e20c1 100644 --- a/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/is_UC_eligible.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/benefit/family/universal_credit/is_UC_eligible.yaml @@ -315,3 +315,22 @@ output: uc_assessable_capital: 0 is_uc_eligible: true + +- name: Private pension wealth is disregarded from Universal Credit capital + period: 2025 + absolute_error_margin: 0 + input: + people: + person: + age: 30 + benunits: + benunit: + members: person + households: + household: + members: person + savings: 10_000 + private_pension_wealth: 150_000 + output: + uc_assessable_capital: 10_000 + is_uc_eligible: true diff --git a/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml index ac6d7c6667..b6cf5c9493 100644 --- a/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml +++ b/policyengine_uk/tests/policy/baseline/gov/dwp/pension_credit/pension_credit_income.yaml @@ -105,3 +105,21 @@ standard_minimum_guarantee: 12_376 guarantee_credit: 3_016 pension_credit: 3_016 + +- name: Pension Credit capital disregards private pension wealth + period: 2026 + absolute_error_margin: 1 + input: + people: + person1: + age: 81 + benunits: + benunit: + members: [person1] + households: + household: + members: [person1] + savings: 12_000 + private_pension_wealth: 200_000 + output: + pension_credit_assessable_capital: 12_000 diff --git a/policyengine_uk/tests/policy/baseline/household/wealth/private_pension_wealth.yaml b/policyengine_uk/tests/policy/baseline/household/wealth/private_pension_wealth.yaml new file mode 100644 index 0000000000..6f97f961f5 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/household/wealth/private_pension_wealth.yaml @@ -0,0 +1,39 @@ +- name: Private pension wealth counts in total wealth and corporate sector wealth + period: 2025 + absolute_error_margin: 0 + input: + people: + person: + age: 40 + benunits: + benunit: + members: person + households: + household: + members: person + property_wealth: 200_000 + corporate_wealth: 30_000 + private_pension_wealth: 120_000 + savings: 10_000 + output: + corporate_sector_wealth: 150_000 + total_wealth: 360_000 + +- name: Private pension wealth defaults to zero so corporate sector wealth equals corporate wealth + period: 2025 + absolute_error_margin: 0 + input: + people: + person: + age: 40 + benunits: + benunit: + members: person + households: + household: + members: person + corporate_wealth: 30_000 + output: + private_pension_wealth: 0 + corporate_sector_wealth: 30_000 + total_wealth: 30_000 diff --git a/policyengine_uk/tests/test_corporate_land_value.py b/policyengine_uk/tests/test_corporate_land_value.py index e4124e9596..6abb0ad51d 100644 --- a/policyengine_uk/tests/test_corporate_land_value.py +++ b/policyengine_uk/tests/test_corporate_land_value.py @@ -63,3 +63,110 @@ def test_corporate_land_value_is_zero_without_corporate_wealth(): ) assert corporate_land_value[0] == 0 + + +def test_corporate_land_value_key_is_unchanged_by_the_pension_split(): + """Moving wealth between corporate_wealth and private_pension_wealth must not + move corporate land value: the allocation key is corporate_sector_wealth.""" + + def land_values(household_1: dict, household_2: dict): + sim = Simulation( + situation={ + "people": { + "person_1": {"age": {2025: 40}}, + "person_2": {"age": {2025: 50}}, + }, + "benunits": { + "benunit_1": {"members": ["person_1"]}, + "benunit_2": {"members": ["person_2"]}, + }, + "households": { + "household_1": { + "members": ["person_1"], + "household_weight": {2025: 2}, + **household_1, + }, + "household_2": { + "members": ["person_2"], + "household_weight": {2025: 1}, + **household_2, + }, + }, + } + ) + return ( + sim.calculate("corporate_land_value", map_to="household", period=2025), + sim.calculate("shareholding", map_to="household", period=2025), + ) + + folded_land, folded_share = land_values( + {"corporate_wealth": {2025: 100_000}}, + {"corporate_wealth": {2025: 300_000}}, + ) + split_land, split_share = land_values( + {"corporate_wealth": {2025: 20_000}, "private_pension_wealth": {2025: 80_000}}, + {"corporate_wealth": {2025: 50_000}, "private_pension_wealth": {2025: 250_000}}, + ) + + assert split_land[0] == pytest.approx(folded_land[0]) + assert split_land[1] == pytest.approx(folded_land[1]) + assert split_share[0] == pytest.approx(folded_share[0]) + assert split_share[1] == pytest.approx(folded_share[1]) + + +def test_employer_ni_capital_incidence_is_unchanged_by_the_pension_split(): + """The employer-NI capital response allocates by corporate_sector_wealth, + so moving wealth between corporate_wealth and private_pension_wealth must + not move any household's incidence.""" + reform = { + "gov.contrib.policyengine.employer_ni.employee_incidence": {"2025": 0.5}, + "gov.contrib.policyengine.employer_ni.capital_incidence": {"2025": 0.5}, + } + + def incidence(household_1: dict, household_2: dict): + sim = Simulation( + reform=reform, + situation={ + "people": { + "person_1": { + "age": {2025: 40}, + "employment_income": {2025: 30_000}, + }, + "person_2": { + "age": {2025: 50}, + "employment_income": {2025: 60_000}, + }, + }, + "benunits": { + "benunit_1": {"members": ["person_1"]}, + "benunit_2": {"members": ["person_2"]}, + }, + "households": { + "household_1": { + "members": ["person_1"], + "household_weight": {2025: 2}, + **household_1, + }, + "household_2": { + "members": ["person_2"], + "household_weight": {2025: 1}, + **household_2, + }, + }, + }, + ) + return sim.calculate( + "employer_ni_response_capital_incidence", map_to="household", period=2025 + ) + + folded = incidence( + {"corporate_wealth": {2025: 100_000}}, + {"corporate_wealth": {2025: 300_000}}, + ) + split = incidence( + {"corporate_wealth": {2025: 20_000}, "private_pension_wealth": {2025: 80_000}}, + {"corporate_wealth": {2025: 50_000}, "private_pension_wealth": {2025: 250_000}}, + ) + + assert split[0] == pytest.approx(folded[0]) + assert split[1] == pytest.approx(folded[1]) diff --git a/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py b/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py index cd29a8de2c..d50987b399 100644 --- a/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py +++ b/policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py @@ -25,7 +25,8 @@ def formula(person, period, parameters): amount_paid_by_employers = (person_weight * change_in_employer_cost).sum() wealth = ( - person.household("corporate_wealth", period) / person.household.nb_persons() + person.household("corporate_sector_wealth", period) + / person.household.nb_persons() ) total_wealth = (wealth * person_weight).sum() share_of_total_wealth = wealth / total_wealth diff --git a/policyengine_uk/variables/household/wealth/corporate_land_value.py b/policyengine_uk/variables/household/wealth/corporate_land_value.py index 29c2b2e6a2..8ada5e20d5 100644 --- a/policyengine_uk/variables/household/wealth/corporate_land_value.py +++ b/policyengine_uk/variables/household/wealth/corporate_land_value.py @@ -11,7 +11,7 @@ class corporate_land_value(Variable): quantity_type = STOCK def formula(household, period, parameters): - corporate_wealth = household("corporate_wealth", period) + corporate_wealth = household("corporate_sector_wealth", period) household_weight = household("household_weight", period) total_weighted_corporate_wealth = (corporate_wealth * household_weight).sum() if total_weighted_corporate_wealth == 0: diff --git a/policyengine_uk/variables/household/wealth/corporate_sector_wealth.py b/policyengine_uk/variables/household/wealth/corporate_sector_wealth.py new file mode 100644 index 0000000000..a1792de135 --- /dev/null +++ b/policyengine_uk/variables/household/wealth/corporate_sector_wealth.py @@ -0,0 +1,26 @@ +from policyengine_uk.model_api import * + + +class corporate_sector_wealth(Variable): + label = "wealth exposed to the corporate sector" + documentation = ( + "Corporate wealth held directly or through investment funds plus private " + "pension wealth, which pension funds invest in the corporate sector. The " + "allocation key for corporate tax incidence (shareholding), corporate " + "land value and the employer NI capital response. A compatibility " + "allocation proxy: it preserves the pre-split key (pension funds hold " + "corporate assets) rather than independently validating how much " + "capitalised pension wealth is corporate-sector exposure. Equals " + "corporate_wealth on datasets built before private pension wealth was " + "split out of it." + ) + entity = Household + definition_period = YEAR + value_type = float + unit = GBP + quantity_type = STOCK + + adds = [ + "corporate_wealth", + "private_pension_wealth", + ] diff --git a/policyengine_uk/variables/household/wealth/shareholding.py b/policyengine_uk/variables/household/wealth/shareholding.py index 68a283eea5..dcf773f8c3 100644 --- a/policyengine_uk/variables/household/wealth/shareholding.py +++ b/policyengine_uk/variables/household/wealth/shareholding.py @@ -10,15 +10,15 @@ class shareholding(Variable): unit = GBP def formula(household, period, parameters): - wealth = household("corporate_wealth", period) + wealth = household("corporate_sector_wealth", period) if ( household.simulation.dataset is not None - and household("corporate_wealth", period).sum() != 0 + and household("corporate_sector_wealth", period).sum() != 0 ): weight = household("household_weight", period) return wealth / (wealth * weight).sum() wealth = parameters(period).household.wealth nbs = wealth.national_balance_sheet - wealth = household("corporate_wealth", period) + wealth = household("corporate_sector_wealth", period) total_wealth = nbs.household.financial_net_worth return wealth / total_wealth diff --git a/policyengine_uk/variables/household/wealth/total_wealth.py b/policyengine_uk/variables/household/wealth/total_wealth.py index 7a1367090c..5334c4f3b2 100644 --- a/policyengine_uk/variables/household/wealth/total_wealth.py +++ b/policyengine_uk/variables/household/wealth/total_wealth.py @@ -12,5 +12,6 @@ class total_wealth(Variable): adds = [ "property_wealth", "corporate_wealth", + "private_pension_wealth", "savings", ] diff --git a/policyengine_uk/variables/input/corporate_wealth.py b/policyengine_uk/variables/input/corporate_wealth.py index 178fae33ed..e1dabe6b62 100644 --- a/policyengine_uk/variables/input/corporate_wealth.py +++ b/policyengine_uk/variables/input/corporate_wealth.py @@ -3,7 +3,15 @@ class corporate_wealth(Variable): label = "corporate wealth" - documentation = "Total owned wealth in corporations, including stocks, mutual funds, private pensions, and corporate bonds" + documentation = ( + "Wealth held in corporations directly or through investment funds: UK " + "shares, employee shares and options, unit and investment trusts, and " + "stocks and shares ISAs, imputed from the Wealth and Assets Survey. The " + "stocks and shares ISA component is also exported on its own as " + "stocks_and_shares_isa, so the two must never be summed. Private pension " + "wealth is carried separately in private_pension_wealth; datasets built " + "before that split folded it into this variable." + ) entity = Household definition_period = YEAR value_type = float diff --git a/policyengine_uk/variables/input/private_pension_wealth.py b/policyengine_uk/variables/input/private_pension_wealth.py new file mode 100644 index 0000000000..566b4d6510 --- /dev/null +++ b/policyengine_uk/variables/input/private_pension_wealth.py @@ -0,0 +1,38 @@ +from policyengine_uk.model_api import * + + +class private_pension_wealth(Variable): + label = "private pension wealth" + documentation = ( + "Value of the household's private (non-state) pension rights other than " + "current-employment defined benefit entitlements, which the data does " + "not yet carry: defined contribution pots, additional voluntary " + "contributions, current personal pensions, retained rights in earlier " + "occupational and personal schemes (defined benefit and defined " + "contribution, including drawdown funds), pensions in payment valued as " + "the capitalised income stream, and pensions expected from a former " + "spouse or partner. Imputed from the Wealth and Assets Survey as total " + "private pension wealth less the current defined benefit component (the " + "survey values defined benefit entitlements and pensions in payment at " + "the SCAPE discount rate; the other components are reported fund " + "values). Datasets built before this column existed folded it into " + "corporate_wealth. The value of a right to receive a pension under an " + "occupational or personal pension scheme is disregarded as capital in " + "every means test the model runs, in Great Britain and Northern Ireland " + "alike (see the capital sources parameters of each benefit for the " + "paragraphs), so this variable is not a capital source anywhere; " + "pension income actually drawn counts through private_pension_income. " + "Not modelled: the notional income rules that can apply from State " + "Pension Credit qualifying age (including the older partner of a " + "mixed-age Universal Credit couple, money purchase benefits not taken, " + "and deferred occupational pension income), and the capital-versus-" + "income treatment of withdrawals (ad hoc or whole-pot withdrawals " + "become capital; regular withdrawals count as income)." + ) + entity = Household + definition_period = YEAR + value_type = float + unit = GBP + uprating = "gov.economic_assumptions.indices.obr.per_capita.gdp" + quantity_type = STOCK + default_value = 0