Calculation catalog › Monte Carlo
Annuitization sweep annual income
Annual life-annuity income the premium buys at the quoted payout rate.
Field: Annuitization sweep annual income Unit: US dollars Basis: nominal dollars Computed by: Engine Status: Complete chain
Appears in: monte-carlo-page (Annuitization frontier table "Income/yr" column)
Calculation records
-
Annuitization sweep point: premium, annual income and effective allocation Model record, justified by derivation
Purpose: What one point of the SPIA allocation sweep actually buys, and the share of the portfolio it costs.
Statement: For each non-zero grid percent, decisions/annuitization.ts#buildAnnuitizationSweep sets premium = min(gridPct / 100 x the plan's total investable balance, 0.95 x the largest cash-or-taxable account's balance) and SKIPS the point when that premium is under $5,000. A retained point publishes annualIncome = premium x the payout rate (the user's quoted rate / 100 when given, else decisions/spiaQuotes.ts#spiaPayoutRate interpolated at startAge = min(95, max(current age, 65)), the current age being that of the person model/peopleOrder.ts#canonicalFirstPerson puts first, the older (between two people born the same day, the sex order female, male, average and then the smaller id by ordinal comparison decide, so for two people with the same birth date and sex renaming the ids can move the annuitant and every figure on that life), whoever is listed first; every sweep annuity is on that person's life and the notes name them, decision D-PEOPLE-ORDER) and effectiveAllocationPct = premium / total investable x 100, which is below the requested grid percent exactly when the funding cap bound the purchase. Units: nominal dollars; percent of investable. Rounding: none.
Formula:
premium = min(g/100 x V, 0.95 x F); income = premium x rate(startAge); effectivePct = premium / V x 100; skip when premium < 5000-
V: Total investable balance (cash, taxable, equity comp, traditional, Roth, HSA) (unit: usd) (domain: positive) -
F: Largest cash or taxable account balance (the funding account) (unit: usd) (domain: nonnegative) -
g: Requested grid allocation (unit: percent of investable) (domain: g > 0) -
rate(startAge): Life-only SPIA payout rate, linearly interpolated between the table anchors and clamped outside them (unit: fraction of premium per year) (domain: 0.06 to 0.153)
Timing: once per sweep, at the comparison's start year
Rounding: none; the $5,000 floor is a strict under-test
Limits:
- A point only reaches the published list when the shared-path Monte Carlo returns a row for its variant, so the evidence has to run one: it uses a two-path comparison over a two-year horizon (a 1954 birth with planning age 73 from 2026 runs 2026 and 2027) with a fixed seed. The three figures themselves are decided before that run and do not depend on its outcome
- Beyond the worksheet's inputs the evidence plan fixes: a 1954-born single filer so the 2026 current age is 72, a $100,000 cash funding account beside a $100,000 traditional account for a $200,000 investable total, a grid of exactly [2, 60] so the skipped and retained points are both present, no user quote, zero return and zero inflation
- The funding account carries no static allocation, so the sweep's Kitces glidepath controls are not constructible here and attributionAvailable is false; the sweep records that as a note rather than an error
- The skipped $4,000 point is asserted as an ABSENT allocationPct, since a skipped point is never pushed rather than published at zero
Provenance: derived by
codex, implemented byclaude.Independent review:
cursorGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: annuitization-sweep-point.md Mutation receipt: annuitization-sweep-point.mutation.md
Evidence tests: annuitization.evidence.test.ts
Implemented in: annuitization.ts; spiaQuotes.ts; peopleOrder.ts
Is the number of: annuitization-sweep-premium, annuitization-sweep-annual-income, annuitization-sweep-effective-allocation-pct
-
Records that feed this number
-
Temporary deferred-QLAC payout-rate placeholder Model record, justified by derivation
Purpose: A conservative annual payout-rate fraction used for a deferred QLAC starting at 80–85 until a quoted deferred rate is sourced.
Statement: QLAC_DEFERRED_PAYOUT_RATE = 0.16 (annual payout / premium) with no interpolation or rounding. For a $100,000 premium the annual payout is $16,000 and the monthly illustration is 16,000/12 = $1,333.33333333333. Units: fraction of premium per year. Rounding: none on the rate; exact cents on the annual figure; monthly illustration tolerance 1e-9 dollars.
Formula:
payout_annual = 0.16 · premium; payout_monthly = payout_annual / 12-
premium: QLAC premium (unit: usd) (domain: worksheet 100,000) -
0.16: Placeholder annual payout-rate fraction (unit: 1/year) (domain: constant)
Timing: a constant; applied when a deferred QLAC candidate is sized
Rounding: none
Limits:
- No direct deferred quote was obtained; the constant is a placeholder to be replaced at the next refresh of the published parameters
- It is intended to understate candidates (16% vs the age-85 immediate 15.3%), not to represent a sourced market quote
- The census has no QLAC-specific family; annuitization-payout-rate-pct and annuitization-sweep-annual-income are named as the nearest families this placeholder feeds when a deferred QLAC candidate is sized, and are not this constant's published number
Provenance: derived by
codex, implemented bygrok.Independent review:
cursorGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: qlac-deferred-payout-placeholder.md Mutation receipt: qlac-deferred-payout-placeholder.mutation.md
Evidence tests: spiaQuotes.evidence.test.ts
Implemented in: spiaQuotes.ts
Feeds: annuitization-payout-rate-pct, annuitization-sweep-annual-income
-
-
Life-only SPIA payout-rate linear interpolation Data record, justified by dataset
Purpose: The default annual payout-rate fraction of premium at a start age, from the embedded female-conservative anchors.
Statement: Anchors (age, annual payout/premium): (60, 0.060), (65, 0.070), (70, 0.084), (75, 0.103), (80, 0.129), (85, 0.153), the last extrapolated. Below 60 the rate is 0.060; above 85 it is 0.153; otherwise linear in age between the bracketing anchors. At 67.5, t = (67.5 − 65)/5 = 1/2 and the rate is 0.070 + 0.5 · (0.084 − 0.070) = 0.077, so $100,000 of premium pays $7,700 per year. Units: fraction of premium per year. Rounding: none after the table's source-side 0.1-percentage-point rounding down. Absolute tolerance 1e-12 on the rate.
Formula:
r(a) = r_i + (a − a_i)(r_{i+1} − r_i)/(a_{i+1} − a_i) for a_i <= a <= a_{i+1}; r(a) = r_60 for a <= 60; r(a) = r_85 for a >= 85-
a: Payment start age (unit: years) (domain: worksheet 67.5) -
r(a): Annual life-only payout as a fraction of premium (unit: 1/year) (domain: between the bracketing anchors) -
premium: Illustrative premium (unit: usd) (domain: worksheet 100,000)
Timing: a time-invariant lookup on the dated quote table
Rounding: none after the source-side 0.1-percentage-point rounding down of the anchors
Limits:
- Planning defaults only; a user-entered quote always wins
- The age-85 anchor is extrapolated, not quoted
- Female column is the conservative unisex default; male quotes are higher
- annuitization-sweep-annual-income is premium times this rate and annuitization-sweep-premium is the grid premium; those families are fed, not this interpolation's published number
Dataset: annuity.org April 2026 $100,000 monthly-payout table by age/sex; anchors take the female column conservatively, rounded down to 0.1%; age 85 is extrapolated , as of 2026-04-01 , retrieved 2026-07-15
Provenance: derived by
codex, implemented bygrok.Independent review:
cursorGates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass
Worksheet: spia-payout-rate-interpolation.md Mutation receipt: spia-payout-rate-interpolation.mutation.md
Evidence tests: spiaQuotes.evidence.test.ts
Implemented in: spiaQuotes.ts
Is the number of: annuitization-payout-rate-pct
Feeds: annuitization-sweep-annual-income, annuitization-sweep-premium
-
Engine source: engine/src/decisions/annuitization.ts
(AnnuitizationSweepPoint.annualIncome)
The evidence links on this page (each record's worksheet, mutation receipt, evidence tests
and implementation, and the source links) are pinned to engine commit
2624dbdba9fd, committed 2026-10-11.
The live calculation index and
output-family census links point at the repository's main
branch, so you can check this snapshot against them.