Income Tax#

Income tax is a tax levied on the income earned by individuals and businesses. It is one of the primary sources of revenue for the UK government and is used to fund public services and government expenditures.

  • Tax Allowances: These are specific amounts of income that individuals can earn before they are required to pay income tax. Various types of allowances exist, such as Personal Allowance, Marriage Allowance, Property Allowance, and Dividend Allowance, each offering different benefits and eligibility criteria.

  • Tax Charges: Tax charges arise when an individual’s income exceeds certain thresholds or when specific conditions are met. These charges fluctuate based on income levels and are influenced by additional factors, such as the High-Income Child Benefit Charge.

  • Tax Rates: The government applies different percentages of tax rates based on the income bracket an individual falls into. There are Basic, Higher, and Additional rates, each applicable to respective income ranges. Moreover, specific types of income, like dividends, have their distinct tax rates.

  • Tax Reliefs: To promote certain behaviors or lower the tax burden for specific groups, the government provides tax reliefs. These provisions reduce tax liability for eligible individuals, with examples including reliefs for Pension Contributions, Charitable Donations, and Work-Related Expenses.

Legislation#

UK income tax legislation is grounded in primary legislation passed by the UK Parliament, supplemented by secondary legislation and administrative guidance issued by Her Majesty’s Revenue and Customs (HMRC).

  • Income Tax Act 2007 (ITA 2007): This is a central piece of legislation consolidating various statutes related to income tax in the UK. It comprehensively covers aspects such as the charge to tax, applicable rates, allowances, and reliefs, serving as a foundational reference for income tax matters.

  • Taxation of Chargeable Gains Act 1992 (TCGA 1992): Though primarily focused on capital gains tax, this Act intersects significantly with income tax, particularly in the realm of taxation of gains. It provides detailed regulations on how gains should be taxed and calculated.

  • Income Tax (Earnings and Pensions) Act 2003 (ITEPA 2003): ITEPA 2003 governs the rules related to the taxation of employment income, pension income, and social security income. It outlines the various categories and criteria for taxable earnings and pensions, ensuring a structured approach to taxation in these areas.

  • HMRC Manuals and Guidance: Produced by HMRC, these comprehensive guides aim to help taxpayers in understanding and complying with the complex tax legislation. They provide practical insights and interpretations of the laws, offering clarity and assistance to both individuals and businesses in navigating the income tax landscape.

Methodology:#

Income tax logic can be found in policyengine-uk/policyengine_uk/variables/gov/hmrc/income_tax.

The following table shows a series of income tax simulations using the PolicyEngine UK model.

Hide code cell source
import pandas as pd
from policyengine_uk import Simulation


def calculate_taxes(
    employment_income, dividend_income, savings_interest_income
):
    simulation = Simulation(
        situation={
            "people": {
                "person": {
                    "employment_income": employment_income,
                    "dividend_income": dividend_income,
                    "savings_interest_income": savings_interest_income,
                }
            }
        }
    )
    income_tax = simulation.calculate("income_tax")[0]
    dividend_income_tax = simulation.calculate("dividend_income_tax")[
        0
    ]  # Added
    savings_income_tax = simulation.calculate("savings_income_tax")[0]  # Added

    return income_tax, dividend_income_tax, savings_income_tax


data = {
    "Person": ["Person1", "Person2", "Person3", "Person4", "Person5"],
    "Employment Income (£)": [50000, 60000, 70000, 80000, 90000],
    "Dividend Income (£)": [10000, 15000, 20000, 25000, 30000],
    "Savings Interest Income (£)": [5000, 10000, 15000, 20000, 25000],
    "Income Tax (£)": [],
    "Dividend Income Tax (£)": [],
    "Savings Income Tax (£)": [],
}

for emp_income, div_income, sav_income in zip(
    data["Employment Income (£)"],
    data["Dividend Income (£)"],
    data["Savings Interest Income (£)"],
):
    income_tax, div_tax, sav_tax = calculate_taxes(
        emp_income, div_income, sav_income
    )
    data["Income Tax (£)"].append(income_tax)
    data["Dividend Income Tax (£)"].append(div_tax)
    data["Savings Income Tax (£)"].append(sav_tax)

df = pd.DataFrame(data)
df
Person Employment Income (£) Dividend Income (£) Savings Interest Income (£) Income Tax (£) Dividend Income Tax (£) Savings Income Tax (£)
0 Person1 50000 10000 5000 10068.5 2582.5 0.0
1 Person2 60000 15000 10000 17457.0 4225.0 1800.0
2 Person3 70000 20000 15000 26082.0 5850.0 3800.0
3 Person4 80000 25000 20000 37707.0 7475.0 5800.0
4 Person5 90000 30000 25000 45360.0 9100.0 7800.0

