You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
total_income leaves out other_investment_income, which income_tax charges #2174
total_income (variables/gov/hmrc/income_tax/total_income.py) cites ITA 2007 s. 23. Step 1 of s. 23 sums every amount of income on which the person is charged to income tax. The variable adds eight inputs:
employment_income;
private_pension_income;
social_security_income;
self_employment_income;
property_income;
savings_interest_income;
dividend_income;
miscellaneous_income.
It does not add other_investment_income, which the input's documentation describes as National Savings interest, securities interest and interest from trusts or settlements. Yet the model charges it:
so savings_income_tax, income_tax and adjusted_net_income all include it.
For anyone with other investment income, total_income is lower than the income the model taxes. Someone whose income is mostly other investment income can show a total_income in the lowest taxpaying band while owing tax on a much larger income.
Where it matters
Five baseline formulas in 2.122.2 read total_income, and each understates the income of anyone with other investment income. Main (2.123.1) still leaves it out.
post_tax_income adds total_income and subtracts income_tax, so it subtracts tax on income it never added.
winter_fuel_allowance uses it as the taxable-income test.
household_benefits_individual_non_dep_deduction and council_tax_reduction_individual_non_dep_deduction band non-dependants' weekly income on it.
housing_benefit_net_earnings uses it, through its adds, for the earnings share of income.
Two contributed basic-income reforms, bi_individual_phaseout and bi_household_phaseout, read it too.
Datasets that band people by total income inherit it too. Microcosm UK binds 47 HMRC targets on total_income: the SPI regional cells (Table 3.11), the national SPI band tables and the ITL rows by total income band. On PolicyEngine/microcosm#1121's build:
The West Midlands £12,570–15,000 income-tax cell started at 6.1 times its target. Every other region's cell in that band started at 0.6–1.1 times.
The cause is fewer than 10 records whose income is mostly other investment income. They fell into that band and carried all their tax into it.
Banded on total_income + other_investment_income, the cell starts at 0.92 times its target, and the other 119 regional income-tax cells move by 8% at most.
Add a test: a person whose only income is other investment income has total_income equal to it, and post_tax_income equal to it net of the tax on it.
housing_benefit_net_earnings iterates total_income.adds to undo losses, so it picks up the new component without a change. Its result should be checked against its existing tests.
Related: statutory pay
housing_benefit_net_earnings already notes the same kind of gap for statutory pay. Its comment says statutory sick and maternity pay are taxed as employment income (employment_benefits, through taxable_employment_income) but left out of total_income.
Adding employment_benefits to total_income.adds would close that gap as well.
But housing_benefit_net_earnings currently adds statutory pay separately on top of total_income, so it would need adjusting in the same change.
Whether to do both here or separately is the maintainers' call.
An alternative is to define total_income as the sum of the taxable components that adjusted_net_income already sums. That would also change how losses and the property and trading allowances enter total_income, because those components floor at zero after the allowances. That's a larger change for every reader above.
Summary
total_income(variables/gov/hmrc/income_tax/total_income.py) cites ITA 2007 s. 23. Step 1 of s. 23 sums every amount of income on which the person is charged to income tax. The variable adds eight inputs:employment_income;private_pension_income;social_security_income;self_employment_income;property_income;savings_interest_income;dividend_income;miscellaneous_income.It does not add
other_investment_income, which the input's documentation describes as National Savings interest, securities interest and interest from trusts or settlements. Yet the model charges it:taxable_savings_interest_income=max(0, savings_interest_income + other_investment_income − tax_free_savings_income);savings_income_tax,income_taxandadjusted_net_incomeall include it.For anyone with other investment income,
total_incomeis lower than the income the model taxes. Someone whose income is mostly other investment income can show atotal_incomein the lowest taxpaying band while owing tax on a much larger income.Where it matters
Five baseline formulas in 2.122.2 read
total_income, and each understates the income of anyone with other investment income. Main (2.123.1) still leaves it out.post_tax_incomeaddstotal_incomeand subtractsincome_tax, so it subtracts tax on income it never added.winter_fuel_allowanceuses it as the taxable-income test.household_benefits_individual_non_dep_deductionandcouncil_tax_reduction_individual_non_dep_deductionband non-dependants' weekly income on it.housing_benefit_net_earningsuses it, through itsadds, for the earnings share of income.Two contributed basic-income reforms,
bi_individual_phaseoutandbi_household_phaseout, read it too.Datasets that band people by total income inherit it too. Microcosm UK binds 47 HMRC targets on
total_income: the SPI regional cells (Table 3.11), the national SPI band tables and the ITL rows by total income band. On PolicyEngine/microcosm#1121's build:total_income + other_investment_income, the cell starts at 0.92 times its target, and the other 119 regional income-tax cells move by 8% at most.Proposed fix
other_investment_incometototal_income.adds.total_incomeequal to it, andpost_tax_incomeequal to it net of the tax on it.housing_benefit_net_earningsiteratestotal_income.addsto undo losses, so it picks up the new component without a change. Its result should be checked against its existing tests.Related: statutory pay
housing_benefit_net_earningsalready notes the same kind of gap for statutory pay. Its comment says statutory sick and maternity pay are taxed as employment income (employment_benefits, throughtaxable_employment_income) but left out oftotal_income.employment_benefitstototal_income.addswould close that gap as well.housing_benefit_net_earningscurrently adds statutory pay separately on top oftotal_income, so it would need adjusting in the same change.An alternative is to define
total_incomeas the sum of the taxable components thatadjusted_net_incomealready sums. That would also change how losses and the property and trading allowances entertotal_income, because those components floor at zero after the allowances. That's a larger change for every reader above.