Conversation
SEINCAM2 records a self-employment loss as a negative profit ("Any losses
are recorded as such", FRS methodology glossary). The build floored it at
zero, so about 74,000 people's £1.28bn a year of losses (2024-25, before
uprating) disappeared. policyengine-uk wants the profit and the loss as two
non-negative inputs, because its programmes treat a loss differently:
Income Tax and tax credits set it against other income, means-tested
benefits do not, and HBAI counts it as negative income.
Split SEINCAM2 into self_employment_income (the profit, unchanged) and
trading_loss (the loss as a positive amount). SPI-donor rows of the
enhanced FRS carry no trading loss: their self-employment profits come
from the SPI, so their FRS donor's loss would sit beside another
taxpayer's imputed incomes.
Tests: Hypothesis properties of the split (non-negative, exclusive,
conserves the reported profit, monotone) and data checks on the built FRS
and enhanced FRS. Adds hypothesis to the dev extras.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FRS 2024-25 records self-employment losses as negative SEINCAM2 ("Any losses are recorded as such", FRS methodology glossary). The build floored them at zero, so about 74,000 people (weighted) and £1.28bn a year of losses (2024-25 prices, before uprating) disappeared from the data.
This PR splits SEINCAM2 into two non-negative inputs:
self_employment_income: the profit, unchanged (stays non-negative, astest_non_negative_incomesrequires);trading_loss: the loss as a positive amount.Their difference is the reported profit. policyengine-uk needs them apart because its programmes treat a loss differently: Income Tax and tax credits set it against other income, Class 4 against trading profits only, means-tested benefits never offset it against other earnings, and HBAI counts it as negative income (PolicyEngine/policyengine-uk#2085).
Checked before relying on the sign: none of the negative values is a survey missing-value code. The five small whole-number values between −£9 and −£1 a week are all different, and each of those adults reports a loss on a self-employed job (PROFIT2).
SPI-donor rows carry no trading loss. Their self-employment profits are imputed from the SPI, which this build does not draw losses from. Keeping the FRS donor's loss would pair one respondent's loss with another taxpayer's imputed incomes. Imputing a loss instead would add random draws and shift the rest of the build. So
impute_incomesets theirtrading_lossto zero, and the FRS rows carry the losses.Nothing else changes: the split adds no random draws, and policyengine-uk releases before #2085 read
trading_lossonly as a deduction from self-employment income, which is zero for every loss-maker in the data, so calibration targets are unchanged.Tests
test_trading_loss.py: Hypothesis properties ofsplit_self_employment_profitfor any weekly profits, including missing values: both outputs non-negative, never both positive, profit less loss equals the annualised reported profit, and monotone in the reported profit. Data checks on the built FRS (no person has both a profit and a loss) and enhanced FRS (SPI-donor rows have no loss).test_non_negative_incomes.pycoverstrading_loss.hypothesisto the dev extras (the same line as Say which joint occupiers each FRS non-dependant family resides with #522, Supply is_claimant_or_partner from the FRS adult table #524 and Set UC gainful self-employment from the FRS main-job status #525; whichever lands second relocks).Impact
Pending: the branch build is queued behind other builds (one heavy job at a time). The runs: policyengine-uk main and #2085 on this build with
trading_losszeroed (must match), then #2085 with the losses.Merge
Part of the batched uk-data release (d833): approved on gates, then merged with the batch on Max's go. Lands after PolicyEngine/policyengine-uk#2085 is released, so the data's losses are read by the new rules.
Review
Pending: independent review on the final head.
🤖 Generated with Claude Code