Appendix:#

The following tables display the parameter values for income tax allowance.

Hide code cell source
from policyengine_uk.system import system
import pandas as pd

default = (
    system.parameters.gov.hmrc.income_tax.allowances.annual_allowance.default
)
minimum = (
    system.parameters.gov.hmrc.income_tax.allowances.annual_allowance.minimum
)
reduction_rate = (
    system.parameters.gov.hmrc.income_tax.allowances.annual_allowance.reduction_rate
)
taper = system.parameters.gov.hmrc.income_tax.allowances.annual_allowance.taper
annual_allowance_data = {
    "Attribute": ["Annual Allowance"] * 4,
    "Type": ["Default", "Minimum", "Reduction Rate", "Taper"],
    "Value": [
        default.values_list[-1].value,
        minimum.values_list[-1].value,
        reduction_rate.values_list[-1].value,
        taper.values_list[-1].value,
    ],
    "Effective Date": [
        default.values_list[-1].instant_str,
        minimum.values_list[-1].instant_str,
        reduction_rate.values_list[-1].instant_str,
        taper.values_list[-1].instant_str,
    ],
    "Unit": [
        default.metadata["unit"],
        minimum.metadata["unit"],
        reduction_rate.metadata["unit"],
        taper.metadata["unit"],
    ],
}


max = system.parameters.gov.hmrc.income_tax.allowances.marriage_allowance.max
rounding_increment = (
    system.parameters.gov.hmrc.income_tax.allowances.marriage_allowance.rounding_increment
)
takeup_rate = (
    system.parameters.gov.hmrc.income_tax.allowances.marriage_allowance.takeup_rate
)
marriage_allowance_data = {
    "Attribute": ["Marriage Allowance"] * 3,
    "Type": ["Max", "Rounding Increment", "Takeup Rate"],
    "Value": [
        max.values_list[-1].value,
        rounding_increment.values_list[-1].value,
        takeup_rate.values_list[-1].value,
    ],
    "Effective Date": [
        max.values_list[-1].instant_str,
        rounding_increment.values_list[-1].instant_str,
        takeup_rate.values_list[-1].instant_str,
    ],
    "Unit": [
        max.metadata["unit"],
        rounding_increment.metadata["unit"],
        takeup_rate.metadata["unit"],
    ],
}


deduction_rate = (
    system.parameters.gov.hmrc.income_tax.allowances.married_couples_allowance.deduction_rate
)
married_couples_allowance_data = {
    "Attribute": ["Married Couples Allowance"],
    "Type": ["Deduction Rate"],
    "Value": [deduction_rate.values_list[-1].value],
    "Effective Date": [deduction_rate.values_list[-1].instant_str],
    "Unit": [deduction_rate.metadata["unit"]],
}


amount = (
    system.parameters.gov.hmrc.income_tax.allowances.personal_allowance.amount
)
values = [item.value for item in amount.values_list]
dates = [item.instant_str for item in amount.values_list]
personal_allowance_data = {
    "Attribute": ["Personal Allowance"] * len(values),
    "Type": ["Amount"] * len(values),
    "Value": values,
    "Effective Date": dates,
    "Unit": [amount.metadata["unit"]] * len(values),
}


addtional_threshold = (
    system.parameters.gov.hmrc.income_tax.allowances.personal_savings_allowance.additional
)
basic_threshold = (
    system.parameters.gov.hmrc.income_tax.allowances.personal_savings_allowance.basic
)
higher_threshold = (
    system.parameters.gov.hmrc.income_tax.allowances.personal_savings_allowance.higher
)
personal_savings_allowance_data = {
    "Attribute": ["Personal Savings Allowance"] * 3,
    "Type": ["Addtional Threshold", "Basic Threshold", "Higher Threshold"],
    "Value": [
        addtional_threshold.values_list[-1].value,
        basic_threshold.values_list[-1].value,
        higher_threshold.values_list[-1].value,
    ],
    "Effective Date": [
        addtional_threshold.values_list[-1].instant_str,
        basic_threshold.values_list[-1].instant_str,
        higher_threshold.values_list[-1].instant_str,
    ],
    "Unit": [
        addtional_threshold.metadata["unit"],
        basic_threshold.metadata["unit"],
        higher_threshold.metadata["unit"],
    ],
}


dividend_allowance = (
    system.parameters.gov.hmrc.income_tax.allowances.dividend_allowance
)
dividend_allowance_data = {
    "Attribute": ["Dividend Allowance"],
    "Type": ["Dividend Allowance"],
    "Value": [dividend_allowance.values_list[-1].value],
    "Effective Date": [dividend_allowance.values_list[-1].instant_str],
    "Unit": [dividend_allowance.metadata["unit"]],
}


