The Senior Portfolio Planner: what's under the bonnet

The Senior Portfolio Planner: what's under the bonnet

This is the technical companion to my retirement-quiz post. The Senior Portfolio Planner is a free retirement modelling app in four parts: Parts 1–3 live in the planner itself, and Part 4 ships as Ballast (ballast.sebastianantony.com), a standalone companion that runs the deepest analysis on a plan you export from the planner.

Below: one or two sentences on what each part does, then the assumptions actually baked into it — because a model you can't interrogate is just an opinion with a chart.

It's an educational modelling tool that compares scenarios under stated assumptions. It is not personalised financial, tax or insurance advice.

Assumptions shared by every part

  • Everything runs in your browser. No account, no network calls with your data, works offline. The app deliberately stores nothing between visits — your plan saves to a JSON file you keep.
  • All results are in today's dollars, from an explicit base year (2026).
  • Deterministic by design. Same inputs and seed produce byte-identical results, regardless of how the work is split across processor threads.
  • Every dataset is checksummed with its source, vintage and licence documented; the app refuses to run on tampered or missing data rather than substituting values.
  • 581 automated tests cover the engines, including golden fixtures hand-derived from official IRS worksheets and SSA factor tables.
  • Each app ships as one self-contained HTML file — Ballast weighs 179 KB, still smaller than a single photo from your phone.

Part 1 — Retirement Scenario Explorer

Given your income, spending and savings, Part 1 replays your retirement through thousands of simulated market histories and reports whether, when, and by how much essential spending might fall short. It compares your current portfolio against conservative, balanced and growth alternatives.

Assumptions and calculations:

  • Market returns are resampled from real history, not a formula: US stocks, 10-year Treasuries, T-bills and CPI, 1928–2025 (Damodaran return data; FRED CPI).
  • Block bootstrap: whole calendar years are sampled together (stocks, bonds, cash and inflation from the same year), in circular blocks of 5–10 consecutive years, so bad-year clustering and inflation regimes survive the resampling. 10,000 paths per scenario.
  • Spending is three-tiered: essential, lifestyle, legacy. Under stress the model cuts legacy first, then lifestyle down to a user-set floor (default 40% reduction). Essentials are never silently cut — a shortfall is recorded and reported instead.
  • Fixed annual timing convention: receive income → pay spending and fees at midyear-equivalent timing → cover any deficit by drawing cash, then taxable, then traditional, then Roth → apply the year's returns → rebalance to target at year-end.
  • Part 1 treats taxes as part of your spending estimate and income as money actually deposited after withholding. (Part 2 removes this simplification.)
  • Costs: fund expense ratio default 0.07%; optional advisory fee, default 0.
  • Comparison portfolios: 30/60/10, 50/40/10 and 70/25/5 stocks/bonds/cash — editable, and explicitly comparison scenarios rather than recommendations.
  • Named stress tests replay the return sequences that began in 1966 and 2000.
  • Losses are reported in dollars, and charts show the median, 25th and 10th percentile — never the mean, which flatters.

Part 2 — Tax and Roth Strategy

Part 2 wraps a tax engine around Part 1: it works out which accounts fund each year's spending, what that creates in federal tax, state tax and Medicare surcharges, and whether a Roth conversion schedule improves the lifetime picture.

Assumptions and calculations:

  • All 2026 constants verified from primary sources — IRS Rev. Proc. 2025-32, CMS premium notices, the Federal Register, Publications 590-B and 915 — with each value carrying its source and effective date inside the app.
  • The engine distinguishes how each value evolves: indexed with inflation (brackets, standard deduction), frozen in nominal dollars (Social Security taxability thresholds, NIIT thresholds), published annually (Medicare premiums, IRMAA), or temporary (the $6,000 enhanced senior deduction, with phase-out, expiring after 2028). Future years are labelled as projections under stated assumptions, not future law.
  • Federal tax is computed in worksheet order: ordinary income → Social Security taxability via the IRS worksheet → long-term gains and qualified dividends stacked above ordinary taxable income → deductions → ordinary tax → capital-gains tax → NIIT. State tax uses your effective rate.
  • The tax torpedo is modelled, not approximated: your true marginal rate is measured by recomputing the whole return with $1,000 more income (test fixtures show 22.2% effective marginal inside the 12% bracket).
  • IRMAA uses the statutory two-year MAGI lookback and explicit bracket intervals — for 2026 the first surcharge tier begins above $109,000 single / $218,000 joint, and the top tier begins at $500,000 / $750,000 inclusive — applied per Medicare enrollee, with warnings surfaced two years before a cliff lands.
  • RMDs start at the SECURE 2.0 ages (73, rising to 75), use the prior December 31 balance and the correct owner; RMD dollars not needed for spending are reinvested in taxable with matching basis.
  • The withdrawal–tax circularity is solved properly: withdrawing to pay tax creates more tax, so the engine runs a bounded bisection until net cash matches spending within $1.
  • Roth conversions are compared, not prescribed: none, fill the 12% bracket, fill the 22%, stay below the first IRMAA tier, or a custom annual target — each showing conversions, tax, IRMAA two years later, and ending after-tax wealth. Conversions are skipped in years with an essential shortfall.
  • QCDs: charitable giving is separated from family gifts; qualified charitable distributions reduce taxable IRA income, count toward the RMD, and respect the annual limit ($111,000 for 2026).
  • Taxable holdings are tracked as lots with cost basis, so selling to rebalance or spend generates realistic gains.
  • All Roth scenarios are evaluated on identical random paths (common random numbers), so differences come from the strategy, not the dice.

