diff --git a/analysis/uk-budget-2026-income-tax/README.md b/analysis/uk-budget-2026-income-tax/README.md new file mode 100644 index 000000000..1a088e993 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/README.md @@ -0,0 +1,74 @@ +# Autumn Budget 2026 income tax explainers + +This shared directory supports three standalone posts: the property income rate increase ([PR #1460](https://github.com/PolicyEngine/policyengine-app-v2/pull/1460)), the savings income rate increase ([PR #1466](https://github.com/PolicyEngine/policyengine-app-v2/pull/1466)) and the trading allowance increase ([PR #1463](https://github.com/PolicyEngine/policyengine-app-v2/pull/1463)). Property and savings were split at the author’s request on 28 October 2026; savings remains a separate draft pending its dashboard data release. The articles compare the newly announced measures with the already legislated 2027–28 baseline. The shared `SAVINGS_PROPERTY` reform in `generate_households.py` changes savings and property rates together; it is not a separate property-only reform. + +## Reproduce the household calculations + +From the repository root, using Python 3.13: + +```sh +uv venv --python 3.13 analysis/uk-budget-2026-income-tax/.venv +uv pip install --python analysis/uk-budget-2026-income-tax/.venv/bin/python -r analysis/uk-budget-2026-income-tax/requirements.txt +analysis/uk-budget-2026-income-tax/.venv/bin/python analysis/uk-budget-2026-income-tax/generate_households.py +``` + +The generator uses hypothetical adults, without population microdata. It records inputs and outputs and checks the results against independent arithmetic. The reform parameters match [dashboard PR #290](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/290) at the immutable commit recorded in `provenance.json`. Both the baseline and reform use the same October 2026 forecast as the [Pension Tax Allowance analysis, PR #1457](https://github.com/PolicyEngine/policyengine-app-v2/pull/1457) (dashboard commit `640426575270224db9b04d6c94d30e264a347be2`). Supplied income amounts remain fixed in 2027–28; the forecast updates statutory and other model parameters. Fixed nominal incomes do not remove the need to use the agreed forecast. + +The checked outputs include 23 household comparisons and 93 displayed points across the two income curves. The displayed lines use £100 intervals and the exact policy breakpoints. All four series are independently checked against the model at every £2 from £500 to £5,000, including a comparison of the plotted interpolation with the engine results; `curve-validation.json` records counts and maximum errors. The non-integer £1,333⅓ expense-choice breakpoint is also calculated with the model. To also verify the original dashboard parameter builder, pass `--dashboard-checkout /path/to/checkout` with that checkout at the recorded commit. This check is optional and performs no download. + +The `landlord_*` records in `households.json` and `households.csv` support the property article. They have no savings income, so the combined reform's savings rate changes do not affect their results. The example with a £30,000 salary, £6,000 of taxable property profit and no eligible finance costs was checked separately with the property-only reform. The `saver_*` and mixed `property_then_savings_order` records, savings curves, and savings-rate and Treasury row 62 metadata in `provenance.json` remain shared records for savings draft #1466; they are not property-only results. + +The savings draft (#1466) reproduces `savings-interest-chart.json`; the trading article (#1463) reproduces `trading-allowance-chart.json`. The property article's native bar chart uses the verified 2027 and 2031 decile means in `property-population/`. Reinsert each chart's contents only into its corresponding article when regenerating it. + +## Current article scope + +The property draft now includes national revenue and decile averages from the approved property-only snapshot in dashboard PR #290. `property-population/` retains the immutable source record, original receipt, three aggregate CSVs and the verification summary. Reach, poverty and inequality figures are omitted pending separate disclosure clearance. It is an approved branch snapshot, not independently verified as the production deployment. Recheck its identity and figures against the final released dashboard before merging. + +The savings and trading posts retain household calculations and Treasury costings only. Withdrawn combined national outputs are not published in this directory. + +## Dataset decision + +Retain the dashboard's adopted `policyengine` 6.11.1 bundle, with UK 2.151.0, core 3.33.3 and national data cut `a6299504`. The certificate, full dataset ID and checksum are recorded in `provenance.json`. The newer candidate in [policyengine.py PR #725](https://github.com/PolicyEngine/policyengine.py/pull/725) is awaiting certification/adoption. A future update must change the package and dataset provenance together and regenerate the analysis. + +The household generators need no population microdata. The property national results reuse the approved single-measure dashboard artifact recorded in `property-population/`; they were not generated locally. Both baseline and reform use the same October 2026 OBR forecast. Series not updated by the overlay retain the model's March forecast path; the underlying calibration remains pre-Budget. + +Treasury forecasts are labelled separately. Compare fiscal-year Treasury receipts with the model's annual government-balance effects, documenting behavioural, timing and coverage differences. Do not attribute a particular discrepancy to one of those factors before reconciliation. No separate winner/loser shares or absolute affected-person counts are provided. Reach, poverty and inequality figures require separate disclosure clearance before publication. + +## Checks before publication + +- Recheck the property draft's `property-population/` artifact identity, figures and comparison flags against the final released dashboard. Restore national scope in the other posts only from their own reconciled sources. Add affected-person counts or shares only when the producer exports them and they have disclosure clearance; do not infer them from average changes. +- Confirm the treatment of Scottish landlords' finance-cost relief against the final Budget implementation. The pinned model links that relief to the UK property basic rate even for Scotland. +- Check trading allowance coverage: gross receipts and actual expenses are needed to model the deduction choice; the pinned model does not apply the allowance to its separate miscellaneous-income input. +- Verify the final public dashboard link and add links to these explainers within the dashboard. The source checkout's README supplies the current Vercel dashboard URL. +- Have the policy interpretation and calculations reviewed before merging. Draft status and publication approval are tracked on each article’s PR. + +The three articles use the site's native tables, chart blocks and cover assets. Household curves use the shared numeric line renderer from [PR #1462](https://github.com/PolicyEngine/policyengine-app-v2/pull/1462); no duplicate chart implementation or country-model code is added. + +## Validation on 28 October 2026 + +`make format`, `make lint`, `make typecheck` and `make test` passed. The tests ran on Node 26.12.1: 6,042 app tests and 508 website tests passed, with 10 app tests skipped by the existing suite. After inserting the final chart data, the chart-parser and post-metadata checks passed again (18 tests). All 23 household comparisons and 20 curve points passed independent arithmetic checks. + +Cover assets and native chart specifications have been validated. The rendered page layout has not been checked at desktop or mobile widths. + + +## Additional trading and calculator examples + +```sh +analysis/uk-budget-2026-income-tax/.venv/bin/python analysis/uk-budget-2026-income-tax/generate_trading_extensions.py +``` + +This checks five additional synthetic pairs requested in the [trading allowance review](https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6472758764), including UC, Class 4 and missing-receipts fallbacks, on the same pinned October forecast as the main generator. `trading_extensions.json` records complete inputs, raw outputs and arithmetic checks. `dashboard_salary_comparison.json` records the calculator's March-index salary comparison. Household examples use no population data. Shared analysis is kept in the property base PR #1460 so the trading article can be reviewed in a separate stacked PR. The savings article is a separate draft PR based on main; its shared-analysis link resolves after #1460 lands. + +## Alignment with the Pension Tax Allowance analysis + +The exact forecast input is retained as `obr_october_2026.json`; `forecast.py` verifies its Git blob before use and reconstructs the source’s rounded fuel-duty path. Its complete eight-path parameter mapping was checked for exact equality with the immutable dashboard source’s `with_forecast(None).parameter_changes`. Both synthetic generators pass that mapping to `pe.uk.calculate_household`. The savings/property generator uses the combined savings and property reform; its savings changes have no effect on the landlord records because those households have no savings income. The trading generator uses the trading allowance reform. There is no population data load to precede, and no other Budget measure is activated. + +The Pension Tax Allowance analysis uses £100 chart sampling plus the true breakpoints and verifies the results on a denser model grid. These drafts follow that method: numeric income axes, explicit £ formats, named threshold markers and independent validation at every £2. Reader-facing tables use whole pounds under the [rounding review](https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6473972686); raw analysis retains precision. + +The household forecast pin and property population forecast pin are recorded separately. Applying the household overlay does not regenerate or validate national results. The property article uses an approved property-only source with execution-bound provenance in `property-population/`. + +The October-forecast rerun passed all 23 household comparisons and all 5 trading extension pairs. All policy deltas remain unchanged. Some absolute levels change: the three Scottish cases’ income-tax levels fall by £2.93 on both sides, and the parent’s total benefits/net income rise by about £20.10 on both sides. These do not change the article’s reported tax or household gains. The 93 displayed chart points passed 18,008 model-liability comparisons and 9,004 interpolation comparisons over 2,251 income points per series. The largest interpolation difference is £0.0033, below the £0.01 tolerance. + +## Editorial cover images + +The posts use original teal editorial illustrations generated with the built-in image tool. Property and savings reuse the original combined-draft cover unchanged under their own asset paths. `cover-prompts.json` records the complete prompts, output paths, encoding settings, dimensions and checksums. The WebP files retain the generated 1672 × 941 pixel dimensions and are selected by each post's `image` metadata, supplying the article hero, research card and social preview. The unused combined-draft SVG cover was removed when the article was split. Article text, charts and calculations are unchanged by the cover update. diff --git a/analysis/uk-budget-2026-income-tax/cover-prompts.json b/analysis/uk-budget-2026-income-tax/cover-prompts.json new file mode 100644 index 000000000..b33bb315a --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/cover-prompts.json @@ -0,0 +1,30 @@ +{ + "tool": "built-in image_gen", + "intent": "Original editorial cover illustrations", + "reference_style": "PolicyEngine Autumn Budget 2026 energy and Pension Tax Allowance covers; deep teal, mint, white, restrained dimensional illustration.", + "assets": [ + { + "path": "app/public/assets/posts/uk-autumn-budget-2026-property-income-tax/cover.webp", + "prompt": "Use case: stylized-concept.\nAsset type: original editorial cover illustration for PolicyEngine's UK Autumn Budget 2026 article on savings and property income tax.\nCreate a polished wide 16:9 landscape illustration, intended final size 1600x900. Match a coherent nonprofit policy research illustration series: deep dark teal background, soft subtle teal vignette, pale mint and turquoise objects, clean vector-like shapes rendered as a raster image, restrained dimensional depth, gentle shadows, crisp edges, professional calm neutral tone.\nScene: a simplified British terraced house and a savings coin stack arranged together beside a large white income-tax statement with a teal header and a few muted grey abstract lines. One mint coin bears a clear British pound symbol (£). House, savings and statement should read as one coherent still life about taxing rental income and savings interest.\nComposition: main objects within the central 65 percent of the canvas, clear at thumbnail size, generous breathing room on every edge, balanced wide layout, a subtle floor line. Avoid tiny details.\nText: only a single £ symbol on the coin; no words, no tax rates, no numbers, no labels, no title, no logos, no watermark.\nConstraints: original illustration, no people, no flags, no political symbolism, no arrows or data charts, no claims about gains or losses. The image should look like a refined flat editorial illustration with subtle depth, not a photograph or a glossy toy render.", + "width": 1672, + "height": 941, + "format": "WebP", + "encoding_quality": 85, + "pixels_resized": false, + "bytes": 59420, + "sha256": "fcaa9776fa6ebfab449034a0423a166f413a9b4a4d5041747ed4610b20e111b6", + "reuse_note": "Originally generated for the combined savings/property draft; retained unchanged for the property article when the articles were split." + }, + { + "path": "app/public/assets/posts/uk-autumn-budget-2026-trading-allowance/cover.webp", + "prompt": "Use case: stylized-concept.\nAsset type: original editorial cover illustration for PolicyEngine's UK Autumn Budget 2026 article about the trading allowance for small businesses and side income.\nCreate a polished wide 16:9 landscape illustration, intended final size 1600x900. Match a coherent nonprofit policy research illustration series: deep dark teal background, soft subtle teal vignette, pale mint and turquoise objects, clean vector-like shapes rendered as a raster image, restrained dimensional depth, gentle shadows, crisp edges, professional calm neutral tone.\nScene: a small-business desktop still life with two simple unbranded parcels, a tidy calculator, a white business receipt or income ledger with a teal header and grey abstract rows, and a small stack of mint coins. One mint coin bears a clear British pound symbol (£). Convey modest self-employment or side-business receipts and expenses. It must not suggest stock-market trading or cryptocurrency.\nComposition: main objects within the central 65 percent of the canvas, readable at thumbnail size, generous breathing room on every edge, balanced wide layout, a subtle floor line. Avoid tiny details.\nText: only a single £ symbol on one coin; no words, no allowance amounts, no numbers on calculator keys, no labels, no title, no logos, no watermark.\nConstraints: original illustration, no people, no flags, no political symbolism, no charts, no arrows or promises of wealth. The image should look like a refined flat editorial illustration with subtle depth, not a photograph or a glossy toy render.", + "width": 1672, + "height": 941, + "format": "WebP", + "encoding_quality": 85, + "pixels_resized": false, + "bytes": 45038, + "sha256": "67f66a172051edf23372d3df5de577fd3724eed21dbb84036bf5cef106b3a9f0" + } + ] +} diff --git a/analysis/uk-budget-2026-income-tax/curve-validation.json b/analysis/uk-budget-2026-income-tax/curve-validation.json new file mode 100644 index 000000000..76f6785dc --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/curve-validation.json @@ -0,0 +1,30 @@ +{ + "range_gbp": [ + 500, + 5000 + ], + "validation_interval_gbp": 2, + "points_per_series": 2251, + "series": 4, + "liability_checks": 18008, + "interpolation_checks": 9004, + "chart_interval_gbp": 100, + "savings_breakpoints_gbp": [ + 500, + 1000 + ], + "trading_breakpoints_gbp": [ + 1000, + 1333.3333333333333, + 3000, + 4000 + ], + "chart_rows": { + "savings": 46, + "trading": 47 + }, + "maximum_model_error_gbp": 2.2737367544323206e-13, + "maximum_chart_interpolation_error_gbp": 0.0033000000000242835, + "tolerance_gbp": 0.01, + "method": "All four series checked against pe.uk at every £2; both scenarios compared with independent tax arithmetic; plotted linear interpolation compared with the engine tax changes. The non-integer expense-choice breakpoint is additionally calculated with pe.uk." +} diff --git a/analysis/uk-budget-2026-income-tax/dashboard_salary_comparison.json b/analysis/uk-budget-2026-income-tax/dashboard_salary_comparison.json new file mode 100644 index 000000000..3c65d13a8 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/dashboard_salary_comparison.json @@ -0,0 +1,54 @@ +{ + "scope": "Synthetic salary-uprating comparison; no population data", + "versions": { + "policyengine": "6.11.1", + "policyengine-uk": "2.151.0", + "policyengine-core": "3.33.3" + }, + "year": 2027, + "salary_input_year": 2026, + "salary_growth_basis": "Pinned UK March OBR average earnings index, Jan1 to Jan1, matching calculator earnings_growth", + "growth_factor": 1.0240009985556604, + "inputs": { + "age": 35, + "employment_income": 46080.04493500472, + "property_income": 6000, + "savings_interest_income": 2000 + }, + "baseline": { + "income_tax": 9014.02, + "savings_income_tax": 630.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 1682.01, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 6000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2680.81, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 9164.02, + "savings_income_tax": 660.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 1802.01, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 6000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2680.81, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "income_tax_change": 150.0, + "reference": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/292#issuecomment-6473170340" +} diff --git a/analysis/uk-budget-2026-income-tax/forecast.py b/analysis/uk-budget-2026-income-tax/forecast.py new file mode 100644 index 000000000..80be8c660 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/forecast.py @@ -0,0 +1,58 @@ +"""The exact October forecast used by Pavel's PTA comparison. + +The stored JSON is unchanged from dashboard commit 640426575270224db9b04d6c94d30e264a347be2. +The fuel-duty path follows that commit's forecast_parameter_changes, including +its ROUND_HALF_UP rule. Synthetic households load no population data, so passing +these changes to pe.uk before calculation is equivalent to with_forecast. +""" + +from decimal import ROUND_HALF_UP, Decimal +from functools import lru_cache +import hashlib +import json +from pathlib import Path + + +COMMIT = "640426575270224db9b04d6c94d30e264a347be2" +FORECAST_PATH = Path(__file__).with_name("obr_october_2026.json") +EXPECTED_BLOB = "b504a48fffb93714ff358d869cad712b6daea20e" + + +@lru_cache(maxsize=None) +def parameter_changes() -> dict: + raw = FORECAST_PATH.read_bytes() + blob = hashlib.sha1(b"blob " + str(len(raw)).encode() + b"\0" + raw).hexdigest() + assert blob == EXPECTED_BLOB, (blob, EXPECTED_BLOB) + record = json.loads(raw) + changes = { + path: dict(entry["values"]) + for path, entry in record["parameter_changes"].items() + } + rate = Decimal("0.6059") + steps = [("2027-04-01", float(rate))] + for year in range(2028, 2033): + growth = Decimal(str(changes["gov.economic_assumptions.yoy_growth.obr.rpi"][f"{year - 1}-01-01.{year - 1}-12-31"])) + rate = (rate * (1 + growth)).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP) + steps.append((f"{year}-04-01", float(rate))) + changes["gov.hmrc.fuel_duty.petrol_and_diesel"] = { + f"{day}.{int(day[:4]) + 1}-03-31": rate for day, rate in steps + } + return changes + + +def with_forecast(reform: dict) -> dict: + """Apply the common forecast, with the isolated measure taking precedence.""" + return {**parameter_changes(), **reform} + + +def provenance() -> dict: + return { + "dashboard_commit": COMMIT, + "source": f"https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/{COMMIT}/src/uk_budget_data/forecast/obr_october_2026.json", + "forecast_file_git_blob": EXPECTED_BLOB, + "forecast_module_git_blob": "b2ca186b6fd514f334ced11934d38b256e6d2127", + "forecast_file_sha256": hashlib.sha256(FORECAST_PATH.read_bytes()).hexdigest(), + "baseline_and_reform": True, + "nominal_household_inputs": "Held fixed in 2027; the forecast updates model parameters, not the supplied income amounts.", + "remaining_series": "March paths remain for cpih, non-labour income, private rent, mortgage interest, per-capita series, council tax and fuel volumes/prices, as recorded by this forecast vintage.", + } diff --git a/analysis/uk-budget-2026-income-tax/generate_households.py b/analysis/uk-budget-2026-income-tax/generate_households.py new file mode 100644 index 000000000..e66fa1605 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/generate_households.py @@ -0,0 +1,433 @@ +"""Reproduce synthetic examples for the two Autumn Budget 2026 explainers. + +Run with this directory's pinned .venv/bin/python. No population data are used. +Tax liability changes isolate each announced measure against the 2027 baseline. +""" + +from __future__ import annotations + +import argparse +import ast +import csv +from datetime import datetime, timezone +import importlib.metadata as metadata +import json +import math +from pathlib import Path +import platform +import subprocess +import warnings + +import policyengine as pe +import numpy as np + +from forecast import provenance as forecast_provenance, with_forecast + + +YEAR = 2027 +EXPECTED_VERSIONS = { + "policyengine": "6.11.1", + "policyengine-uk": "2.151.0", + "policyengine-core": "3.33.3", +} +SOURCE_COMMIT = "b50787aa75ef5aed36b822c973afa6b569464d55" +SOURCE_PR = "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/290" +RATE_ROOT = "gov.hmrc.income_tax.rates" +SAVINGS_PROPERTY = { + f"{RATE_ROOT}.{income}.{band}": rate + for income in ("savings", "property") + for band, rate in (("basic", 0.24), ("higher", 0.44), ("additional", 0.49)) +} +TRADING_PATH = "gov.hmrc.income_tax.allowances.trading_allowance" +TRADING = {TRADING_PATH: 3_000} +PERSON_OUTPUTS = [ + "income_tax", "savings_income_tax", "savings_allowance", + "savings_starter_rate_income", "basic_rate_savings_income", + "higher_rate_savings_income", "add_rate_savings_income", + "property_income_tax", "property_finance_cost_relief", + "taxable_property_income", "trading_allowance_deduction", + "taxable_self_employment_income", "national_insurance", "ni_class_4", +] + + +def close(actual: float, expected: float, label: str) -> None: + # Country-model monetary arrays are float32; two pence covers their + # representation error without concealing a material example discrepancy. + if not math.isclose(actual, expected, abs_tol=0.02, rel_tol=0): + raise AssertionError(f"{label}: engine {actual}, independent oracle {expected}") + + +def rounded(value): + if isinstance(value, list): + return [round(float(item), 2) for item in value] + return round(float(value), 2) + + +def calculate(person: dict, region: str, reform: dict, axes=None) -> dict: + result = pe.uk.calculate_household( + people=[{"age": 35, **person}], + household={"region": region}, + year=YEAR, + reform=with_forecast(reform), + axes=axes, + extra_variables=PERSON_OUTPUTS, + ) + output = {name: rounded(getattr(result.person[0], name)) for name in PERSON_OUTPUTS} + output["household_benefits"] = rounded(result.household.household_benefits) + return output + + +def verify_baseline_parameters() -> dict: + # Direct country access inspects parameters only. Tax calculations use pe.uk. + from policyengine_uk.system import system + + baseline = { + path: system.parameters.get_child(path)(f"{YEAR}-04-06") + for path in SAVINGS_PROPERTY + } + for path in SAVINGS_PROPERTY: + expected = {"basic": 0.22, "higher": 0.42, "additional": 0.47}[path.rsplit(".", 1)[1]] + close(baseline[path], expected, path) + baseline[TRADING_PATH] = system.parameters.get_child(TRADING_PATH)(f"{YEAR}-04-06") + close(baseline[TRADING_PATH], 1_000, TRADING_PATH) + return baseline + + +def source_comparison(checkout: Path | None) -> dict: + """Optionally execute the dashboard's relevant builder, not its pipeline.""" + record = { + "pull_request": SOURCE_PR, + "commit": SOURCE_COMMIT, + "source_file_url": f"https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/{SOURCE_COMMIT}/src/uk_budget_data/reforms.py", + "compared_file": "src/uk_budget_data/reforms.py", + "baseline_parameters": verify_baseline_parameters(), + "reform_parameters": {**SAVINGS_PROPERTY, **TRADING}, + "dashboard_builder_verified": checkout is not None, + } + if checkout is None: + return { + **record, + "comparison": "Independent reform dictionaries and baseline parameters verified. Optional dashboard-builder comparison not requested; immutable source reference recorded above.", + } + commit = subprocess.check_output( + ["git", "rev-parse", "HEAD"], cwd=checkout, text=True + ).strip() + if commit != SOURCE_COMMIT: + raise AssertionError(f"Dashboard checkout changed: {commit}") + source_file = checkout / "src/uk_budget_data/reforms.py" + tree = ast.parse(source_file.read_text()) + names = { + "INCOME_TAX_RATES", "UNEARNED_INCOME_RATE_PATHS", + "UNEARNED_INCOME_RATE_RISE", "UNEARNED_INCOME_RATES_FROM", + "TRADING_ALLOWANCE", "TRADING_ALLOWANCE_RAISED", "TRADING_ALLOWANCE_FROM", + } + selected = [ + node for node in tree.body + if ( + isinstance(node, ast.Assign) + and any(isinstance(target, ast.Name) and target.id in names for target in node.targets) + ) or (isinstance(node, ast.FunctionDef) and node.name == "unearned_income_rates_up") + ] + scope = { + "POLICY_YEARS": list(range(2026, 2032)), + # The real template validates then returns this same dictionary shape. + "rate_change": lambda path, years: {path: years}, + } + exec(compile(ast.Module(body=selected, type_ignores=[]), str(source_file), "exec"), scope) + dashboard = scope["unearned_income_rates_up"]() + flat = {path: values[str(YEAR)] for path, values in dashboard.items()} + assert flat == SAVINGS_PROPERTY, (flat, SAVINGS_PROPERTY) + assert scope["UNEARNED_INCOME_RATES_FROM"] == YEAR + assert scope["TRADING_ALLOWANCE_FROM"] == YEAR + assert {scope["TRADING_ALLOWANCE"]: scope["TRADING_ALLOWANCE_RAISED"]} == TRADING + return { + **record, + "comparison": "Relevant parameter declarations and savings/property builder match the independent flat reform dictionaries; no combined-package modifiers run.", + } + + +def cases() -> list[dict]: + rows = [] + + def add(case_id, policy, person, expected, region="LONDON", detail=None): + rows.append({ + "id": case_id, "policy": policy, "region": region, + "person": person, "independent_oracle": expected, + "detail": detail, + }) + + for case_id, salary, interest, allowance, before, after in [ + ("saver_below_allowance", 30_000, 500, 1_000, 0, 0), + ("saver_basic", 30_000, 2_000, 1_000, 220, 240), + ("saver_higher", 60_000, 2_000, 500, 630, 660), + ("saver_additional", 150_000, 2_000, 0, 940, 980), + ("saver_crosses_basic_higher", 49_270, 2_000, 500, 530, 560), + ("saver_starting_rate", 15_000, 4_000, 1_000, 94.60, 103.20), + ]: + add(case_id, "savings_property", { + "employment_income": salary, "savings_interest_income": interest, + }, { + "baseline": {"savings_allowance": allowance, "savings_income_tax": before}, + "reform": {"savings_allowance": allowance, "savings_income_tax": after}, + "change": {"income_tax": after - before}, + }) + add("saver_scotland_higher", "savings_property", { + "employment_income": 60_000, "savings_interest_income": 2_000, + }, {"baseline": {"savings_income_tax": 630}, "reform": {"savings_income_tax": 660}, + "change": {"income_tax": 30}}, region="SCOTLAND") + + for band, salary, before, after, total in [ + ("basic", 30_000, 2_200, 2_400, 4_806), + ("higher", 60_000, 4_200, 4_400, 14_752), + ("additional", 150_000, 4_700, 4_900, 57_523), + ("crosses_basic_higher", 45_000, 3_146, 3_346, 8_752), + ]: + add(f"landlord_{band}_mortgage", "savings_property", { + "employment_income": salary, "property_income": 10_000, + "property_finance_costs": 4_000, + }, { + "baseline": {"property_income_tax": before, "property_finance_cost_relief": 880, "income_tax": total}, + "reform": {"property_income_tax": after, "property_finance_cost_relief": 960, "income_tax": total + 120}, + "change": {"income_tax": 120}, + }, detail={"gross_rent": 12_000, "actual_non_finance_expenses": 2_000}) + for region in ("LONDON", "WALES", "NORTHERN_IRELAND"): + add(f"landlord_mortgage_free_{region.lower()}", "savings_property", { + "employment_income": 30_000, "property_income": 10_000, + }, {"baseline": {"property_income_tax": 2_200}, "reform": {"property_income_tax": 2_400}, + "change": {"income_tax": 200}}, region=region) + for finance, change in ((0, 0), (4_000, -80)): + add(f"landlord_scotland_finance_{finance}", "savings_property", { + "employment_income": 60_000, "property_income": 10_000, + "property_finance_costs": finance, + }, {"change": {"property_income_tax": 0, "property_finance_cost_relief": finance * 0.02, "income_tax": change}}, + region="SCOTLAND", detail="Scottish property rates do not change; the UK-wide finance-cost credit rate does.") + add("property_then_savings_order", "savings_property", { + "employment_income": 45_000, "property_income": 6_000, + "savings_interest_income": 2_000, + }, { + "baseline": {"property_income_tax": 1_466, "savings_income_tax": 630, "income_tax": 8_582}, + "reform": {"property_income_tax": 1_586, "savings_income_tax": 660, "income_tax": 8_732}, + "change": {"income_tax": 150}, + }) + + for salary, marginal in ((30_000, 0.2), (60_000, 0.4)): + wages_tax = 3_486 if salary == 30_000 else 11_432 + for expenses in (500, 2_500, 3_500): + receipts = 4_000 + before = max(0, receipts - max(expenses, 1_000)) + after = max(0, receipts - max(expenses, 3_000)) + add(f"trader_salary_{salary}_expenses_{expenses}", "trading", { + "employment_income": salary, + "self_employment_gross_receipts": receipts, + "self_employment_income": receipts - expenses, + }, { + "baseline": {"taxable_self_employment_income": before, "income_tax": wages_tax + before * marginal, "ni_class_4": 0}, + "reform": {"taxable_self_employment_income": after, "income_tax": wages_tax + after * marginal, "ni_class_4": 0}, + "change": {"income_tax": (after - before) * marginal, "national_insurance": 0}, + }, detail={"gross_receipts": receipts, "actual_expenses": expenses}) + return rows + + +def generate_cases() -> list[dict]: + output = [] + for case in cases(): + reform = SAVINGS_PROPERTY if case["policy"] == "savings_property" else TRADING + baseline = calculate(case["person"], case["region"], {}) + reformed = calculate(case["person"], case["region"], reform) + change = {name: round(reformed[name] - baseline[name], 2) for name in baseline} + result = {**case, "baseline": baseline, "reform": reformed, "change": change} + for scenario, expectations in case["independent_oracle"].items(): + for variable, expected in expectations.items(): + close(result[scenario][variable], expected, f"{case['id']} {scenario} {variable}") + close(baseline["household_benefits"], 0, f"{case['id']} baseline benefits") + close(reformed["household_benefits"], 0, f"{case['id']} reform benefits") + output.append(result) + return output + + +def generate_curves() -> tuple[list[dict], list[dict], dict]: + # Model checks use every £2. Displayed curves include all £100 points and + # the exact deduction-choice breakpoints, matching the PTA chart method. + grid = list(range(500, 5_001, 2)) + interest_rows = [{"interest": value} for value in range(500, 5_001, 100)] + model_errors = [] + interpolation_errors = [] + for label, salary, allowance, old_rate in ( + ("basic", 30_000, 1_000, 0.22), ("higher", 60_000, 500, 0.42), + ): + axes = [[{"name": "savings_interest_income", "min": 500, "max": 5_000, "count": len(grid)}]] + baseline = calculate({"employment_income": salary}, "LONDON", {}, axes) + reformed = calculate({"employment_income": salary}, "LONDON", SAVINGS_PROPERTY, axes) + changes = [] + for index, interest in enumerate(grid): + taxable = max(0, interest - allowance) + before, after = baseline["savings_income_tax"][index], reformed["savings_income_tax"][index] + close(before, taxable * old_rate, f"{label} savings curve baseline") + close(after, taxable * (old_rate + 0.02), f"{label} savings curve reform") + model_errors.extend((abs(before - taxable * old_rate), abs(after - taxable * (old_rate + 0.02)))) + changes.append(round(after - before, 2)) + for row in interest_rows: + index = grid.index(row["interest"]) + before, after = baseline["savings_income_tax"][index], reformed["savings_income_tax"][index] + row[f"{label}_baseline_tax"] = before + row[f"{label}_reform_tax"] = after + row[f"{label}_tax_increase"] = round(after - before, 2) + interpolated = np.interp(grid, [row["interest"] for row in interest_rows], [row[f"{label}_tax_increase"] for row in interest_rows]) + interpolation_errors.extend(abs(float(plotted) - actual) for plotted, actual in zip(interpolated, changes)) + + trading_breakpoints = (1_000, 4_000 / 3, 3_000, 4_000) + trading_rows = [{"receipts": value} for value in sorted(set(range(500, 5_001, 100)) | set(trading_breakpoints))] + for label, expense_share in (("no_expenses", 0), ("expenses_75_percent", 0.75)): + profit_share = 1 - expense_share + axes = [[ + {"name": "self_employment_gross_receipts", "min": 500, "max": 5_000, "count": len(grid)}, + {"name": "self_employment_income", "min": 500 * profit_share, "max": 5_000 * profit_share, "count": len(grid)}, + ]] + baseline = calculate({"employment_income": 30_000}, "LONDON", {}, axes) + reformed = calculate({"employment_income": 30_000}, "LONDON", TRADING, axes) + changes = [] + for index, receipts in enumerate(grid): + expenses = receipts * expense_share + old_taxable = max(0, receipts - max(expenses, 1_000)) + new_taxable = max(0, receipts - max(expenses, 3_000)) + close(baseline["taxable_self_employment_income"][index], old_taxable, f"{label} trading baseline") + close(reformed["taxable_self_employment_income"][index], new_taxable, f"{label} trading reform") + reduction = round(baseline["income_tax"][index] - reformed["income_tax"][index], 2) + close(reduction, (old_taxable - new_taxable) * 0.2, f"{label} trading tax reduction") + close(baseline["ni_class_4"][index], 0, f"{label} baseline Class 4") + close(reformed["ni_class_4"][index], 0, f"{label} reform Class 4") + model_errors.extend((abs(baseline["income_tax"][index] - (3_486 + old_taxable * 0.2)), abs(reformed["income_tax"][index] - (3_486 + new_taxable * 0.2)))) + changes.append(reduction) + # This non-integer breakpoint cannot be represented by a regular axis. + special_inputs = {"employment_income": 30_000, "self_employment_gross_receipts": 4_000 / 3, "self_employment_income": (4_000 / 3) * profit_share} + special_before = calculate(special_inputs, "LONDON", {}) + special_after = calculate(special_inputs, "LONDON", TRADING) + for row in trading_rows: + receipts = row["receipts"] + expenses = receipts * expense_share + old_taxable = max(0, receipts - max(expenses, 1_000)) + new_taxable = max(0, receipts - max(expenses, 3_000)) + if receipts in grid: + index = grid.index(receipts) + reduction = changes[index] + else: + reduction = round(special_before["income_tax"] - special_after["income_tax"], 2) + close(reduction, (old_taxable - new_taxable) * 0.2, f"{label} plotted trading reduction") + row[f"{label}_actual_expenses"] = expenses + row[f"{label}_baseline_taxable_profit"] = old_taxable + row[f"{label}_reform_taxable_profit"] = new_taxable + row[f"{label}_tax_reduction"] = reduction + interpolated = np.interp(grid, [row["receipts"] for row in trading_rows], [row[f"{label}_tax_reduction"] for row in trading_rows]) + interpolation_errors.extend(abs(float(plotted) - actual) for plotted, actual in zip(interpolated, changes)) + maximum_model_error = max(model_errors) + maximum_interpolation_error = max(interpolation_errors) + assert maximum_model_error <= 0.01, maximum_model_error + assert maximum_interpolation_error <= 0.01, maximum_interpolation_error + validation = { + "range_gbp": [500, 5_000], "validation_interval_gbp": 2, + "points_per_series": len(grid), "series": 4, + "liability_checks": len(model_errors), "interpolation_checks": len(interpolation_errors), + "chart_interval_gbp": 100, + "savings_breakpoints_gbp": [500, 1_000], + "trading_breakpoints_gbp": list(trading_breakpoints), + "chart_rows": {"savings": len(interest_rows), "trading": len(trading_rows)}, + "maximum_model_error_gbp": maximum_model_error, + "maximum_chart_interpolation_error_gbp": maximum_interpolation_error, + "tolerance_gbp": 0.01, + "method": "All four series checked against pe.uk at every £2; both scenarios compared with independent tax arithmetic; plotted linear interpolation compared with the engine tax changes. The non-integer expense-choice breakpoint is additionally calculated with pe.uk.", + } + return interest_rows, trading_rows, validation + + +def chart_specs(savings, trading) -> dict: + source = "PolicyEngine 6.11.1 / UK 2.151.0; synthetic adults, 2027–28; incomes held fixed." + return { + "savings-interest-chart.json": { + "type": "line", "title": "Savings tax increases apply above the Personal Savings Allowance", + "subtitle": "Annual income tax increase; England, salaries £30,000 and £60,000, 2027–28", + "xKey": "interest", "xLabel": "Annual savings interest", "yLabel": "Extra annual income tax", + "format": {"prefix": "£", "decimals": 0, "separator": True}, + "xFormat": {"prefix": "£", "decimals": 0, "separator": True}, "source": source, + "series": [ + {"key": "basic", "name": "£30,000 salary", "color": "negative"}, + {"key": "higher", "name": "£60,000 salary", "color": "secondary"}, + ], + "markers": [{"x": 500, "label": "£60,000 salary: savings allowance"}, {"x": 1_000, "label": "£30,000 salary: savings allowance"}], + "data": [{"interest": row["interest"], "basic": row["basic_tax_increase"], "higher": row["higher_tax_increase"]} for row in savings], + }, + "trading-allowance-chart.json": { + "type": "line", "title": "Trading allowance: the income tax reduction depends on expenses", + "subtitle": "Annual income tax reduction; England, £30,000 salary, 2027–28", + "xKey": "receipts", "xLabel": "Annual side-business receipts", "yLabel": "Annual income tax reduction", + "format": {"prefix": "£", "decimals": 0, "separator": True}, + "xFormat": {"prefix": "£", "decimals": 0, "separator": True}, "source": source, + "series": [ + {"key": "noExpenses", "name": "No business expenses", "color": "primary"}, + {"key": "highExpenses", "name": "Expenses equal 75% of receipts", "color": "secondary"}, + ], + "markers": [{"x": 1_000, "label": "Current allowance"}, {"x": 3_000, "label": "New allowance"}, {"x": 4_000, "label": "75% expenses equal £3,000"}], + "data": [{"receipts": row["receipts"], "noExpenses": row["no_expenses_tax_reduction"], "highExpenses": row["expenses_75_percent_tax_reduction"]} for row in trading], + }, + } + + +def write_csv(path: Path, rows: list[dict]) -> None: + with path.open("w", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=list(rows[0])) + writer.writeheader() + writer.writerows(rows) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dashboard-checkout", type=Path, help="Optional checkout at the recorded PR290 commit for source-builder comparison; not needed for household calculations.") + parser.add_argument("--output-dir", type=Path, default=Path(__file__).resolve().parent) + args = parser.parse_args() + versions = {package: metadata.version(package) for package in EXPECTED_VERSIONS} + assert versions == EXPECTED_VERSIONS, (versions, EXPECTED_VERSIONS) + # Formula files are dynamically loaded, so their warning module names do + # not consistently match policyengine_uk. Filter these exact known messages. + warnings.filterwarnings("ignore", category=RuntimeWarning, message="(divide by zero|invalid value) encountered in (divide|multiply)") + warnings.filterwarnings("ignore", category=UserWarning, message="Accessing \\.values on a MicroSeries returns a plain numpy array without weights\\.") + comparison = source_comparison(args.dashboard_checkout) + households = generate_cases() + savings, trading, curve_validation = generate_curves() + payload = { + "metadata": { + "generated_at_utc": datetime.now(timezone.utc).isoformat(), + "tax_year": "2027–28", "model_year": YEAR, "versions": versions, + "python": platform.python_version(), "dashboard_comparison": comparison, + "scope": "Synthetic single adults age 35; no microdata, no behavioural responses or national estimates. Income and expenses held fixed; tax liabilities, not full household net-income changes.", + "assumptions": "No children, pensions, Gift Aid, student loans, capital gains, other tax reliefs, property losses or carried-forward finance costs. Savings are outside ISAs. Trading receipts and profit are both supplied; no connected-party receipts or partnership income. All example benefit totals are checked to be zero.", + "oracle_tolerance_gbp": 0.02, + "forecast": forecast_provenance(), + "warning_filters": "Known household divide/invalid RuntimeWarnings and single-household model decile .values warnings only; no population weights are accessed by this generator.", + }, + "reforms": {"savings_property": SAVINGS_PROPERTY, "trading": TRADING}, + "households": households, + "savings_interest_curve": savings, "trading_receipts_curve": trading, + "curve_validation": curve_validation, + } + args.output_dir.mkdir(parents=True, exist_ok=True) + (args.output_dir / "households.json").write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n") + flat = [] + for row in households: + record = {"id": row["id"], "policy": row["policy"], "region": row["region"], "model_year": YEAR} + record.update({f"input_{name}": row["person"].get(name, 0) for name in ( + "employment_income", "savings_interest_income", "property_income", + "property_finance_costs", "self_employment_gross_receipts", "self_employment_income", + )}) + for scenario in ("baseline", "reform", "change"): + record.update({f"{scenario}_{name}": value for name, value in row[scenario].items()}) + flat.append(record) + write_csv(args.output_dir / "households.csv", flat) + write_csv(args.output_dir / "savings-interest-curve.csv", savings) + write_csv(args.output_dir / "trading-receipts-curve.csv", trading) + for filename, spec in chart_specs(savings, trading).items(): + (args.output_dir / filename).write_text(json.dumps(spec, indent=2, ensure_ascii=False) + "\n") + (args.output_dir / "curve-validation.json").write_text(json.dumps(curve_validation, indent=2, ensure_ascii=False) + "\n") + print(f"Verified {len(households)} household comparisons, {len(savings) + len(trading)} plotted curve points and {curve_validation['interpolation_checks']} dense chart checks; wrote {args.output_dir}") + + +if __name__ == "__main__": + main() diff --git a/analysis/uk-budget-2026-income-tax/generate_trading_extensions.py b/analysis/uk-budget-2026-income-tax/generate_trading_extensions.py new file mode 100644 index 000000000..5792ebf2d --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/generate_trading_extensions.py @@ -0,0 +1,228 @@ +"""Reproduce synthetic trading-allowance examples requested in Max's review. + +Run: .venv/bin/python generate_trading_extensions.py +Only trading_extensions.json is written; no population data are used. +""" + +from __future__ import annotations + +import argparse +from datetime import datetime, timezone +import importlib.metadata as metadata +import json +import math +from pathlib import Path +import platform +import warnings + +import policyengine as pe + +from forecast import provenance as forecast_provenance, with_forecast + + +YEAR = 2027 +ALLOWANCE_PATH = "gov.hmrc.income_tax.allowances.trading_allowance" +REFORM = {ALLOWANCE_PATH: 3_000} +VERSIONS = {"policyengine": "6.11.1", "policyengine-uk": "2.151.0", "policyengine-core": "3.33.3"} +REVIEW_URL = "https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6472758764" +PERSON_OUTPUTS = [ + "employment_income", "self_employment_income", "self_employment_gross_receipts", + "income_tax", "national_insurance", "ni_class_4", "taxable_self_employment_income", + "trading_allowance_deduction", "uc_income_tax_on_earnings", "uc_income_tax_on_trade", + "uc_national_insurance_on_earnings", "uc_national_insurance_on_trade", + "uc_individual_earned_income_before_mif", "uc_individual_earned_income", + "uc_is_in_gainful_self_employment", "uc_mif_applies", +] +BENUNIT_OUTPUTS = [ + "universal_credit", "universal_credit_pre_benefit_cap", "claims_universal_credit", + "uc_maximum_amount", "uc_standard_allowance", "uc_child_element", + "uc_housing_costs_element", "uc_work_allowance", "uc_earned_income_before_work_allowance", + "uc_earned_income", "uc_income_reduction", "uc_benefit_cap_reduction", "child_benefit", +] +HOUSEHOLD_OUTPUTS = [ + "household_net_income", "hbai_household_net_income", "household_benefits", + "household_tax", "household_market_income", "household_gross_income", "rent", "council_tax", +] + + +def close(actual: float, expected: float, label: str) -> None: + if not math.isclose(actual, expected, abs_tol=0.02, rel_tol=0): + raise AssertionError(f"{label}: actual {actual}, independent expectation {expected}") + + +def parameters() -> dict: + # Parameter inspection only; all tax/benefit computation uses pe.uk below. + from policyengine_uk.system import system + + nodes = { + "trading_allowance": ALLOWANCE_PATH, + "uc_taper": "gov.dwp.universal_credit.means_test.reduction_rate", + "uc_work_allowance_monthly_with_housing": "gov.dwp.universal_credit.means_test.work_allowance.with_housing", + "uc_work_allowance_monthly_without_housing": "gov.dwp.universal_credit.means_test.work_allowance.without_housing", + } + values = {name: float(system.parameters.get_child(path)(f"{YEAR}-04-06")) for name, path in nodes.items()} + close(values["trading_allowance"], 1_000, "baseline trading allowance") + close(values["uc_taper"], 0.55, "UC taper") + return values + + +def lone_parent(receipts: int, supply_receipts: bool = True) -> dict: + adult = { + "age": 35, "employment_status": "PT_EMPLOYED", "hours_worked": 20 * 52, + "employment_income": 18_000, "self_employment_income": receipts, + # Employment is the main job. This is the statutory gainful-employment + # determination, not an override of an income floor or UC award. + "uc_is_in_gainful_self_employment": False, + } + if supply_receipts: + adult["self_employment_gross_receipts"] = receipts + return { + "people": [adult, {"age": 4, "employment_status": "CHILD"}], + "benunit": {"would_claim_uc": True, "would_claim_child_benefit": True}, + "household": { + "region": "LONDON", "brma": "CENTRAL_LONDON", + "tenure_type": "RENT_PRIVATELY", "rent": 12_000, "council_tax": 0, + }, + } + + +def sole_trader(supply_receipts: bool = True) -> dict: + adult = { + "age": 35, "employment_status": "FT_SELF_EMPLOYED", "hours_worked": 35 * 52, + "employment_income": 0, "self_employment_income": 19_500, + "uc_is_in_gainful_self_employment": True, + } + if supply_receipts: + adult["self_employment_gross_receipts"] = 20_000 + return { + "people": [adult], "benunit": {"would_claim_uc": False, "would_claim_child_benefit": False}, + "household": {"region": "LONDON", "brma": "CENTRAL_LONDON", "tenure_type": "OWNED_OUTRIGHT", "rent": 0, "council_tax": 0}, + } + + +def calculate(inputs: dict, reform: dict) -> dict: + result = pe.uk.calculate_household( + **inputs, year=YEAR, reform=with_forecast(reform), + extra_variables=PERSON_OUTPUTS + BENUNIT_OUTPUTS + HOUSEHOLD_OUTPUTS, + ) + # Preserve wrapper-provided floating-point values, including float32 + # representation differences, rather than rounding the recorded raw output. + return { + "person": [{name: float(getattr(person, name)) for name in PERSON_OUTPUTS} for person in result.person], + "benunit": {name: float(getattr(result.benunit, name)) for name in BENUNIT_OUTPUTS}, + "household": {name: float(getattr(result.household, name)) for name in HOUSEHOLD_OUTPUTS}, + } + + +def run_case(case: dict, law: dict) -> dict: + baseline = calculate(case["inputs"], {}) + reformed = calculate(case["inputs"], REFORM) + delta = { + "income_tax": sum(person["income_tax"] for person in reformed["person"]) - sum(person["income_tax"] for person in baseline["person"]), + "national_insurance": sum(person["national_insurance"] for person in reformed["person"]) - sum(person["national_insurance"] for person in baseline["person"]), + "ni_class_4": sum(person["ni_class_4"] for person in reformed["person"]) - sum(person["ni_class_4"] for person in baseline["person"]), + "universal_credit": reformed["benunit"]["universal_credit"] - baseline["benunit"]["universal_credit"], + "household_benefits": reformed["household"]["household_benefits"] - baseline["household"]["household_benefits"], + "household_net_income": reformed["household"]["household_net_income"] - baseline["household"]["household_net_income"], + "hbai_household_net_income": reformed["household"]["hbai_household_net_income"] - baseline["household"]["hbai_household_net_income"], + } + for scenario, expected in case["independent_oracle"].items(): + for name, amount in expected.items(): + actual = delta[name] if scenario == "change" else baseline["person"][0][name] if scenario == "baseline" else reformed["person"][0][name] + close(actual, amount, f"{case['id']} {scenario} {name}") + close(delta["household_benefits"], delta["universal_credit"], f"{case['id']} other benefits unchanged") + close(delta["household_net_income"], -delta["income_tax"] - delta["national_insurance"] + delta["universal_credit"], f"{case['id']} net-income identity") + trace = None + if case["type"] == "lone_parent": + old_uc, new_uc = baseline["benunit"], reformed["benunit"] + for result in (baseline, reformed): + assert result["benunit"]["universal_credit"] > 0 + close(result["person"][0]["uc_mif_applies"], 0, f"{case['id']} MIF") + assert result["benunit"]["uc_earned_income_before_work_allowance"] > result["benunit"]["uc_work_allowance"] + close(new_uc["uc_work_allowance"], old_uc["uc_work_allowance"], f"{case['id']} work allowance unchanged") + earnings_change = new_uc["uc_earned_income_before_work_allowance"] - old_uc["uc_earned_income_before_work_allowance"] + close(earnings_change, -delta["income_tax"] - delta["national_insurance"], f"{case['id']} UC net-earnings increase") + close(delta["universal_credit"], -law["uc_taper"] * earnings_change, f"{case['id']} UC taper arithmetic") + trace = { + "baseline_annual_uc_earnings_before_work_allowance": old_uc["uc_earned_income_before_work_allowance"], + "reform_annual_uc_earnings_before_work_allowance": new_uc["uc_earned_income_before_work_allowance"], + "annual_work_allowance": old_uc["uc_work_allowance"], + "baseline_earnings_above_work_allowance": old_uc["uc_earned_income"], + "reform_earnings_above_work_allowance": new_uc["uc_earned_income"], + "explanation": "Employment earnings already exceed the work allowance. The entire increase in UC net earnings is tapered at 55%; no work-allowance boundary is crossed.", + } + comparison = None + if "review_claim" in case: + comparison = { + "claim": case["review_claim"], + "matches": all(math.isclose(delta[name], amount, abs_tol=0.02, rel_tol=0) for name, amount in case["review_claim"].items()), + } + return {**case, "baseline": baseline, "reform": reformed, "change": delta, "uc_trace": trace, "review_comparison": comparison} + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", type=Path, default=Path(__file__).with_name("trading_extensions.json")) + args = parser.parse_args() + versions = {name: metadata.version(name) for name in VERSIONS} + assert versions == VERSIONS, (versions, VERSIONS) + warnings.filterwarnings("ignore", category=RuntimeWarning, message="(divide by zero|invalid value) encountered in (divide|multiply)") + warnings.filterwarnings("ignore", category=UserWarning, message="Accessing \\.values on a MicroSeries returns a plain numpy array without weights\\.") + law = parameters() + cases = [ + { + "id": "lone_parent_4000_receipts", "type": "lone_parent", "inputs": lone_parent(4_000), + "gross_receipts_supplied": True, "actual_expenses": 0, + "independent_oracle": {"baseline": {"taxable_self_employment_income": 3_000, "income_tax": 1_686}, "reform": {"taxable_self_employment_income": 1_000, "income_tax": 1_286}, "change": {"income_tax": -400, "national_insurance": 0, "universal_credit": -220, "household_net_income": 180}}, + "review_claim": {"income_tax": -400, "universal_credit": -220, "household_net_income": 180}, + }, + { + "id": "lone_parent_1500_receipts", "type": "lone_parent", "inputs": lone_parent(1_500), + "gross_receipts_supplied": True, "actual_expenses": 0, + "independent_oracle": {"baseline": {"taxable_self_employment_income": 500, "income_tax": 1_186}, "reform": {"taxable_self_employment_income": 0, "income_tax": 1_086}, "change": {"income_tax": -100, "national_insurance": 0, "universal_credit": -55, "household_net_income": 45}}, + "review_claim": {"income_tax": -100, "universal_credit": -21, "household_net_income": 79}, + }, + { + "id": "lone_parent_1500_profit_receipts_omitted", "type": "lone_parent", "inputs": lone_parent(1_500, False), + "gross_receipts_supplied": False, "actual_expenses": 0, + "independent_oracle": {"baseline": {"taxable_self_employment_income": 1_500, "income_tax": 1_386}, "reform": {"taxable_self_employment_income": 0, "income_tax": 1_086}, "change": {"income_tax": -300, "national_insurance": 0, "universal_credit": -165, "household_net_income": 135}}, + "limitation": "Omitting receipts activates the pinned model's fallback. This £300 tax reduction exceeds the legally calculated £100 with receipts supplied; the resulting net gain is £135 instead of £45.", + }, + { + "id": "sole_trader_20000_receipts_500_expenses", "type": "sole_trader", "inputs": sole_trader(), + "gross_receipts_supplied": True, "actual_expenses": 500, + "independent_oracle": {"baseline": {"taxable_self_employment_income": 19_000, "income_tax": 1_286, "ni_class_4": 385.8}, "reform": {"taxable_self_employment_income": 17_000, "income_tax": 886, "ni_class_4": 265.8}, "change": {"income_tax": -400, "national_insurance": -120, "universal_credit": 0, "household_net_income": 520}}, + "review_claim": {"income_tax": -400, "ni_class_4": -120, "household_net_income": 520}, + }, + { + "id": "sole_trader_19500_profit_receipts_omitted", "type": "sole_trader", "inputs": sole_trader(False), + "gross_receipts_supplied": False, "actual_expenses": 500, + "independent_oracle": {"baseline": {"taxable_self_employment_income": 19_500, "income_tax": 1_386, "ni_class_4": 415.8}, "reform": {"taxable_self_employment_income": 19_500, "income_tax": 1_386, "ni_class_4": 415.8}, "change": {"income_tax": 0, "national_insurance": 0, "universal_credit": 0, "household_net_income": 0}}, + "limitation": "With receipts omitted, profit exceeds both allowance amounts, so the pinned fallback applies no relief on either side. It misses the £520 gain calculated when £20,000 receipts and £500 expenses are represented.", + }, + ] + outputs = [] + for case in cases: + output = run_case(case, law) + outputs.append(output) + print(f"{case['id']}: " + json.dumps({name: round(value, 2) for name, value in output["change"].items()}), flush=True) + payload = { + "metadata": { + "generated_at_utc": datetime.now(timezone.utc).isoformat(), "model_year": YEAR, + "tax_year": "2027–28", "versions": versions, "python": platform.python_version(), + "review_url": REVIEW_URL, "review_comment_timestamp_utc": "2026-10-28T15:11:33Z", + "baseline_parameters": law, "reform": REFORM, + "scope": "Five synthetic case pairs; no population data, behavioural responses or national estimates. Annual model calculations; actual UC assessment periods and timing of tax payments can differ.", + "assumptions": "Lone parent age35 with child age4, employment as main job, £18,000 annual wages, side business with zero expenses, London/Central London private rent £12,000/year, UC and Child Benefit take-up true. Sole trader age35, full-time35hours/week, £20,000 receipts and £500 costs, no other income, owns home outright, no UC claim. Both: council tax input zero; no childcare costs, capital, disability, pensions, losses or other income. Omitted inputs otherwise retain pinned model defaults. No UC award, floor amount, work allowance, or earnings intermediate is forced.", + "oracle_tolerance_gbp": 0.02, + "forecast": forecast_provenance(), + "independent_arithmetic": "Basic-rate income tax20% above Personal Allowance£12,570; known-receipt taxable profit=max(0,receipts-max(expenses,allowance)); Class4 NI6% above£12,570; active UC award falls55% of extra UC net earnings above its unchanged work allowance. Missing-receipt outputs separately test the pinned fallback, not the legal receipt-based calculation.", + }, + "cases": outputs, + } + args.output.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n") + print(f"Verified {len(outputs)} case pairs; wrote {args.output}", flush=True) + + +if __name__ == "__main__": + main() diff --git a/analysis/uk-budget-2026-income-tax/households.csv b/analysis/uk-budget-2026-income-tax/households.csv new file mode 100644 index 000000000..1ce14b9b1 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/households.csv @@ -0,0 +1,24 @@ +id,policy,region,model_year,input_employment_income,input_savings_interest_income,input_property_income,input_property_finance_costs,input_self_employment_gross_receipts,input_self_employment_income,baseline_income_tax,baseline_savings_income_tax,baseline_savings_allowance,baseline_savings_starter_rate_income,baseline_basic_rate_savings_income,baseline_higher_rate_savings_income,baseline_add_rate_savings_income,baseline_property_income_tax,baseline_property_finance_cost_relief,baseline_taxable_property_income,baseline_trading_allowance_deduction,baseline_taxable_self_employment_income,baseline_national_insurance,baseline_ni_class_4,baseline_household_benefits,reform_income_tax,reform_savings_income_tax,reform_savings_allowance,reform_savings_starter_rate_income,reform_basic_rate_savings_income,reform_higher_rate_savings_income,reform_add_rate_savings_income,reform_property_income_tax,reform_property_finance_cost_relief,reform_taxable_property_income,reform_trading_allowance_deduction,reform_taxable_self_employment_income,reform_national_insurance,reform_ni_class_4,reform_household_benefits,change_income_tax,change_savings_income_tax,change_savings_allowance,change_savings_starter_rate_income,change_basic_rate_savings_income,change_higher_rate_savings_income,change_add_rate_savings_income,change_property_income_tax,change_property_finance_cost_relief,change_taxable_property_income,change_trading_allowance_deduction,change_taxable_self_employment_income,change_national_insurance,change_ni_class_4,change_household_benefits +saver_below_allowance,savings_property,LONDON,2027,30000,500,0,0,0,0,3486.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1394.4,0.0,0.0,3486.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1394.4,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_basic,savings_property,LONDON,2027,30000,2000,0,0,0,0,3706.0,220.0,1000.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1394.4,0.0,0.0,3726.0,240.0,1000.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1394.4,0.0,0.0,20.0,20.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_higher,savings_property,LONDON,2027,60000,2000,0,0,0,0,12062.0,630.0,500.0,0.0,0.0,1500.0,0.0,0.0,0.0,0.0,0.0,0.0,3210.6,0.0,0.0,12092.0,660.0,500.0,0.0,0.0,1500.0,0.0,0.0,0.0,0.0,0.0,0.0,3210.6,0.0,0.0,30.0,30.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_additional,savings_property,LONDON,2027,150000,2000,0,0,0,0,54643.0,940.0,0.0,0.0,0.0,0.0,2000.0,0.0,0.0,0.0,0.0,0.0,5010.6,0.0,0.0,54683.0,980.0,0.0,0.0,0.0,0.0,2000.0,0.0,0.0,0.0,0.0,0.0,5010.6,0.0,0.0,40.0,40.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_crosses_basic_higher,savings_property,LONDON,2027,49270,2000,0,0,0,0,7870.0,530.0,500.0,0.0,500.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,2936.0,0.0,0.0,7900.0,560.0,500.0,0.0,500.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,2936.0,0.0,0.0,30.0,30.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_starting_rate,savings_property,LONDON,2027,15000,4000,0,0,0,0,580.6,94.6,1000.0,2570.0,430.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,194.4,0.0,0.0,589.2,103.2,1000.0,2570.0,430.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,194.4,0.0,0.0,8.6,8.6,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +saver_scotland_higher,savings_property,SCOTLAND,2027,60000,2000,0,0,0,0,13804.94,630.0,500.0,0.0,0.0,1500.0,0.0,0.0,0.0,0.0,0.0,0.0,3210.6,0.0,0.0,13834.94,660.0,500.0,0.0,0.0,1500.0,0.0,0.0,0.0,0.0,0.0,0.0,3210.6,0.0,0.0,30.0,30.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_basic_mortgage,savings_property,LONDON,2027,30000,0,10000,4000,0,0,4806.0,0.0,1000.0,0.0,0.0,0.0,0.0,2200.0,880.0,10000.0,0.0,0.0,1394.4,0.0,0.0,4926.0,0.0,1000.0,0.0,0.0,0.0,0.0,2400.0,960.0,10000.0,0.0,0.0,1394.4,0.0,0.0,120.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,80.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_higher_mortgage,savings_property,LONDON,2027,60000,0,10000,4000,0,0,14752.0,0.0,500.0,0.0,0.0,0.0,0.0,4200.0,880.0,10000.0,0.0,0.0,3210.6,0.0,0.0,14872.0,0.0,500.0,0.0,0.0,0.0,0.0,4400.0,960.0,10000.0,0.0,0.0,3210.6,0.0,0.0,120.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,80.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_additional_mortgage,savings_property,LONDON,2027,150000,0,10000,4000,0,0,57523.0,0.0,0.0,0.0,0.0,0.0,0.0,4700.0,880.0,10000.0,0.0,0.0,5010.6,0.0,0.0,57643.0,0.0,0.0,0.0,0.0,0.0,0.0,4900.0,960.0,10000.0,0.0,0.0,5010.6,0.0,0.0,120.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,80.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_crosses_basic_higher_mortgage,savings_property,LONDON,2027,45000,0,10000,4000,0,0,8752.0,0.0,500.0,0.0,0.0,0.0,0.0,3146.0,880.0,10000.0,0.0,0.0,2594.4,0.0,0.0,8872.0,0.0,500.0,0.0,0.0,0.0,0.0,3346.0,960.0,10000.0,0.0,0.0,2594.4,0.0,0.0,120.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,80.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_mortgage_free_london,savings_property,LONDON,2027,30000,0,10000,0,0,0,5686.0,0.0,1000.0,0.0,0.0,0.0,0.0,2200.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,5886.0,0.0,1000.0,0.0,0.0,0.0,0.0,2400.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_mortgage_free_wales,savings_property,WALES,2027,30000,0,10000,0,0,0,5686.0,0.0,1000.0,0.0,0.0,0.0,0.0,2200.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,5886.0,0.0,1000.0,0.0,0.0,0.0,0.0,2400.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_mortgage_free_northern_ireland,savings_property,NORTHERN_IRELAND,2027,30000,0,10000,0,0,0,5686.0,0.0,1000.0,0.0,0.0,0.0,0.0,2200.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,5886.0,0.0,1000.0,0.0,0.0,0.0,0.0,2400.0,0.0,10000.0,0.0,0.0,1394.4,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,200.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_scotland_finance_0,savings_property,SCOTLAND,2027,60000,0,10000,0,0,0,17374.94,0.0,500.0,0.0,0.0,0.0,0.0,4200.0,0.0,10000.0,0.0,0.0,3210.6,0.0,0.0,17374.94,0.0,500.0,0.0,0.0,0.0,0.0,4200.0,0.0,10000.0,0.0,0.0,3210.6,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +landlord_scotland_finance_4000,savings_property,SCOTLAND,2027,60000,0,10000,4000,0,0,16494.94,0.0,500.0,0.0,0.0,0.0,0.0,4200.0,880.0,10000.0,0.0,0.0,3210.6,0.0,0.0,16414.94,0.0,500.0,0.0,0.0,0.0,0.0,4200.0,960.0,10000.0,0.0,0.0,3210.6,0.0,0.0,-80.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,80.0,0.0,0.0,0.0,0.0,0.0,0.0 +property_then_savings_order,savings_property,LONDON,2027,45000,2000,6000,0,0,0,8582.0,630.0,500.0,0.0,0.0,1500.0,0.0,1466.0,0.0,6000.0,0.0,0.0,2594.4,0.0,0.0,8732.0,660.0,500.0,0.0,0.0,1500.0,0.0,1586.0,0.0,6000.0,0.0,0.0,2594.4,0.0,0.0,150.0,30.0,0.0,0.0,0.0,0.0,0.0,120.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +trader_salary_30000_expenses_500,trading,LONDON,2027,30000,0,0,0,4000,3500,4086.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,3000.0,1394.4,0.0,0.0,3686.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2500.0,1000.0,1394.4,0.0,0.0,-400.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2000.0,-2000.0,0.0,0.0,0.0 +trader_salary_30000_expenses_2500,trading,LONDON,2027,30000,0,0,0,4000,1500,3786.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1500.0,1394.4,0.0,0.0,3686.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,1000.0,1394.4,0.0,0.0,-100.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,-500.0,0.0,0.0,0.0 +trader_salary_30000_expenses_3500,trading,LONDON,2027,30000,0,0,0,4000,500,3586.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,1394.4,0.0,0.0,3586.0,0.0,1000.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,1394.4,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +trader_salary_60000_expenses_500,trading,LONDON,2027,60000,0,0,0,4000,3500,12632.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,3000.0,3210.6,0.0,0.0,11832.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2500.0,1000.0,3210.6,0.0,0.0,-800.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2000.0,-2000.0,0.0,0.0,0.0 +trader_salary_60000_expenses_2500,trading,LONDON,2027,60000,0,0,0,4000,1500,12032.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1500.0,3210.6,0.0,0.0,11832.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,1000.0,3210.6,0.0,0.0,-200.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,-500.0,0.0,0.0,0.0 +trader_salary_60000_expenses_3500,trading,LONDON,2027,60000,0,0,0,4000,500,11632.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,3210.6,0.0,0.0,11632.0,0.0,500.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,500.0,3210.6,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/analysis/uk-budget-2026-income-tax/households.json b/analysis/uk-budget-2026-income-tax/households.json new file mode 100644 index 000000000..c40b4fca3 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/households.json @@ -0,0 +1,2786 @@ +{ + "metadata": { + "generated_at_utc": "2026-10-28T16:18:33.153156+00:00", + "tax_year": "2027–28", + "model_year": 2027, + "versions": { + "policyengine": "6.11.1", + "policyengine-uk": "2.151.0", + "policyengine-core": "3.33.3" + }, + "python": "3.13.14", + "dashboard_comparison": { + "pull_request": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/290", + "commit": "b50787aa75ef5aed36b822c973afa6b569464d55", + "source_file_url": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/b50787aa75ef5aed36b822c973afa6b569464d55/src/uk_budget_data/reforms.py", + "compared_file": "src/uk_budget_data/reforms.py", + "baseline_parameters": { + "gov.hmrc.income_tax.rates.savings.basic": 0.22, + "gov.hmrc.income_tax.rates.savings.higher": 0.42, + "gov.hmrc.income_tax.rates.savings.additional": 0.47, + "gov.hmrc.income_tax.rates.property.basic": 0.22, + "gov.hmrc.income_tax.rates.property.higher": 0.42, + "gov.hmrc.income_tax.rates.property.additional": 0.47, + "gov.hmrc.income_tax.allowances.trading_allowance": 1000 + }, + "reform_parameters": { + "gov.hmrc.income_tax.rates.savings.basic": 0.24, + "gov.hmrc.income_tax.rates.savings.higher": 0.44, + "gov.hmrc.income_tax.rates.savings.additional": 0.49, + "gov.hmrc.income_tax.rates.property.basic": 0.24, + "gov.hmrc.income_tax.rates.property.higher": 0.44, + "gov.hmrc.income_tax.rates.property.additional": 0.49, + "gov.hmrc.income_tax.allowances.trading_allowance": 3000 + }, + "dashboard_builder_verified": false, + "comparison": "Independent reform dictionaries and baseline parameters verified. Optional dashboard-builder comparison not requested; immutable source reference recorded above." + }, + "scope": "Synthetic single adults age 35; no microdata, no behavioural responses or national estimates. Income and expenses held fixed; tax liabilities, not full household net-income changes.", + "assumptions": "No children, pensions, Gift Aid, student loans, capital gains, other tax reliefs, property losses or carried-forward finance costs. Savings are outside ISAs. Trading receipts and profit are both supplied; no connected-party receipts or partnership income. All example benefit totals are checked to be zero.", + "oracle_tolerance_gbp": 0.02, + "forecast": { + "dashboard_commit": "640426575270224db9b04d6c94d30e264a347be2", + "source": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/640426575270224db9b04d6c94d30e264a347be2/src/uk_budget_data/forecast/obr_october_2026.json", + "forecast_file_git_blob": "b504a48fffb93714ff358d869cad712b6daea20e", + "forecast_module_git_blob": "b2ca186b6fd514f334ced11934d38b256e6d2127", + "forecast_file_sha256": "dc039d30660d17f30a45e49538dbd22953e02bd4f6b63eda2eaebcf8252baf54", + "baseline_and_reform": true, + "nominal_household_inputs": "Held fixed in 2027; the forecast updates model parameters, not the supplied income amounts.", + "remaining_series": "March paths remain for cpih, non-labour income, private rent, mortgage interest, per-capita series, council tax and fuel volumes/prices, as recorded by this forecast vintage." + }, + "warning_filters": "Known household divide/invalid RuntimeWarnings and single-household model decile .values warnings only; no population weights are accessed by this generator." + }, + "reforms": { + "savings_property": { + "gov.hmrc.income_tax.rates.savings.basic": 0.24, + "gov.hmrc.income_tax.rates.savings.higher": 0.44, + "gov.hmrc.income_tax.rates.savings.additional": 0.49, + "gov.hmrc.income_tax.rates.property.basic": 0.24, + "gov.hmrc.income_tax.rates.property.higher": 0.44, + "gov.hmrc.income_tax.rates.property.additional": 0.49 + }, + "trading": { + "gov.hmrc.income_tax.allowances.trading_allowance": 3000 + } + }, + "households": [ + { + "id": "saver_below_allowance", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 30000, + "savings_interest_income": 500 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 1000, + "savings_income_tax": 0 + }, + "reform": { + "savings_allowance": 1000, + "savings_income_tax": 0 + }, + "change": { + "income_tax": 0 + } + }, + "detail": null, + "baseline": { + "income_tax": 3486.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 3486.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 0.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_basic", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 30000, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 1000, + "savings_income_tax": 220 + }, + "reform": { + "savings_allowance": 1000, + "savings_income_tax": 240 + }, + "change": { + "income_tax": 20 + } + }, + "detail": null, + "baseline": { + "income_tax": 3706.0, + "savings_income_tax": 220.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 1000.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 3726.0, + "savings_income_tax": 240.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 1000.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 20.0, + "savings_income_tax": 20.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_higher", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 60000, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 500, + "savings_income_tax": 630 + }, + "reform": { + "savings_allowance": 500, + "savings_income_tax": 660 + }, + "change": { + "income_tax": 30 + } + }, + "detail": null, + "baseline": { + "income_tax": 12062.0, + "savings_income_tax": 630.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 12092.0, + "savings_income_tax": 660.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 30.0, + "savings_income_tax": 30.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_additional", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 150000, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 0, + "savings_income_tax": 940 + }, + "reform": { + "savings_allowance": 0, + "savings_income_tax": 980 + }, + "change": { + "income_tax": 40 + } + }, + "detail": null, + "baseline": { + "income_tax": 54643.0, + "savings_income_tax": 940.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 2000.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 5010.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 54683.0, + "savings_income_tax": 980.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 2000.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 5010.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 40.0, + "savings_income_tax": 40.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_crosses_basic_higher", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 49270, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 500, + "savings_income_tax": 530 + }, + "reform": { + "savings_allowance": 500, + "savings_income_tax": 560 + }, + "change": { + "income_tax": 30 + } + }, + "detail": null, + "baseline": { + "income_tax": 7870.0, + "savings_income_tax": 530.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 500.0, + "higher_rate_savings_income": 1000.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2936.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 7900.0, + "savings_income_tax": 560.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 500.0, + "higher_rate_savings_income": 1000.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2936.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 30.0, + "savings_income_tax": 30.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_starting_rate", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 15000, + "savings_interest_income": 4000 + }, + "independent_oracle": { + "baseline": { + "savings_allowance": 1000, + "savings_income_tax": 94.6 + }, + "reform": { + "savings_allowance": 1000, + "savings_income_tax": 103.2 + }, + "change": { + "income_tax": 8.600000000000009 + } + }, + "detail": null, + "baseline": { + "income_tax": 580.6, + "savings_income_tax": 94.6, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 2570.0, + "basic_rate_savings_income": 430.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 194.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 589.2, + "savings_income_tax": 103.2, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 2570.0, + "basic_rate_savings_income": 430.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 194.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 8.6, + "savings_income_tax": 8.6, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "saver_scotland_higher", + "policy": "savings_property", + "region": "SCOTLAND", + "person": { + "employment_income": 60000, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "savings_income_tax": 630 + }, + "reform": { + "savings_income_tax": 660 + }, + "change": { + "income_tax": 30 + } + }, + "detail": null, + "baseline": { + "income_tax": 13804.94, + "savings_income_tax": 630.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 13834.94, + "savings_income_tax": 660.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 30.0, + "savings_income_tax": 30.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_basic_mortgage", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 30000, + "property_income": 10000, + "property_finance_costs": 4000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 2200, + "property_finance_cost_relief": 880, + "income_tax": 4806 + }, + "reform": { + "property_income_tax": 2400, + "property_finance_cost_relief": 960, + "income_tax": 4926 + }, + "change": { + "income_tax": 120 + } + }, + "detail": { + "gross_rent": 12000, + "actual_non_finance_expenses": 2000 + }, + "baseline": { + "income_tax": 4806.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2200.0, + "property_finance_cost_relief": 880.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 4926.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2400.0, + "property_finance_cost_relief": 960.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 120.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 80.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_higher_mortgage", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 60000, + "property_income": 10000, + "property_finance_costs": 4000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 4200, + "property_finance_cost_relief": 880, + "income_tax": 14752 + }, + "reform": { + "property_income_tax": 4400, + "property_finance_cost_relief": 960, + "income_tax": 14872 + }, + "change": { + "income_tax": 120 + } + }, + "detail": { + "gross_rent": 12000, + "actual_non_finance_expenses": 2000 + }, + "baseline": { + "income_tax": 14752.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4200.0, + "property_finance_cost_relief": 880.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 14872.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4400.0, + "property_finance_cost_relief": 960.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 120.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 80.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_additional_mortgage", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 150000, + "property_income": 10000, + "property_finance_costs": 4000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 4700, + "property_finance_cost_relief": 880, + "income_tax": 57523 + }, + "reform": { + "property_income_tax": 4900, + "property_finance_cost_relief": 960, + "income_tax": 57643 + }, + "change": { + "income_tax": 120 + } + }, + "detail": { + "gross_rent": 12000, + "actual_non_finance_expenses": 2000 + }, + "baseline": { + "income_tax": 57523.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4700.0, + "property_finance_cost_relief": 880.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 5010.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 57643.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4900.0, + "property_finance_cost_relief": 960.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 5010.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 120.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 80.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_crosses_basic_higher_mortgage", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 45000, + "property_income": 10000, + "property_finance_costs": 4000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 3146, + "property_finance_cost_relief": 880, + "income_tax": 8752 + }, + "reform": { + "property_income_tax": 3346, + "property_finance_cost_relief": 960, + "income_tax": 8872 + }, + "change": { + "income_tax": 120 + } + }, + "detail": { + "gross_rent": 12000, + "actual_non_finance_expenses": 2000 + }, + "baseline": { + "income_tax": 8752.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 3146.0, + "property_finance_cost_relief": 880.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2594.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 8872.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 3346.0, + "property_finance_cost_relief": 960.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2594.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 120.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 80.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_mortgage_free_london", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 30000, + "property_income": 10000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 2200 + }, + "reform": { + "property_income_tax": 2400 + }, + "change": { + "income_tax": 200 + } + }, + "detail": null, + "baseline": { + "income_tax": 5686.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 5886.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2400.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 200.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_mortgage_free_wales", + "policy": "savings_property", + "region": "WALES", + "person": { + "employment_income": 30000, + "property_income": 10000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 2200 + }, + "reform": { + "property_income_tax": 2400 + }, + "change": { + "income_tax": 200 + } + }, + "detail": null, + "baseline": { + "income_tax": 5686.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 5886.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2400.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 200.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_mortgage_free_northern_ireland", + "policy": "savings_property", + "region": "NORTHERN_IRELAND", + "person": { + "employment_income": 30000, + "property_income": 10000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 2200 + }, + "reform": { + "property_income_tax": 2400 + }, + "change": { + "income_tax": 200 + } + }, + "detail": null, + "baseline": { + "income_tax": 5686.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 5886.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 2400.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 200.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_scotland_finance_0", + "policy": "savings_property", + "region": "SCOTLAND", + "person": { + "employment_income": 60000, + "property_income": 10000, + "property_finance_costs": 0 + }, + "independent_oracle": { + "change": { + "property_income_tax": 0, + "property_finance_cost_relief": 0.0, + "income_tax": 0 + } + }, + "detail": "Scottish property rates do not change; the UK-wide finance-cost credit rate does.", + "baseline": { + "income_tax": 17374.94, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 17374.94, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4200.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 0.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "landlord_scotland_finance_4000", + "policy": "savings_property", + "region": "SCOTLAND", + "person": { + "employment_income": 60000, + "property_income": 10000, + "property_finance_costs": 4000 + }, + "independent_oracle": { + "change": { + "property_income_tax": 0, + "property_finance_cost_relief": 80.0, + "income_tax": -80 + } + }, + "detail": "Scottish property rates do not change; the UK-wide finance-cost credit rate does.", + "baseline": { + "income_tax": 16494.94, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4200.0, + "property_finance_cost_relief": 880.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 16414.94, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 4200.0, + "property_finance_cost_relief": 960.0, + "taxable_property_income": 10000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": -80.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 80.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "property_then_savings_order", + "policy": "savings_property", + "region": "LONDON", + "person": { + "employment_income": 45000, + "property_income": 6000, + "savings_interest_income": 2000 + }, + "independent_oracle": { + "baseline": { + "property_income_tax": 1466, + "savings_income_tax": 630, + "income_tax": 8582 + }, + "reform": { + "property_income_tax": 1586, + "savings_income_tax": 660, + "income_tax": 8732 + }, + "change": { + "income_tax": 150 + } + }, + "detail": null, + "baseline": { + "income_tax": 8582.0, + "savings_income_tax": 630.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 1466.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 6000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2594.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 8732.0, + "savings_income_tax": 660.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 1500.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 1586.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 6000.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 2594.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 150.0, + "savings_income_tax": 30.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 120.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_30000_expenses_500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 30000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 3500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 3000, + "income_tax": 4086.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 1000, + "income_tax": 3686.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": -400.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 500 + }, + "baseline": { + "income_tax": 4086.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": 3000.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 3686.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 2500.0, + "taxable_self_employment_income": 1000.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": -400.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 2000.0, + "taxable_self_employment_income": -2000.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_30000_expenses_2500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 30000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 1500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 1500, + "income_tax": 3786.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 1000, + "income_tax": 3686.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": -100.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 2500 + }, + "baseline": { + "income_tax": 3786.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 1500.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 3686.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": 1000.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": -100.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": -500.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_30000_expenses_3500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 30000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 500, + "income_tax": 3586.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 500, + "income_tax": 3586.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": 0.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 3500 + }, + "baseline": { + "income_tax": 3586.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 500.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 3586.0, + "savings_income_tax": 0.0, + "savings_allowance": 1000.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 500.0, + "national_insurance": 1394.4, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 0.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_60000_expenses_500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 60000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 3500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 3000, + "income_tax": 12632.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 1000, + "income_tax": 11832.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": -800.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 500 + }, + "baseline": { + "income_tax": 12632.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": 3000.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 11832.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 2500.0, + "taxable_self_employment_income": 1000.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": -800.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 2000.0, + "taxable_self_employment_income": -2000.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_60000_expenses_2500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 60000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 1500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 1500, + "income_tax": 12032.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 1000, + "income_tax": 11832.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": -200.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 2500 + }, + "baseline": { + "income_tax": 12032.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 1500.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 11832.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": 1000.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": -200.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 500.0, + "taxable_self_employment_income": -500.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + }, + { + "id": "trader_salary_60000_expenses_3500", + "policy": "trading", + "region": "LONDON", + "person": { + "employment_income": 60000, + "self_employment_gross_receipts": 4000, + "self_employment_income": 500 + }, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 500, + "income_tax": 11632.0, + "ni_class_4": 0 + }, + "reform": { + "taxable_self_employment_income": 500, + "income_tax": 11632.0, + "ni_class_4": 0 + }, + "change": { + "income_tax": 0.0, + "national_insurance": 0 + } + }, + "detail": { + "gross_receipts": 4000, + "actual_expenses": 3500 + }, + "baseline": { + "income_tax": 11632.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 500.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "reform": { + "income_tax": 11632.0, + "savings_income_tax": 0.0, + "savings_allowance": 500.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 500.0, + "national_insurance": 3210.6, + "ni_class_4": 0.0, + "household_benefits": 0.0 + }, + "change": { + "income_tax": 0.0, + "savings_income_tax": 0.0, + "savings_allowance": 0.0, + "savings_starter_rate_income": 0.0, + "basic_rate_savings_income": 0.0, + "higher_rate_savings_income": 0.0, + "add_rate_savings_income": 0.0, + "property_income_tax": 0.0, + "property_finance_cost_relief": 0.0, + "taxable_property_income": 0.0, + "trading_allowance_deduction": 0.0, + "taxable_self_employment_income": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "household_benefits": 0.0 + } + } + ], + "savings_interest_curve": [ + { + "interest": 500, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 0.0, + "higher_reform_tax": 0.0, + "higher_tax_increase": 0.0 + }, + { + "interest": 600, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 42.0, + "higher_reform_tax": 44.0, + "higher_tax_increase": 2.0 + }, + { + "interest": 700, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 84.0, + "higher_reform_tax": 88.0, + "higher_tax_increase": 4.0 + }, + { + "interest": 800, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 126.0, + "higher_reform_tax": 132.0, + "higher_tax_increase": 6.0 + }, + { + "interest": 900, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 168.0, + "higher_reform_tax": 176.0, + "higher_tax_increase": 8.0 + }, + { + "interest": 1000, + "basic_baseline_tax": 0.0, + "basic_reform_tax": 0.0, + "basic_tax_increase": 0.0, + "higher_baseline_tax": 210.0, + "higher_reform_tax": 220.0, + "higher_tax_increase": 10.0 + }, + { + "interest": 1100, + "basic_baseline_tax": 22.0, + "basic_reform_tax": 24.0, + "basic_tax_increase": 2.0, + "higher_baseline_tax": 252.0, + "higher_reform_tax": 264.0, + "higher_tax_increase": 12.0 + }, + { + "interest": 1200, + "basic_baseline_tax": 44.0, + "basic_reform_tax": 48.0, + "basic_tax_increase": 4.0, + "higher_baseline_tax": 294.0, + "higher_reform_tax": 308.0, + "higher_tax_increase": 14.0 + }, + { + "interest": 1300, + "basic_baseline_tax": 66.0, + "basic_reform_tax": 72.0, + "basic_tax_increase": 6.0, + "higher_baseline_tax": 336.0, + "higher_reform_tax": 352.0, + "higher_tax_increase": 16.0 + }, + { + "interest": 1400, + "basic_baseline_tax": 88.0, + "basic_reform_tax": 96.0, + "basic_tax_increase": 8.0, + "higher_baseline_tax": 378.0, + "higher_reform_tax": 396.0, + "higher_tax_increase": 18.0 + }, + { + "interest": 1500, + "basic_baseline_tax": 110.0, + "basic_reform_tax": 120.0, + "basic_tax_increase": 10.0, + "higher_baseline_tax": 420.0, + "higher_reform_tax": 440.0, + "higher_tax_increase": 20.0 + }, + { + "interest": 1600, + "basic_baseline_tax": 132.0, + "basic_reform_tax": 144.0, + "basic_tax_increase": 12.0, + "higher_baseline_tax": 462.0, + "higher_reform_tax": 484.0, + "higher_tax_increase": 22.0 + }, + { + "interest": 1700, + "basic_baseline_tax": 154.0, + "basic_reform_tax": 168.0, + "basic_tax_increase": 14.0, + "higher_baseline_tax": 504.0, + "higher_reform_tax": 528.0, + "higher_tax_increase": 24.0 + }, + { + "interest": 1800, + "basic_baseline_tax": 176.0, + "basic_reform_tax": 192.0, + "basic_tax_increase": 16.0, + "higher_baseline_tax": 546.0, + "higher_reform_tax": 572.0, + "higher_tax_increase": 26.0 + }, + { + "interest": 1900, + "basic_baseline_tax": 198.0, + "basic_reform_tax": 216.0, + "basic_tax_increase": 18.0, + "higher_baseline_tax": 588.0, + "higher_reform_tax": 616.0, + "higher_tax_increase": 28.0 + }, + { + "interest": 2000, + "basic_baseline_tax": 220.0, + "basic_reform_tax": 240.0, + "basic_tax_increase": 20.0, + "higher_baseline_tax": 630.0, + "higher_reform_tax": 660.0, + "higher_tax_increase": 30.0 + }, + { + "interest": 2100, + "basic_baseline_tax": 242.0, + "basic_reform_tax": 264.0, + "basic_tax_increase": 22.0, + "higher_baseline_tax": 672.0, + "higher_reform_tax": 704.0, + "higher_tax_increase": 32.0 + }, + { + "interest": 2200, + "basic_baseline_tax": 264.0, + "basic_reform_tax": 288.0, + "basic_tax_increase": 24.0, + "higher_baseline_tax": 714.0, + "higher_reform_tax": 748.0, + "higher_tax_increase": 34.0 + }, + { + "interest": 2300, + "basic_baseline_tax": 286.0, + "basic_reform_tax": 312.0, + "basic_tax_increase": 26.0, + "higher_baseline_tax": 756.0, + "higher_reform_tax": 792.0, + "higher_tax_increase": 36.0 + }, + { + "interest": 2400, + "basic_baseline_tax": 308.0, + "basic_reform_tax": 336.0, + "basic_tax_increase": 28.0, + "higher_baseline_tax": 798.0, + "higher_reform_tax": 836.0, + "higher_tax_increase": 38.0 + }, + { + "interest": 2500, + "basic_baseline_tax": 330.0, + "basic_reform_tax": 360.0, + "basic_tax_increase": 30.0, + "higher_baseline_tax": 840.0, + "higher_reform_tax": 880.0, + "higher_tax_increase": 40.0 + }, + { + "interest": 2600, + "basic_baseline_tax": 352.0, + "basic_reform_tax": 384.0, + "basic_tax_increase": 32.0, + "higher_baseline_tax": 882.0, + "higher_reform_tax": 924.0, + "higher_tax_increase": 42.0 + }, + { + "interest": 2700, + "basic_baseline_tax": 374.0, + "basic_reform_tax": 408.0, + "basic_tax_increase": 34.0, + "higher_baseline_tax": 924.0, + "higher_reform_tax": 968.0, + "higher_tax_increase": 44.0 + }, + { + "interest": 2800, + "basic_baseline_tax": 396.0, + "basic_reform_tax": 432.0, + "basic_tax_increase": 36.0, + "higher_baseline_tax": 966.0, + "higher_reform_tax": 1012.0, + "higher_tax_increase": 46.0 + }, + { + "interest": 2900, + "basic_baseline_tax": 418.0, + "basic_reform_tax": 456.0, + "basic_tax_increase": 38.0, + "higher_baseline_tax": 1008.0, + "higher_reform_tax": 1056.0, + "higher_tax_increase": 48.0 + }, + { + "interest": 3000, + "basic_baseline_tax": 440.0, + "basic_reform_tax": 480.0, + "basic_tax_increase": 40.0, + "higher_baseline_tax": 1050.0, + "higher_reform_tax": 1100.0, + "higher_tax_increase": 50.0 + }, + { + "interest": 3100, + "basic_baseline_tax": 462.0, + "basic_reform_tax": 504.0, + "basic_tax_increase": 42.0, + "higher_baseline_tax": 1092.0, + "higher_reform_tax": 1144.0, + "higher_tax_increase": 52.0 + }, + { + "interest": 3200, + "basic_baseline_tax": 484.0, + "basic_reform_tax": 528.0, + "basic_tax_increase": 44.0, + "higher_baseline_tax": 1134.0, + "higher_reform_tax": 1188.0, + "higher_tax_increase": 54.0 + }, + { + "interest": 3300, + "basic_baseline_tax": 506.0, + "basic_reform_tax": 552.0, + "basic_tax_increase": 46.0, + "higher_baseline_tax": 1176.0, + "higher_reform_tax": 1232.0, + "higher_tax_increase": 56.0 + }, + { + "interest": 3400, + "basic_baseline_tax": 528.0, + "basic_reform_tax": 576.0, + "basic_tax_increase": 48.0, + "higher_baseline_tax": 1218.0, + "higher_reform_tax": 1276.0, + "higher_tax_increase": 58.0 + }, + { + "interest": 3500, + "basic_baseline_tax": 550.0, + "basic_reform_tax": 600.0, + "basic_tax_increase": 50.0, + "higher_baseline_tax": 1260.0, + "higher_reform_tax": 1320.0, + "higher_tax_increase": 60.0 + }, + { + "interest": 3600, + "basic_baseline_tax": 572.0, + "basic_reform_tax": 624.0, + "basic_tax_increase": 52.0, + "higher_baseline_tax": 1302.0, + "higher_reform_tax": 1364.0, + "higher_tax_increase": 62.0 + }, + { + "interest": 3700, + "basic_baseline_tax": 594.0, + "basic_reform_tax": 648.0, + "basic_tax_increase": 54.0, + "higher_baseline_tax": 1344.0, + "higher_reform_tax": 1408.0, + "higher_tax_increase": 64.0 + }, + { + "interest": 3800, + "basic_baseline_tax": 616.0, + "basic_reform_tax": 672.0, + "basic_tax_increase": 56.0, + "higher_baseline_tax": 1386.0, + "higher_reform_tax": 1452.0, + "higher_tax_increase": 66.0 + }, + { + "interest": 3900, + "basic_baseline_tax": 638.0, + "basic_reform_tax": 696.0, + "basic_tax_increase": 58.0, + "higher_baseline_tax": 1428.0, + "higher_reform_tax": 1496.0, + "higher_tax_increase": 68.0 + }, + { + "interest": 4000, + "basic_baseline_tax": 660.0, + "basic_reform_tax": 720.0, + "basic_tax_increase": 60.0, + "higher_baseline_tax": 1470.0, + "higher_reform_tax": 1540.0, + "higher_tax_increase": 70.0 + }, + { + "interest": 4100, + "basic_baseline_tax": 682.0, + "basic_reform_tax": 744.0, + "basic_tax_increase": 62.0, + "higher_baseline_tax": 1512.0, + "higher_reform_tax": 1584.0, + "higher_tax_increase": 72.0 + }, + { + "interest": 4200, + "basic_baseline_tax": 704.0, + "basic_reform_tax": 768.0, + "basic_tax_increase": 64.0, + "higher_baseline_tax": 1554.0, + "higher_reform_tax": 1628.0, + "higher_tax_increase": 74.0 + }, + { + "interest": 4300, + "basic_baseline_tax": 726.0, + "basic_reform_tax": 792.0, + "basic_tax_increase": 66.0, + "higher_baseline_tax": 1596.0, + "higher_reform_tax": 1672.0, + "higher_tax_increase": 76.0 + }, + { + "interest": 4400, + "basic_baseline_tax": 748.0, + "basic_reform_tax": 816.0, + "basic_tax_increase": 68.0, + "higher_baseline_tax": 1638.0, + "higher_reform_tax": 1716.0, + "higher_tax_increase": 78.0 + }, + { + "interest": 4500, + "basic_baseline_tax": 770.0, + "basic_reform_tax": 840.0, + "basic_tax_increase": 70.0, + "higher_baseline_tax": 1680.0, + "higher_reform_tax": 1760.0, + "higher_tax_increase": 80.0 + }, + { + "interest": 4600, + "basic_baseline_tax": 792.0, + "basic_reform_tax": 864.0, + "basic_tax_increase": 72.0, + "higher_baseline_tax": 1722.0, + "higher_reform_tax": 1804.0, + "higher_tax_increase": 82.0 + }, + { + "interest": 4700, + "basic_baseline_tax": 814.0, + "basic_reform_tax": 888.0, + "basic_tax_increase": 74.0, + "higher_baseline_tax": 1764.0, + "higher_reform_tax": 1848.0, + "higher_tax_increase": 84.0 + }, + { + "interest": 4800, + "basic_baseline_tax": 836.0, + "basic_reform_tax": 912.0, + "basic_tax_increase": 76.0, + "higher_baseline_tax": 1806.0, + "higher_reform_tax": 1892.0, + "higher_tax_increase": 86.0 + }, + { + "interest": 4900, + "basic_baseline_tax": 858.0, + "basic_reform_tax": 936.0, + "basic_tax_increase": 78.0, + "higher_baseline_tax": 1848.0, + "higher_reform_tax": 1936.0, + "higher_tax_increase": 88.0 + }, + { + "interest": 5000, + "basic_baseline_tax": 880.0, + "basic_reform_tax": 960.0, + "basic_tax_increase": 80.0, + "higher_baseline_tax": 1890.0, + "higher_reform_tax": 1980.0, + "higher_tax_increase": 90.0 + } + ], + "trading_receipts_curve": [ + { + "receipts": 500, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 375.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 600, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 450.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 700, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 525.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 800, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 600.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 900, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 675.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 1000, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 0, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 0.0, + "expenses_75_percent_actual_expenses": 750.0, + "expenses_75_percent_baseline_taxable_profit": 0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 1100, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 100, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 20.0, + "expenses_75_percent_actual_expenses": 825.0, + "expenses_75_percent_baseline_taxable_profit": 100, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 20.0 + }, + { + "receipts": 1200, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 200, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 40.0, + "expenses_75_percent_actual_expenses": 900.0, + "expenses_75_percent_baseline_taxable_profit": 200, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 40.0 + }, + { + "receipts": 1300, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 300, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 60.0, + "expenses_75_percent_actual_expenses": 975.0, + "expenses_75_percent_baseline_taxable_profit": 300, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 60.0 + }, + { + "receipts": 1333.3333333333333, + "no_expenses_actual_expenses": 0.0, + "no_expenses_baseline_taxable_profit": 333.33333333333326, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 66.67, + "expenses_75_percent_actual_expenses": 1000.0, + "expenses_75_percent_baseline_taxable_profit": 333.33333333333326, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 66.67 + }, + { + "receipts": 1400, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 400, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 80.0, + "expenses_75_percent_actual_expenses": 1050.0, + "expenses_75_percent_baseline_taxable_profit": 350.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 70.0 + }, + { + "receipts": 1500, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 500, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 100.0, + "expenses_75_percent_actual_expenses": 1125.0, + "expenses_75_percent_baseline_taxable_profit": 375.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 75.0 + }, + { + "receipts": 1600, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 600, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 120.0, + "expenses_75_percent_actual_expenses": 1200.0, + "expenses_75_percent_baseline_taxable_profit": 400.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 80.0 + }, + { + "receipts": 1700, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 700, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 140.0, + "expenses_75_percent_actual_expenses": 1275.0, + "expenses_75_percent_baseline_taxable_profit": 425.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 85.0 + }, + { + "receipts": 1800, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 800, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 160.0, + "expenses_75_percent_actual_expenses": 1350.0, + "expenses_75_percent_baseline_taxable_profit": 450.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 90.0 + }, + { + "receipts": 1900, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 900, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 180.0, + "expenses_75_percent_actual_expenses": 1425.0, + "expenses_75_percent_baseline_taxable_profit": 475.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 95.0 + }, + { + "receipts": 2000, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1000, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 200.0, + "expenses_75_percent_actual_expenses": 1500.0, + "expenses_75_percent_baseline_taxable_profit": 500.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 100.0 + }, + { + "receipts": 2100, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1100, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 220.0, + "expenses_75_percent_actual_expenses": 1575.0, + "expenses_75_percent_baseline_taxable_profit": 525.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 105.0 + }, + { + "receipts": 2200, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1200, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 240.0, + "expenses_75_percent_actual_expenses": 1650.0, + "expenses_75_percent_baseline_taxable_profit": 550.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 110.0 + }, + { + "receipts": 2300, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1300, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 260.0, + "expenses_75_percent_actual_expenses": 1725.0, + "expenses_75_percent_baseline_taxable_profit": 575.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 115.0 + }, + { + "receipts": 2400, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1400, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 280.0, + "expenses_75_percent_actual_expenses": 1800.0, + "expenses_75_percent_baseline_taxable_profit": 600.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 120.0 + }, + { + "receipts": 2500, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1500, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 300.0, + "expenses_75_percent_actual_expenses": 1875.0, + "expenses_75_percent_baseline_taxable_profit": 625.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 125.0 + }, + { + "receipts": 2600, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1600, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 320.0, + "expenses_75_percent_actual_expenses": 1950.0, + "expenses_75_percent_baseline_taxable_profit": 650.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 130.0 + }, + { + "receipts": 2700, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1700, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 340.0, + "expenses_75_percent_actual_expenses": 2025.0, + "expenses_75_percent_baseline_taxable_profit": 675.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 135.0 + }, + { + "receipts": 2800, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1800, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 360.0, + "expenses_75_percent_actual_expenses": 2100.0, + "expenses_75_percent_baseline_taxable_profit": 700.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 140.0 + }, + { + "receipts": 2900, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 1900, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 380.0, + "expenses_75_percent_actual_expenses": 2175.0, + "expenses_75_percent_baseline_taxable_profit": 725.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 145.0 + }, + { + "receipts": 3000, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2000, + "no_expenses_reform_taxable_profit": 0, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2250.0, + "expenses_75_percent_baseline_taxable_profit": 750.0, + "expenses_75_percent_reform_taxable_profit": 0, + "expenses_75_percent_tax_reduction": 150.0 + }, + { + "receipts": 3100, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2100, + "no_expenses_reform_taxable_profit": 100, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2325.0, + "expenses_75_percent_baseline_taxable_profit": 775.0, + "expenses_75_percent_reform_taxable_profit": 100, + "expenses_75_percent_tax_reduction": 135.0 + }, + { + "receipts": 3200, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2200, + "no_expenses_reform_taxable_profit": 200, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2400.0, + "expenses_75_percent_baseline_taxable_profit": 800.0, + "expenses_75_percent_reform_taxable_profit": 200, + "expenses_75_percent_tax_reduction": 120.0 + }, + { + "receipts": 3300, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2300, + "no_expenses_reform_taxable_profit": 300, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2475.0, + "expenses_75_percent_baseline_taxable_profit": 825.0, + "expenses_75_percent_reform_taxable_profit": 300, + "expenses_75_percent_tax_reduction": 105.0 + }, + { + "receipts": 3400, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2400, + "no_expenses_reform_taxable_profit": 400, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2550.0, + "expenses_75_percent_baseline_taxable_profit": 850.0, + "expenses_75_percent_reform_taxable_profit": 400, + "expenses_75_percent_tax_reduction": 90.0 + }, + { + "receipts": 3500, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2500, + "no_expenses_reform_taxable_profit": 500, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2625.0, + "expenses_75_percent_baseline_taxable_profit": 875.0, + "expenses_75_percent_reform_taxable_profit": 500, + "expenses_75_percent_tax_reduction": 75.0 + }, + { + "receipts": 3600, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2600, + "no_expenses_reform_taxable_profit": 600, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2700.0, + "expenses_75_percent_baseline_taxable_profit": 900.0, + "expenses_75_percent_reform_taxable_profit": 600, + "expenses_75_percent_tax_reduction": 60.0 + }, + { + "receipts": 3700, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2700, + "no_expenses_reform_taxable_profit": 700, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2775.0, + "expenses_75_percent_baseline_taxable_profit": 925.0, + "expenses_75_percent_reform_taxable_profit": 700, + "expenses_75_percent_tax_reduction": 45.0 + }, + { + "receipts": 3800, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2800, + "no_expenses_reform_taxable_profit": 800, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2850.0, + "expenses_75_percent_baseline_taxable_profit": 950.0, + "expenses_75_percent_reform_taxable_profit": 800, + "expenses_75_percent_tax_reduction": 30.0 + }, + { + "receipts": 3900, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 2900, + "no_expenses_reform_taxable_profit": 900, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 2925.0, + "expenses_75_percent_baseline_taxable_profit": 975.0, + "expenses_75_percent_reform_taxable_profit": 900, + "expenses_75_percent_tax_reduction": 15.0 + }, + { + "receipts": 4000, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3000, + "no_expenses_reform_taxable_profit": 1000, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3000.0, + "expenses_75_percent_baseline_taxable_profit": 1000.0, + "expenses_75_percent_reform_taxable_profit": 1000.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4100, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3100, + "no_expenses_reform_taxable_profit": 1100, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3075.0, + "expenses_75_percent_baseline_taxable_profit": 1025.0, + "expenses_75_percent_reform_taxable_profit": 1025.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4200, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3200, + "no_expenses_reform_taxable_profit": 1200, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3150.0, + "expenses_75_percent_baseline_taxable_profit": 1050.0, + "expenses_75_percent_reform_taxable_profit": 1050.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4300, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3300, + "no_expenses_reform_taxable_profit": 1300, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3225.0, + "expenses_75_percent_baseline_taxable_profit": 1075.0, + "expenses_75_percent_reform_taxable_profit": 1075.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4400, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3400, + "no_expenses_reform_taxable_profit": 1400, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3300.0, + "expenses_75_percent_baseline_taxable_profit": 1100.0, + "expenses_75_percent_reform_taxable_profit": 1100.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4500, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3500, + "no_expenses_reform_taxable_profit": 1500, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3375.0, + "expenses_75_percent_baseline_taxable_profit": 1125.0, + "expenses_75_percent_reform_taxable_profit": 1125.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4600, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3600, + "no_expenses_reform_taxable_profit": 1600, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3450.0, + "expenses_75_percent_baseline_taxable_profit": 1150.0, + "expenses_75_percent_reform_taxable_profit": 1150.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4700, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3700, + "no_expenses_reform_taxable_profit": 1700, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3525.0, + "expenses_75_percent_baseline_taxable_profit": 1175.0, + "expenses_75_percent_reform_taxable_profit": 1175.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4800, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3800, + "no_expenses_reform_taxable_profit": 1800, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3600.0, + "expenses_75_percent_baseline_taxable_profit": 1200.0, + "expenses_75_percent_reform_taxable_profit": 1200.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 4900, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 3900, + "no_expenses_reform_taxable_profit": 1900, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3675.0, + "expenses_75_percent_baseline_taxable_profit": 1225.0, + "expenses_75_percent_reform_taxable_profit": 1225.0, + "expenses_75_percent_tax_reduction": 0.0 + }, + { + "receipts": 5000, + "no_expenses_actual_expenses": 0, + "no_expenses_baseline_taxable_profit": 4000, + "no_expenses_reform_taxable_profit": 2000, + "no_expenses_tax_reduction": 400.0, + "expenses_75_percent_actual_expenses": 3750.0, + "expenses_75_percent_baseline_taxable_profit": 1250.0, + "expenses_75_percent_reform_taxable_profit": 1250.0, + "expenses_75_percent_tax_reduction": 0.0 + } + ], + "curve_validation": { + "range_gbp": [ + 500, + 5000 + ], + "validation_interval_gbp": 2, + "points_per_series": 2251, + "series": 4, + "liability_checks": 18008, + "interpolation_checks": 9004, + "chart_interval_gbp": 100, + "savings_breakpoints_gbp": [ + 500, + 1000 + ], + "trading_breakpoints_gbp": [ + 1000, + 1333.3333333333333, + 3000, + 4000 + ], + "chart_rows": { + "savings": 46, + "trading": 47 + }, + "maximum_model_error_gbp": 2.2737367544323206e-13, + "maximum_chart_interpolation_error_gbp": 0.0033000000000242835, + "tolerance_gbp": 0.01, + "method": "All four series checked against pe.uk at every £2; both scenarios compared with independent tax arithmetic; plotted linear interpolation compared with the engine tax changes. The non-integer expense-choice breakpoint is additionally calculated with pe.uk." + } +} diff --git a/analysis/uk-budget-2026-income-tax/obr_october_2026.json b/analysis/uk-budget-2026-income-tax/obr_october_2026.json new file mode 100644 index 000000000..b504a48ff --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/obr_october_2026.json @@ -0,0 +1,89 @@ +{ + "vintage": "OBR EFO October 2026", + "source": "OBR, Economic and fiscal outlook, October 2026, Annex A", + "source_url": "https://www.gov.uk/government/publications/october-2026-economic-and-fiscal-outlook", + "replaces": "OBR EFO March 2026, as shipped in policyengine-uk 2.151.0 (gov.economic_assumptions.yoy_growth.obr)", + "applies_to": "Every simulation the dashboard builds, baseline and reform alike (uk_budget_data.forecast.with_forecast). Applied before data load, so the dataset's projected years follow it.", + "notes": [ + "Growth rates are Table A.1 (Economy forecast, EFO page 180), percentage change on a year earlier, calendar years 2026 to 2031, keyed YYYY-01-01.YYYY-12-31. 2025 is outturn in Table A.1 and is left as shipped; after 2031 the engine's long-run path is kept.", + "The engine's March values equal the March Table A.1 rows: the October value minus the Table A.2 change since March, to within 0.1pp rounding (tests/test_forecast_basis.py).", + "Statutory uprating inputs keep their published outturns (September 2026 CPI 3.5%, May-July 2026 earnings 3.9%). Their forecast years are calendar-year growth plus the engine's forecast_gap, which still holds the March 2026 quarterly gaps except where noted below.", + "September 2027 CPI: Table A.3 (EFO page 181) gives the 2027-28 triple-lock guarantee as 3.4%, the highest of Q2 2027 earnings growth, Q3 2027 CPI and 2.5%. Q2 earnings cannot reach 3.4% (calendar-year 2027 earnings growth is 3.0%), so Q3 2027 CPI is 3.4%, equal to calendar-year 2027 CPI: the gap is 0. The March gap (+0.07pp) would have given 3.5%.", + "Every later Table A.3 triple-lock figure (2.5, 2.5, 2.5, 2.6 for 2028-29 to 2031-32) is reproduced by these series and the remaining March gaps (tests/test_forecast_basis.py).", + "Fuel duty (gov.hmrc.fuel_duty.petrol_and_diesel), added in code (uk_budget_data.forecast.fuel_duty_rpi_steps): policyengine-uk stores current law's RPI steps as values from its March RPI. Current law here is the OBR's 60.59p from April 2027 (EFO paragraph 3.19: on 1 July 2027 the 5p cut is reversed with an RPI uprating, 52.95p to 60.59p; the Budget defers that same planned RPI increase from April), then each 1 April the previous calendar year's Table A.1 RPI. The baseline and the fuel duty measure both read this one path.", + "Not updated (the OBR detailed forecast tables could not be retrieved): cpih, non_labour_income, rent, mortgage_interest, per_capita, council_tax, fuel volume and price series. They keep the March 2026 path. consumer_price_index_ahc and social_rent are derived from Table A.1 CPI (see their sources)." + ], + "parameter_changes": { + "gov.economic_assumptions.yoy_growth.obr.consumer_price_index": { + "source": "Table A.1, Inflation: CPI", + "values": { + "2026-01-01.2026-12-31": 0.031, + "2027-01-01.2027-12-31": 0.034, + "2028-01-01.2028-12-31": 0.021, + "2029-01-01.2029-12-31": 0.021, + "2030-01-01.2030-12-31": 0.02, + "2031-01-01.2031-12-31": 0.02 + } + }, + "gov.economic_assumptions.yoy_growth.obr.rpi": { + "source": "Table A.1, Inflation: RPI", + "values": { + "2026-01-01.2026-12-31": 0.036, + "2027-01-01.2027-12-31": 0.043, + "2028-01-01.2028-12-31": 0.03, + "2029-01-01.2029-12-31": 0.03, + "2030-01-01.2030-12-31": 0.023, + "2031-01-01.2031-12-31": 0.022 + } + }, + "gov.economic_assumptions.yoy_growth.obr.average_earnings": { + "source": "Table A.1, Labour market: Average weekly earnings (wages and salaries divided by employees)", + "values": { + "2026-01-01.2026-12-31": 0.037, + "2027-01-01.2027-12-31": 0.03, + "2028-01-01.2028-12-31": 0.022, + "2029-01-01.2029-12-31": 0.023, + "2030-01-01.2030-12-31": 0.025, + "2031-01-01.2031-12-31": 0.026 + } + }, + "gov.economic_assumptions.yoy_growth.obr.house_prices": { + "source": "Table A.1, Household sector: House prices", + "values": { + "2026-01-01.2026-12-31": 0.021, + "2027-01-01.2027-12-31": 0.024, + "2028-01-01.2028-12-31": 0.028, + "2029-01-01.2029-12-31": 0.028, + "2030-01-01.2030-12-31": 0.027, + "2031-01-01.2031-12-31": 0.027 + } + }, + "gov.economic_assumptions.yoy_growth.obr.consumer_price_index_ahc": { + "source": "Table A.1, CPI, as a change: PolicyEngine approximation (not an OBR series), policyengine-uk's March 2026 CPI after housing costs moved by the change in Table A.1 CPI for the same year, as the Living standards tab's October series (living_standards/forecast.py)", + "values": { + "2026-01-01.2026-12-31": 0.0297, + "2027-01-01.2027-12-31": 0.0328, + "2028-01-01.2028-12-31": 0.0204, + "2029-01-01.2029-12-31": 0.0204, + "2030-01-01.2030-12-31": 0.0192, + "2031-01-01.2031-12-31": 0.0192 + } + }, + "gov.economic_assumptions.yoy_growth.obr.social_rent": { + "source": "Table A.1, CPI: England social rent policy cap, the previous calendar year's CPI + 1% (2026 is set by September 2025 CPI outturn and kept), as the Living standards tab's October series", + "values": { + "2027-01-01.2027-12-31": 0.041, + "2028-01-01.2028-12-31": 0.044, + "2029-01-01.2029-12-31": 0.031, + "2030-01-01.2030-12-31": 0.031, + "2031-01-01.2031-12-31": 0.03 + } + }, + "gov.economic_assumptions.statutory_uprating_inputs.forecast_gap.cpi_september": { + "source": "Table A.3, 'Triple-lock' guarantee 2027-28: 3.4 (Q3 2027 CPI) minus Table A.1 calendar-year 2027 CPI 3.4", + "values": { + "2027-09-01.2028-08-31": 0.0 + } + } + } +} diff --git a/analysis/uk-budget-2026-income-tax/property-population/README.md b/analysis/uk-budget-2026-income-tax/property-population/README.md new file mode 100644 index 000000000..58e8e4462 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/README.md @@ -0,0 +1,37 @@ +# Property-only population results + +This folder supports the property article in PR #1460. It retains the approved property-only national results from dashboard PR #290 at immutable commit `637bb26c34264e0491ed182c363df751466458ed`. + +These results identify an approved branch snapshot; the snapshot has not been independently verified as the production deployment. + +## Source and verification + +- Manifest revision: 14. +- Measure and artifact: `property_income_rates_up/7bf77b35e33233e0`. +- Generation commit: `4de166f05eebbc7e501fcf39206cdc82fd199213`; the later snapshot commit does not mean that the simulation was regenerated. +- Runtime: `policyengine` 6.11.1, PolicyEngine UK 2.151.0, core 3.33.3. +- Certified national dataset: `microcosm-uk-2024-25-national-20261025T091414Z-a6299504`, SHA256 `b96a8cd625b645a409c063b1de5158532708a2f0d3c3897a794a8fb0bbd5064e`. +- Baseline and reform use the detailed October 2026 forecast. The reform changes only the property-income measure, including finance-cost relief. + +The canonical receipt validator returned no document or dashboard problems. The artifact, receipt, outputs, execution identity and approval digests match the manifest; all eight source CSV hashes match the receipt. Reconciliation is `pass` and responsiveness is `responsive`. The receipt's disclosure-floor result covers the decile, age and binned-scatter tables: the decile and age tables use a three-survey-household floor, while the binned scatter uses its separate ten-household minimum. No thin or withheld cells were recorded in those covered tables. That result does not extend to the reach, poverty or inequality outputs in `metrics.csv` or `poverty_inequality.csv`; neither file is retained here. `summary.json` retains the checks, source URLs, article values and definitions, with reach, poverty and inequality figures omitted pending separate disclosure clearance. The retained receipt and three CSVs are public national aggregates; no household records or population H5 are stored here. + +## Files and definitions + +- `budgetary_impact.csv`: annual reform-minus-baseline government balance, in £ billion. This includes tax and spending interactions and is not income tax alone. +- `winners_losers.csv`: despite its name, it contains household-weighted **mean income changes**, not winner/loser counts or shares. The article's chart uses the 2027 and 2031 decile means, retaining raw precision and rendering whole pounds. +- `distributional_impact.csv`: change in aggregate household net income divided by aggregate baseline household net income within each decile, as a percentage. It is not the mean of household percentage changes. +- `summary.json`: retains provenance, validation records, annual revenue, and decile and all-household average income changes. Reach, poverty and inequality figures are omitted pending separate disclosure clearance. No taxpayer count, affected-household count, or separate winner/loser shares are provided. + +Decile ranks are recomputed for each year from baseline, person-weighted equivalised HBAI household net income before housing costs. Negative ranking income is reset to zero, and equal-income households share a rank. The displayed averages are annual, unequivalised household-net-income changes over **all households** in each decile, including those unaffected. No top-decile revenue share is inferred from these means. + +The official comparison marks 2027–28 and 2028–29 as not comparable; its comparison values are null. The source Treasury table separately reports £35 million and £575 million, which the article shows with those flags. Later-year Treasury values are £435 million, £445 million and £455 million. The article compares PolicyEngine with the income tax line of measure 61 in the OBR's October 2026 detailed policy table (`efo-october-2026-detailed-forecast-tables-policy.xlsx`, sheet 1.1, rows 297 to 302, SHA-256 `cdcc2a06b100241bf3010bd159a4e5d43daef2348a3850797b1e88a308fd45fd`): £0, £0, £539.10 million, £394.29 million, £403.38 million and £412.24 million for 2026–27 to 2031–32. The measure's lines there total £0.23 million, £33.86 million, £575.47 million, £433.16 million, £444.91 million and £456.93 million, which Table 6.1 rounds to the nearest £5 million; the article shows that total for context. All article values round only for presentation. + +## Immutable sources + +- [Approved manifest](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/public/data/manifest.json). +- [Property receipt and aggregate CSVs](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/tree/637bb26c34264e0491ed182c363df751466458ed/public/data/artifacts/property_income_rates_up/7bf77b35e33233e0). +- [Official comparison flags](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/public/data/official_costings.json). +- [Treasury row 61 source values](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/data_inputs/treasury/sources/AB2026-T6.1.csv). +- [National calculator definitions](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/src/uk_budget_data/calculators.py). + +The other five source CSVs are not copied; their hashes remain as source-verification records in the original receipt and verification summary. No reach, poverty or inequality figures from those files are republished here. This folder is the property article's sole national-results record; withdrawn combined outputs are not published here. diff --git a/analysis/uk-budget-2026-income-tax/property-population/budgetary_impact.csv b/analysis/uk-budget-2026-income-tax/property-population/budgetary_impact.csv new file mode 100644 index 000000000..91bc389a5 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/budgetary_impact.csv @@ -0,0 +1,7 @@ +reform_id,reform_name,year,value +property_income_rates_up,Property income tax rates up,2026,0.0 +property_income_rates_up,Property income tax rates up,2027,0.39904530993807763 +property_income_rates_up,Property income tax rates up,2028,0.41197579165650017 +property_income_rates_up,Property income tax rates up,2029,0.4294018583620151 +property_income_rates_up,Property income tax rates up,2030,0.4455556472126524 +property_income_rates_up,Property income tax rates up,2031,0.4594904420641682 diff --git a/analysis/uk-budget-2026-income-tax/property-population/distributional_impact.csv b/analysis/uk-budget-2026-income-tax/property-population/distributional_impact.csv new file mode 100644 index 000000000..d57134cf7 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/distributional_impact.csv @@ -0,0 +1,61 @@ +reform_id,reform_name,year,decile,value +property_income_rates_up,Property income tax rates up,2026,10th,0.0 +property_income_rates_up,Property income tax rates up,2026,1st,0.0 +property_income_rates_up,Property income tax rates up,2026,2nd,0.0 +property_income_rates_up,Property income tax rates up,2026,3rd,0.0 +property_income_rates_up,Property income tax rates up,2026,4th,0.0 +property_income_rates_up,Property income tax rates up,2026,5th,0.0 +property_income_rates_up,Property income tax rates up,2026,6th,0.0 +property_income_rates_up,Property income tax rates up,2026,7th,0.0 +property_income_rates_up,Property income tax rates up,2026,8th,0.0 +property_income_rates_up,Property income tax rates up,2026,9th,0.0 +property_income_rates_up,Property income tax rates up,2027,10th,-0.03642741783840644 +property_income_rates_up,Property income tax rates up,2027,1st,-0.003280773264211483 +property_income_rates_up,Property income tax rates up,2027,2nd,-0.013350311964002826 +property_income_rates_up,Property income tax rates up,2027,3rd,-0.011525877414268887 +property_income_rates_up,Property income tax rates up,2027,4th,-0.011279160134081867 +property_income_rates_up,Property income tax rates up,2027,5th,-0.008254816852157155 +property_income_rates_up,Property income tax rates up,2027,6th,-0.011073457809747176 +property_income_rates_up,Property income tax rates up,2027,7th,-0.013220674146739093 +property_income_rates_up,Property income tax rates up,2027,8th,-0.022890621117303365 +property_income_rates_up,Property income tax rates up,2027,9th,-0.028773800606848924 +property_income_rates_up,Property income tax rates up,2028,10th,-0.03682928346233305 +property_income_rates_up,Property income tax rates up,2028,1st,-0.00396262869494753 +property_income_rates_up,Property income tax rates up,2028,2nd,-0.014058514806218834 +property_income_rates_up,Property income tax rates up,2028,3rd,-0.012221464774932082 +property_income_rates_up,Property income tax rates up,2028,4th,-0.01059609327640011 +property_income_rates_up,Property income tax rates up,2028,5th,-0.008768780707967789 +property_income_rates_up,Property income tax rates up,2028,6th,-0.009981645101563434 +property_income_rates_up,Property income tax rates up,2028,7th,-0.014231064030165044 +property_income_rates_up,Property income tax rates up,2028,8th,-0.023066587924497953 +property_income_rates_up,Property income tax rates up,2028,9th,-0.028403468574895112 +property_income_rates_up,Property income tax rates up,2029,10th,-0.037463291687989404 +property_income_rates_up,Property income tax rates up,2029,1st,-0.00462627376162737 +property_income_rates_up,Property income tax rates up,2029,2nd,-0.014419047872334282 +property_income_rates_up,Property income tax rates up,2029,3rd,-0.012040446785788873 +property_income_rates_up,Property income tax rates up,2029,4th,-0.009427296076210491 +property_income_rates_up,Property income tax rates up,2029,5th,-0.011131388435235272 +property_income_rates_up,Property income tax rates up,2029,6th,-0.006430151305216017 +property_income_rates_up,Property income tax rates up,2029,7th,-0.017949330941909994 +property_income_rates_up,Property income tax rates up,2029,8th,-0.02299527301085211 +property_income_rates_up,Property income tax rates up,2029,9th,-0.028798712554661515 +property_income_rates_up,Property income tax rates up,2030,10th,-0.03773594112904485 +property_income_rates_up,Property income tax rates up,2030,1st,-0.006202837895635574 +property_income_rates_up,Property income tax rates up,2030,2nd,-0.014112826863091262 +property_income_rates_up,Property income tax rates up,2030,3rd,-0.013047267766294033 +property_income_rates_up,Property income tax rates up,2030,4th,-0.009417348651021297 +property_income_rates_up,Property income tax rates up,2030,5th,-0.011329984886564396 +property_income_rates_up,Property income tax rates up,2030,6th,-0.004905744274060609 +property_income_rates_up,Property income tax rates up,2030,7th,-0.019269608517530193 +property_income_rates_up,Property income tax rates up,2030,8th,-0.023458041818215283 +property_income_rates_up,Property income tax rates up,2030,9th,-0.028992003379557544 +property_income_rates_up,Property income tax rates up,2031,10th,-0.03787213684431531 +property_income_rates_up,Property income tax rates up,2031,1st,-0.007485439939025164 +property_income_rates_up,Property income tax rates up,2031,2nd,-0.013468208570510315 +property_income_rates_up,Property income tax rates up,2031,3rd,-0.013115738483115622 +property_income_rates_up,Property income tax rates up,2031,4th,-0.00963653500158797 +property_income_rates_up,Property income tax rates up,2031,5th,-0.011316030290009606 +property_income_rates_up,Property income tax rates up,2031,6th,-0.004412148335646833 +property_income_rates_up,Property income tax rates up,2031,7th,-0.01972931434903989 +property_income_rates_up,Property income tax rates up,2031,8th,-0.02405452667513538 +property_income_rates_up,Property income tax rates up,2031,9th,-0.028820511996950758 diff --git a/analysis/uk-budget-2026-income-tax/property-population/receipt.json b/analysis/uk-budget-2026-income-tax/property-population/receipt.json new file mode 100644 index 000000000..e797e21eb --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/receipt.json @@ -0,0 +1,174 @@ +{ + "dashboard": { + "basis": { + "calibration": { + "source": "the certified dataset pinned by the installed policyengine bundle: Microcosm UK from policyengine 6.10.1, policyengine-uk-data before it", + "status": "pre_budget", + "vintage": "as pinned by the installed bundle" + }, + "forecast": { + "source": "OBR EFO October 2026", + "status": "updated", + "vintage": "OBR Economic and fiscal outlook, October 2026 (Annex A, Tables A.1 and A.3), applied over policyengine-uk's March 2026 growth rates by src/uk_budget_data/forecast/obr_october_2026.json" + }, + "notes": "The forecast is rebased on the Budget's OBR forecast: every simulation, baseline and reform alike, is built on the October 2026 growth rates in src/uk_budget_data/forecast/obr_october_2026.json (CPI, RPI, average earnings, house prices; the September 2027 CPI gap). Series that file does not list keep the March 2026 path the installed policyengine-uk ships; the receipt records the exact model version." + }, + "composition": null, + "config_baseline": { + "binding": "content", + "kind": "current_law", + "name": "configured baseline", + "reform_sha256": null, + "representation": null + }, + "data_limits": [], + "data_limits_registry_sha256": "c48a8fe082168969b5c3e6d6689a630c9f47ac64fa9de7efd11a055d2cab1a4b", + "dataset_years": [ + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032 + ], + "description": "From 6 April 2027 the income tax rates on property income rise to 24%, 44% and 49% at the basic, higher and additional rates in England, Wales and Northern Ireland: 2 percentage points above current law, which already includes Budget 2025's rises. Finance cost relief for landlords follows the property basic rate, so rises to 24%, Scottish landlords' included. Incomes are held fixed, with no behavioural response.", + "digests": { + "execution_identity_sha256": "3db871d8c1fcebfefdfd938e39512408196621a4f5d7374ad3abd5b586dc0d03", + "outputs_sha256": "6748d5ee971f1b8428186ca778b4bd01ee1320c4e9f7cc67f34b5fc398330d47", + "receipt_sha256": "777e8839f0f7c541229eb281de5fd497819c34c07ebad865456bbb639d4806e6" + }, + "disclosure_floor": { + "checked": true, + "survey_households": 3, + "thin_cells": [], + "thin_cells_in_tables": false, + "withheld_cells": [] + }, + "files": { + "age_impact.csv": "58739a9b47fcb4e76983119c87131e88362375275fbd4fe7d8933f8772c0b02a", + "budgetary_impact.csv": "5c2abf677accb05d3616c2038823aa1a8f22897ce6dd19700a8e0444eb6ba4ec", + "distributional_impact.csv": "ea4e02c19d075a12cf4922fbca80e65cc7fbc0eaf40d6526619f6e18024318b3", + "household_scatter_binned.csv": "287909c485122279e4502489da0962d2452fcd10fda1950cfb857facc4b0751c", + "income_curve.csv": "5d8083b7dfc7782b856fac38f6632258f12c6840ed4c119d72bec7319a740916", + "metrics.csv": "a2b3d8532a12002ea330342a548ba9ef6ef2480ebd693e8716c25ad4262579ee", + "poverty_inequality.csv": "e58160aff8fa5d3d3285889c60e1deebc7ed38f2b9ea7121ad76f3f8681e2fde", + "winners_losers.csv": "25a9145c0873baf8fee612a1340414090b82ff1421839d22f8c23e5272941841" + }, + "generated_at": "2026-10-28T17:10:45.376537+00:00", + "generator_argv": [ + "/private/tmp/claude-501/-Users-vahid/59114aef-a9b7-4663-a8bc-32b2c6146551/scratchpad/final/property_income_rates_up/src/uk_budget_data/cli.py", + "generate", + "--artifacts", + "--backend", + "modal", + "--reforms", + "property_income_rates_up" + ], + "git_sha": "4de166f05eebbc7e501fcf39206cdc82fd199213", + "key": "property_income_rates_up", + "measure_ids": [ + "property_income_rates_up" + ], + "member_outputs_sha256": null, + "members": null, + "model_limits": [], + "model_limits_registry_sha256": "9d3479f1f5ac859ab6bd2644aaff443a29c0dad3f2944b1ef98866028f9d4b89", + "modifier_templates": { + "baseline": [], + "reform": [] + }, + "name": "Property income tax rates up", + "publishable": true, + "reasons": [], + "receipt_source": "policyengine==6.11.1", + "tree_clean": true, + "unsupported_years": [] + }, + "execution_receipt": { + "baseline": { + "binding": "content", + "kind": "current_law", + "name": "property_income_rates_up baseline" + }, + "certificate": { + "bundle_version": "6.11.1", + "certificate_sha256": "f2e6fc9faafab32b50c1c76067fb070ae9686b6f375e44417776de16e9c3521f", + "certificate_source": "packaged", + "certified_by": "policyengine.py bundle certification", + "certified_dataset_sha256": "b96a8cd625b645a409c063b1de5158532708a2f0d3c3897a794a8fb0bbd5064e", + "certified_for_core_version": "3.33.3", + "certified_for_model_version": "2.151.0", + "compatibility_basis": "built_with_model_package", + "country_id": "uk", + "tro_composition_fingerprint": "ec8e6c4194b5e1ec0acd64c8718d0eecb6b41648b53f0b453c425b516e5a4489" + }, + "certification_status": "certified", + "core": { + "name": "policyengine-core", + "version": "3.33.3" + }, + "country_id": "uk", + "data": { + "build_id": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "build_model_version": "2.151.0", + "data_package": "microcosm-data", + "dataset": "microcosm_uk_2024_25", + "dataset_revision": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "dataset_sha256": "b96a8cd625b645a409c063b1de5158532708a2f0d3c3897a794a8fb0bbd5064e", + "dataset_uri": "hf://policyengine/populace-uk-private/microcosm_uk_2024_25.h5@microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "release_manifest_revision": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "release_version": "0.1.0" + }, + "fiscal_year": { + "convention": "uk_fiscal_year", + "parameter_annualisation": "policyengine-uk/fiscal-year-parameters", + "period_start": "04-06", + "year_label": "start_year" + }, + "model": { + "name": "policyengine-uk", + "version": "2.151.0" + }, + "outputs_sha256": "6748d5ee971f1b8428186ca778b4bd01ee1320c4e9f7cc67f34b5fc398330d47", + "receipt_type": "policyengine.execution_receipt", + "reform": { + "binding": "content", + "kind": "reform", + "name": "property_income_rates_up", + "reform_sha256": "d46bf10b10b298db4059d7b6a2dccac7997e09afec0a88542c2059ea70646aa0", + "representation": "policyengine-uk.scenario/v1" + }, + "runtime": { + "platform": "linux", + "python_version": "3.13.3" + }, + "schema_version": 1, + "supported_years": [ + 2024, + 2025, + 2026, + 2027, + 2028, + 2029, + 2030, + 2031, + 2032 + ], + "wrapper": { + "name": "policyengine", + "version": "6.11.1" + }, + "years": [ + 2026, + 2027, + 2028, + 2029, + 2030, + 2031 + ] + }, + "schema": "uk-budget-dashboard/artifact-receipt/v1" +} diff --git a/analysis/uk-budget-2026-income-tax/property-population/summary.json b/analysis/uk-budget-2026-income-tax/property-population/summary.json new file mode 100644 index 000000000..2aed7ea8c --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/summary.json @@ -0,0 +1,427 @@ +{ + "schema": "property-blog/verified-dashboard-snapshot/v1", + "source": { + "repository": "PolicyEngine/uk-autumn-budget-dashboard-2026", + "snapshot_commit": "637bb26c34264e0491ed182c363df751466458ed", + "snapshot_status": "Approved single-measure artifact in dashboard PR290; not independently verified as a production deployment", + "manifest_revision": 14, + "manifest_sha256": "b26a5bd5542157bd23317befd9f6814f33ca610d53e644de18c06db3de1a3ea3", + "manifest_updated_at": "2026-10-28T18:29:07.541727+00:00", + "manifest_url": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/public/data/manifest.json", + "artifact_path": "artifacts/property_income_rates_up/7bf77b35e33233e0", + "artifact_sha256": "7bf77b35e33233e0f8174f4be78c7bd6e4eca46f95f1f72b100a68f19280dcfd", + "receipt_sha256": "777e8839f0f7c541229eb281de5fd497819c34c07ebad865456bbb639d4806e6", + "outputs_sha256": "6748d5ee971f1b8428186ca778b4bd01ee1320c4e9f7cc67f34b5fc398330d47", + "execution_identity_sha256": "3db871d8c1fcebfefdfd938e39512408196621a4f5d7374ad3abd5b586dc0d03", + "receipt_url": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/637bb26c34264e0491ed182c363df751466458ed/public/data/artifacts/property_income_rates_up/7bf77b35e33233e0/receipt.json", + "approval": { + "artifact_sha256": "7bf77b35e33233e0f8174f4be78c7bd6e4eca46f95f1f72b100a68f19280dcfd", + "at": "2026-10-28T18:29:07.541217+00:00", + "by": "vahid-ahmadi", + "outputs_sha256": "6748d5ee971f1b8428186ca778b4bd01ee1320c4e9f7cc67f34b5fc398330d47" + }, + "generation_commit": "4de166f05eebbc7e501fcf39206cdc82fd199213", + "generated_at": "2026-10-28T17:10:45.376537+00:00", + "basis": { + "calibration": { + "source": "the certified dataset pinned by the installed policyengine bundle: Microcosm UK from policyengine 6.10.1, policyengine-uk-data before it", + "status": "pre_budget", + "vintage": "as pinned by the installed bundle" + }, + "forecast": { + "source": "OBR EFO October 2026", + "status": "updated", + "vintage": "OBR Economic and fiscal outlook, October 2026 (Annex A, Tables A.1 and A.3), applied over policyengine-uk's March 2026 growth rates by src/uk_budget_data/forecast/obr_october_2026.json" + }, + "notes": "The forecast is rebased on the Budget's OBR forecast: every simulation, baseline and reform alike, is built on the October 2026 growth rates in src/uk_budget_data/forecast/obr_october_2026.json (CPI, RPI, average earnings, house prices; the September 2027 CPI gap). Series that file does not list keep the March 2026 path the installed policyengine-uk ships; the receipt records the exact model version." + }, + "versions": { + "wrapper": { + "name": "policyengine", + "version": "6.11.1" + }, + "model": { + "name": "policyengine-uk", + "version": "2.151.0" + }, + "core": { + "name": "policyengine-core", + "version": "3.33.3" + } + }, + "data": { + "build_id": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "build_model_version": "2.151.0", + "data_package": "microcosm-data", + "dataset": "microcosm_uk_2024_25", + "dataset_revision": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "dataset_sha256": "b96a8cd625b645a409c063b1de5158532708a2f0d3c3897a794a8fb0bbd5064e", + "dataset_uri": "hf://policyengine/populace-uk-private/microcosm_uk_2024_25.h5@microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "release_manifest_revision": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "release_version": "0.1.0" + }, + "fiscal_year": { + "convention": "uk_fiscal_year", + "parameter_annualisation": "policyengine-uk/fiscal-year-parameters", + "period_start": "04-06", + "year_label": "start_year" + } + }, + "verification": { + "canonical_document_problems": [], + "canonical_dashboard_problems": [], + "artifact_digest_matches_manifest": true, + "approval_binds_artifact_and_outputs": true, + "entry_and_receipt_digests_match": true, + "file_hashes": { + "age_impact.csv": { + "sha256": "58739a9b47fcb4e76983119c87131e88362375275fbd4fe7d8933f8772c0b02a", + "verified": true + }, + "budgetary_impact.csv": { + "sha256": "5c2abf677accb05d3616c2038823aa1a8f22897ce6dd19700a8e0444eb6ba4ec", + "verified": true + }, + "distributional_impact.csv": { + "sha256": "ea4e02c19d075a12cf4922fbca80e65cc7fbc0eaf40d6526619f6e18024318b3", + "verified": true + }, + "household_scatter_binned.csv": { + "sha256": "287909c485122279e4502489da0962d2452fcd10fda1950cfb857facc4b0751c", + "verified": true + }, + "income_curve.csv": { + "sha256": "5d8083b7dfc7782b856fac38f6632258f12c6840ed4c119d72bec7319a740916", + "verified": true + }, + "metrics.csv": { + "sha256": "a2b3d8532a12002ea330342a548ba9ef6ef2480ebd693e8716c25ad4262579ee", + "verified": true + }, + "poverty_inequality.csv": { + "sha256": "e58160aff8fa5d3d3285889c60e1deebc7ed38f2b9ea7121ad76f3f8681e2fde", + "verified": true + }, + "winners_losers.csv": { + "sha256": "25a9145c0873baf8fee612a1340414090b82ff1421839d22f8c23e5272941841", + "verified": true + } + }, + "disclosure": { + "checked": true, + "survey_households": 3, + "thin_cells": [], + "thin_cells_in_tables": false, + "withheld_cells": [], + "covered_tables": [ + "distributional_impact", + "winners_losers", + "age_impact", + "household_scatter_binned" + ], + "coverage_note": "The three-survey-household floor covers the decile and age tables; the binned scatter uses its separate ten-household minimum. The recorded absence of thin or withheld cells applies only to these covered tables, not to reach, poverty or inequality outputs. Reach, poverty and inequality figures are omitted from this summary pending separate disclosure clearance." + }, + "data_limits": [], + "model_limits": [], + "reconciliation": { + "responsiveness_status": "responsive", + "summary_status": "pass" + }, + "file_hashes_scope": "Hashes verified against all eight CSVs in the source artifact. Only budgetary_impact.csv, distributional_impact.csv and winners_losers.csv are retained in this folder; the other source hashes do not imply that those files or all their metrics are published here.", + "retained_aggregate_files": [ + "budgetary_impact.csv", + "distributional_impact.csv", + "winners_losers.csv" + ] + }, + "definitions": { + "revenue": "Change in weighted government balance: reform gov_balance minus baseline gov_balance. Positive is a government gain. Includes tax and spending interactions; not income tax alone.", + "decile_ranking": "Recomputed from the baseline for each reported year. Deciles of person-weighted equivalised HBAI household net income before housing costs; negative ranking income is reset to zero and equal-income households share a rank.", + "decile_mean": "Weighted mean annual unequivalised household_net_income change among all households in the baseline decile, including unaffected households; household-weighted, not per person and not the mean among affected households.", + "relative_change": "Sum of weighted household income change divided by sum of weighted baseline household income within that year's baseline decile, times100; not the mean of individual percentage changes." + }, + "annual_revenue": [ + { + "year": 2026, + "fiscal_year": "2026-27", + "net_government_revenue_bn": 0.0, + "net_government_revenue_million": 0.0, + "rounded_net_government_revenue_million": 0, + "treasury_post_behavioural_revenue_bn": 0.0, + "treasury_post_behavioural_revenue_million": 0.0, + "dashboard_marks_comparable": true, + "relative_difference_pct_if_comparable": null + }, + { + "year": 2027, + "fiscal_year": "2027-28", + "net_government_revenue_bn": 0.39904530993807763, + "net_government_revenue_million": 399.04530993807765, + "rounded_net_government_revenue_million": 399, + "treasury_post_behavioural_revenue_bn": 0.035, + "treasury_post_behavioural_revenue_million": 35.0, + "dashboard_marks_comparable": false, + "relative_difference_pct_if_comparable": null + }, + { + "year": 2028, + "fiscal_year": "2028-29", + "net_government_revenue_bn": 0.41197579165650017, + "net_government_revenue_million": 411.9757916565002, + "rounded_net_government_revenue_million": 412, + "treasury_post_behavioural_revenue_bn": 0.575, + "treasury_post_behavioural_revenue_million": 575.0, + "dashboard_marks_comparable": false, + "relative_difference_pct_if_comparable": null + }, + { + "year": 2029, + "fiscal_year": "2029-30", + "net_government_revenue_bn": 0.4294018583620151, + "net_government_revenue_million": 429.4018583620151, + "rounded_net_government_revenue_million": 429, + "treasury_post_behavioural_revenue_bn": 0.435, + "treasury_post_behavioural_revenue_million": 435.0, + "dashboard_marks_comparable": true, + "relative_difference_pct_if_comparable": -1.286929112180435 + }, + { + "year": 2030, + "fiscal_year": "2030-31", + "net_government_revenue_bn": 0.4455556472126524, + "net_government_revenue_million": 445.5556472126524, + "rounded_net_government_revenue_million": 446, + "treasury_post_behavioural_revenue_bn": 0.445, + "treasury_post_behavioural_revenue_million": 445.0, + "dashboard_marks_comparable": true, + "relative_difference_pct_if_comparable": 0.1248645421690675 + }, + { + "year": 2031, + "fiscal_year": "2031-32", + "net_government_revenue_bn": 0.4594904420641682, + "net_government_revenue_million": 459.49044206416823, + "rounded_net_government_revenue_million": 459, + "treasury_post_behavioural_revenue_bn": 0.455, + "treasury_post_behavioural_revenue_million": 455.0, + "dashboard_marks_comparable": true, + "relative_difference_pct_if_comparable": 0.9869103437732285 + } + ], + "distribution_by_year": { + "2026": { + "average_household_change_gbp": { + "1": 0.0, + "10": 0.0, + "2": 0.0, + "3": 0.0, + "4": 0.0, + "5": 0.0, + "6": 0.0, + "7": 0.0, + "8": 0.0, + "9": 0.0, + "all": 0.0 + }, + "relative_household_income_change_pct": { + "10": 0.0, + "1": 0.0, + "2": 0.0, + "3": 0.0, + "4": 0.0, + "5": 0.0, + "6": 0.0, + "7": 0.0, + "8": 0.0, + "9": 0.0 + } + }, + "2027": { + "average_household_change_gbp": { + "1": -0.849537805191413, + "10": -57.73388219873782, + "2": -5.331535772669214, + "3": -5.137292004488854, + "4": -5.459680740488306, + "5": -4.476027967687162, + "6": -6.548908036603635, + "7": -8.616921384043795, + "8": -16.837105996038773, + "9": -25.074336564023735, + "all": -13.620114207766957 + }, + "relative_household_income_change_pct": { + "10": -0.03642741783840644, + "1": -0.003280773264211483, + "2": -0.013350311964002826, + "3": -0.011525877414268887, + "4": -0.011279160134081867, + "5": -0.008254816852157155, + "6": -0.011073457809747176, + "7": -0.013220674146739093, + "8": -0.022890621117303365, + "9": -0.028773800606848924 + } + }, + "2028": { + "average_household_change_gbp": { + "1": -1.0282712839047559, + "10": -59.549155329481145, + "2": -5.715677861175117, + "3": -5.584747370215322, + "4": -5.2512098656084465, + "5": -4.798992223420793, + "6": -6.028070282235387, + "7": -9.481668059696128, + "8": -17.197736512628875, + "9": -25.12637604042441, + "all": -14.00541887387593 + }, + "relative_household_income_change_pct": { + "10": -0.03682928346233305, + "1": -0.00396262869494753, + "2": -0.014058514806218834, + "3": -0.012221464774932082, + "4": -0.01059609327640011, + "5": -0.008768780707967789, + "6": -0.009981645101563434, + "7": -0.014231064030165044, + "8": -0.023066587924497953, + "9": -0.028403468574895112 + } + }, + "2029": { + "average_household_change_gbp": { + "1": -1.2188237707516856, + "10": -61.77850851299002, + "2": -5.906583275815774, + "3": -5.601067991807482, + "4": -4.7320101656624844, + "5": -6.2140821405456865, + "6": -3.9427657667675993, + "7": -12.100268466500745, + "8": -17.448636393663204, + "9": -25.887010061766002, + "all": -14.533926712827615 + }, + "relative_household_income_change_pct": { + "10": -0.037463291687989404, + "1": -0.00462627376162737, + "2": -0.014419047872334282, + "3": -0.012040446785788873, + "4": -0.009427296076210491, + "5": -0.011131388435235272, + "6": -0.006430151305216017, + "7": -0.017949330941909994, + "8": -0.02299527301085211, + "9": -0.028798712554661515 + } + }, + "2030": { + "average_household_change_gbp": { + "1": -1.6599752643717125, + "10": -63.76110972653078, + "2": -5.839922483061514, + "3": -6.16570323447446, + "4": -4.815746712350739, + "5": -6.406727790315784, + "6": -3.079084257142678, + "7": -13.212370865292934, + "8": -18.136158769994683, + "9": -26.507196831273163, + "all": -15.013106871297852 + }, + "relative_household_income_change_pct": { + "10": -0.03773594112904485, + "1": -0.006202837895635574, + "2": -0.014112826863091262, + "3": -0.013047267766294033, + "4": -0.009417348651021297, + "5": -0.011329984886564396, + "6": -0.004905744274060609, + "7": -0.019269608517530193, + "8": -0.023458041818215283, + "9": -0.028992003379557544 + } + }, + "2031": { + "average_household_change_gbp": { + "1": -2.0255155229193846, + "10": -65.56126504216287, + "2": -5.635177868688589, + "3": -6.31798337071894, + "4": -5.009629578700846, + "5": -6.514231403074363, + "6": -2.8345851636943533, + "7": -13.776544201366882, + "8": -19.013018309750667, + "9": -26.922877825449845, + "all": -15.416369573636034 + }, + "relative_household_income_change_pct": { + "10": -0.03787213684431531, + "1": -0.007485439939025164, + "2": -0.013468208570510315, + "3": -0.013115738483115622, + "4": -0.00963653500158797, + "5": -0.011316030290009606, + "6": -0.004412148335646833, + "7": -0.01972931434903989, + "8": -0.02405452667513538, + "9": -0.028820511996950758 + } + } + }, + "official_comparability": { + "2026": { + "post_behavioural": 0.0, + "static_costing": null + }, + "2027": { + "not_comparable": { + "reason": "Self Assessment tax on 2027-28 property income is mostly paid from 31 January 2029, so the Treasury's costing (on a National Accounts basis) has £35m in 2027-28 and about 1.5 years of liability in 2028-29 (£575m), while the model scores each tax year's liability. From 2029-30 the two agree within 1.5%. Table 6.1 row 61." + }, + "post_behavioural": null, + "static_costing": null + }, + "2028": { + "not_comparable": { + "reason": "Self Assessment tax on 2027-28 property income is mostly paid from 31 January 2029, so the Treasury's costing (on a National Accounts basis) has £35m in 2027-28 and about 1.5 years of liability in 2028-29 (£575m), while the model scores each tax year's liability. From 2029-30 the two agree within 1.5%. Table 6.1 row 61." + }, + "post_behavioural": null, + "static_costing": null + }, + "2029": { + "post_behavioural": 0.435, + "static_costing": null + }, + "2030": { + "post_behavioural": 0.445, + "static_costing": null + }, + "2031": { + "post_behavioural": 0.455, + "static_costing": null + } + }, + "unavailable_exports": [ + "Absolute affected-person count", + "Winner and loser shares, either nationally or by decile", + "Average change conditional on being affected", + "Income-source decomposition of the bottom decile", + "Household counts and income-tax/revenue totals by decile for revenue-concentration shares" + ], + "important_limits": [ + "The approved artifact was generated at4de166f0. Its approval in the later snapshot does not prove a new post-freeze simulation or a production deployment.", + "Recheck the property artifact identity against the final released manifest before merging the blog. A changed artifact requires re-extracting and reviewing figures.", + "Do not infer loser counts or extra-taxpayer shares from the affected-household metric.", + "Do not derive revenue shares from decile average household changes without weighted counts/totals.", + "Treasury rows2027/2028 are retained from source for a labelled annual table, but the dashboard comparison deliberately suppresses them as not comparable.", + "Static model, fixed incomes/no incorporation response; Treasury figures include behavioural assumptions and a different collection profile." + ], + "omitted_outputs_pending_disclosure_clearance": [ + "People living in affected households percentage", + "Poverty changes", + "Inequality changes" + ] +} diff --git a/analysis/uk-budget-2026-income-tax/property-population/winners_losers.csv b/analysis/uk-budget-2026-income-tax/property-population/winners_losers.csv new file mode 100644 index 000000000..757099871 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/property-population/winners_losers.csv @@ -0,0 +1,67 @@ +reform_id,reform_name,year,decile,avg_change +property_income_rates_up,Property income tax rates up,2026,1,0.0 +property_income_rates_up,Property income tax rates up,2026,10,0.0 +property_income_rates_up,Property income tax rates up,2026,2,0.0 +property_income_rates_up,Property income tax rates up,2026,3,0.0 +property_income_rates_up,Property income tax rates up,2026,4,0.0 +property_income_rates_up,Property income tax rates up,2026,5,0.0 +property_income_rates_up,Property income tax rates up,2026,6,0.0 +property_income_rates_up,Property income tax rates up,2026,7,0.0 +property_income_rates_up,Property income tax rates up,2026,8,0.0 +property_income_rates_up,Property income tax rates up,2026,9,0.0 +property_income_rates_up,Property income tax rates up,2026,all,0.0 +property_income_rates_up,Property income tax rates up,2027,1,-0.849537805191413 +property_income_rates_up,Property income tax rates up,2027,10,-57.73388219873782 +property_income_rates_up,Property income tax rates up,2027,2,-5.331535772669214 +property_income_rates_up,Property income tax rates up,2027,3,-5.137292004488854 +property_income_rates_up,Property income tax rates up,2027,4,-5.459680740488306 +property_income_rates_up,Property income tax rates up,2027,5,-4.476027967687162 +property_income_rates_up,Property income tax rates up,2027,6,-6.548908036603635 +property_income_rates_up,Property income tax rates up,2027,7,-8.616921384043795 +property_income_rates_up,Property income tax rates up,2027,8,-16.837105996038773 +property_income_rates_up,Property income tax rates up,2027,9,-25.074336564023735 +property_income_rates_up,Property income tax rates up,2027,all,-13.620114207766957 +property_income_rates_up,Property income tax rates up,2028,1,-1.0282712839047559 +property_income_rates_up,Property income tax rates up,2028,10,-59.549155329481145 +property_income_rates_up,Property income tax rates up,2028,2,-5.715677861175117 +property_income_rates_up,Property income tax rates up,2028,3,-5.584747370215322 +property_income_rates_up,Property income tax rates up,2028,4,-5.2512098656084465 +property_income_rates_up,Property income tax rates up,2028,5,-4.798992223420793 +property_income_rates_up,Property income tax rates up,2028,6,-6.028070282235387 +property_income_rates_up,Property income tax rates up,2028,7,-9.481668059696128 +property_income_rates_up,Property income tax rates up,2028,8,-17.197736512628875 +property_income_rates_up,Property income tax rates up,2028,9,-25.12637604042441 +property_income_rates_up,Property income tax rates up,2028,all,-14.00541887387593 +property_income_rates_up,Property income tax rates up,2029,1,-1.2188237707516856 +property_income_rates_up,Property income tax rates up,2029,10,-61.77850851299002 +property_income_rates_up,Property income tax rates up,2029,2,-5.906583275815774 +property_income_rates_up,Property income tax rates up,2029,3,-5.601067991807482 +property_income_rates_up,Property income tax rates up,2029,4,-4.7320101656624844 +property_income_rates_up,Property income tax rates up,2029,5,-6.2140821405456865 +property_income_rates_up,Property income tax rates up,2029,6,-3.9427657667675993 +property_income_rates_up,Property income tax rates up,2029,7,-12.100268466500745 +property_income_rates_up,Property income tax rates up,2029,8,-17.448636393663204 +property_income_rates_up,Property income tax rates up,2029,9,-25.887010061766002 +property_income_rates_up,Property income tax rates up,2029,all,-14.533926712827615 +property_income_rates_up,Property income tax rates up,2030,1,-1.6599752643717125 +property_income_rates_up,Property income tax rates up,2030,10,-63.76110972653078 +property_income_rates_up,Property income tax rates up,2030,2,-5.839922483061514 +property_income_rates_up,Property income tax rates up,2030,3,-6.16570323447446 +property_income_rates_up,Property income tax rates up,2030,4,-4.815746712350739 +property_income_rates_up,Property income tax rates up,2030,5,-6.406727790315784 +property_income_rates_up,Property income tax rates up,2030,6,-3.079084257142678 +property_income_rates_up,Property income tax rates up,2030,7,-13.212370865292934 +property_income_rates_up,Property income tax rates up,2030,8,-18.136158769994683 +property_income_rates_up,Property income tax rates up,2030,9,-26.507196831273163 +property_income_rates_up,Property income tax rates up,2030,all,-15.013106871297852 +property_income_rates_up,Property income tax rates up,2031,1,-2.0255155229193846 +property_income_rates_up,Property income tax rates up,2031,10,-65.56126504216287 +property_income_rates_up,Property income tax rates up,2031,2,-5.635177868688589 +property_income_rates_up,Property income tax rates up,2031,3,-6.31798337071894 +property_income_rates_up,Property income tax rates up,2031,4,-5.009629578700846 +property_income_rates_up,Property income tax rates up,2031,5,-6.514231403074363 +property_income_rates_up,Property income tax rates up,2031,6,-2.8345851636943533 +property_income_rates_up,Property income tax rates up,2031,7,-13.776544201366882 +property_income_rates_up,Property income tax rates up,2031,8,-19.013018309750667 +property_income_rates_up,Property income tax rates up,2031,9,-26.922877825449845 +property_income_rates_up,Property income tax rates up,2031,all,-15.416369573636034 diff --git a/analysis/uk-budget-2026-income-tax/provenance.json b/analysis/uk-budget-2026-income-tax/provenance.json new file mode 100644 index 000000000..c713c69eb --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/provenance.json @@ -0,0 +1,137 @@ +{ + "as_of": "2026-10-28", + "household_year": 2027, + "package_versions": { + "policyengine": "6.11.1", + "policyengine-uk": "2.151.0", + "policyengine-core": "3.33.3" + }, + "dashboard_reforms": { + "repository": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026", + "pull_request": 290, + "commit": "b50787aa75ef5aed36b822c973afa6b569464d55", + "path": "src/uk_budget_data/reforms.py", + "measures": [ + "unearned_income_rates_up", + "trading_allowance_raise" + ] + }, + "population": { + "status": "approved_property_branch_snapshot_used_in_property_draft", + "dataset": "microcosm-uk-2024-25-national-20261025T091414Z-a6299504", + "sha256": "b96a8cd625b645a409c063b1de5158532708a2f0d3c3897a794a8fb0bbd5064e", + "certificate": "https://github.com/PolicyEngine/policyengine.py/pull/720", + "dashboard_adoption": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/237", + "raw_microdata_used_for_households": false, + "forecast": "October 2026 OBR inputs, applied to both baseline and reform when population scoring is run", + "replacement_policy": "Retain this adopted bundle until a later explicitly recorded update; do not silently use the candidate in policyengine.py PR725.", + "national_results_generated_locally": false, + "national_results_reused_from_dashboard": true, + "article_national_results_published": false, + "article_scope_note": "The property draft includes national revenue and decile averages from the approved property-only dashboard artifact recorded in property-population/. Savings and trading retain household calculations and Treasury costings only. Withdrawn combined outputs are not published. Reach, poverty and inequality figures are omitted pending separate disclosure clearance.", + "national_results_record": "property-population/summary.json", + "retained_national_measures": [ + "property_income_rates_up" + ], + "national_results_scope": "Approved property-only national revenue and decile outputs; reach, poverty and inequality outputs are omitted pending separate disclosure clearance." + }, + "treasury_costings": { + "source": "https://www.gov.uk/government/publications/budget-2026-document/budget-2026-html", + "table": "6.1", + "units": "GBP million; positive values below indicate revenue for savings/property and cost for trading", + "fiscal_years": [ + "2026-27", + "2027-28", + "2028-29", + "2029-30", + "2030-31", + "2031-32" + ], + "property_row_61_revenue": [ + 0, + 35, + 575, + 435, + 445, + 455 + ], + "savings_row_62_revenue": [ + 15, + 125, + 555, + 520, + 555, + 590 + ], + "trading_row_15_cost": [ + 0, + 0, + 225, + 165, + 175, + 180 + ] + }, + "review_follow_up": { + "trading_comment": "https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6472758764", + "savings_property_comment": "https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6472939282", + "dashboard_households_pr": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/pull/292", + "additional_household_pairs": 5, + "raw_population_accessed": false, + "additional_internal_population_numbers_adopted": false, + "final_regeneration_note": "Compare the approved property artifact recorded in property-population/ with the final released dashboard before publication; update and review the article if its execution-bound results change.", + "remaining_comments_resolution": "The property draft uses approved property-only national revenue and decile results alongside verified household examples and separate Treasury costings. Savings and trading retain household calculations and Treasury costings only. Withdrawn combined outputs and uncleared reach, poverty and inequality figures are not published." + }, + "household_forecast": { + "dashboard_commit": "640426575270224db9b04d6c94d30e264a347be2", + "forecast_file_git_blob": "b504a48fffb93714ff358d869cad712b6daea20e", + "forecast_module_git_blob": "b2ca186b6fd514f334ced11934d38b256e6d2127", + "both_baseline_and_reform": true, + "fixed_nominal_inputs": true, + "reference_pr": "https://github.com/PolicyEngine/policyengine-app-v2/pull/1457", + "reference_pr_head": "d282ef870176c81feb87175d02584121bdc50197", + "equivalence": "Exact eight-path equality with source with_forecast(None).parameter_changes was checked; synthetic households have no population data load.", + "national_outputs_regenerated": false, + "national_forecast_still_recorded_separately": true, + "forecast_file_sha256": "dc039d30660d17f30a45e49538dbd22953e02bd4f6b63eda2eaebcf8252baf54" + }, + "chart_methodology": { + "renderer_dependency": "https://github.com/PolicyEngine/policyengine-app-v2/pull/1462", + "type": "numeric line", + "chart_interval_gbp": 100, + "validation_interval_gbp": 2, + "validation_record": "curve-validation.json", + "tolerance_gbp": 0.01, + "breakpoints": "All allowance and expense-choice breakpoints within the plotted £500–£5,000 range.", + "validation_results": { + "range_gbp": [ + 500, + 5000 + ], + "validation_interval_gbp": 2, + "points_per_series": 2251, + "series": 4, + "liability_checks": 18008, + "interpolation_checks": 9004, + "chart_interval_gbp": 100, + "savings_breakpoints_gbp": [ + 500, + 1000 + ], + "trading_breakpoints_gbp": [ + 1000, + 1333.3333333333333, + 3000, + 4000 + ], + "chart_rows": { + "savings": 46, + "trading": 47 + }, + "maximum_model_error_gbp": 2.2737367544323206e-13, + "maximum_chart_interpolation_error_gbp": 0.0033000000000242835, + "tolerance_gbp": 0.01, + "method": "All four series checked against pe.uk at every £2; both scenarios compared with independent tax arithmetic; plotted linear interpolation compared with the engine tax changes. The non-integer expense-choice breakpoint is additionally calculated with pe.uk." + } + } +} diff --git a/analysis/uk-budget-2026-income-tax/requirements.txt b/analysis/uk-budget-2026-income-tax/requirements.txt new file mode 100644 index 000000000..dcb085836 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/requirements.txt @@ -0,0 +1,3 @@ +policyengine[uk]==6.11.1 +policyengine-uk==2.151.0 +policyengine-core==3.33.3 diff --git a/analysis/uk-budget-2026-income-tax/savings-interest-chart.json b/analysis/uk-budget-2026-income-tax/savings-interest-chart.json new file mode 100644 index 000000000..b471abc31 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/savings-interest-chart.json @@ -0,0 +1,273 @@ +{ + "type": "line", + "title": "Savings tax increases apply above the Personal Savings Allowance", + "subtitle": "Annual income tax increase; England, salaries £30,000 and £60,000, 2027–28", + "xKey": "interest", + "xLabel": "Annual savings interest", + "yLabel": "Extra annual income tax", + "format": { + "prefix": "£", + "decimals": 0, + "separator": true + }, + "xFormat": { + "prefix": "£", + "decimals": 0, + "separator": true + }, + "source": "PolicyEngine 6.11.1 / UK 2.151.0; synthetic adults, 2027–28; incomes held fixed.", + "series": [ + { + "key": "basic", + "name": "£30,000 salary", + "color": "negative" + }, + { + "key": "higher", + "name": "£60,000 salary", + "color": "secondary" + } + ], + "markers": [ + { + "x": 500, + "label": "£60,000 salary: savings allowance" + }, + { + "x": 1000, + "label": "£30,000 salary: savings allowance" + } + ], + "data": [ + { + "interest": 500, + "basic": 0.0, + "higher": 0.0 + }, + { + "interest": 600, + "basic": 0.0, + "higher": 2.0 + }, + { + "interest": 700, + "basic": 0.0, + "higher": 4.0 + }, + { + "interest": 800, + "basic": 0.0, + "higher": 6.0 + }, + { + "interest": 900, + "basic": 0.0, + "higher": 8.0 + }, + { + "interest": 1000, + "basic": 0.0, + "higher": 10.0 + }, + { + "interest": 1100, + "basic": 2.0, + "higher": 12.0 + }, + { + "interest": 1200, + "basic": 4.0, + "higher": 14.0 + }, + { + "interest": 1300, + "basic": 6.0, + "higher": 16.0 + }, + { + "interest": 1400, + "basic": 8.0, + "higher": 18.0 + }, + { + "interest": 1500, + "basic": 10.0, + "higher": 20.0 + }, + { + "interest": 1600, + "basic": 12.0, + "higher": 22.0 + }, + { + "interest": 1700, + "basic": 14.0, + "higher": 24.0 + }, + { + "interest": 1800, + "basic": 16.0, + "higher": 26.0 + }, + { + "interest": 1900, + "basic": 18.0, + "higher": 28.0 + }, + { + "interest": 2000, + "basic": 20.0, + "higher": 30.0 + }, + { + "interest": 2100, + "basic": 22.0, + "higher": 32.0 + }, + { + "interest": 2200, + "basic": 24.0, + "higher": 34.0 + }, + { + "interest": 2300, + "basic": 26.0, + "higher": 36.0 + }, + { + "interest": 2400, + "basic": 28.0, + "higher": 38.0 + }, + { + "interest": 2500, + "basic": 30.0, + "higher": 40.0 + }, + { + "interest": 2600, + "basic": 32.0, + "higher": 42.0 + }, + { + "interest": 2700, + "basic": 34.0, + "higher": 44.0 + }, + { + "interest": 2800, + "basic": 36.0, + "higher": 46.0 + }, + { + "interest": 2900, + "basic": 38.0, + "higher": 48.0 + }, + { + "interest": 3000, + "basic": 40.0, + "higher": 50.0 + }, + { + "interest": 3100, + "basic": 42.0, + "higher": 52.0 + }, + { + "interest": 3200, + "basic": 44.0, + "higher": 54.0 + }, + { + "interest": 3300, + "basic": 46.0, + "higher": 56.0 + }, + { + "interest": 3400, + "basic": 48.0, + "higher": 58.0 + }, + { + "interest": 3500, + "basic": 50.0, + "higher": 60.0 + }, + { + "interest": 3600, + "basic": 52.0, + "higher": 62.0 + }, + { + "interest": 3700, + "basic": 54.0, + "higher": 64.0 + }, + { + "interest": 3800, + "basic": 56.0, + "higher": 66.0 + }, + { + "interest": 3900, + "basic": 58.0, + "higher": 68.0 + }, + { + "interest": 4000, + "basic": 60.0, + "higher": 70.0 + }, + { + "interest": 4100, + "basic": 62.0, + "higher": 72.0 + }, + { + "interest": 4200, + "basic": 64.0, + "higher": 74.0 + }, + { + "interest": 4300, + "basic": 66.0, + "higher": 76.0 + }, + { + "interest": 4400, + "basic": 68.0, + "higher": 78.0 + }, + { + "interest": 4500, + "basic": 70.0, + "higher": 80.0 + }, + { + "interest": 4600, + "basic": 72.0, + "higher": 82.0 + }, + { + "interest": 4700, + "basic": 74.0, + "higher": 84.0 + }, + { + "interest": 4800, + "basic": 76.0, + "higher": 86.0 + }, + { + "interest": 4900, + "basic": 78.0, + "higher": 88.0 + }, + { + "interest": 5000, + "basic": 80.0, + "higher": 90.0 + } + ] +} diff --git a/analysis/uk-budget-2026-income-tax/savings-interest-curve.csv b/analysis/uk-budget-2026-income-tax/savings-interest-curve.csv new file mode 100644 index 000000000..ff48dc299 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/savings-interest-curve.csv @@ -0,0 +1,47 @@ +interest,basic_baseline_tax,basic_reform_tax,basic_tax_increase,higher_baseline_tax,higher_reform_tax,higher_tax_increase +500,0.0,0.0,0.0,0.0,0.0,0.0 +600,0.0,0.0,0.0,42.0,44.0,2.0 +700,0.0,0.0,0.0,84.0,88.0,4.0 +800,0.0,0.0,0.0,126.0,132.0,6.0 +900,0.0,0.0,0.0,168.0,176.0,8.0 +1000,0.0,0.0,0.0,210.0,220.0,10.0 +1100,22.0,24.0,2.0,252.0,264.0,12.0 +1200,44.0,48.0,4.0,294.0,308.0,14.0 +1300,66.0,72.0,6.0,336.0,352.0,16.0 +1400,88.0,96.0,8.0,378.0,396.0,18.0 +1500,110.0,120.0,10.0,420.0,440.0,20.0 +1600,132.0,144.0,12.0,462.0,484.0,22.0 +1700,154.0,168.0,14.0,504.0,528.0,24.0 +1800,176.0,192.0,16.0,546.0,572.0,26.0 +1900,198.0,216.0,18.0,588.0,616.0,28.0 +2000,220.0,240.0,20.0,630.0,660.0,30.0 +2100,242.0,264.0,22.0,672.0,704.0,32.0 +2200,264.0,288.0,24.0,714.0,748.0,34.0 +2300,286.0,312.0,26.0,756.0,792.0,36.0 +2400,308.0,336.0,28.0,798.0,836.0,38.0 +2500,330.0,360.0,30.0,840.0,880.0,40.0 +2600,352.0,384.0,32.0,882.0,924.0,42.0 +2700,374.0,408.0,34.0,924.0,968.0,44.0 +2800,396.0,432.0,36.0,966.0,1012.0,46.0 +2900,418.0,456.0,38.0,1008.0,1056.0,48.0 +3000,440.0,480.0,40.0,1050.0,1100.0,50.0 +3100,462.0,504.0,42.0,1092.0,1144.0,52.0 +3200,484.0,528.0,44.0,1134.0,1188.0,54.0 +3300,506.0,552.0,46.0,1176.0,1232.0,56.0 +3400,528.0,576.0,48.0,1218.0,1276.0,58.0 +3500,550.0,600.0,50.0,1260.0,1320.0,60.0 +3600,572.0,624.0,52.0,1302.0,1364.0,62.0 +3700,594.0,648.0,54.0,1344.0,1408.0,64.0 +3800,616.0,672.0,56.0,1386.0,1452.0,66.0 +3900,638.0,696.0,58.0,1428.0,1496.0,68.0 +4000,660.0,720.0,60.0,1470.0,1540.0,70.0 +4100,682.0,744.0,62.0,1512.0,1584.0,72.0 +4200,704.0,768.0,64.0,1554.0,1628.0,74.0 +4300,726.0,792.0,66.0,1596.0,1672.0,76.0 +4400,748.0,816.0,68.0,1638.0,1716.0,78.0 +4500,770.0,840.0,70.0,1680.0,1760.0,80.0 +4600,792.0,864.0,72.0,1722.0,1804.0,82.0 +4700,814.0,888.0,74.0,1764.0,1848.0,84.0 +4800,836.0,912.0,76.0,1806.0,1892.0,86.0 +4900,858.0,936.0,78.0,1848.0,1936.0,88.0 +5000,880.0,960.0,80.0,1890.0,1980.0,90.0 diff --git a/analysis/uk-budget-2026-income-tax/trading-allowance-chart.json b/analysis/uk-budget-2026-income-tax/trading-allowance-chart.json new file mode 100644 index 000000000..b98422ec4 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/trading-allowance-chart.json @@ -0,0 +1,282 @@ +{ + "type": "line", + "title": "Trading allowance: the income tax reduction depends on expenses", + "subtitle": "Annual income tax reduction; England, £30,000 salary, 2027–28", + "xKey": "receipts", + "xLabel": "Annual side-business receipts", + "yLabel": "Annual income tax reduction", + "format": { + "prefix": "£", + "decimals": 0, + "separator": true + }, + "xFormat": { + "prefix": "£", + "decimals": 0, + "separator": true + }, + "source": "PolicyEngine 6.11.1 / UK 2.151.0; synthetic adults, 2027–28; incomes held fixed.", + "series": [ + { + "key": "noExpenses", + "name": "No business expenses", + "color": "primary" + }, + { + "key": "highExpenses", + "name": "Expenses equal 75% of receipts", + "color": "secondary" + } + ], + "markers": [ + { + "x": 1000, + "label": "Current allowance" + }, + { + "x": 3000, + "label": "New allowance" + }, + { + "x": 4000, + "label": "75% expenses equal £3,000" + } + ], + "data": [ + { + "receipts": 500, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 600, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 700, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 800, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 900, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 1000, + "noExpenses": 0.0, + "highExpenses": 0.0 + }, + { + "receipts": 1100, + "noExpenses": 20.0, + "highExpenses": 20.0 + }, + { + "receipts": 1200, + "noExpenses": 40.0, + "highExpenses": 40.0 + }, + { + "receipts": 1300, + "noExpenses": 60.0, + "highExpenses": 60.0 + }, + { + "receipts": 1333.3333333333333, + "noExpenses": 66.67, + "highExpenses": 66.67 + }, + { + "receipts": 1400, + "noExpenses": 80.0, + "highExpenses": 70.0 + }, + { + "receipts": 1500, + "noExpenses": 100.0, + "highExpenses": 75.0 + }, + { + "receipts": 1600, + "noExpenses": 120.0, + "highExpenses": 80.0 + }, + { + "receipts": 1700, + "noExpenses": 140.0, + "highExpenses": 85.0 + }, + { + "receipts": 1800, + "noExpenses": 160.0, + "highExpenses": 90.0 + }, + { + "receipts": 1900, + "noExpenses": 180.0, + "highExpenses": 95.0 + }, + { + "receipts": 2000, + "noExpenses": 200.0, + "highExpenses": 100.0 + }, + { + "receipts": 2100, + "noExpenses": 220.0, + "highExpenses": 105.0 + }, + { + "receipts": 2200, + "noExpenses": 240.0, + "highExpenses": 110.0 + }, + { + "receipts": 2300, + "noExpenses": 260.0, + "highExpenses": 115.0 + }, + { + "receipts": 2400, + "noExpenses": 280.0, + "highExpenses": 120.0 + }, + { + "receipts": 2500, + "noExpenses": 300.0, + "highExpenses": 125.0 + }, + { + "receipts": 2600, + "noExpenses": 320.0, + "highExpenses": 130.0 + }, + { + "receipts": 2700, + "noExpenses": 340.0, + "highExpenses": 135.0 + }, + { + "receipts": 2800, + "noExpenses": 360.0, + "highExpenses": 140.0 + }, + { + "receipts": 2900, + "noExpenses": 380.0, + "highExpenses": 145.0 + }, + { + "receipts": 3000, + "noExpenses": 400.0, + "highExpenses": 150.0 + }, + { + "receipts": 3100, + "noExpenses": 400.0, + "highExpenses": 135.0 + }, + { + "receipts": 3200, + "noExpenses": 400.0, + "highExpenses": 120.0 + }, + { + "receipts": 3300, + "noExpenses": 400.0, + "highExpenses": 105.0 + }, + { + "receipts": 3400, + "noExpenses": 400.0, + "highExpenses": 90.0 + }, + { + "receipts": 3500, + "noExpenses": 400.0, + "highExpenses": 75.0 + }, + { + "receipts": 3600, + "noExpenses": 400.0, + "highExpenses": 60.0 + }, + { + "receipts": 3700, + "noExpenses": 400.0, + "highExpenses": 45.0 + }, + { + "receipts": 3800, + "noExpenses": 400.0, + "highExpenses": 30.0 + }, + { + "receipts": 3900, + "noExpenses": 400.0, + "highExpenses": 15.0 + }, + { + "receipts": 4000, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4100, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4200, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4300, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4400, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4500, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4600, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4700, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4800, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 4900, + "noExpenses": 400.0, + "highExpenses": 0.0 + }, + { + "receipts": 5000, + "noExpenses": 400.0, + "highExpenses": 0.0 + } + ] +} diff --git a/analysis/uk-budget-2026-income-tax/trading-receipts-curve.csv b/analysis/uk-budget-2026-income-tax/trading-receipts-curve.csv new file mode 100644 index 000000000..be6044f8c --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/trading-receipts-curve.csv @@ -0,0 +1,48 @@ +receipts,no_expenses_actual_expenses,no_expenses_baseline_taxable_profit,no_expenses_reform_taxable_profit,no_expenses_tax_reduction,expenses_75_percent_actual_expenses,expenses_75_percent_baseline_taxable_profit,expenses_75_percent_reform_taxable_profit,expenses_75_percent_tax_reduction +500,0,0,0,0.0,375.0,0,0,0.0 +600,0,0,0,0.0,450.0,0,0,0.0 +700,0,0,0,0.0,525.0,0,0,0.0 +800,0,0,0,0.0,600.0,0,0,0.0 +900,0,0,0,0.0,675.0,0,0,0.0 +1000,0,0,0,0.0,750.0,0,0,0.0 +1100,0,100,0,20.0,825.0,100,0,20.0 +1200,0,200,0,40.0,900.0,200,0,40.0 +1300,0,300,0,60.0,975.0,300,0,60.0 +1333.3333333333333,0.0,333.33333333333326,0,66.67,1000.0,333.33333333333326,0,66.67 +1400,0,400,0,80.0,1050.0,350.0,0,70.0 +1500,0,500,0,100.0,1125.0,375.0,0,75.0 +1600,0,600,0,120.0,1200.0,400.0,0,80.0 +1700,0,700,0,140.0,1275.0,425.0,0,85.0 +1800,0,800,0,160.0,1350.0,450.0,0,90.0 +1900,0,900,0,180.0,1425.0,475.0,0,95.0 +2000,0,1000,0,200.0,1500.0,500.0,0,100.0 +2100,0,1100,0,220.0,1575.0,525.0,0,105.0 +2200,0,1200,0,240.0,1650.0,550.0,0,110.0 +2300,0,1300,0,260.0,1725.0,575.0,0,115.0 +2400,0,1400,0,280.0,1800.0,600.0,0,120.0 +2500,0,1500,0,300.0,1875.0,625.0,0,125.0 +2600,0,1600,0,320.0,1950.0,650.0,0,130.0 +2700,0,1700,0,340.0,2025.0,675.0,0,135.0 +2800,0,1800,0,360.0,2100.0,700.0,0,140.0 +2900,0,1900,0,380.0,2175.0,725.0,0,145.0 +3000,0,2000,0,400.0,2250.0,750.0,0,150.0 +3100,0,2100,100,400.0,2325.0,775.0,100,135.0 +3200,0,2200,200,400.0,2400.0,800.0,200,120.0 +3300,0,2300,300,400.0,2475.0,825.0,300,105.0 +3400,0,2400,400,400.0,2550.0,850.0,400,90.0 +3500,0,2500,500,400.0,2625.0,875.0,500,75.0 +3600,0,2600,600,400.0,2700.0,900.0,600,60.0 +3700,0,2700,700,400.0,2775.0,925.0,700,45.0 +3800,0,2800,800,400.0,2850.0,950.0,800,30.0 +3900,0,2900,900,400.0,2925.0,975.0,900,15.0 +4000,0,3000,1000,400.0,3000.0,1000.0,1000.0,0.0 +4100,0,3100,1100,400.0,3075.0,1025.0,1025.0,0.0 +4200,0,3200,1200,400.0,3150.0,1050.0,1050.0,0.0 +4300,0,3300,1300,400.0,3225.0,1075.0,1075.0,0.0 +4400,0,3400,1400,400.0,3300.0,1100.0,1100.0,0.0 +4500,0,3500,1500,400.0,3375.0,1125.0,1125.0,0.0 +4600,0,3600,1600,400.0,3450.0,1150.0,1150.0,0.0 +4700,0,3700,1700,400.0,3525.0,1175.0,1175.0,0.0 +4800,0,3800,1800,400.0,3600.0,1200.0,1200.0,0.0 +4900,0,3900,1900,400.0,3675.0,1225.0,1225.0,0.0 +5000,0,4000,2000,400.0,3750.0,1250.0,1250.0,0.0 diff --git a/analysis/uk-budget-2026-income-tax/trading_extensions.json b/analysis/uk-budget-2026-income-tax/trading_extensions.json new file mode 100644 index 000000000..370dd58d9 --- /dev/null +++ b/analysis/uk-budget-2026-income-tax/trading_extensions.json @@ -0,0 +1,976 @@ +{ + "metadata": { + "generated_at_utc": "2026-10-28T16:15:44.057920+00:00", + "model_year": 2027, + "tax_year": "2027–28", + "versions": { + "policyengine": "6.11.1", + "policyengine-uk": "2.151.0", + "policyengine-core": "3.33.3" + }, + "python": "3.13.14", + "review_url": "https://github.com/PolicyEngine/policyengine-app-v2/pull/1460#issuecomment-6472758764", + "review_comment_timestamp_utc": "2026-10-28T15:11:33Z", + "baseline_parameters": { + "trading_allowance": 1000.0, + "uc_taper": 0.55, + "uc_work_allowance_monthly_with_housing": 441.94429445251563, + "uc_work_allowance_monthly_without_housing": 734.8488268414194 + }, + "reform": { + "gov.hmrc.income_tax.allowances.trading_allowance": 3000 + }, + "scope": "Five synthetic case pairs; no population data, behavioural responses or national estimates. Annual model calculations; actual UC assessment periods and timing of tax payments can differ.", + "assumptions": "Lone parent age35 with child age4, employment as main job, £18,000 annual wages, side business with zero expenses, London/Central London private rent £12,000/year, UC and Child Benefit take-up true. Sole trader age35, full-time35hours/week, £20,000 receipts and £500 costs, no other income, owns home outright, no UC claim. Both: council tax input zero; no childcare costs, capital, disability, pensions, losses or other income. Omitted inputs otherwise retain pinned model defaults. No UC award, floor amount, work allowance, or earnings intermediate is forced.", + "oracle_tolerance_gbp": 0.02, + "forecast": { + "dashboard_commit": "640426575270224db9b04d6c94d30e264a347be2", + "source": "https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/blob/640426575270224db9b04d6c94d30e264a347be2/src/uk_budget_data/forecast/obr_october_2026.json", + "forecast_file_git_blob": "b504a48fffb93714ff358d869cad712b6daea20e", + "forecast_module_git_blob": "b2ca186b6fd514f334ced11934d38b256e6d2127", + "forecast_file_sha256": "dc039d30660d17f30a45e49538dbd22953e02bd4f6b63eda2eaebcf8252baf54", + "baseline_and_reform": true, + "nominal_household_inputs": "Held fixed in 2027; the forecast updates model parameters, not the supplied income amounts.", + "remaining_series": "March paths remain for cpih, non-labour income, private rent, mortgage interest, per-capita series, council tax and fuel volumes/prices, as recorded by this forecast vintage." + }, + "independent_arithmetic": "Basic-rate income tax20% above Personal Allowance£12,570; known-receipt taxable profit=max(0,receipts-max(expenses,allowance)); Class4 NI6% above£12,570; active UC award falls55% of extra UC net earnings above its unchanged work allowance. Missing-receipt outputs separately test the pinned fallback, not the legal receipt-based calculation." + }, + "cases": [ + { + "id": "lone_parent_4000_receipts", + "type": "lone_parent", + "inputs": { + "people": [ + { + "age": 35, + "employment_status": "PT_EMPLOYED", + "hours_worked": 1040, + "employment_income": 18000, + "self_employment_income": 4000, + "uc_is_in_gainful_self_employment": false, + "self_employment_gross_receipts": 4000 + }, + { + "age": 4, + "employment_status": "CHILD" + } + ], + "benunit": { + "would_claim_uc": true, + "would_claim_child_benefit": true + }, + "household": { + "region": "LONDON", + "brma": "CENTRAL_LONDON", + "tenure_type": "RENT_PRIVATELY", + "rent": 12000, + "council_tax": 0 + } + }, + "gross_receipts_supplied": true, + "actual_expenses": 0, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 3000, + "income_tax": 1686 + }, + "reform": { + "taxable_self_employment_income": 1000, + "income_tax": 1286 + }, + "change": { + "income_tax": -400, + "national_insurance": 0, + "universal_credit": -220, + "household_net_income": 180 + } + }, + "review_claim": { + "income_tax": -400, + "universal_credit": -220, + "household_net_income": 180 + }, + "baseline": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 4000.0, + "self_employment_gross_receipts": 4000.0, + "income_tax": 1686.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 3000.0, + "trading_allowance_deduction": 1000.0, + "uc_income_tax_on_earnings": 1686.0, + "uc_income_tax_on_trade": 600.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 19879.59765625, + "uc_individual_earned_income": 19879.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 13076.5009765625, + "universal_credit_pre_benefit_cap": 13076.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 19879.59765625, + "uc_earned_income": 14576.265625, + "uc_income_reduction": 8016.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 36821.58984375, + "hbai_household_net_income": 34411.92578125, + "household_benefits": 17121.994140625, + "household_tax": 2300.403076171875, + "household_market_income": 22000.0, + "household_gross_income": 39121.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "reform": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 4000.0, + "self_employment_gross_receipts": 4000.0, + "income_tax": 1286.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 1000.0, + "trading_allowance_deduction": 3000.0, + "uc_income_tax_on_earnings": 1286.0, + "uc_income_tax_on_trade": 200.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 20279.59765625, + "uc_individual_earned_income": 20279.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 12856.5009765625, + "universal_credit_pre_benefit_cap": 12856.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 20279.59765625, + "uc_earned_income": 14976.265625, + "uc_income_reduction": 8236.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 37001.58984375, + "hbai_household_net_income": 34591.92578125, + "household_benefits": 16901.994140625, + "household_tax": 1900.403076171875, + "household_market_income": 22000.0, + "household_gross_income": 38901.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "change": { + "income_tax": -400.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "universal_credit": -220.0, + "household_benefits": -220.0, + "household_net_income": 180.0, + "hbai_household_net_income": 180.0 + }, + "uc_trace": { + "baseline_annual_uc_earnings_before_work_allowance": 19879.59765625, + "reform_annual_uc_earnings_before_work_allowance": 20279.59765625, + "annual_work_allowance": 5303.33154296875, + "baseline_earnings_above_work_allowance": 14576.265625, + "reform_earnings_above_work_allowance": 14976.265625, + "explanation": "Employment earnings already exceed the work allowance. The entire increase in UC net earnings is tapered at 55%; no work-allowance boundary is crossed." + }, + "review_comparison": { + "claim": { + "income_tax": -400, + "universal_credit": -220, + "household_net_income": 180 + }, + "matches": true + } + }, + { + "id": "lone_parent_1500_receipts", + "type": "lone_parent", + "inputs": { + "people": [ + { + "age": 35, + "employment_status": "PT_EMPLOYED", + "hours_worked": 1040, + "employment_income": 18000, + "self_employment_income": 1500, + "uc_is_in_gainful_self_employment": false, + "self_employment_gross_receipts": 1500 + }, + { + "age": 4, + "employment_status": "CHILD" + } + ], + "benunit": { + "would_claim_uc": true, + "would_claim_child_benefit": true + }, + "household": { + "region": "LONDON", + "brma": "CENTRAL_LONDON", + "tenure_type": "RENT_PRIVATELY", + "rent": 12000, + "council_tax": 0 + } + }, + "gross_receipts_supplied": true, + "actual_expenses": 0, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 500, + "income_tax": 1186 + }, + "reform": { + "taxable_self_employment_income": 0, + "income_tax": 1086 + }, + "change": { + "income_tax": -100, + "national_insurance": 0, + "universal_credit": -55, + "household_net_income": 45 + } + }, + "review_claim": { + "income_tax": -100, + "universal_credit": -21, + "household_net_income": 79 + }, + "baseline": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 1500.0, + "self_employment_gross_receipts": 1500.0, + "income_tax": 1186.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 500.0, + "trading_allowance_deduction": 1000.0, + "uc_income_tax_on_earnings": 1186.0, + "uc_income_tax_on_trade": 100.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 17879.59765625, + "uc_individual_earned_income": 17879.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 14176.5009765625, + "universal_credit_pre_benefit_cap": 14176.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 17879.59765625, + "uc_earned_income": 12576.265625, + "uc_income_reduction": 6916.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 35921.58984375, + "hbai_household_net_income": 33511.92578125, + "household_benefits": 18221.994140625, + "household_tax": 1800.403076171875, + "household_market_income": 19500.0, + "household_gross_income": 37721.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "reform": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 1500.0, + "self_employment_gross_receipts": 1500.0, + "income_tax": 1086.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 1500.0, + "uc_income_tax_on_earnings": 1086.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 17979.59765625, + "uc_individual_earned_income": 17979.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 14121.5009765625, + "universal_credit_pre_benefit_cap": 14121.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 17979.59765625, + "uc_earned_income": 12676.265625, + "uc_income_reduction": 6971.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 35966.58984375, + "hbai_household_net_income": 33556.92578125, + "household_benefits": 18166.994140625, + "household_tax": 1700.403076171875, + "household_market_income": 19500.0, + "household_gross_income": 37666.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "change": { + "income_tax": -100.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "universal_credit": -55.0, + "household_benefits": -55.0, + "household_net_income": 45.0, + "hbai_household_net_income": 45.0 + }, + "uc_trace": { + "baseline_annual_uc_earnings_before_work_allowance": 17879.59765625, + "reform_annual_uc_earnings_before_work_allowance": 17979.59765625, + "annual_work_allowance": 5303.33154296875, + "baseline_earnings_above_work_allowance": 12576.265625, + "reform_earnings_above_work_allowance": 12676.265625, + "explanation": "Employment earnings already exceed the work allowance. The entire increase in UC net earnings is tapered at 55%; no work-allowance boundary is crossed." + }, + "review_comparison": { + "claim": { + "income_tax": -100, + "universal_credit": -21, + "household_net_income": 79 + }, + "matches": false + } + }, + { + "id": "lone_parent_1500_profit_receipts_omitted", + "type": "lone_parent", + "inputs": { + "people": [ + { + "age": 35, + "employment_status": "PT_EMPLOYED", + "hours_worked": 1040, + "employment_income": 18000, + "self_employment_income": 1500, + "uc_is_in_gainful_self_employment": false + }, + { + "age": 4, + "employment_status": "CHILD" + } + ], + "benunit": { + "would_claim_uc": true, + "would_claim_child_benefit": true + }, + "household": { + "region": "LONDON", + "brma": "CENTRAL_LONDON", + "tenure_type": "RENT_PRIVATELY", + "rent": 12000, + "council_tax": 0 + } + }, + "gross_receipts_supplied": false, + "actual_expenses": 0, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 1500, + "income_tax": 1386 + }, + "reform": { + "taxable_self_employment_income": 0, + "income_tax": 1086 + }, + "change": { + "income_tax": -300, + "national_insurance": 0, + "universal_credit": -165, + "household_net_income": 135 + } + }, + "limitation": "Omitting receipts activates the pinned model's fallback. This £300 tax reduction exceeds the legally calculated £100 with receipts supplied; the resulting net gain is £135 instead of £45.", + "baseline": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 1500.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 1386.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 1500.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 1386.0, + "uc_income_tax_on_trade": 300.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 17679.59765625, + "uc_individual_earned_income": 17679.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 14286.5009765625, + "universal_credit_pre_benefit_cap": 14286.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 17679.59765625, + "uc_earned_income": 12376.265625, + "uc_income_reduction": 6806.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 35831.58984375, + "hbai_household_net_income": 33421.92578125, + "household_benefits": 18331.994140625, + "household_tax": 2000.403076171875, + "household_market_income": 19500.0, + "household_gross_income": 37831.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "reform": { + "person": [ + { + "employment_income": 18000.0, + "self_employment_income": 1500.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 1086.0, + "national_insurance": 434.4031066894531, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 1500.0, + "uc_income_tax_on_earnings": 1086.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 434.4031066894531, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 17979.59765625, + "uc_individual_earned_income": 17979.59765625, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + }, + { + "employment_income": 0.0, + "self_employment_income": 0.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "taxable_self_employment_income": 0.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 0.0, + "uc_income_tax_on_trade": 0.0, + "uc_national_insurance_on_earnings": 0.0, + "uc_national_insurance_on_trade": 0.0, + "uc_individual_earned_income_before_mif": 0.0, + "uc_individual_earned_income": 0.0, + "uc_is_in_gainful_self_employment": 0.0, + "uc_mif_applies": 0.0 + } + ], + "benunit": { + "universal_credit": 14121.5009765625, + "universal_credit_pre_benefit_cap": 14121.5009765625, + "claims_universal_credit": 1.0, + "uc_maximum_amount": 21093.447265625, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 3774.9287109375, + "uc_housing_costs_element": 12000.0, + "uc_work_allowance": 5303.33154296875, + "uc_earned_income_before_work_allowance": 17979.59765625, + "uc_earned_income": 12676.265625, + "uc_income_reduction": 6971.9462890625, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 1455.8287353515625 + }, + "household": { + "household_net_income": 35966.58984375, + "hbai_household_net_income": 33556.92578125, + "household_benefits": 18166.994140625, + "household_tax": 1700.403076171875, + "household_market_income": 19500.0, + "household_gross_income": 37666.9921875, + "rent": 12000.0, + "council_tax": 0.0 + } + }, + "change": { + "income_tax": -300.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "universal_credit": -165.0, + "household_benefits": -165.0, + "household_net_income": 135.0, + "hbai_household_net_income": 135.0 + }, + "uc_trace": { + "baseline_annual_uc_earnings_before_work_allowance": 17679.59765625, + "reform_annual_uc_earnings_before_work_allowance": 17979.59765625, + "annual_work_allowance": 5303.33154296875, + "baseline_earnings_above_work_allowance": 12376.265625, + "reform_earnings_above_work_allowance": 12676.265625, + "explanation": "Employment earnings already exceed the work allowance. The entire increase in UC net earnings is tapered at 55%; no work-allowance boundary is crossed." + }, + "review_comparison": null + }, + { + "id": "sole_trader_20000_receipts_500_expenses", + "type": "sole_trader", + "inputs": { + "people": [ + { + "age": 35, + "employment_status": "FT_SELF_EMPLOYED", + "hours_worked": 1820, + "employment_income": 0, + "self_employment_income": 19500, + "uc_is_in_gainful_self_employment": true, + "self_employment_gross_receipts": 20000 + } + ], + "benunit": { + "would_claim_uc": false, + "would_claim_child_benefit": false + }, + "household": { + "region": "LONDON", + "brma": "CENTRAL_LONDON", + "tenure_type": "OWNED_OUTRIGHT", + "rent": 0, + "council_tax": 0 + } + }, + "gross_receipts_supplied": true, + "actual_expenses": 500, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 19000, + "income_tax": 1286, + "ni_class_4": 385.8 + }, + "reform": { + "taxable_self_employment_income": 17000, + "income_tax": 886, + "ni_class_4": 265.8 + }, + "change": { + "income_tax": -400, + "national_insurance": -120, + "universal_credit": 0, + "household_net_income": 520 + } + }, + "review_claim": { + "income_tax": -400, + "ni_class_4": -120, + "household_net_income": 520 + }, + "baseline": { + "person": [ + { + "employment_income": 0.0, + "self_employment_income": 19500.0, + "self_employment_gross_receipts": 20000.0, + "income_tax": 1286.0, + "national_insurance": 385.79998779296875, + "ni_class_4": 385.79998779296875, + "taxable_self_employment_income": 19000.0, + "trading_allowance_deduction": 500.0, + "uc_income_tax_on_earnings": 1286.0, + "uc_income_tax_on_trade": 1286.0, + "uc_national_insurance_on_earnings": 385.79998779296875, + "uc_national_insurance_on_trade": 385.79998779296875, + "uc_individual_earned_income_before_mif": 17828.19921875, + "uc_individual_earned_income": 20386.02734375, + "uc_is_in_gainful_self_employment": 1.0, + "uc_mif_applies": 1.0 + } + ], + "benunit": { + "universal_credit": 0.0, + "universal_credit_pre_benefit_cap": 0.0, + "claims_universal_credit": 0.0, + "uc_maximum_amount": 5318.5185546875, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 0.0, + "uc_housing_costs_element": 0.0, + "uc_work_allowance": 0.0, + "uc_earned_income_before_work_allowance": 20386.02734375, + "uc_earned_income": 20386.02734375, + "uc_income_reduction": 5318.5185546875, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 0.0 + }, + "household": { + "household_net_income": 17648.19921875, + "hbai_household_net_income": 17828.19921875, + "household_benefits": 0.0, + "household_tax": 1851.800048828125, + "household_market_income": 19500.0, + "household_gross_income": 19500.0, + "rent": 0.0, + "council_tax": 0.0 + } + }, + "reform": { + "person": [ + { + "employment_income": 0.0, + "self_employment_income": 19500.0, + "self_employment_gross_receipts": 20000.0, + "income_tax": 886.0, + "national_insurance": 265.79998779296875, + "ni_class_4": 265.79998779296875, + "taxable_self_employment_income": 17000.0, + "trading_allowance_deduction": 2500.0, + "uc_income_tax_on_earnings": 886.0, + "uc_income_tax_on_trade": 886.0, + "uc_national_insurance_on_earnings": 265.79998779296875, + "uc_national_insurance_on_trade": 265.79998779296875, + "uc_individual_earned_income_before_mif": 18348.19921875, + "uc_individual_earned_income": 20386.02734375, + "uc_is_in_gainful_self_employment": 1.0, + "uc_mif_applies": 1.0 + } + ], + "benunit": { + "universal_credit": 0.0, + "universal_credit_pre_benefit_cap": 0.0, + "claims_universal_credit": 0.0, + "uc_maximum_amount": 5318.5185546875, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 0.0, + "uc_housing_costs_element": 0.0, + "uc_work_allowance": 0.0, + "uc_earned_income_before_work_allowance": 20386.02734375, + "uc_earned_income": 20386.02734375, + "uc_income_reduction": 5318.5185546875, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 0.0 + }, + "household": { + "household_net_income": 18168.19921875, + "hbai_household_net_income": 18348.19921875, + "household_benefits": 0.0, + "household_tax": 1331.800048828125, + "household_market_income": 19500.0, + "household_gross_income": 19500.0, + "rent": 0.0, + "council_tax": 0.0 + } + }, + "change": { + "income_tax": -400.0, + "national_insurance": -120.0, + "ni_class_4": -120.0, + "universal_credit": 0.0, + "household_benefits": 0.0, + "household_net_income": 520.0, + "hbai_household_net_income": 520.0 + }, + "uc_trace": null, + "review_comparison": { + "claim": { + "income_tax": -400, + "ni_class_4": -120, + "household_net_income": 520 + }, + "matches": true + } + }, + { + "id": "sole_trader_19500_profit_receipts_omitted", + "type": "sole_trader", + "inputs": { + "people": [ + { + "age": 35, + "employment_status": "FT_SELF_EMPLOYED", + "hours_worked": 1820, + "employment_income": 0, + "self_employment_income": 19500, + "uc_is_in_gainful_self_employment": true + } + ], + "benunit": { + "would_claim_uc": false, + "would_claim_child_benefit": false + }, + "household": { + "region": "LONDON", + "brma": "CENTRAL_LONDON", + "tenure_type": "OWNED_OUTRIGHT", + "rent": 0, + "council_tax": 0 + } + }, + "gross_receipts_supplied": false, + "actual_expenses": 500, + "independent_oracle": { + "baseline": { + "taxable_self_employment_income": 19500, + "income_tax": 1386, + "ni_class_4": 415.8 + }, + "reform": { + "taxable_self_employment_income": 19500, + "income_tax": 1386, + "ni_class_4": 415.8 + }, + "change": { + "income_tax": 0, + "national_insurance": 0, + "universal_credit": 0, + "household_net_income": 0 + } + }, + "limitation": "With receipts omitted, profit exceeds both allowance amounts, so the pinned fallback applies no relief on either side. It misses the £520 gain calculated when £20,000 receipts and £500 expenses are represented.", + "baseline": { + "person": [ + { + "employment_income": 0.0, + "self_employment_income": 19500.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 1386.0, + "national_insurance": 415.79998779296875, + "ni_class_4": 415.79998779296875, + "taxable_self_employment_income": 19500.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 1386.0, + "uc_income_tax_on_trade": 1386.0, + "uc_national_insurance_on_earnings": 415.79998779296875, + "uc_national_insurance_on_trade": 415.79998779296875, + "uc_individual_earned_income_before_mif": 17698.19921875, + "uc_individual_earned_income": 20386.02734375, + "uc_is_in_gainful_self_employment": 1.0, + "uc_mif_applies": 1.0 + } + ], + "benunit": { + "universal_credit": 0.0, + "universal_credit_pre_benefit_cap": 0.0, + "claims_universal_credit": 0.0, + "uc_maximum_amount": 5318.5185546875, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 0.0, + "uc_housing_costs_element": 0.0, + "uc_work_allowance": 0.0, + "uc_earned_income_before_work_allowance": 20386.02734375, + "uc_earned_income": 20386.02734375, + "uc_income_reduction": 5318.5185546875, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 0.0 + }, + "household": { + "household_net_income": 17518.19921875, + "hbai_household_net_income": 17698.19921875, + "household_benefits": 0.0, + "household_tax": 1981.800048828125, + "household_market_income": 19500.0, + "household_gross_income": 19500.0, + "rent": 0.0, + "council_tax": 0.0 + } + }, + "reform": { + "person": [ + { + "employment_income": 0.0, + "self_employment_income": 19500.0, + "self_employment_gross_receipts": 0.0, + "income_tax": 1386.0, + "national_insurance": 415.79998779296875, + "ni_class_4": 415.79998779296875, + "taxable_self_employment_income": 19500.0, + "trading_allowance_deduction": 0.0, + "uc_income_tax_on_earnings": 1386.0, + "uc_income_tax_on_trade": 1386.0, + "uc_national_insurance_on_earnings": 415.79998779296875, + "uc_national_insurance_on_trade": 415.79998779296875, + "uc_individual_earned_income_before_mif": 17698.19921875, + "uc_individual_earned_income": 20386.02734375, + "uc_is_in_gainful_self_employment": 1.0, + "uc_mif_applies": 1.0 + } + ], + "benunit": { + "universal_credit": 0.0, + "universal_credit_pre_benefit_cap": 0.0, + "claims_universal_credit": 0.0, + "uc_maximum_amount": 5318.5185546875, + "uc_standard_allowance": 5318.5185546875, + "uc_child_element": 0.0, + "uc_housing_costs_element": 0.0, + "uc_work_allowance": 0.0, + "uc_earned_income_before_work_allowance": 20386.02734375, + "uc_earned_income": 20386.02734375, + "uc_income_reduction": 5318.5185546875, + "uc_benefit_cap_reduction": 0.0, + "child_benefit": 0.0 + }, + "household": { + "household_net_income": 17518.19921875, + "hbai_household_net_income": 17698.19921875, + "household_benefits": 0.0, + "household_tax": 1981.800048828125, + "household_market_income": 19500.0, + "household_gross_income": 19500.0, + "rent": 0.0, + "council_tax": 0.0 + } + }, + "change": { + "income_tax": 0.0, + "national_insurance": 0.0, + "ni_class_4": 0.0, + "universal_credit": 0.0, + "household_benefits": 0.0, + "household_net_income": 0.0, + "hbai_household_net_income": 0.0 + }, + "uc_trace": null, + "review_comparison": null + } + ] +} diff --git a/app/public/assets/posts/uk-autumn-budget-2026-property-income-tax/cover.webp b/app/public/assets/posts/uk-autumn-budget-2026-property-income-tax/cover.webp new file mode 100644 index 000000000..e4c17ef58 Binary files /dev/null and b/app/public/assets/posts/uk-autumn-budget-2026-property-income-tax/cover.webp differ diff --git a/app/src/data/posts/articles/uk-autumn-budget-2026-property-income-tax.md b/app/src/data/posts/articles/uk-autumn-budget-2026-property-income-tax.md new file mode 100644 index 000000000..e78edda0a --- /dev/null +++ b/app/src/data/posts/articles/uk-autumn-budget-2026-property-income-tax.md @@ -0,0 +1,199 @@ +The Autumn Budget 2026 announces a further two-percentage-point increase in the basic, higher and additional income tax rates on property income from **6 April 2027**, taking them to **24%, 44% and 49%** in England, Wales and Northern Ireland, as [Budget paragraph 6.246](https://assets.publishing.service.gov.uk/media/6ae1ec57bdb574cf1c9b3f12/E03668986_HMT_Budget_2026_ELAY__2_.pdf#page=142) sets out. The government plans to legislate for the new rates in Finance Bill 2026–27. The property rate increase does not apply to Scottish taxpayers. Because finance-cost relief follows the property basic rate, residential landlords' relief rises too. + +Key figures: + +- A landlord in England with £10,000 of property profit and £4,000 of fully usable mortgage interest pays £120 more income tax. +- A mortgage-free landlord in England with the same profit pays £200 more. +- A landlord who lives in Scotland, with £4,000 of fully usable finance costs, pays £80 less income tax. The property income tax rate rise does not apply to Scottish taxpayers, but their finance-cost reduction still rises with the property basic rate. +- PolicyEngine estimates £399 million of additional net government revenue and a £14 reduction in average household net income in 2027–28. +- The government's costing, certified by the OBR, has £394 million to £412 million a year of extra income tax from 2029–30 to 2031–32, £539 million in 2028–29 and none in 2027–28. Its total in the Budget's Table 6.1, which adds the costing's other lines, is £35 million in 2027–28, £575 million in 2028–29 and £435 million to £455 million a year from 2029–30. + +The 2027–28 and 2028–29 figures use different collection-timing bases and are not directly comparable. From 2029–30, PolicyEngine's estimate exceeds the costing's income tax line by 9% to 11%; see the [budgetary impact section](#budgetary-impact). + +Our [Autumn Budget 2026 dashboard](https://www.policyengine.org/uk/autumn-budget-2026) is where we publish estimates for the Budget measures we model. A [separate explainer](/uk/research/uk-autumn-budget-2026-trading-allowance) covers the trading allowance increase. The Budget also raises savings income tax rates; we will cover that measure separately. + +## What changes in April 2027? + +The [Budget 2025 technical note](https://www.gov.uk/government/publications/changes-to-tax-rates-for-property-savings-and-dividend-income/change-to-tax-rates-for-property-savings-and-dividend-income-technical-note) had already set property rates at 22%, 42% and 47% from April 2027. The additional two-point increase is measured against those existing 2027 rules. + +| Income tax band | Already scheduled for 2027–28 | Budget 2026 rate | Change | +| --- | ---: | ---: | ---: | +| Basic | 22% | 24% | +2 percentage points | +| Higher | 42% | 44% | +2 percentage points | +| Additional | 47% | 49% | +2 percentage points | + +From April 2027, employment, pension and trading income fill the tax bands before property income. Property income comes before savings and dividends. Allowances first reduce income other than property, savings or dividends. A landlord's other income therefore affects the rate charged on rental profits. + +## Household impacts + +The examples below isolate the announced property measure in 2027–28. They hold the stated income and expenses fixed and show income tax rather than household income after means-tested benefits. + +### Landlords' mortgage-interest relief rises too + +For individual residential landlords, mortgage interest normally produces a tax reduction rather than a deduction from rental profits. The reduction is limited by finance costs, property profits, adjusted total income and the tax liability. [HMRC's explanation of residential finance-cost relief](https://www.gov.uk/guidance/changes-to-tax-relief-for-residential-landlords-how-its-worked-out-including-case-studies) describes these limits. + +From April 2027 the relief follows the property basic rate, as the [Treasury policy costings](https://assets.publishing.service.gov.uk/media/6ae1883fe4367e5c8b0467df/AB26_Policy_Costing.pdf#page=74) confirm. This Budget therefore raises it from the already scheduled 22% to 24%. That offsets part of the tax increase for landlords with eligible finance costs. + +Consider two adults in England, each with £12,000 of rent, £2,000 of allowable non-finance expenses and £4,000 of qualifying mortgage interest. Deducting actual non-finance expenses leaves £10,000 of property profit. Both can use the full finance-cost reduction. + +| Calculation, 2027–28 | £30,000 salary: before | £30,000 salary: after | £60,000 salary: before | £60,000 salary: after | +| --- | ---: | ---: | ---: | ---: | +| Property profit | £10,000 | £10,000 | £10,000 | £10,000 | +| Rate on that profit | 22% | 24% | 42% | 44% | +| Tax before finance-cost relief | £2,200 | £2,400 | £4,200 | £4,400 | +| Finance-cost reduction | £880 | £960 | £880 | £960 | +| Tax attributable to property | £1,320 | £1,440 | £3,320 | £3,440 | +| Extra annual income tax | — | £120 | — | £120 | + +Both pay £200 more before relief, while their finance-cost reduction rises by £4,000 × 2% = £80. Their net increase is £200 − £80 = £120. A mortgage-free landlord with the same profit pays £200 more. Both tax bands rise by two points, explaining the identical increases despite different starting liabilities. + +The property **rate** increase excludes Scottish taxpayers, whose rental income is taxed under Scottish Income Tax rules. Finance-cost relief is a separate calculation. The [Finance Act 2026 amendment](https://www.legislation.gov.uk/ukpga/2026/11/schedule/1/paragraph/40/enacted) ties it to the UK property basic rate without a Scottish exception. Applying that rule, a Scottish taxpayer who lets property and can use the full reduction on £4,000 of eligible finance costs receives £80 more relief, reducing their income tax by £80 if nothing else changes. A mortgage-free Scottish taxpayer has no change from this measure. + +### A smaller rental profit + +A landlord in England with a £30,000 salary has already used the Personal Allowance against salary. If they also have £6,000 of taxable property profit after deductions and no eligible finance costs, they pay £120 more income tax in 2027–28: £6,000 × 2% = £120. This property-only calculation holds their income fixed and changes no other Budget measure. + +## Population impacts + +We model the property measure alone on a representative sample of UK households. The [property-only microsimulation results](https://github.com/PolicyEngine/uk-autumn-budget-dashboard-2026/tree/637bb26c34264e0491ed182c363df751466458ed/public/data/artifacts/property_income_rates_up/7bf77b35e33233e0) use the certified Microcosm UK dataset and the OBR's October 2026 forecast. They are static estimates, with no behavioural response. + +### Budgetary impact + +PolicyEngine estimates that the measure raises £399 million of net government revenue in 2027–28, rising to £459 million in 2031–32. We compare it with the income tax line of the government's costing, certified by the OBR, in the OBR's [detailed policy table](https://obr.uk/download/october-2026-economic-and-fiscal-outlook-detailed-forecast-tables-zip-file/) (Table 1.1, measure 61). We use that line as the closest comparison; PolicyEngine's estimate also includes interactions with other taxes and benefits. The costing's other non-zero lines are labelled “Onshore CT”, “Scottish BGA (current)” and “Scottish self-financed expenditure”. The Budget's [Table 6.1, row 61](https://www.gov.uk/government/publications/supporting-documents-for-budget-2026) gives the total of all the lines, rounded to the nearest £5 million and on a National Accounts basis; we show it for context. + +| Year | PolicyEngine net government revenue, £ million | OBR income tax line, £ million | PolicyEngine against the OBR line | Table 6.1 total, £ million | +| --- | ---: | ---: | --- | ---: | +| 2026–27 | 0 | 0 | Before implementation | 0 | +| 2027–28 | 399 | 0 | Not comparable | 35 | +| 2028–29 | 412 | 539 | Not comparable | 575 | +| 2029–30 | 429 | 394 | 9% higher | 435 | +| 2030–31 | 446 | 403 | 10% higher | 445 | +| 2031–32 | 459 | 412 | 11% higher | 455 | + +Positive values are additional revenue. PolicyEngine measures the change in government taxes less spending, including benefit interactions. In 2029–30, its £429 million estimate exceeds the OBR's £394 million income tax line by £35 million, or about 9%. Percentages use unrounded figures. + +**The first two years, 2027–28 and 2028–29, are not comparable without a collection-timing adjustment.** PolicyEngine scores each tax year's liabilities in that year. Self Assessment payments on account are normally based on the previous year's tax bill; the balancing payment for 2027–28 is due on 31 January 2029, alongside the first payment on account for 2028–29. [HMRC's payment guidance](https://www.gov.uk/understand-self-assessment-bill/payments-on-account) explains that schedule. + +The [ONS public-finance methodology, section 6.1.2](https://www.ons.gov.uk/economy/governmentpublicsectorandtaxes/publicsectorfinance/methodologies/monthlystatisticsonthepublicsectorfinancesamethodologicalguide) records Self Assessment income tax using cash receipts, without shifting them back to the year the income arose. This can produce a small first-year receipts effect followed by a catch-up. Comparing those first two years with same-year model liabilities requires a collection-timing adjustment; it does not by itself establish a difference in the tax base. + +The government's costing also allows for some landlords incorporating, as the [policy costings](https://assets.publishing.service.gov.uk/media/6ae1883fe4367e5c8b0467df/AB26_Policy_Costing.pdf#page=74) set out. PolicyEngine holds that choice fixed. We have not yet explained the later-year gap; differences in data, behaviour and accounting could each contribute. + +### Distribution + +Across all households, average annual net income falls by £14 in 2027–28 and £15 in 2031–32. In 2027–28, the average reduction ranges from £1 in the lowest income decile to £58 in the highest; in 2031–32, those averages are £2 and £66. + +Income deciles rank people by their household's baseline equivalised net income before housing costs. The analysis calculates rankings separately for each year. The changes below are averages per household in each group, including households whose income does not change. + +| Income decile | Average household net income change, 2027–28 | Average household net income change, 2031–32 | +| --- | ---: | ---: | +| 1 (lowest income) | −£1 | −£2 | +| 2 | −£5 | −£6 | +| 3 | −£5 | −£6 | +| 4 | −£5 | −£5 | +| 5 | −£4 | −£7 | +| 6 | −£7 | −£3 | +| 7 | −£9 | −£14 | +| 8 | −£17 | −£19 | +| 9 | −£25 | −£27 | +| 10 (highest income) | −£58 | −£66 | +| All households | −£14 | −£15 | + +```chart +{ + "type": "bar", + "title": "Average change in household net income by income decile", + "subtitle": "Property income tax measure, all households", + "xKey": "decile", + "series": [ + { + "key": "y2027", + "name": "2027–28", + "color": "negative" + }, + { + "key": "y2031", + "name": "2031–32", + "color": "quinary" + } + ], + "data": [ + { + "decile": "1st", + "y2027": -0.849537805191413, + "y2031": -2.0255155229193846 + }, + { + "decile": "2nd", + "y2027": -5.331535772669214, + "y2031": -5.635177868688589 + }, + { + "decile": "3rd", + "y2027": -5.137292004488854, + "y2031": -6.31798337071894 + }, + { + "decile": "4th", + "y2027": -5.459680740488306, + "y2031": -5.009629578700846 + }, + { + "decile": "5th", + "y2027": -4.476027967687162, + "y2031": -6.514231403074363 + }, + { + "decile": "6th", + "y2027": -6.548908036603635, + "y2031": -2.8345851636943533 + }, + { + "decile": "7th", + "y2027": -8.616921384043795, + "y2031": -13.776544201366882 + }, + { + "decile": "8th", + "y2027": -16.837105996038773, + "y2031": -19.013018309750667 + }, + { + "decile": "9th", + "y2027": -25.074336564023735, + "y2031": -26.922877825449845 + }, + { + "decile": "10th", + "y2027": -57.73388219873782, + "y2031": -65.56126504216287 + } + ], + "yLabel": "Average annual change in net income", + "format": { + "prefix": "£", + "decimals": 0, + "separator": true + }, + "valueLabels": false, + "source": "Source: PolicyEngine UK 2.151.0 microsimulation on the certified Microcosm UK dataset and the OBR's October 2026 forecast." +} +``` + +## Assumptions and limitations + +- The worked examples are hypothetical single adults aged 35. Their income is fixed at the stated 2027–28 amounts. They include no pension contributions, Gift Aid, student loans, property losses, carried-forward finance costs or other reliefs. +- The household tables show tax attributable to property income. The mortgage examples assume the full finance-cost reduction can be used. +- The Scottish mortgage example applies the existing Finance Act rule linking relief to the UK property basic rate. The Finance Bill will set the final implementation of the new rates. +- National estimates hold households' behaviour fixed. They do not model landlords incorporating in response to the tax change. +- This post does not report poverty, inequality or people-affected estimates. +- Population estimates include changes in means-tested benefits. The worked household examples show income tax; a change in benefits can offset part of a household's extra tax. + +## Methodology + +The calculations use the `policyengine` Python package (version 6.11.1), PolicyEngine UK (version 2.151.0) and PolicyEngine core (version 3.33.3). + +The household generator changes savings and property rates together against the already scheduled 2027–28 rules. The landlord examples in this article have no savings income, so the savings rate change has no effect on them: their tax differences isolate the property changes, including finance-cost relief. The £6,000 property-only example was checked separately. The baseline and reform household calculations both use the OBR’s October 2026 forecast update. Supplied 2027–28 income stays fixed; the forecast updates the model’s projected parameters. Independent arithmetic checks the tax calculations. + +The population run uses the certified Microcosm UK 2024–25 dataset (`a6299504`) and the detailed October forecast at dashboard commit `4de166f0`, applied to baseline and reform alike. It changes the property measure alone and includes the finance-cost-relief increase. Household net income and government revenue include interactions with the other taxes and benefits in the model. The decile averages are household-weighted means of unequivalised household net income changes; the income ranking uses person-weighted equivalised HBAI income before housing costs. Monetary values are rounded only for presentation. + +The [shared analysis files](https://github.com/PolicyEngine/policyengine-app-v2/tree/main/analysis/uk-budget-2026-income-tax) record the household inputs, model versions, forecast settings and validation for the property, savings and trading explainers. The property population records retain the exact source outputs and provenance. Monetary amounts in tables are rounded to whole pounds; the calculation records retain precision. The hypothetical household calculations do not require population microdata. diff --git a/app/src/data/posts/posts.json b/app/src/data/posts/posts.json index a187d2163..3505a0e3a 100644 --- a/app/src/data/posts/posts.json +++ b/app/src/data/posts/posts.json @@ -1,4 +1,13 @@ [ + { + "title": "Autumn Budget 2026: higher tax on property income", + "description": "Worked examples of the additional two percentage point property income tax increase from April 2027, including landlords' mortgage-interest relief and the treatment of Scotland.", + "date": "2026-10-28 14:00:00", + "tags": ["uk", "policy", "tax", "autumn-budget"], + "authors": ["ziming-hua"], + "filename": "uk-autumn-budget-2026-property-income-tax.md", + "image": "uk-autumn-budget-2026-property-income-tax/cover.webp" + }, { "title": "The fuel duty cut extension in the Autumn Budget 2026", "description": "The Budget keeps fuel duty at 52.95p a litre to 30 June 2027. We show how the duty and VAT on each litre change, and what this means for households by the fuel they use.",