property_allowance = (
    system.parameters.gov.hmrc.income_tax.allowances.property_allowance
)
property_allowance_data = {
    "Attribute": ["Property Allowance"],
    "Type": ["Property Allowance"],
    "Value": [property_allowance.values_list[-1].value],
    "Effective Date": [property_allowance.values_list[-1].instant_str],
    "Unit": [property_allowance.metadata["unit"]],
}


trading_allowance = (
    system.parameters.gov.hmrc.income_tax.allowances.trading_allowance
)
trading_allowance_data = {
    "Attribute": ["Trading Allowance"],
    "Type": ["Trading Allowance"],
    "Value": [trading_allowance.values_list[-1].value],
    "Effective Date": [trading_allowance.values_list[-1].instant_str],
    "Unit": [trading_allowance.metadata["unit"]],
}

annual_allowance_df = pd.DataFrame(annual_allowance_data)
marriage_allowance_df = pd.DataFrame(marriage_allowance_data)
married_couples_allowance_df = pd.DataFrame(married_couples_allowance_data)
personal_allowance_df = pd.DataFrame(personal_allowance_data)
personal_savings_allowance_df = pd.DataFrame(personal_savings_allowance_data)
dividend_allowance_df = pd.DataFrame(dividend_allowance_data)
property_allowance_df = pd.DataFrame(property_allowance_data)
trading_allowance_df = pd.DataFrame(trading_allowance_data)

income_tax_allowance_df = pd.concat(
    [
        annual_allowance_df,
        marriage_allowance_df,
        married_couples_allowance_df,
        personal_allowance_df,
        personal_savings_allowance_df,
        dividend_allowance_df,
        property_allowance_df,
        trading_allowance_df,
    ],
    ignore_index=True,
)
income_tax_allowance_df
Attribute Type Value Effective Date Unit
0 Annual Allowance Default 40000.0 2015-06-01 currency-GBP
1 Annual Allowance Minimum 4000.0 2015-06-01 currency-GBP
2 Annual Allowance Reduction Rate 0.5 2015-06-01 marginal-rate
3 Annual Allowance Taper 240000.0 2015-06-01 currency-GBP
4 Marriage Allowance Max 0.1 2016-04-01 /1
5 Marriage Allowance Rounding Increment 10.0 2016-04-01 currency-GBP
6 Marriage Allowance Takeup Rate 1.0 2000-01-01 /1
7 Married Couples Allowance Deduction Rate 0.1 2010-01-01 /1
8 Personal Allowance Amount 12570.0 2025-04-06 currency-GBP
9 Personal Allowance Amount 12570.0 2021-04-06 currency-GBP
10 Personal Allowance Amount 12500.0 2019-04-06 currency-GBP
11 Personal Allowance Amount 11850.0 2018-04-06 currency-GBP
12 Personal Allowance Amount 11500.0 2017-04-06 currency-GBP
13 Personal Allowance Amount 10600.0 2015-04-06 currency-GBP
14 Personal Savings Allowance Addtional Threshold 0.0 2005-06-01 currency-GBP
15 Personal Savings Allowance Basic Threshold 1000.0 2005-06-01 currency-GBP
16 Personal Savings Allowance Higher Threshold 500.0 2005-06-01 currency-GBP
17 Dividend Allowance Dividend Allowance 2000.0 2015-06-05 currency-GBP
18 Property Allowance Property Allowance 1000.0 2005-06-01 currency-GBP
19 Trading Allowance Trading Allowance 1000.0 2005-06-01 currency-GBP

Other income tax parameters can be found in policyengine-uk/policyengine_uk/parameters/gov/hmrc/income_tax.

Simulation#

The figure illustrates the implementation of a simulation for computing income tax and dividend income tax using PolicyEngine UK model. The simulation is conducted for an individual aged 30 with a fixed dividend income of £10,000 while varying the employment income between £0 and £200,000.

Hide code cell source
from policyengine_uk import Simulation

simulation = Simulation(
    situation=dict(
        people=dict(
            person=dict(
                age=30,
                dividend_income=10_000,
            )
        ),
        axes=[
            [
                dict(
                    name="employment_income",
                    min=0,
                    max=200_000,
                    count=1_000,
                )
            ]
        ],
    ),
)

import plotly.express as px
import pandas as pd
from policyengine_core.charts import format_fig

df = pd.DataFrame(
    {
        "Employment income": simulation.calculate("employment_income"),
        "Income tax": simulation.calculate("income_tax"),
        "Dividend income tax": simulation.calculate("dividend_income_tax"),
    }
)

fig = px.line(
    df,
    x="Employment income",
    y=["Income tax", "Dividend income tax"],
    title="Income tax vs employment income",
    labels={
        "value": "Income tax (£)",
        "variable": "Tax type",
    },
)

format_fig(fig)