Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

UK: model landlord property income on the taxable (net of expenses) concept, not rent received

Chiusa
#1,106 2 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@juaristi22 ci sta già lavorando.

Dal 5/10/2026.

  • #1145 di @juaristi22 — aperta

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

The question

HMRC has confirmed to an external user of its statistics that the Property Rental Income Statistics report property income as declared, before allowable expenses (repairs, insurance, legal and letting fees and so on). Net of those expenses, the totals line up with HMRC's other property-income figures and with the SPI public-use tape. The published PRIS amounts are therefore a gross concept, while income tax is charged on landlords' profit after allowable expenses.

This raises two questions:

  1. What property-income concept does Microcosm UK hold, and what does it calibrate against?
  2. How should property income be modelled, so that property-tax and income-tax analyses use the taxable concept at the right level?

Where Microcosm UK stands today (main)

  • The spine's property_income is FRS rent received, not landlord profit. frs_spine.py:585-599 builds it from the household head's sub-let rent (subrent, tenure types 5–6), plus cvpay (lodgers) and royyr1 (royalties), annualised. Landlords' income from letting other properties isn't in it as a profit concept.
  • No property-income target is bound. All 26 HMRC SPI property-income rows (13 amounts, 13 counts, by total-income band) are excluded. docs/uk-income-anchors-280.md ("Not done here") explains why: the SPI concept is landlords' net income after expenses, and the spine doesn't hold that. hmrc_income_replay_report.json fences the rows (full_frs_tei_band_unavailable, blocked on hmrc_spi_assessable_income).
  • There is no PRIS target anywhere.
  • WAS round 8's DVNetRentAmtAnnualR8 (net rent) is read only as a predictor in was_wealth, never as a target.

So the release neither overstates property income through a gross target nor corrects the FRS's known under-reporting of it. It is close to raw FRS, which is likely too low for landlords.

Related, outside this repo: the Enhanced FRS pipeline (policyengine-uk-data) calibrates property income to the PRIS amount (about £55.5bn for 2023-24). Given HMRC's clarification, that is a gross target, and it overstates taxable property income in analyses built on the Enhanced FRS. That should get its own issue in policyengine-uk-data; this one covers Microcosm UK.

What we should do

The target concept is taxable property profit after allowable expenses, the SPI concept. PRIS should be used for counts of landlords, not for amounts.

1. Put a landlord-profit variable on the spine
  • Keep sub-lets, lodgers and royalties as they are, under a name that says what they are, and add landlord net property profit as its own person-level input. Then the engine's property_income can be the taxable concept without mixing in other things.
  • Check what the engine treats as taxable property income before choosing names:
    • the £1,000 property allowance;
    • Rent-a-Room;
    • the s.24 finance-cost restriction. Residential finance costs aren't deducted from profit and get a 20% tax reduction instead, so "profit after expenses" in the SPI may or may not be before finance costs. Pin down which before binding anything.
2. Impute landlord profit from the SPI
  • Draw it through the existing SPI channel. Use a QRF on the SPI property-profit field, conditioned on:
    • age;
    • region;
    • total income and the other income components;
    • tenure;
    • WAS other-property wealth (the buy-to-let value that #1089 now places).
  • Keep it coherent with wealth. A household with landlord profit should hold other residential property, and the reverse should mostly hold too. The WAS coherence gate added in #1089 is the natural place for that check.
  • Use identity-keyed draws, as the newer stages do, so later stages don't reshuffle it.
3. Bind the right targets
  • Amounts: un-exclude the 26 SPI property-income rows once the spine holds the matching concept. They are net of expenses, which is the taxable concept.
  • Counts: the PRIS landlord count is fine to bind (or keep as a diagnostic beside the SPI counts), because expenses change the amount per landlord, not the number of landlords.
  • PRIS amounts: only as a diagnostic, reported against the modelled gross equivalent (profit plus imputed expenses) if we model expenses. Never as a bound amount.
4. Acceptance checks (receipts)
  • The aggregate net property profit against the SPI total, and against HMRC's net figures.
  • The landlord count against PRIS.
  • The distribution across the SPI income bands, inside the usual fit.
  • Income tax on property income against HMRC's estimate, if one is available.
  • A short note quantifying the gross-to-net gap (PRIS against SPI), so the size of the concept difference is on record.
5. Downstream
  • Flag in the release notes that property-tax analyses (LVT, high-value property charges, property CGT) should read the new landlord-profit variable once it lands.
  • Once a fix is decided, open the matching issue in policyengine-uk-data.

Suggested order

  1. Confirm the engine's taxable property-income definition (allowance, Rent-a-Room, finance costs).
  2. Pin down the SPI field and its concept (before or after finance costs).
  3. Add the spine variable and the SPI-channel imputation behind a stage, with the coherence check.
  4. Un-exclude the SPI amount rows, add the PRIS count, and run a licensed arm with receipts.

This can go on the #1095 tracker if that's simpler.

Lingua principale
Python
Stelle
0
Fork
6
Merge medio
1g 20h
PR unite (30g)
133

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di PolicyEngine/microcosm

Tutte le issue di PolicyEngine/microcosm

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.