Part 3 — Social Security and Survivor Planning

Part 3 compares claiming ages for each spouse and models the household transition when the first spouse dies — survivor benefits, single filing status, and the "widow's penalty."

Assumptions and calculations:

  • Longevity comes from the official SSA 2023 period life table (as in the 2026 Trustees Report), by sex and age, checksummed; each spouse's death year is drawn separately on every path. Table anchors: an average 65-year-old woman has a median age at death around 86–87 and a 4.6% chance of reaching 99.
  • Benefit factors follow SSA rules by the month: early-claiming reductions of 5/9 of 1% per month for the first 36 months and 5/12 of 1% beyond; delayed credits of 2/3 of 1% per month (8% per year) to age 70.
  • Spousal benefits include the top-up and deemed-filing rules; delayed credits do not accrue on spousal benefits.
  • Survivor benefits scale from 71.5% at age 60 to 100% at survivor full retirement age, carry the deceased's delayed credits, and apply the 82.5% RIB-LIM cap when the deceased claimed early.
  • The earnings test applies if you claim before full retirement age while working ($24,480 / $65,160 thresholds for 2026), with withheld months credited back through recomputation at FRA.
  • COLA never goes below zero, and benefits already stated in current dollars are not double-COLA'd.
  • Decisions already made are respected: an existing claim is modelled at its actual benefit and age, never re-optimised.
  • The first-death transition follows the real checklist: joint filing kept for the year of death, single filing after; the year-of-death RMD still taken; accounts rolled to the survivor exactly once; basis step-up applied (default half for joint ownership, full for community property — a user setting, not an inference); pensions cut to their survivor percentage; household spending reduced by a survivor factor you choose.
  • Claiming scenarios share identical simulated markets and lifespans (common random numbers), and results include explicit long-life checks at ages 95, 100 and 105.
  • The recommendation language is deliberate: "model-preferred under these assumptions," never "best claiming age."

Part 4 — Ballast (the advanced analysis)

Part 4 adds the risks that need specialised modelling — paid long-term care, annuities, TIPS ladders, home equity — and a search across all the levers at once. It lives in Ballast, its own app: export your plan from the planner, drop the file into Ballast, run the search, and carry the updated plan back. Parts 1–3 remain a complete app without it.

Assumptions and calculations:

  • Long-term care uses age-conditional incidence and duration, calibrated so that roughly 48% of adults 65+ receive some paid care over their lifetime, and about 24% of all older adults — roughly half of care recipients — receive more than two years.
  • Care costs progress through home care, assisted living and nursing care under a documented transition model, inflating at CPI plus an explicit care-cost premium.
  • LTC insurance is modelled mechanically: elimination period before benefits start, benefit period limits, inflation riders compounding from the issue year, payouts never exceeding covered costs.
  • HSA dollars fund only model-qualified expenses (Medigap premiums are not qualified), and HSA-first versus HSA-preserve strategies are compared rather than assumed.
  • A TIPS ladder is modelled as actual maturities with real cash flows — not "TIPS as a percentage of bonds."
  • Annuities come from user-entered quotes with purchase age, single/joint life, survivor percentage, tax treatment and a displayed as-of date.
  • The policy search covers a finite, understandable menu — five stock allocations, cash-reserve sizes, the claiming and Roth scenarios already validated in Parts 2 and 3, optional annuity or ladder — every candidate scored on identical random paths.
  • The objective is a transparent hierarchy, not a composite score: minimise essential-shortfall severity, then frequency; reject plans exceeding your dollar loss tolerance; then maximise lifestyle funding and the bequest goal; prefer the simpler plan when results are close. Every component is reported separately.
  • Risk need, capacity and tolerance are treated as bounds — and if the return you need exceeds what your capacity supports, the app reports the plan as infeasible under current inputs rather than hiding the conflict.

If you want to check any of this against the sources, the app documents its data sources and vintages — IRS, CMS, SSA, and the return series, each with a date. Run your own numbers, then load your exported plan into Ballast when you're ready for the deep end; the key assumptions are yours to change, which is rather the point. A plan you can't stress-test isn't a plan — it's a hope with formatting.