Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1822.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Corrected dividend income-tax band thresholds from 2016 to 2025 to use their statutory tax-year dates.
43 changes: 43 additions & 0 deletions policyengine_uk/parameters/gov/hmrc/income_tax/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
# Income Tax

## Dividend bands

[Income Tax Act 2007 s. 13](https://www.legislation.gov.uk/ukpga/2007/3/section/13)
ties the dividend rates to the corresponding UK taxable-income bands, including
when determining the dividend bands for a Scottish taxpayer.
[Section 16](https://www.legislation.gov.uk/ukpga/2007/3/section/16) places
dividends above other income. The dividend nil-rate amount uses band capacity;
it does not reduce income when determining the remaining capacity in each band.

The dated dividend scale records these basic-rate limits:

| Tax year beginning 6 April | Basic-rate limit | Authority |
| --- | ---: | --- |
| 2016 | £32,000 | [Finance (No. 2) Act 2015 s. 6](https://www.legislation.gov.uk/ukpga/2015/33/section/6/enacted) |
| 2017 | £33,500 | [Finance Act 2016 s. 2](https://www.legislation.gov.uk/ukpga/2016/24/section/2/enacted) |
| 2018 | £34,500 | [SI 2017/1184 art 2](https://www.legislation.gov.uk/uksi/2017/1184/article/2/made) |
| 2019 and 2020 | £37,500 | [Finance Act 2019 s. 5](https://www.legislation.gov.uk/ukpga/2019/1/section/5/enacted) |
| From 2021 | £37,700 | [SI 2021/111 art 2](https://www.legislation.gov.uk/uksi/2021/111/article/2/made) |

The additional-rate threshold falls from £150,000 to £125,140 from 6 April 2023
under [Finance Act 2023 s. 6](https://www.legislation.gov.uk/ukpga/2023/1/section/6/enacted).
These limits apply after allowances. For example, in 2025, £49,000 of pay uses
£36,430 of taxable band capacity after the £12,570 Personal Allowance. Of a
further £2,000 of dividends, £1,270 fits in the basic band, including the £500
dividend nil-rate amount. The charge is £770 × 8.75% + £730 × 33.75% = £313.75.

The threshold history does not certify the pre-2016 dividend-tax-credit regime
or all historical allowance calculations. The inherited 2016 Personal Allowance
is a separate issue tracked in [#2359](https://github.com/PolicyEngine/policyengine-uk/issues/2359):
the inherited amount was £10,600 while the statutory amount is £11,000. The 2016 regression
uses £160,000 of dividends, which naturally withdraws the full allowance under
either amount. It exercises the dividend bands without selecting an allowance
through an intermediate input. Dividend rates, allowance allocation, Gift Aid
extensions and the optional extra dividend bracket retain their existing
interfaces.

The existing fixed-order allowance allocation does not always implement the
most-beneficial allocation required by ITA 2007 s. 25(2) for mixed wages and
dividends. The 2017, 2021 and 2026 threshold regressions also use dividend-only
income with a naturally zero Personal Allowance. The selected 2018, 2019 and
2025 mixed-income cases have independently checked allowance allocations;
they do not certify the allocation formula for other situations.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,36 @@ brackets:
label: Dividends higher rate threshold
values:
2015-04-01: 37_500
2016-04-06:
value: 32_000
metadata:
reference:
- title: Finance (No. 2) Act 2015 s. 6(a)
href: https://www.legislation.gov.uk/ukpga/2015/33/section/6/enacted
2017-04-06:
value: 33_500
metadata:
reference:
- title: Finance Act 2016 s. 2
href: https://www.legislation.gov.uk/ukpga/2016/24/section/2/enacted
2018-04-06:
value: 34_500
metadata:
reference:
- title: The Income Tax (Indexation) Order 2017 art 2
href: https://www.legislation.gov.uk/uksi/2017/1184/article/2/made
2019-04-06:
value: 37_500
metadata:
reference:
- title: Finance Act 2019 s. 5(1)
href: https://www.legislation.gov.uk/ukpga/2019/1/section/5/enacted
2021-04-06:
value: 37_700
metadata:
reference:
- title: The Income Tax (Indexation) Order 2021 art 2
href: https://www.legislation.gov.uk/uksi/2021/111/article/2/made
2026-04-06:
value: 37_700
metadata:
Expand All @@ -79,6 +109,12 @@ brackets:
threshold:
values:
2015-04-01: 150_000
2023-04-06:
value: 125_140
metadata:
reference:
- title: Finance Act 2023 s. 6(3)-(4)
href: https://www.legislation.gov.uk/ukpga/2023/1/section/6/enacted
2026-04-06:
value: 125_140
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Literal official-source band arithmetic; the dividend nil rate occupies band capacity.
# PA0 cases isolate2016/2017/2021/2026 bands from separate allowance limitations.
- name: 2016 dividends with wages 0 and dividends 160000
period: 2016
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 0
dividend_income: 160000
output:
dividend_income_tax: 44185.0
income_tax: 44185.0
- name: 2017 dividends with wages 0 and dividends 160000
period: 2017
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 0
dividend_income: 160000
output:
dividend_income_tax: 43810.0
income_tax: 43810.0
- name: 2018 dividends with wages 40000 and dividends 10000
period: 2018
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 40000
dividend_income: 10000
output:
dividend_income_tax: 1512.5
income_tax: 7142.5
- name: 2019 dividends with wages 40000 and dividends 10000
period: 2019
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 40000
dividend_income: 10000
output:
dividend_income_tax: 600.0
income_tax: 6100.0
- name: 2021 dividends with wages 0 and dividends 160000
period: 2021
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 0
dividend_income: 160000
output:
dividend_income_tax: 42985.0
income_tax: 42985.0
- name: 2023 dividends with wages 130000 and dividends 10000
period: 2023
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 130000
dividend_income: 10000
output:
dividend_income_tax: 3541.5
income_tax: 48244.5
- name: 2025 dividends with wages 49000 and dividends 2000
period: 2025
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 49000
dividend_income: 2000
output:
dividend_income_tax: 313.75
income_tax: 7599.75
- name: 2025 dividends with wages 130000 and dividends 10000
period: 2025
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 130000
dividend_income: 10000
output:
dividend_income_tax: 3738.25
income_tax: 48441.25
- name: 2026 dividends with wages 0 and dividends 160000
period: 2026
absolute_error_margin: 0.01
input:
age: 40
region: LONDON
employment_income: 0
dividend_income: 160000
output:
dividend_income_tax: 48976.21
income_tax: 48976.21
73 changes: 73 additions & 0 deletions policyengine_uk/tests/test_dividend_band_dates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""Dated dividend limits and preserved rate/reform interfaces.

ITA 2007 s.13 uses the corresponding UK taxable-income bands. Earlier
unchanged values below are regression controls, not a pre-2016 law audit.
"""

from pathlib import Path

import pytest
import yaml
from policyengine_core.parameters import Parameter

import policyengine_uk
from policyengine_uk import CountryTaxBenefitSystem

PATH = "gov.hmrc.income_tax.rates.dividends"
FILE = (
Path(policyengine_uk.__file__).parent
/ "parameters/gov/hmrc/income_tax/rates/dividends.yaml"
)


@pytest.mark.parametrize(
"bracket,before,after,old,new",
[
(1, "2016-04-05", "2016-04-06", 37_500, 32_000),
(1, "2017-04-05", "2017-04-06", 32_000, 33_500),
(1, "2018-04-05", "2018-04-06", 33_500, 34_500),
(1, "2019-04-05", "2019-04-06", 34_500, 37_500),
(1, "2021-04-05", "2021-04-06", 37_500, 37_700),
(2, "2023-04-05", "2023-04-06", 150_000, 125_140),
],
)
def test_raw_dividend_limits_change_on_the_statutory_tax_year_date(
bracket, before, after, old, new
):
data = yaml.safe_load(FILE.read_text())["brackets"][bracket]["threshold"]
data["values"] = {str(date): value for date, value in data["values"].items()}
raw = Parameter(f"{PATH}[{bracket}].threshold", data=data, file_path=str(FILE))
assert raw(before) == old
assert raw(after) == new


@pytest.fixture(scope="module")
def system():
return CountryTaxBenefitSystem()


@pytest.mark.parametrize(
"year,basic_limit,additional_limit",
[
(2016, 32_000, 150_000),
(2017, 33_500, 150_000),
(2018, 34_500, 150_000),
(2019, 37_500, 150_000),
(2020, 37_500, 150_000),
(2021, 37_700, 150_000),
(2023, 37_700, 125_140),
(2025, 37_700, 125_140),
(2026, 37_700, 125_140),
],
)
def test_annual_dividend_limits_include_restoration_and_current_years(
system, year, basic_limit, additional_limit
):
scale = system.parameters.get_child(PATH)(f"{year}-01-01")
assert scale.thresholds == [0, basic_limit, additional_limit, 10_000_000]


def test_2026_dividend_rates_and_optional_extra_bracket_are_unchanged(system):
scale = system.parameters.get_child(PATH)("2026-01-01")
assert scale.rates == [0.1075, 0.3575, 0.3935, 0.3935]
assert scale.thresholds == [0, 37_700, 125_140, 10_000_000]
Loading