Skip to content

UK CGT: sub-exempt gains capped at exactly the annual exempt amount become 10.8m taxpayers under uprating; interpolate the remainder below the threshold and anchor incidence #970

Description

@juaristi22

Found 2026-09-21 while running the uk-equalising-cgt dashboard on the staged
uk-spine-assessment-v20-calibration candidate (microcosm_uk_2024.h5, sha256
8883e592…, staged 2026-09-18) through policyengine-uk 2.99.1 via policyengine.py
4.22.3. The fix below keeps the Table 3 methodology for taxable gains and
changes only the remainder's amounts and the clone mass.

What happens

cgt_imputation (approximation 4) keeps every gainer beyond HMRC's taxpayer
mass with their existing amount capped at the annual exempt amount
(np.minimum(existing[remainder], annual_exempt_amount)). In the v20 file,
19,094 of the 20,642 sub_aea person records sit at exactly £3,000.00;
weighted, 10.82m of 11.66m sub-exempt gainers.

The engine holds the exempt amount at £3,000 in every year (frozen in law,
gov.hmrc.cgt.annual_exempt_amount has no value after 2024-01-01) but uprates
capital_gains with OBR GDP per capita (cumulative 1.074 by 2026, 1.214 by
2030). Every person at the cap therefore crosses the threshold in the first
projected year:

2026-27, engine period v20 candidate Enhanced FRS 1.57.3
CGT taxpayers (gains > exempt amount) 11.54m 597k
of which base-year non-taxpayers carried past the threshold by uprating 10.99m 12k
taxpayers excluding them 555k 586k
gains held by them £35.4bn £0.04bn
baseline CGT paid by them £0.46bn ~0

Revenue is barely affected (£0.46bn of £30.5bn), but every count and every
"share of people affected" is. Under a rate-rise reform with a realisation
elasticity the response applies to the whole £3,223, not the £223 above the
threshold, so the group's gains fall back under the exempt amount: it
contributes −£0.46bn to the yield and spreads a ~£970 net-income "loss" over
11m people across every income quintile (lowest quintile −0.34% on v20 against
−0.05% on the incumbent).

Any consumer that projects the dataset forward hits this, the app's 2026+
years included. The certified 2024 measurement is unaffected because the CGT
targets are measured at the base year, where the group owes nothing.

Two causes, not one

  1. The cap. The remainder's amounts are a mass point at the threshold, so
    the first positive uprating tips all of it at once. A smooth distribution
    below the threshold produces a thin flow of entrants each year (the
    fiscal-drag effect of a frozen exempt amount, which is real), not a step.
  2. The incidence. cgt_incidence_clone is an equal-mass clone: half of
    every household's weight sits on a gainer household, one gainer each, and
    nothing afterwards matches the incidence of gains to any observation. The
    CGT calibration targets describe only the liable population (gains above
    the exempt amount), so the sub-exempt gainers keep ordinary weights (mean
    565 against a population mean of 549): 12.2m weighted people carry a
    nonzero gain (0.55m liable, 11.66m sub-exempt, 2.5m loss-makers). The
    incumbent's imputation matches the weighted share of people with gains in
    each income band to Advani & Summers' percent_with_gains (a per-household
    weight split optimised before calibration), which puts the total near 1m.

Fixing the cap alone leaves cause 2 in place. With v20's 11.66m sub-exempt
mass spread uniformly over (0, £3,000], the engine's factors still tip 6.9% of
it in 2026 (0.80m entrants), 9.8% in 2027 (1.15m), 12.5% in 2028 (1.46m), 15.0%
in 2029 (1.75m) and 17.6% in 2030 (2.06m). With an incidence consistent with
Advani & Summers (a remainder of a few hundred thousand at most) the same
shares give tens of thousands of entrants a year, the order HMRC's small
bands imply (below).

Proposed fix

Keep the taxable methodology as it is: the Table 3 (2024-25) redraw still
assigns amounts to HMRC's taxpayer mass in rank order within income × age ×
region cells, the band donors still carry the top bands, and the asset-type
stage still follows. The change is confined to the remainder and to the clone
mass.

1. Interpolate the remainder's gains in (0, exempt amount]

