diff --git a/changelog.d/1799.fixed.md b/changelog.d/1799.fixed.md new file mode 100644 index 0000000000..1c60444d27 --- /dev/null +++ b/changelog.d/1799.fixed.md @@ -0,0 +1 @@ +- Reduced the savings starting-rate band from the first pound of taxable non-savings income, correcting savings tax on mixed incomes. diff --git a/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/savings_starter_rate_income.yaml b/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/savings_starter_rate_income.yaml index 65bd9f68b4..630f38ccd1 100644 --- a/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/savings_starter_rate_income.yaml +++ b/policyengine_uk/tests/policy/baseline/finance/tax/income_tax/savings_starter_rate_income.yaml @@ -1,54 +1,220 @@ -- name: Full savings starter rate allowance - period: 2024 +# ITA 2007 ss.12(1),(5) and16 place savings above taxable non-savings +# income, and dividends above savings. The £5,000 starting band is reduced +# from the first taxable non-savings pound, after lawful allowance deduction. +# Sources: https://www.legislation.gov.uk/ukpga/2007/3/section/12 +# https://www.legislation.gov.uk/ukpga/2007/3/section/16 +# https://www.gov.uk/apply-tax-free-interest-on-savings/how-much-is-tax-free +# 2026-27: PA £12,570; starting band £5,000; basic savings rate20%; +# PSA £1,000/basic or£500/higher; dividend nil band£500, rates10.75/35.75%. +# All cases use actual annual income inputs. No intermediate tax base or +# allowance is forced. These ordinary cases use the PA allocation giving +# greatest overall relief under s25(2), not the future2027-28 s25(3A) rule. + +- name: First taxable non-savings income reduces the starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 14_000 + savings_interest_income: 6_000 + output: + savings_income_tax: 286 + income_tax: 572 + # N=14,000-12,570=1,430; starter=5,000-1,430=3,570. + # Savings tax=(6,000-3,570-1,000)*20%=286; wage tax=286. + savings_starter_rate_income: 3_570 + savings_allowance: 1_000 + +- name: Wages above the starting-band ceiling give no starting rate + period: 2026 + absolute_error_margin: 0.01 input: - basic_rate_savings_income_pre_starter: 5_000 - taxable_savings_interest_income: 6_000 - received_allowances_savings_income: 0 - earned_taxable_income: 15_000 - taxable_dividend_income: 0 + age: 55 + region: LONDON + employment_income: 30_000 + savings_interest_income: 4_000 output: + savings_income_tax: 600 + income_tax: 4_086 + # The issue's £30,000 wages/£4,000 interest reproduction: + # savings=(4,000-1,000)*20%=600; wages=17,430*20%=3,486. + savings_starter_rate_income: 0 + +- name: Wages at the personal allowance leave the full starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 12_570 + savings_interest_income: 6_000 + output: + savings_income_tax: 0 + income_tax: 0 savings_starter_rate_income: 5_000 -- name: Partial savings starter rate allowance - period: 2024 +- name: One pound above the personal allowance uses one pound of the band + period: 2026 + absolute_error_margin: 0.01 input: - basic_rate_savings_income_pre_starter: 4_000 - taxable_savings_interest_income: 5_000 - received_allowances_savings_income: 0 - earned_taxable_income: 19_000 - taxable_dividend_income: 0 + age: 55 + region: LONDON + employment_income: 12_571 + savings_interest_income: 6_000 output: - savings_starter_rate_income: 3_570 + savings_income_tax: 0.20 + income_tax: 0.40 + savings_starter_rate_income: 4_999 -- name: No savings starter rate allowance due to high non-savings income - period: 2024 +- name: One pound below the starting-band ceiling leaves one pound + period: 2026 + absolute_error_margin: 0.01 input: - basic_rate_savings_income_pre_starter: 2_000 - taxable_savings_interest_income: 3_000 - received_allowances_savings_income: 0 - earned_taxable_income: 23_000 - taxable_dividend_income: 1_000 + age: 55 + region: LONDON + employment_income: 17_569 + savings_interest_income: 6_000 output: + savings_income_tax: 999.80 + income_tax: 1_999.60 + savings_starter_rate_income: 1 + +- name: Wages at the starting-band ceiling exhaust the band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 17_570 + savings_interest_income: 6_000 + output: + savings_income_tax: 1_000 + income_tax: 2_000 savings_starter_rate_income: 0 -- name: Savings income exceeds allowance - period: 2024 +- name: Starting-rate income is capped by the available interest + period: 2026 + absolute_error_margin: 0.01 input: - basic_rate_savings_income_pre_starter: 10_000 - taxable_savings_interest_income: 11_000 - received_allowances_savings_income: 0 - earned_taxable_income: 16_000 - taxable_dividend_income: 0 + age: 55 + region: LONDON + employment_income: 14_000 + savings_interest_income: 1_000 output: - savings_starter_rate_income: 5_000 + savings_income_tax: 0 + income_tax: 286 + savings_starter_rate_income: 1_000 -- name: Partial allowance with dividend income - period: 2024 +- name: Unused personal allowance covers savings before the starting band + period: 2026 + absolute_error_margin: 0.01 input: - basic_rate_savings_income_pre_starter: 5_000 - taxable_savings_interest_income: 6_000 - received_allowances_savings_income: 0 - earned_taxable_income: 16_000 - taxable_dividend_income: 2_000 + age: 55 + region: LONDON + employment_income: 10_000 + savings_interest_income: 9_000 output: + savings_income_tax: 86 + income_tax: 86 + # £2,570 unused PA leaves£6,430 interest, then£5,000 starter+£1,000 PSA. savings_starter_rate_income: 5_000 + +- name: Private pension income reduces the starting band like wages + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + private_pension_income: 14_000 + savings_interest_income: 6_000 + output: + savings_income_tax: 286 + income_tax: 572 + savings_starter_rate_income: 3_570 + +- name: Chargeable property profits reduce the starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + # £16,000 receipts less£2,000 actual expenses:£14,000 profit. + # Actual expenses exceed the property allowance; no finance-cost credit. + property_rental_income: 16_000 + property_allowable_expenses: 2_000 + property_income: 14_000 + savings_interest_income: 6_000 + output: + savings_income_tax: 286 + income_tax: 572 + taxable_property_income: 14_000 + savings_starter_rate_income: 3_570 + +- name: Wages and property together reduce the same starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 10_000 + property_rental_income: 6_000 + property_allowable_expenses: 2_000 + property_income: 4_000 + savings_interest_income: 6_000 + output: + savings_income_tax: 286 + income_tax: 572 + # Combined non-savings income£14,000; PA leaves£1,430 taxable. + savings_starter_rate_income: 3_570 + +- name: Dividends above savings do not directly reduce the starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 14_000 + savings_interest_income: 6_000 + dividend_income: 1_000 + output: + savings_income_tax: 286 + income_tax: 625.75 + savings_starter_rate_income: 3_570 + savings_allowance: 1_000 + dividend_income_tax: 53.75 + +- name: Higher-rate dividends reduce the PSA without consuming the starting band + period: 2026 + absolute_error_margin: 0.01 + input: + age: 55 + region: LONDON + employment_income: 14_000 + savings_interest_income: 6_000 + dividend_income: 40_000 + output: + savings_income_tax: 386 + income_tax: 7_350.75 + # £1,430 non-savings+£6,000 savings occupy£7,430 of the basic band. + # Dividends:£29,770*10.75%+£9,730*35.75%=£6,678.75 after£500 nil rate. + savings_starter_rate_income: 3_570 + savings_allowance: 500 + dividend_income_tax: 6_678.75 + +- name: Starting-band limit and phase-out remain reformable + period: 2026 + absolute_error_margin: 0.01 + input: + # Synthetic parameter control, not a statement of current law: + # £4,000 band less50% of£1,430 leaves£3,285; tax£343+£286=£629. + gov.hmrc.income_tax.rates.savings_starter_rate.allowance: 4_000 + gov.hmrc.income_tax.rates.savings_starter_rate.phase_out: 0.5 + age: 55 + region: LONDON + employment_income: 14_000 + savings_interest_income: 6_000 + output: + savings_income_tax: 343 + income_tax: 629 + savings_starter_rate_income: 3_285 diff --git a/policyengine_uk/variables/gov/hmrc/income_tax/bracketized_savings_income/savings_starter_rate_income.py b/policyengine_uk/variables/gov/hmrc/income_tax/bracketized_savings_income/savings_starter_rate_income.py index 94e38d7101..c5ac5e089d 100644 --- a/policyengine_uk/variables/gov/hmrc/income_tax/bracketized_savings_income/savings_starter_rate_income.py +++ b/policyengine_uk/variables/gov/hmrc/income_tax/bracketized_savings_income/savings_starter_rate_income.py @@ -5,16 +5,26 @@ class savings_starter_rate_income(Variable): value_type = float entity = Person label = "Savings income which is tax-free under the starter rate" + documentation = ( + "Savings within the annual starting-rate band left after taxable " + "non-savings income, including property income. The non-savings " + "base already reflects allowance deductions; dividends sit above " + "savings and do not directly reduce the starting-rate band." + ) definition_period = YEAR reference = list( [ dict( - title="Income Tax Act 2007, s. 12", + title="Income Tax Act 2007, s. 12 (1) and (5)", href="https://www.legislation.gov.uk/ukpga/2007/3/section/12", ), + dict( + title="Income Tax Act 2007, s. 16 (3) and (5)", + href="https://www.legislation.gov.uk/ukpga/2007/3/section/16", + ), dict( title="Tax on savings interest", - href="https://www.gov.uk/apply-tax-free-interest-on-savings", + href="https://www.gov.uk/apply-tax-free-interest-on-savings/how-much-is-tax-free", ), ] ) @@ -25,10 +35,6 @@ def formula(person, period, parameters): limit = p.rates.savings_starter_rate.allowance phase_out_rate = p.rates.savings_starter_rate.phase_out - max_personal_allowance = p.allowances.personal_allowance.amount - - starter_rate_taper_start = max_personal_allowance + limit - savings_income = min_( person("basic_rate_savings_income_pre_starter", period), max_( @@ -37,16 +43,12 @@ def formula(person, period, parameters): - person("received_allowances_savings_income", period), ), ) - # The taper reads all non-savings income, property income included - # (ITA 2007 s. 16). Where the taper starts is a separate, known defect: - # s. 12 shrinks the band from the first pound of taxable non-savings - # income, not from the personal allowance plus the band (#1799). - earned_taxable_income = person("non_savings_taxable_income", period) + # ITA 2007 ss.12(5) and16 put taxable non-savings income below + # savings. This base already reflects allowances, so every pound + # reduces the starting band without deducting the PA again. + non_savings_taxable_income = person("non_savings_taxable_income", period) - removed_amount = max_( - 0, - (earned_taxable_income - starter_rate_taper_start) * phase_out_rate, - ) + removed_amount = max_(0, non_savings_taxable_income * phase_out_rate) post_taper_max = max_(0, limit - removed_amount)