Replace min(existing, AEA) with a draw from the Advani & Summers within-band
distribution restricted to the sub-exempt range. Table A1 of Advani & Summers
(2020, CAGE WP 465), already vendored as
advani_summers_capital_gains_distribution.json, gives for 61 total-income
bands the 5th, 10th, 25th, 50th, 75th, 90th and 95th percentiles of gains
among individuals with any reported gain. The p05 and p10 values are losses
and p25 sits near £3,000–4,000, so the linear spline the incumbent fits
through the seven points crosses zero at about the 18.6th percentile (range
16.5–24.8 across bands) and £3,000 at about the 24.5th: 5.9% of reporters
(range 4.4–6.9%) fall in (0, £3,000] in the table's nominal terms.

For each remainder gainer in income band b: draw a uniform quantile q in
[q₀(b), q_AEA(b)], where q₀ is the spline's zero crossing and q_AEA the point
where it reaches the base-year exempt amount, and set the gain to spline_b(q).
Equivalently, map the remainder's existing amounts into (0, AEA] preserving
their rank within the band. Either way the support is strictly below the
threshold, there is no mass point, and the crossing flow under uprating is a
smooth few per cent a year. Negative draws (loss-makers) are unchanged, as
now.

Honesty note for the issue text: between p10 and p25 the spline is one
straight segment, so the conditional distribution on (0, AEA] is close to
uniform. This is interpolation of two published percentiles, not an observed
density. It is the incumbent's behaviour (its sub-exempt quartiles are 746,
1,527 and 2,263) and it has the properties that matter here; it is not a
claim about the true shape of small gains.

2. Vintage (no uprating of the table)

Table A1 describes tax year 2017-18 in nominal terms (the paper's data notes:
"all reported taxable capital gains going to individuals in 2017"; the
population is "all individuals who reported gains", net of in-year losses,
trusts excluded). The exempt amount then was £11,300. Neither the incumbent
nor the spine uprates the table ("assumes that the capital gains distribution
is the same for all years").

For the interpolated slice the vintage is close to immaterial: scaling the
table by an uprating factor moves q₀ and q_AEA but leaves the near-uniform
shape on (0, AEA] unchanged, and the number of remainder gainers is fixed by
the taxpayer mass in any case. So the table is used as published, in its
2017-18 nominal terms, and the stage documents that. Where the vintage does
bite is the incidence (percent_with_gains), which HMRC's own counts show has
roughly doubled since 2017-18 (taxpayers 2017-18 ≈ 0.28m, 2024-25 551k, partly
the exempt-amount cuts). Component 3 handles that by anchoring the level to
current HMRC counts and taking only the income gradient from the table.

3. Anchor the incidence (in the clone stage)

Make cgt_incidence_clone split each household's mass by an income-band
propensity instead of equally. Composition from Advani & Summers, level from
HMRC:

  • Composition: among reporters, the spline gives the share with losses
    (≈18.6%), the share in (0, AEA] (≈5.9% at £3,000 nominal; ≈4.5% if the
    table is uprated by ~1.3) and the liable share (the rest, ≈75%).
  • Level: total reporters = HMRC Table 1 taxpayers for the calibration year
    (551,000 for 2024-25) ÷ liable share ≈ 0.73m. That puts the sub-exempt
    remainder at about 40k–45k people and loss-makers at about 135k, against
    11.66m and 2.5m today.
  • Gradient: distribute that total across income bands in proportion to
    percent_with_gains, so the clone mass per household is the band's share
    rather than one half.

Calibration then still hits the liable targets (the Table 3 redraw defines
the liable set by rank, and the weights it starts from are on the right
scale). Without this component the amounts fix leaves 0.8m–2.1m entrants a
year; with it the flow is tens of thousands, and the 2.5m weighted
loss-makers, which nothing observes either, shrink to the same order as the
reporters they came from.

4. Validation against HMRC Table 2 (a check, not a source)

The exempt amount fell from £12,300 (2022-23) to £6,000 (2023-24) to £3,000
(2024-25), so gains that were exempt are now observed as taxable bands in
Table 2 (2026 release): 65k taxpayers at £6,000–£10,000 and 24k at
£10,000–£12,300 in 2023-24; 73k at £3,000–£6,000 (£311m), 57k at
£6,000–£10,000 and 26k at £10,000–£12,300 in 2024-25. That is a density of
roughly 24k reporters per £1,000 of gain just above the current threshold. A
smooth extension below £3,000 puts the sub-exempt population among filers in
the tens of thousands to low hundreds of thousands, consistent with component
3's 40k–45k, and 160 times smaller than v20's 11.66m. Use these bands as the
acceptance check on the rebuilt remainder (count in (0, AEA], count within
one year's uprating of the threshold), not as the source of the distribution:
they cover only people with a liability, and people with gains under the
exempt amount need not file unless proceeds exceed £50,000.

5. Gate

Add a terminal check that projects the base-year gains with the engine's
capital_gains factors to the release horizon (2030) and refuses when the
weighted count of base-year non-taxpayers carried past the frozen exempt
amount exceeds the Table 2 £3,000–£6,000 band count for the calibration
vintage (73k for 2024-25) in any projected year. It would have failed v20 at
10.8m.

Why not extrapolate from Table 2

Table 2 gives counts by band for liable taxpayers only; turning it into a
distribution below the threshold needs a parametric tail assumption and a
filing-behaviour assumption, both unobserved. Table A1 already describes
reporters below the threshold directly, is vendored and reviewed, and the
incumbent has used it for this purpose since the imputation was written.
Table 2 is the right check on the result.

Evidence

  • Dashboard branch audit-cgt-uprating of PolicyEngine/uk-equalising-cgt:
    data/dataset_comparison.json (rows entrants_by_uprating.*),
    data/cgt_uprating_audit.json (baseline_by_year.microcosm_uk_2024_v20),
    and the comparison comment on Audit the capital-gains projection the engine applies (issue #2, item 1) uk-cgt-reform#3 (Audit the capital-gains projection the engine applies (issue #2, item 1) uk-cgt-reform#3 (comment)).
  • Direct file check: capital_gains_asset_type == "sub_aea" value counts
    (19,094 records at 3000.00; 10.82m weighted); household weights of gainer
    households (mean 565).
  • microcosm: cgt_imputation.py docstring approximation 4 and the
    np.minimum(existing[remainder], parameters.annual_exempt_amount) line;
    source_stages.json cgt_incidence_clone ("Spine-only equal-mass
    incidence clone").
  • Incumbent uk-data build: datasets/imputations/capital_gains.py
    (impute_cg_to_doubled_dataset: blend-factor weight split to
    percent_with_gains; UnivariateSpline through p05–p95 with seeded uniform
    quantiles).
  • Advani & Summers (2020) Appendix B.1 and Table A1 notes; HMRC Capital Gains
    Tax statistics 2026 release, Tables 1 and 2 (sheets 2_3_2022-23,
    2_2a_2023-24, 2_1a_2024-25).

Decisions

  • Component 3 lives in cgt_incidence_clone: the clone mass per household is
    the income band's share of a total anchored to HMRC Table 1 (level) with the
    Advani & Summers composition and gradient, not a calibration target.
  • Table A1 is used as published (2017-18 nominal), with the vintage documented;
    uprating it changes nothing material for the slice.
  • The gate bound is the Table 2 £3,000–£6,000 band count for the calibration
    vintage, per projected year.

Related: #725 (the amounts redraw and asset types this sits on top of).

Activity

  1. juaristi22 commented on Sep 23, 2026

    @juaristi22
    CollaboratorAuthor

    Two amendments from the implementation (#979), and one thing the new gate found.

    Component 3 (incidence) moved out of the clone stage. The issue proposed making cgt_incidence_clone split each household's mass by an income-band propensity instead of equally. Implementing it showed that the split is the wrong lever:

    • The Table 3 redraw scales any cell short of gainer mass down silently and only reports the residual, so shrinking the clone side starves those cells while keeping it large leaves millions of sub-exempt gainers.
    • Ordinary stage kernels discard weights; only EXPAND kernels return them, and an importance-to-importance REWEIGHT is refused by the executor.

    The PR therefore adds a post-redraw, weights-only structural stage cgt_incidence_anchor (after hmrc_cgt_asset_type_spine). It derives the sub-exempt and loss-making clone mass from the redrawn liable mass and the Advani-Summers reporter composition (each band's zero and exempt-amount crossings, averaged over clone carriers by weight × incidence), trims each group to its target with a factor rising in the band's incidence and capped at one, and moves every unit of removed mass to the clone's paired original. No cell is written, every pair and the household total are conserved to rounding, liable clones, zero-gain clone carriers (no reporters) and band donors are untouched, and a stage-time gate holds the anchor to its declared composition. The level is the liable mass after the redraw (557k on the rebuilt spine, which the redraw pins to HMRC's published taxpayer mass), not Table 1 read directly; the implied reporter total is 748k. On the rebuilt licensed spine the clone side goes from 11.29m sub-exempt and 2.71m loss-making weighted persons to 40.7k and 150k, with the liable clone mass (486.7k) unchanged.

    Component 5 (gate) as built. The fence counts, for every year to 2030, the cumulative stock of build-period sub-exempt gainers whose uprated gains exceed that year's exempt amount, and the largest count must not exceed the vendored Table 2.1a count for the £3,000–£5,999 band (73,000 in 2024-25). 2030 is the last year of the OBR per-capita path in the engine's parameter tree; the path and the exempt amount by year are pinned in the gate's manifest entry and drift-checked. On the calibrated v20 artifact it fails at 10.83m in the first projected year; on the rebuilt candidate calibrated the same way it passes at 67.6k by 2030.

    A second source the fence found. With the clones anchored, most of the remaining entrants are not clones at all. The redraw ranks every gainer in an income band by its prior and fills the published cells from the top, and it never distinguishes the band donors: 119 of the 270 donors, almost all of them in the £12.3k–£250k bands where the clones' Advani-Summers tails outrank the band means, fall into the sub-exempt remainder (321k weighted persons before calibration, 291k after). Of the 67.6k crossers by 2030, 61.2k are demoted donors and 6.4k are clones, so the margin under the bound is about one year of trend. The same demotion existed on v20, where those donors sat at the £3,000 cap. The donor stage's notes call them support households and exclude bands below £12.3k because "the spline body already supplies that support", so a demoted donor is redundant support that has kept its mass as a sub-exempt gainer. How to treat them (protect donors in the redraw's cell selection, drop their mass, or stack donors only where the clone pool is short) is a separate decision this PR does not take.

    Of the three decisions recorded above, the vintage (Table A1 as published, 2017-18 nominal) and the gate bound stand as written; the first is amended as described: component 3 lives in a post-redraw stage, not in cgt_incidence_clone. Measurements and receipts: experiments/970-cgt-sub-exempt-remainder.md and the aggregate-only extracts under docs/evidence/uk-cgt-970/ on the branch.

  2. juaristi22 commented on Sep 30, 2026

    @juaristi22
    CollaboratorAuthor

    Ruling on the demoted donors (29 September): the band-donor stack is retired rather than protected, in #1045.

    The diagnosis first. On every licensed spine of the #1014 line the fence failed at 98,600 to 129,300 against the 73,000 bound, and the whole excess sat on one mechanism: cgt_band_donors stacked 30 copied households per Table 2.1a band at up to 3,267 people each, the Table 3 redraw places each cell's top slice by wealth rank (its second pass never runs on these spines, because pass 1 already overshoots every income band), so three quarters of the donors fell to the sub-exempt remainder and were mapped just under £3,000. They carried 93 percent of the crossing mass and 392,000 households of created mass, and the solver could move them ten-fold. c5's wealth-blended rank made it worse, not better (120 of 270 demoted before it, 204 after), because a donor's wealth is its source household's. A mass-conserving redesign of the stack drawn by income propensity was predicted to demote 300,000 to 360,000 and fail again.

    The redraw owns every gain amount (the Table 3 joint, the size bands, age and region, wealth rank within cells), and calibration binds the twelve Table 2.1a bands at final weights, so the donors' band-mean values were notional and their one remaining function was row support at the top of the distribution, which they failed to deliver because they were drawn by income and placed by wealth. #1045 replaces the stage with cgt_support_split: before the incidence clone, the wealthiest households of each Table 3 income column, up to 2 × 1.25 × the published count of gainers at or above £250,000 in that column, are split into copies of at most 60 (30 after the clone), each copy the same household at an equal share of its weight, no draw and no value assigned. Mass is conserved exactly; the clone stage gives every copy its own prior; the redraw's own walk places them.

    On the licensed spine at the PR head every spine gate and every terminal gate passes. The fence reads 6,711 in 2030, all of it clones (the support copies cross nothing), the anchor's sub-exempt composition sits on its Advani–Summers target, the open band lands at 2,643 people and £47.7bn on 84 rows with the heaviest at 254 against one row near 900 and £62.7bn before, and the weight-ratio fence holds at 1,079 against 1,151 (it needed the headroom at 1.25: at 2.0 the median weight halved as light rows joined). Part G of experiments/1014-cgt-badr-table3-wealth.md carries the five arms. Two things stay open elsewhere: the SPI income-band donors add mass the same way (#1063), and the asset-type stage's residential draw turned out to be fragile on families of copies (a cap of 80 missed its gains bound by a factor of two where every other arm sits at five percent), which deserves its own note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions