QuantCalc Methodology
Technical Documentation v1.4 · Last updated: July 2026
QuantCalc is a browser-based Monte Carlo retirement engine. It simulates a plan in monthly steps across thousands of market scenarios using log-normal returns, Cholesky-correlated assets, and forward-looking capital market expectations from published sources. The engine models stochastic inflation, federal and 51-jurisdiction state taxes, RMDs, IRMAA, and the ACA subsidy cliff, then reports the probability the portfolio sustains retirement — computed locally, with no account or data collection. Details at quantcalc.app.
Looking for the calculator itself? Try the free Monte Carlo simulation calculator →
Prefer plain English on the tax side? See How QuantCalc models retirement taxes — a short FAQ on Social Security taxation, IRMAA, state tax, capital gains, Roth conversions, RMDs and the ACA cliff.
- Introduction
- Monte Carlo Overview
- Asset Return Modeling
- Generating Correlated Returns
- Capital Market Expectations
- Portfolio Return Calculation
- Cash Flow Modeling
- Simulation Execution
- Success Rate and Statistics
- Quasi-Monte Carlo Methods
- Optimization Problem Formulation
- Objective Functions
- Constraints
- Sequential Quadratic Programming
- Multi-Period Optimization
- Initial Point Selection
- Convergence and Termination
- Practical Considerations
- Gompertz Gender-Specific Mortality
- Fat-Tail Returns & Regime Switching
- Stochastic Inflation
- Per-Asset Inflation Coupling (β)
- State Tax, Roth, QCD & IRMAA
- Randomized QMC & Wilson CI
1. Introduction
QuantCalc uses Monte Carlo simulation to model the uncertainty inherent in retirement planning. Unlike deterministic calculators that assume fixed returns, Monte Carlo methods generate thousands of possible future scenarios based on the statistical properties of financial markets.
The fundamental question we answer is: Given your savings, contributions, spending needs, and asset allocation, what is the probability that your portfolio will sustain your retirement?
Real vs nominal dollars
QuantCalc separates three distinct dollar concepts so that the math behind every figure is unambiguous:
- What you enter is in today's dollars. Monthly contribution, annual spending, Social Security, life-event amounts — all interpreted as the purchasing power those amounts have right now. You don't need to project them forward yourself.
- What the engine simulates is nominal. The published Capital Market Expectations (CME) used for asset returns are nominal (before inflation). Internally, the engine inflates your cash flows forward at your inflation rate so that nominal flows meet nominal returns — the arithmetically consistent way to model purchasing-power growth.
- What you see is deflated back to today's dollars. All percentile bands, projection-chart values, sample paths, and yearly statistics are divided by the cumulative inflation factor at each point so the chart reads in today's purchasing power. If you turn off "adjust for inflation," the engine treats your inputs as fixed nominal amounts and skips the deflation step.
Worked example: $100,000 starting balance, 7% nominal return, 3% inflation, no cash flows, 30-year horizon. Internally the engine grows the portfolio to $100,000 × 1.07³⁰ ≈ $761,225 in nominal dollars. Before display, it divides by (1 + 0.03/12)¹²·³⁰ ≈ 2.457 to give ≈ $309,800 in today's purchasing power — the figure you'll see on the chart. The 4% real return implied by the inputs (7% nominal − 3% inflation, approximately) is what's actually visible.
For stochastic-inflation models (AR(1), regime-switching, AR(1) multi-category), each simulation path has its own inflation trajectory, and each path is deflated by its own per-path cumulative CPI factor before percentiles are computed. The deflation is correct path-by-path, not just on average.
Cash-flow timing convention
The simulation runs in monthly steps. Cash flows you enter as annual amounts are divided by 12 and applied at the end of each month, after that month's growth. So a $12,000/year contribution becomes 12 separate $1,000 cash flows: the first lands at the end of month 1 and earns 11 more months of growth before "year 1" on the chart; the last lands at the end of month 12 and earns no further growth in year 1. The effective center of mass of each year's cash flow is roughly mid-year.
This is the institutional convention — it matches how paychecks, bills, and retirement withdrawals actually move through real life. It is not the convention used by typical textbook PMT/FV/PV formulas in Excel or Google Sheets, which assume one annual lump sum either at year-start (annuity due) or year-end (ordinary annuity). When you compare a QuantCalc result against a hand-built annual spreadsheet, the gap is real and predictable:
| Scenario | QuantCalc (monthly) | EOY annual spreadsheet | Gap |
|---|---|---|---|
| $1,000/month contribution, 30 years, 7% nominal | $1,169,452 | $1,133,529 | +3.17% (engine higher; monthly contributions earn more growth) |
| 4% rule on $1M, 30 years, 4% real return | $502,315 leftover | $551,320 leftover | −8.9% (engine lower; monthly withdrawals leave the account earlier) |
| Drawdown to zero: $100k, 10y, 7% | Supports $13,800/yr | Supports $14,237/yr | $437/yr ≈ half a year of growth on $100k |
If you build a verification spreadsheet to sanity-check QuantCalc, you'll see these gaps. They are not arithmetic errors in either model — both are internally consistent. They reflect the difference between annual-lump and monthly-uniform cash-flow timing. To match a QuantCalc number with an annual spreadsheet exactly, your spreadsheet would need to compound monthly and place 1/12 of the annual cash flow at the end of every month.
2. Monte Carlo Simulation Overview
Monte Carlo simulation is a computational technique that uses repeated random sampling to obtain numerical results. For retirement planning, we simulate many possible "paths" that a portfolio might take over time.
The Basic Algorithm
For each simulation s = 1, 2, ..., N:
Initialize portfolio value V₀
For each time period t = 1, 2, ..., T:
Generate random asset returns
Update portfolio value based on returns and cash flows
Record portfolio value Vₜ
Record final outcome (success or failure)
Calculate statistics across all N simulations
With N = 1,000 to 10,000 simulations, we obtain a distribution of outcomes that reflects the range of possibilities given market uncertainty.
3. Asset Return Modeling
Log-Normal Returns
Financial returns are commonly modeled as log-normally distributed. If $P_t$ is the price of an asset at time $t$, the continuously compounded return over one period is:
We assume these log-returns follow a normal distribution:
where $\mu$ is the expected (mean) return per period and $\sigma$ is the volatility (standard deviation) per period.
Converting Annual to Monthly Parameters
Capital Market Expectations are typically quoted as annual figures. For monthly simulation:
The division by $\sqrt{12}$ for volatility follows from the property that variance scales linearly with time for independent returns.
Growth Factor
Given a monthly return $r_t$, the portfolio growth factor is:
4. Generating Correlated Returns
The Challenge
Real asset classes don't move independently. Stocks tend to move together, bonds often move inversely to stocks during crises, etc. We must generate returns that respect these correlations.
Correlation Matrix
For $n$ asset classes, the correlation matrix $\mathbf{R}$ is an $n \times n$ symmetric matrix where $R_{ij}$ is the correlation between assets $i$ and $j$:
Covariance Matrix
The covariance matrix $\mathbf{\Sigma}$ combines volatilities and correlations:
Or in matrix form: $\mathbf{\Sigma} = \mathbf{D} \cdot \mathbf{R} \cdot \mathbf{D}$, where $\mathbf{D} = \text{diag}(\sigma_1, \sigma_2, \ldots, \sigma_n)$.
Cholesky Decomposition
To generate correlated random variables, we use the Cholesky decomposition. Any positive-definite covariance matrix can be factored as:
where $\mathbf{L}$ is a lower triangular matrix.
- Generate $n$ independent standard normal variables: $\mathbf{z} = (z_1, z_2, \ldots, z_n)^T$ where $z_i \sim \mathcal{N}(0, 1)$
- Transform using Cholesky factor: $\mathbf{x} = \mathbf{L} \cdot \mathbf{z}$
- The resulting vector $\mathbf{x}$ has covariance matrix $\mathbf{\Sigma}$
- Add means to get final returns: $r_i = \mu_i + x_i$
5. Capital Market Expectations
QuantCalc references return assumptions derived from publicly available publications by major asset managers. QuantCalc is not affiliated with any of these firms. The data is sourced from publicly available reports, press releases, and financial media coverage.
Capital Market Expectations (CME) are forward-looking estimates of expected returns, volatilities, and correlations for each asset class. Major asset managers publish CMEs annually, and these forecasts are widely reported in public financial media.
QuantCalc's Asset Classes
| Asset Class | Description |
|---|---|
| US Stocks | Large-cap US equities (S&P 500-like) |
| International Stocks | Developed market ex-US equities |
| Bonds | Investment-grade fixed income |
| Real Estate | REITs / Real estate securities |
| Cash | Money market / Short-term treasuries |
Source mapping: Each firm publishes forecasts at varying levels of granularity. Where a source provides separate forecasts for US Large Cap, Mid Cap, and Small Cap equities, QuantCalc uses the Large Cap figure for "US Stocks" as it most closely represents the S&P 500 universe. Similarly, "Bonds" uses investment-grade aggregate or core bond forecasts, and "International Stocks" uses developed-market ex-US figures. For exact sub-category details, consult each firm's published report linked below.
Volatility estimates: Most firms do not publicly publish volatility estimates for exactly QuantCalc's 5 asset classes. Where a source publishes volatility data (e.g., J.P. Morgan's LTCMA includes volatility estimates in their full report), those figures inform our estimates. For other sources, volatilities are representative estimates based on long-term historical realized volatility for each asset class. Typical ranges: US equities 15-17%, international equities 17.5-20%, bonds 5-6.5%, real estate 13-16%, cash ~1%.
Correlation estimates: Published correlation matrices vary by source and methodology. J.P. Morgan's LTCMA includes a comprehensive correlation matrix in their full report. For sources that do not publish complete correlation matrices for these specific asset classes, QuantCalc uses representative estimates consistent with long-term empirical relationships (e.g., US/Intl equity correlation of 0.75-0.85, equity/bond correlation of 0.05-0.15, as documented in Dimson, Marsh & Staunton and other academic research). All correlation matrices are verified to be positive semi-definite for valid Cholesky decomposition.
Real vs. nominal returns: Most sources publish nominal returns (before adjusting for inflation). GMO is a notable exception — they publish real returns (after inflation). QuantCalc converts GMO's real returns to nominal by adding an assumed 2.5% long-term inflation rate, as noted in the GMO source description below. This enables consistent comparison across all sources.
Arithmetic vs. geometric return conventions: Published expected returns come in two conventions. Forward-looking firm forecasts (BlackRock, J.P. Morgan, Vanguard, GMO, Schwab, Invesco) are geometric (compound annual) expectations — the long-run growth rate a buy-and-hold investor would experience. Long-run historical averages, by contrast, are conventionally quoted as arithmetic means of annual returns, which for a volatile asset overstate the achievable compound growth rate by approximately σ²/2 (about 1.9 percentage points for an equity series with 19.5% volatility). QuantCalc tags every source with its convention and converts arithmetic inputs to geometric (μgeometric ≈ μarithmetic − σ²/2) before they enter the lognormal return-generation step, so the Historical source no longer compounds an arithmetic mean as if it were a growth rate — a subtle convention mismatch that roughly doubled long-horizon Historical wealth projections before being corrected in May 2026. All sources therefore simulate on a consistent geometric basis, and Historical-source results are directly comparable with the forward-looking forecasts.
Independent Source Selection
QuantCalc allows you to select separate sources for each of the three CME components:
- Return Expectations: The expected annual return for each asset class. All 8 sources are available since every source publishes return estimates.
- Correlation Matrix: The pairwise correlations between asset classes. Only sources that publish verified correlation data are available (currently JPMorgan LTCMA, Historical, and Equilibrium).
- Volatility: The expected annual standard deviation of returns. Only sources that publish volatility estimates are available (currently JPMorgan, Vanguard, Historical, and Equilibrium).
This separation is important because different firms have different strengths. For example, you might prefer GMO's bearish return outlook combined with JPMorgan's well-documented correlation structure and historical volatility estimates. The backend automatically recomputes the Cholesky decomposition of the correlation matrix whenever sources are mixed, ensuring mathematically consistent correlated return generation.
By default, QuantCalc uses JPMorgan for returns and correlations (their LTCMA is the most comprehensive publicly available dataset) and Historical for volatility (long-term realized volatility is a robust baseline).
Example CME Data (Illustrative — BlackRock, as of Sep 2025)
| Asset | Expected Return | Volatility |
|---|---|---|
| US Stocks | 5.2% | 16.5% |
| Intl Stocks | 7.2% | 17.5% |
| Bonds | 4.1% | 5.5% |
| Real Estate | 6.8% | 14.0% |
| Cash | 3.1% | 1.0% |
CME Sources
QuantCalc references return assumptions derived from publicly available publications by major asset managers. QuantCalc is not affiliated with any of these firms. The data is sourced from publicly available reports, press releases, and financial media coverage.
QuantCalc references Capital Market Expectations from six publicly available sources, each with distinct methodological approaches:
BlackRock Investment Institute
Source: BlackRock return assumptions as reported in Morningstar's annual Capital Market Expectations survey (Christine Benz, "Experts Forecast Stock and Bond Returns: 2026 Edition") and other public financial media.
Last Updated: September 2025 (data as of Sep 30, 2025)
BlackRock's CMAs use a building-block approach combining current yields, expected growth, and valuation adjustments. Their methodology emphasizes regime-based analysis and incorporates macro factors including demographic trends, productivity growth, and monetary policy normalization. 10-year nominal return estimates: US equity 5.2%, US aggregate bonds 4.1%.
J.P. Morgan Asset Management
Source: As published in J.P. Morgan's publicly available Long-Term Capital Market Assumptions (Annual). Available at am.jpmorgan.com and via public press releases.
Last Updated: November 2025
J.P. Morgan's LTCMAs provide 10-15 year forecasts using equilibrium models adjusted for current valuations. Their framework integrates global macro research with quantitative factor models, producing return estimates that account for mean reversion in valuations and yields.
Vanguard Investment Strategy Group
Source: As published in Vanguard's publicly available Economic and Market Outlook (Annual). Available at vanguard.com.
Last Updated: December 2025
Vanguard employs the Vanguard Capital Markets Model (VCMM), a proprietary Monte Carlo simulation tool. VCMM generates 10,000 simulations based on historical relationships, current market conditions, and forward-looking yield curves to produce return distributions rather than point estimates.
GMO (Grantham, Mayo, Van Otterloo)
Source: Headline figures from GMO's 7-Year Asset Class Forecasts (Quarterly), as widely reported in financial press (Reuters, Bloomberg, FT). The underlying GMO research library is at gmo.com/americas/research-library.
Last Updated: January 2026 (Q4 2025 data)
GMO's forecasts are explicitly mean-reverting, assuming asset prices return to historical fair value over a 7-year horizon. Their methodology adjusts current prices for profit margins, valuations (P/E, Shiller CAPE), and dividend yields relative to long-term averages, producing forecasts that often diverge significantly from consensus.
Important note on return type: GMO publishes real returns (after inflation), while all other sources in QuantCalc publish nominal returns. To enable apples-to-apples comparison, GMO's real return forecasts have been converted to nominal by adding an assumed 2.5% long-term inflation rate. For example, GMO's published -6.0% real return for US equities becomes -3.5% nominal. This conversion is approximate; actual future inflation may differ. Users should be aware that GMO's forecasts are notably more pessimistic than other sources, reflecting their mean-reversion methodology and current high equity valuations.
Charles Schwab
Source: As published in Schwab's publicly available Long-Term Capital Market Expectations. Available at schwab.com/learn.
Last Updated: January 2026
Schwab's CMEs provide 10-year forward-looking return estimates derived from their proprietary framework. Their 2026 forecasts project 5.9% for US large cap equities and 4.8% for bonds. Published on their consumer-facing Learn page, these estimates are widely cited in public financial media and press releases.
Invesco
Source: As published in Invesco's publicly available Capital Market Assumptions (Annual). Available at invesco.com as public PDFs.
Last Updated: December 2025
Invesco's Capital Market Assumptions provide long-term return forecasts across a broad range of asset classes. Their methodology combines macroeconomic analysis with valuation-driven models, producing estimates that are published in publicly downloadable PDF reports across multiple regional pages.
Historical Bootstrap PRO
As an alternative to the parametric CME framework above, PRO users can switch to a historical bootstrap return model that resamples actual monthly history instead of drawing from a fitted log-normal distribution. Block lengths follow a geometric distribution averaging 24 months (a Politis–Romano stationary block bootstrap), and all five asset classes are resampled jointly — the same historical month drives every asset at once — so real correlation, volatility clustering, and regime sequencing carry through directly rather than being approximated.
The dataset spans July 1990 through May 2026 (431 months): US and developed ex-US market returns and the listed real-estate industry portfolio (REIT-dominated in the modern era) from the Ken French Data Library, par-bond returns derived from FRED's 10-year constant-maturity yield, and cash returns from FRED's 3-month T-bill yield. Returns are nominal and compose with QuantCalc's inflation model as usual.
Fat tails, regime clustering, and return–inflation coupling are already embedded in the resampled history, so those parametric add-ons don't apply here; the portfolio optimizer continues to use the parametric model. Limitation: the 1990 start excludes the 1970s stagflation era.
6. Portfolio Return Calculation
Weighted Portfolio Return
Given asset allocation weights $w_1, w_2, \ldots, w_n$ (summing to 1) and individual asset returns $r_1, r_2, \ldots, r_n$, the portfolio return is:
Portfolio Statistics
The expected portfolio return: $\mathbb{E}[r_p] = \sum_{i=1}^{n} w_i \cdot \mu_i$
The portfolio variance:
7. Cash Flow Modeling
Time Periods
QuantCalc simulates on a monthly basis from current age to end of plan. Total months:
Cash Flow Components
At each month $t$, the net cash flow $C_t$ consists of:
Pre-Retirement Phase
Before retirement (month $t < t_{\text{retire}}$): $C_t = M_{\text{contribution}} \times I_t$
Post-Retirement Phase
After retirement (month $t \geq t_{\text{retire}}$):
Social Security and Pension
Social Security begins at the specified claiming age:
Supplemental income streams are opt-in. Social Security and pension income are each zero unless you enter an amount — the engine does not assume a benefit on your behalf. A simulation with no Social Security and no pension entered draws spending entirely from the portfolio, which is the conservative baseline for an early-retirement or FIRE plan. To include a benefit, enter its annual amount (today's dollars) and the age it begins; it is then inflated forward like every other cash flow.
Inflation Adjustment
Cash flows are adjusted for inflation to maintain purchasing power:
8. Simulation Execution
Portfolio Evolution
The portfolio value evolves according to:
where $V_t$ is portfolio value, $G_t = 1 + r_{p,t}$ is the growth factor, and $C_t$ is net cash flow.
Handling Ruin
If the portfolio value goes negative, it is floored at zero:
Once $V_t = 0$ during retirement, the simulation is marked as a "failure" (ruin).
9. Success Rate and Statistics
Success Rate
A simulation is "successful" if the portfolio never hits zero during retirement:
Percentiles
- 10th percentile: "Pessimistic" outcome (90% did better)
- 50th percentile (median): "Typical" outcome
- 90th percentile: "Optimistic" outcome
Confidence Interval
The standard error of the success rate estimate is:
For $p = 0.95$ and $N = 1000$: $SE \approx 0.007$, so the 95% CI is approximately $\pm 1.4\%$.
10. Quasi-Monte Carlo Methods
Sobol Sequences
Standard Monte Carlo uses pseudo-random numbers which can exhibit clustering. Quasi-Monte Carlo (QMC) methods use deterministic low-discrepancy sequences designed to fill the sample space more uniformly.
QuantCalc uses Sobol sequences, which provide:
- Deterministic, reproducible results
- Better space coverage than pseudo-random
- Faster convergence: $O(1/N)$ vs $O(1/\sqrt{N})$
Transformation to Normal
Sobol points $u \in [0,1]$ are transformed to standard normal via the inverse CDF:
11. Optimization Problem Formulation
QuantCalc's portfolio optimizer finds the asset allocation that maximizes retirement success probability (or other objectives) subject to real-world constraints. Unlike simple mean-variance optimization, our approach directly optimizes the Monte Carlo simulation output—accounting for sequence-of-returns risk, cash flows, and the full distribution of outcomes.
General Form
Decision Variables
Single-period: $\mathbf{w} = (w_{\text{US}}, w_{\text{Intl}}, w_{\text{Bonds}}, w_{\text{RE}}, w_{\text{Cash}})^T$ — 5 variables
Multi-period (glide path): For $k$ periods, we optimize $k \times n$ weights:
| Periods | Variables | Description |
|---|---|---|
| 1 | 5 | Static allocation |
| 2 | 10 | Two-phase (accumulation/retirement) |
| 3 | 15 | Three-phase glide path |
12. Objective Functions
Maximize Success Rate
Maximize Median Final Value
13. Constraints
Equality: For each period $p$: $\sum_{i=1}^{n} w_{p,i} = 1$
Bounds: $0 \leq w_{p,i} \leq 1$ for all weights (no short selling)
14. Sequential Quadratic Programming (SLSQP)
We use SLSQP because it handles exactly the constraint structure we need: equality constraints (weights sum to 1), bound constraints (0–100% per asset), and a smooth but simulation-derived objective.
The Quadratic Subproblem
At each iteration $k$:
Gradient Estimation
We estimate gradients numerically using finite differences:
A fixed random seed is used for all objective evaluations to eliminate stochastic noise.
BFGS Hessian Update
15. Multi-Period Optimization
For $k$ periods, we flatten the weight matrix into a single decision vector:
| Periods | Variables | Equality Constraints | Gradient Evaluations |
|---|---|---|---|
| 1 | 5 | 1 | 6 |
| 2 | 10 | 2 | 11 |
| 3 | 15 | 3 | 16 |
16. Initial Point Selection
Strategy 1: User's current allocation extended to all periods
Strategy 2: Balanced portfolio: $w_{p,i}^{(0)} = 1/n$ (20% each)
Strategy 3: Age-based heuristic: $w_{\text{stocks}}^{(0)} = 1 - \text{age}/100$
17. Convergence and Termination
The optimization terminates when any condition is met:
- Gradient tolerance: $\|\nabla f\| < 10^{-4}$
- Step tolerance: $\|\mathbf{w}^{(k+1)} - \mathbf{w}^{(k)}\| < 10^{-6}$
- Function tolerance: $|f^{(k+1)} - f^{(k)}| < 10^{-6}$
- Maximum iterations: $k > 100$
18. Practical Considerations
Simulation Noise
A fixed random seed is used for all objective evaluations within the optimization loop. The final optimized allocation is then validated with a fresh simulation run.
Computational Cost
Flat Regions
When success rate is very high (>95%) or very low (<5%), the objective surface becomes flat. Switching to median value objective can help.
19. Tax-Aware Withdrawal Optimization
QuantCalc's Tax-Aware Mode optimizes retirement withdrawals across multiple account types to minimize lifetime tax costs. Unlike naive withdrawal strategies that draw from accounts proportionally or in a fixed sequence, the tax-aware optimizer evaluates hundreds of withdrawal combinations each year to find the mix that minimizes total tax burden while meeting spending needs.
The Tax Problem in Retirement
Retirees typically hold assets across three account types, each with different tax treatment:
| Account Type | Contributions | Growth | Withdrawals |
|---|---|---|---|
| Traditional IRA/401k | Pre-tax (deductible) | Tax-deferred | Fully taxable as ordinary income |
| Roth IRA/401k | After-tax (non-deductible) | Tax-free | Tax-free (qualified distributions) |
| Taxable Brokerage | After-tax | Taxed annually (dividends, interest) | Long-term capital gains rate on appreciation |
Choosing which accounts to withdraw from—and in what amounts—directly impacts:
- Federal income tax (10% to 37% marginal rates)
- Capital gains tax (0%, 15%, or 20% depending on income)
- IRMAA surcharges (Medicare Part B/D premium increases based on MAGI)
- ACA subsidy eligibility (for early retirees under age 65)
- Early withdrawal penalties (10% penalty if withdrawing before age 59½ from traditional accounts)
A naive strategy—such as "withdraw from taxable first, then traditional, then Roth"—can cost tens of thousands of dollars in unnecessary taxes over a 30-year retirement.
Account Structure
The optimizer tracks three account balances:
For the taxable account, we also track the cost basis ratio:
This determines what fraction of a taxable withdrawal is principal (not taxed) versus capital gains (taxed at preferential rates). The single cost-basis ratio is the default model, and is described first because it is what most plans use. The engine internally represents it as a single tax lot; the lot-level model below is a strict generalization that reduces to it exactly when there is one lot.
Taxable Account: Per-Lot Cost-Basis Accounting
Rather than carry a single blended cost-basis ratio for the whole taxable account, the engine tracks the taxable account as a ledger of individual tax lots, each with its own dollar value and cost basis. This matters because a real taxable account is not homogeneous: shares bought at different times have different embedded gains, and which shares you sell changes the tax bill.
The ledger evolves over each simulated path:
- Growth applies to the whole ledger through a single shared growth index, so a lot's current value is its units times that index. Growth never changes the ordering of lots by cost-basis-per-dollar, which keeps the per-month update inexpensive.
- Simulation-created purchases become new lots. After-tax money that flows into the taxable account during the run — reinvested required-minimum-distribution excess, or a positive life-event windfall — is added as a fresh lot whose basis equals the full amount deposited (new money is not phantom gain), tagged with the month it was purchased.
- Sales use specific identification, highest-basis-first (HIFO). When the optimizer draws from the taxable account, it sells the highest-cost-basis lots first, which realizes the smallest gain (or harvests the largest loss) for a given dollar of proceeds — the standard tax-aware lot-selection order.
Short-term vs. long-term character
Each sale carries the correct holding-period character. A lot sold less than 12 months after it was purchased realizes a short-term gain; a lot held 12 months or longer realizes a long-term gain. The distinction is not cosmetic:
- Long-term gains are taxed at the preferential 0% / 15% / 20% capital-gains rates (stacked on top of ordinary income) and flow into the Net Investment Income Tax base.
- Short-term gains are taxed as ordinary income at your marginal bracket, and are likewise included in net investment income for the 3.8% surtax.
Because the initial holdings and user-supplied lots are treated as long-term, short-term character arises only on money the simulation itself deposited and then sold within a year — an uncommon but correctly-priced case.
Optional custom lots PRO
By default the initial taxable balance becomes a single long-term lot whose basis is taxableBalance × costBasisRatio — the same information the single-ratio model used, expressed as one lot. PRO users who know their actual holdings can instead supply up to 8 custom lots, each a {current value, cost basis} pair. The supplied values must sum to the taxable balance (checked to within about 0.1% of the balance, with a $1 floor; otherwise the request is rejected with a clear message); when custom lots are provided the single cost-basis ratio is ignored. All custom lots are treated as long-term. The response reports which mode was used and how many lots are tracked, so the assumptions are visible rather than hidden.
Withdrawal Decision Variables
In each year, the optimizer chooses amounts to withdraw from each account:
where $W_t$ is the target withdrawal amount needed to cover spending for year $t$.
Tax Cost Function
The total tax cost for a given withdrawal mix is:
Every term is evaluated for each candidate mix, and the optimizer selects the mix with the lowest total for that year. In addition to the federal income, capital-gains and penalty terms below, the objective includes the state income tax for the selected state (Section 25), the Net Investment Income Tax (the 3.8% surtax under §1411, levied on long- and short-term gains once modified AGI clears its threshold), and the IRMAA Medicare surcharge. Short-term gains realized from the taxable lot ledger are added to ordinary income before the income-tax term is computed.
Income Tax Component
Ordinary income includes traditional IRA withdrawals, Social Security (if applicable), pensions, and interest/dividends from the taxable account:
Federal income tax is computed using the progressive bracket structure. For married filing jointly in 2026 (indexed for inflation):
| Taxable Income | Marginal Rate |
|---|---|
| $0 – $24,800 | 10% |
| $24,800 – $100,800 | 12% |
| $100,800 – $211,400 | 22% |
| $211,400 – $403,550 | 24% |
| $403,550 – $512,450 | 32% |
| $512,450 – $768,700 | 35% |
| Over $768,700 | 37% |
Capital Gains Component
When withdrawing from a taxable account, only the appreciated portion is subject to capital gains tax:
Long-term capital gains rates (for assets held >1 year) are preferential:
| Taxable Income | LTCG Rate |
|---|---|
| $0 – $94,050 (MFJ) | 0% |
| $94,050 – $583,750 | 15% |
| Over $583,750 | 20% |
Notably, the 0% capital gains bracket creates an opportunity: if ordinary income is low enough, retirees can sell appreciated assets and pay zero tax on the gains.
IRMAA Surcharges
Medicare Part B and Part D premiums increase for high-income beneficiaries based on Modified Adjusted Gross Income (MAGI) from two years prior. For 2026 (based on 2024 MAGI):
| MAGI (MFJ) | Part B Surcharge | Part D Surcharge | Total Annual |
|---|---|---|---|
| Under $206,000 | $0 | $0 | $0 |
| $206,000 – $258,000 | +$70/mo | +$12/mo | +$1,968/yr |
| $258,000 – $322,000 | +$175/mo | +$31/mo | +$4,944/yr |
| $322,000 – $386,000 | +$280/mo | +$50/mo | +$7,920/yr |
| $386,000 – $750,000 | +$385/mo | +$69/mo | +$10,896/yr |
| Over $750,000 | +$420/mo | +$77/mo | +$11,928/yr |
IRMAA creates income cliffs: earning $1 over a threshold can cost thousands in additional premiums.
Early Withdrawal Penalty
Traditional IRA/401k withdrawals before age 59½ incur a 10% penalty (with certain exceptions like Rule 72(t) SEPP):
Required Minimum Distributions (RMDs)
Starting at age 73 (for those born 1951-1959), the IRS requires minimum annual withdrawals from traditional accounts based on the Uniform Lifetime Table:
The optimizer enforces: $w_{\text{trad}} \geq \text{RMD}_t$ when RMDs apply. Failing to take RMDs results in a 25% penalty on the shortfall (recently reduced from 50%). The RMD start age is birth-year dependent under SECURE 2.0: age 73 for those born 1951–1959 and age 75 for those born 1960 or later, derived from the plan's calendar base year rather than hard-coded, so conversion and IRMAA timing line up with the correct first-RMD year.
Standard Deduction and Senior Deductions
Ordinary taxable income is computed after the standard deduction for the filing status, plus two age-based additions once a filer reaches 65:
- Additional standard deduction for the aged (IRC §63(f)). A set add-on to the standard deduction for each filer 65 or older ($1,650 per qualifying married filer, $2,050 unmarried, 2026 amounts). On a joint return it is granted per spouse who is 65+, so a couple where both are 65+ receives it twice. It has no income phase-out.
- OBBBA senior deduction (§70103). A separate $6,000-per-qualifying-individual deduction for filers 65+, available for tax years 2025 through 2028 only, and unavailable to married-filing-separately filers. It phases out at 6% of modified AGI above $75,000 (single / head of household) or $150,000 (joint), applied to each qualifying individual's amount — so a joint return with both spouses 65+ loses $0.12 of deduction per dollar over the threshold and reaches zero at $250,000 of joint MAGI. Because the phase-out depends on MAGI, the deduction is applied after the year's income is known.
Yearly Cash-Flow Sequencing
Within each simulated year the engine resolves the interacting tax events in a set order so that later steps see the correct income base:
- Required minimum distribution first. The RMD floor is computed and, where a Qualified Charitable Distribution is specified, the QCD is applied against that floor (a QCD satisfies the RMD without adding to taxable income). Any RMD beyond the QCD is a taxable distribution.
- Roth conversion. A conversion is ordinary income in the year it occurs. Conversions run only inside their configured age window, which typically ends before RMDs begin.
- Withdrawal optimization chooses the account mix for the remaining spending need.
- Conversion tax funded from real dollars. The additional tax caused by a Roth conversion is paid with actual money drawn from the taxable account, not conjured for free. The engine attributes this cost marginally — the tax with the conversion minus the tax without it — and debits the taxable ledger accordingly (a HIFO sale), so the conversion's true after-tax drag is reflected.
- Reinvestment of RMD excess. When a required distribution forces more out of the traditional account than the spending need, the after-tax excess is not discarded — it is reinvested into the taxable account as a new full-basis lot, matching how a retiree who does not need the RMD for spending actually redeploys it.
IRMAA Two-Year MAGI Lookback
Medicare's income-related surcharge for a given premium year is set from modified AGI two years earlier. The simulation carries this lag explicitly: each year's surcharge is driven by the MAGI recorded two years prior (a short ring buffer of recent MAGI values), rather than the current year's income. In the first years of Medicare, before two years of simulated history exist, the current-year MAGI is used. Married-filing-separately filers use the compressed IRMAA schedule (a steeper ladder with two surcharge steps rather than the five surcharge steps on joint or single returns), and on a joint return where both spouses are Medicare-age the surcharge is levied on each spouse at the couple's joint MAGI — effectively doubling it.
Tax-Exempt (Municipal) Interest
Tax-exempt interest is optional annual income that is deliberately treated the way the tax code treats it — it counts in exactly the places it legally counts, and nowhere else. It is added to the provisional-income base that determines how much Social Security is taxable, and to the modified AGI used for IRMAA, but it is not ordinary taxable income and is not part of the Net Investment Income Tax base. Like pension and Social Security amounts, it is entered in today's dollars and inflated forward.
Social Security Taxation (Provisional Income)
The taxable portion of Social Security is computed with the provisional-income tiers of IRS Publication 915: up to 85% of benefits become taxable as provisional income (AGI excluding Social Security, plus tax-exempt interest, plus half of benefits) rises through the tier thresholds. Married-filing-separately filers who lived apart from their spouse for the entire year use the single thresholds ($25,000 / $34,000); otherwise the separate-filer thresholds are $0 / $0, so their benefits are taxable from the first dollar. This lived-apart distinction is an optional input.
Optimization Algorithm: Grid Search
QuantCalc uses a brute-force grid search over possible withdrawal mixes. For computational efficiency, we discretize the search space:
- Divide total withdrawal $W_t$ into increments of 10%
- Enumerate all combinations: $(w_{\text{trad}}, w_{\text{roth}}, w_{\text{tax}})$ where each is a multiple of $0.1 \times W_t$
- Subject to: $w_{\text{trad}} + w_{\text{roth}} + w_{\text{tax}} = W_t$ and $w_{\text{trad}} \geq \text{RMD}_t$
This produces 66 unique combinations per year. For each combination, we compute total tax cost $C(\mathbf{w}_t)$ and select the minimum.
- Tax brackets create a non-smooth objective with discontinuities
- IRMAA thresholds introduce sharp cliffs
- The search space is small (66 points) and evaluation is fast
- Global optimum is guaranteed (no local minima trap)
Multi-Year Simulation
Each Monte Carlo simulation path now includes yearly tax optimization:
For each simulation s = 1, 2, ..., N:
Initialize accounts: A₀ = (B_trad, B_roth, B_tax)
For each year t = 1, 2, ..., T:
Generate portfolio returns
Apply returns to all accounts
Determine target withdrawal W_t (spending need)
Compute RMD_t if age ≥ 73
Run grid search over withdrawal mixes
Select mix w_t* that minimizes C(w_t)
Deduct withdrawals from accounts
Record tax cost, account balances
Calculate success rate and tax metrics
Metrics Reported
Tax-Aware Mode adds these outputs:
- Lifetime tax cost: Total taxes paid (income + CG + IRMAA + penalties) across all years
- Effective tax rate: Total taxes / Total withdrawals
- Tax savings vs. naive: Comparison against a "taxable-first" strategy
- IRMAA exposure: Years spent in IRMAA brackets
- Account depletion sequence: Which accounts run out first
Practical Impact
For a typical retiree with $2M split across account types, tax-aware optimization can save $100,000 to $300,000+ over a 30-year retirement compared to naive strategies. The savings come from:
- Staying in lower tax brackets by mixing Roth withdrawals
- Harvesting capital gains at 0% when income allows
- Avoiding IRMAA cliffs
- Strategic Roth conversions in low-income years
20. ACA Subsidy Cliff Management
For early retirees (ages 55-64, before Medicare eligibility), the Affordable Care Act (ACA) subsidy cliff represents one of the most significant financial risks in retirement planning. The cliff creates a scenario where earning just $1 of additional income can eliminate $15,000 to $30,000 in annual health insurance subsidies—an effective marginal tax rate exceeding 1,000%.
QuantCalc's Tax-Aware Mode includes ACA cliff detection and optimization to help early retirees navigate this challenge.
What is the ACA Subsidy Cliff?
The ACA provides premium tax credits (subsidies) to reduce the cost of marketplace health insurance for individuals and families below certain income thresholds. Prior to 2026, enhanced subsidies phased out gradually. Starting in 2026, the subsidies revert to the original ACA structure with a hard cutoff at 400% of the Federal Poverty Level (FPL).
For 2026, the cliff occurs at:
| Household Size | 400% FPL (MAGI Threshold) |
|---|---|
| 1 (Single) | $62,600 |
| 2 (Married) | $84,600 |
| 3 | $102,400 |
| 4 | $123,040 |
| +1 per additional | +$20,880 |
If Modified Adjusted Gross Income (MAGI) exceeds the threshold by even $1, the entire subsidy disappears. There is no gradual phase-out.
Subsidy Calculation
ACA subsidies are calculated as the difference between the "benchmark plan" premium (second-lowest-cost Silver plan in your area) and a capped percentage of your income:
where $r_{\text{cap}}$ is the income-based required-contribution percentage. With the ARPA/IRA enhanced subsidies expired after 2025 (and not extended), 2026 reverts to the indexed §36B applicable-percentage table of IRS Rev. Proc. 2025-25 — running from 2.10% up to 9.96%, with the hard 400% FPL cliff restored. The percentage is piecewise-linear within each band:
| MAGI as % of FPL | Required contribution (% of MAGI) |
|---|---|
| Under 133% | 2.10% |
| 133% – 150% | 3.14% – 4.19% |
| 150% – 200% | 4.19% – 6.60% |
| 200% – 250% | 6.60% – 8.44% |
| 250% – 300% | 8.44% – 9.96% |
| 300% – 400% | 9.96% |
| Over 400% | No subsidy (cliff) |
Example: The $1 Cliff
Consider a 62-year-old married couple in Denver, Colorado:
Scenario A: MAGI = $84,000 (below the $84,600 couple cliff)
- Benchmark Silver plan premium: $24,000/year
- Required contribution (9.96% of MAGI): $8,366
- ACA subsidy: $24,000 - $8,366 = $15,634
- Out-of-pocket: $8,366/year
Scenario B: MAGI = $85,000 (above the cliff by $400)
- Benchmark Silver plan premium: $24,000/year
- ACA subsidy: $0 (cliff)
- Out-of-pocket: $24,000/year
Result: Earning an extra $1,000 cost this couple $15,634 in lost subsidies—a 1,563% marginal tax rate.
MAGI for ACA Purposes
ACA subsidies are based on Modified Adjusted Gross Income (MAGI), which is AGI plus certain add-backs. Critically, not all retirement income counts toward MAGI.
Income that COUNTS toward ACA MAGI:
- Traditional IRA/401k withdrawals
- Wages and self-employment income
- Taxable interest and dividends
- Capital gains (including from portfolio rebalancing)
- Rental income (net of expenses)
- Pension income
- Taxable Social Security benefits (if applicable)
Income that DOES NOT count toward ACA MAGI:
- Roth IRA withdrawals (contributions or earnings)
- Municipal bond interest
- HSA withdrawals for qualified medical expenses
- Qualified Charitable Distributions (QCDs) from IRAs
- Return of principal from non-qualified annuities
- Borrowed money (home equity lines of credit, margin loans)
QuantCalc's ACA Cliff Detection
When Tax-Aware Mode is enabled and the user's age is under 65, QuantCalc checks for ACA cliff risk:
- Determine household size from inputs
- Calculate 400% FPL threshold for the applicable year
- Monitor projected MAGI each year during simulation
- Flag cliff proximity: if MAGI is within 5% of the threshold, mark as "cliff risk"
Optimization Strategy
When the ACA cliff is detected, the withdrawal optimizer adjusts its strategy:
Priority 1: Maximize Roth Withdrawals
Since Roth withdrawals don't count toward MAGI, the optimizer prioritizes Roth over traditional accounts when ACA subsidies are at stake:
Priority 2: Harvest Taxable Gains at 0%
If MAGI is low enough to stay in the 0% long-term capital gains bracket (under ~$94,000 for married couples), the optimizer may recommend withdrawing from taxable accounts to "harvest" gains tax-free while staying under the ACA cliff.
Priority 3: Avoid Traditional Withdrawals
Traditional IRA withdrawals add dollar-for-dollar to MAGI. The optimizer minimizes traditional withdrawals except when:
- RMDs require them (age 73+)
- Roth and taxable accounts are depleted
- The cliff is unavoidable (e.g., large RMDs push MAGI over regardless)
Priority 4: Reduce Spending if Necessary
If reducing traditional withdrawals would keep MAGI under the cliff and the subsidy value exceeds the foregone spending, the optimizer may recommend reducing withdrawals (and thus spending) in that year.
Example: If crossing the cliff costs $18,000 in subsidies, it's better to spend $15,000 less that year (living on Roth or reducing discretionary expenses) than to lose $18,000 in subsidies.
Multi-Year Considerations
The ACA cliff is a multi-year optimization problem. Spending down Roth balances aggressively in early retirement (ages 55-64) preserves ACA subsidies but leaves less tax-free money for later years. The optimizer balances:
- Near-term subsidy preservation (Roth-heavy withdrawals during ACA years)
- Long-term tax efficiency (preserving Roth for high-tax years in late retirement)
Cliff Avoidance Tactics
QuantCalc models several advanced tactics automatically or via user configuration:
1. Roth Conversion Ladder (Pre-Retirement)
Convert traditional IRA funds to Roth IRA in low-income years (ages 50-54, or immediately post-retirement). This builds a Roth "cushion" for the ACA years.
2. Tax-Loss Harvesting (Taxable Accounts)
Sell losing positions to offset capital gains from winners, keeping net realized gains (and thus MAGI) low.
3. Bunching Income into Non-ACA Years
If a large income event is unavoidable (stock options vesting, real estate sale), time it for:
- Before retirement (still on employer insurance)
- After age 65 (on Medicare, ACA no longer applies)
4. Spending Flexibility
Model variable spending: reduce discretionary expenses during ACA years to stay under the cliff, then increase spending after Medicare eligibility.
Metrics Reported
When ACA cliff logic is active, QuantCalc reports:
- ACA cliff exposure: Number of years projected MAGI exceeds 400% FPL
- Subsidy value at risk: Total dollar value of subsidies lost due to cliff crossings
- Optimal withdrawal sequence: Recommended mix of Roth, traditional, and taxable withdrawals each year
- MAGI trajectory: Year-by-year projected MAGI relative to the cliff threshold
- Break-even analysis: Trade-off between spending less vs. losing subsidies
Limitations and Assumptions
QuantCalc's ACA cliff modeling assumes:
- Cliff remains at 400% FPL: If Congress restores enhanced subsidies, the cliff may be eliminated or softened
- Benchmark premium estimates: Actual premiums vary by location, age, and plan design
- No mid-year income changes: ACA subsidies are reconciled annually; mid-year income spikes require estimated tax payments
References and Further Reading
For detailed guidance on ACA subsidy optimization, see QuantCalc's ACA Subsidy Cliff 2026 blog post and the ACA Subsidy Calculator.
Part IV documents the PRO-gated modeling extensions. Each feature is off by default and preserves bit-for-bit output when disabled — the baseline Monte Carlo engine described in Parts I–III is a strict subset.
21. Gompertz Gender-Specific Mortality
By default, simulations run a fixed horizon from current_age to life_expectancy. Under the mortality model, we draw per-path terminal ages from a Gompertz distribution with gender-specific parameters, so outcomes reflect the joint distribution of portfolio performance and longevity.
where $M$ is the modal age at death and $b$ is the dispersion parameter. Calibration follows Milevsky (2020) using SSA period life tables:
| Gender | Modal age $M$ | Dispersion $b$ |
|---|---|---|
| Male | 86.0 | 9.5 |
| Female | 89.0 | 9.0 |
| Unisex (default) | 87.5 | 9.25 |
For joint-life scenarios (joint filers with a spouse), each simulation path draws two independent Gompertz death ages. Supplying the spouse's current age enables stochastic widowhood: each path draws a spouse-death year from the gender-specific Gompertz table, so the timing of the first death varies across the distribution rather than being held constant. (A single deterministic spouse-death age can be specified instead when a constant assumption is preferred.)
The first death is a material tax event, and the engine models its consequences. At the start of the year following the first death the filing status flips from joint to single: the brackets compress, the standard deduction and its age-based additions halve, and the IRMAA thresholds halve. Conversely, while both spouses are alive and 65 or older, the couple receives the age-based deductions per spouse and pays the Medicare surcharge on each spouse — effects driven by the same spouse-age input. Social Security is reduced in the year following the first death to reflect the survivor benefit.
22. Fat-Tail Returns & Regime Switching
The two overlays in this section — fat tails and regime switching — add empirical realism to the parametric return model. They are the parametric route to the same properties that the Historical Bootstrap return model (Section 5) captures non-parametrically by resampling actual history. The two are alternatives: when the bootstrap return model is active these parametric overlays (and inflation coupling, Section 24) are disabled, because fat tails, volatility clustering and return–inflation coupling are already present in the resampled data.
Student-t Variance Mixture (Fat Tails)
The Gaussian return model understates the empirical kurtosis of equity returns. When Fat-Tail Returns is enabled, each monthly shock is drawn from a Student-t variance mixture:
The result is Student-t distributed with $\nu$ degrees of freedom. Variance is rescaled by $\sqrt{(\nu-2)/\nu}$ so the marginal variance still matches CME inputs. Recommended: $\nu=5$ reproduces empirical equity kurtosis $\approx 7$.
2-State Markov Regime Switching (Bull / Bear)
A Markov chain with transition matrix $P$ governs monthly switching between a bull and bear regime. In the bear state, the vol of the joint shock is multiplied by regime_bear_vol_mult and the drift shifted by regime_bear_drift_shift:
Defaults ($p_{bb}=0.01$, $p_{\bar b b}=0.15$, vol multiplier $1.8\times$) imply mean bear duration $\approx 6.7$ months and long-run bear probability $\approx 6.3\%$ — consistent with post-war US equity data.
Variance compensation. Under lognormal monthly growth $\exp(\mu_a + \sigma_a z)$, scaling the shock by $m$ in stressed months would, by Jensen's inequality, multiply that month's arithmetic expected return by $e^{(m^2-1)\sigma_a^2/2}$ — a hidden upward drift the user never asked for. The engine cancels it exactly: each asset's log-return in a stressed month receives the Itô correction $-(m^2-1)\,\sigma_a^2/2$. Stressed months therefore have higher variance but unchanged unconditional expected arithmetic return, so enabling regime switching widens the distribution without quietly changing its mean.
For a fully data-driven companion to this model — a Gaussian hidden-Markov fit to 150+ years of monthly real S&P total returns, with a current filtered regime reading refreshed monthly — see the Market Regime Monitor.
Fitted (1871–2026) Preset
The PRO regime panel offers a preset that transfers the fitted two-state structure into the engine: monthly transition probabilities $p_{bb}=0.031$, $p_{\bar b b}=0.151$, a stressed/calm volatility ratio of $2.55\times$, and the full fitted bull–bear drift spread of $-0.0278$/month (log). Because forward-looking capital market expectations are unconditional — they already average over historical bear markets — applying the spread as a raw bear-only drag would double-count bears and depress the unconditional mean by $\pi_{bear}\times$ spread $\approx 5.8\%$/yr. The preset therefore re-centers the shift under the chain's stationary distribution: every month receives $-\pi_{bear}\,\Delta$, leaving the calm state at a small positive offset and the stressed state carrying the full spread. The unconditional expected return matches your CME inputs in expectation; what changes is where losses concentrate — contiguous stressed episodes — which is exactly the sequence-of-returns channel. The spread is estimated on real returns and applied to nominal paths; the difference is second-order because inflation is common to both regimes. Calm-state volatility equals your CME volatility, so unconditional volatility under the preset is moderately above the CME input (regime switching is deliberately a vol-increase overlay, as above).
23. Stochastic Inflation
The default engine compounds a constant CPI rate. The stochastic-inflation module replaces this with one of three user-selectable calibrated processes. Cash flows are stored in real (2025-dollar) terms and multiplied by a per-path cumulative inflation factor inside the simulation loop; this preserves bit-identical output when the model is deterministic.
Method 1 — AR(1) on CPI
Calibrated on FRED CPIAUCSL monthly log-differences, 1947–present (backend/calibration/fit_inflation_ar1.py). Anchored fit (post-1985 sample): $\bar\pi = 2.53\%$/yr, $\varphi = 0.4495$, $\sigma = 0.80\%$/yr.
Method 3 — Multi-Category Correlated AR(1)
Retirement spending is not single-index CPI. Medical, education, and housing categories compound at different rates with imperfect correlations. The multi-category model runs four parallel AR(1) processes on:
| Category | BLS Series | Long-run $\bar\pi$ | $\varphi$ | $\sigma$ (%/yr) |
|---|---|---|---|---|
| CPI (all items) | CPIAUCSL | 2.53% | 0.45 | 0.80 |
| Medical care | CPIMEDSL | 3.48% | 0.55 | 1.20 |
| Education | CUSR0000SAE | 4.54% | 0.60 | 1.50 |
| Housing | CUSR0000SAH | 3.01% | 0.65 | 1.00 |
Shocks are cross-correlated via a Cholesky factor $L$ of a user-overridable correlation matrix (defaults land in backend/calibration/fit_inflation_multi.py). Each life event has a inflationCategory tag that selects which factor compounds that line item — medical events ride the medical-CPI path, tuition rides education, etc.
Method 4 — 2-State Regime (Anchored / Unanchored)
The 1970s and 2021–23 episodes are poorly described by a single Gaussian AR(1). We fit a 2-state hidden Markov model (Hamilton 1989) via the EM algorithm on the full postwar sample:
| State | Mean | Std | Transition to other state |
|---|---|---|---|
| 0 — Anchored | 2.0%/yr | 0.6%/yr | $p_{01} = 0.4\%$/mo |
| 1 — Unanchored | 6.0%/yr | 2.2%/yr | $p_{10} = 2.0\%$/mo |
Stationary distribution gives $P(\text{unanchored}) \approx 17\%$, matching the empirical unanchored months in 1965–1982 + 2021–2023. Calibration is in backend/calibration/fit_inflation_regime.py.
Method 5 — Stationary Block Bootstrap (internal validation only)
Politis-Romano (1994) stationary block bootstrap on historical CPI returns. Blocks are drawn with Geometric lengths (default mean 30 months) and resampled with wraparound. Used as a non-parametric yardstick against which methods 1/3/4 are validated; not user-exposed.
24. Per-Asset Inflation Coupling (β)
Real assets don't respond neutrally to inflation surprises. When coupling is enabled, each asset's monthly log-return is shifted by its inflation beta times the current surprise:
Literature defaults (Ang & Piazzesi 2003; Fama & Gibbons 1984; Bekaert & Wang 2010):
| Asset | $\beta$ | Interpretation |
|---|---|---|
| US Equity | -0.30 | Mildly negative; long-duration cashflows hurt by surprise |
| Intl Equity | -0.20 | Smaller due to FX hedging |
| Bonds | -5.00 | Nominal duration risk — large sensitivity |
| Real Estate | +1.00 | Partial hedge; rents reset with CPI |
| Cash | +0.00 | Near-neutral at monthly horizon |
25. State Tax, Roth Conversion, QCD & IRMAA Refinements
State Tax Engine (51 jurisdictions)
Federal-only tax mode still accounts for most of QuantCalc's audience, but single-state filers see meaningful divergence (FL/TX 0% vs CA 13.3% top). The state engine carries the real 2026 statutory law for all 50 US states plus the District of Columbia. It is not a single blended rate per state: each jurisdiction has its own bracket schedule per filing status, standard deduction, retirement-income treatment, Social Security rule, and capital-gains treatment. The 2025 schedules are checked against each state's Department of Revenue filings and projected forward inside the simulation loop by scaling every dollar-denominated threshold, cap and bracket edge by cumulative inflation (constant statutory thresholds, such as a $1,000,000 surtax floor that does not index, are left unscaled).
Rate schedules
Both progressive (multi-bracket) and flat-rate states are represented, with the correct schedule selected for single, married-filing-jointly, married-filing-separately, and head-of-household filers. Separate filers are handled per each state's actual rule — some states compress the joint brackets by half, others apply one shared schedule across statuses. Distinct head-of-household schedules are carried where a state publishes them.
Retirement-income exclusions
Retirement income is not taxed uniformly across states, and the engine encodes each state's actual rule rather than a flat inclusion:
- Full exclusions — a handful of states (for example Illinois, Pennsylvania, Mississippi) exclude qualified pension and IRA distributions entirely, with no dollar cap; in these states a traditional-to-Roth conversion is likewise not taxed.
- Capped exclusions — many states exclude the first $N of retirement distributions (for example a $20,000 private-pension exclusion, or larger age-tiered caps), sometimes with a lower cap for a younger age band.
- Age gates — exclusions frequently apply only at or above a threshold age.
- AGI cliffs and ramps — some states remove the exclusion entirely above an income limit, others phase it out ratably over an income range.
- Public vs. private pensions — certain states fully exempt government or employer-funded pensions while capping private pensions and IRAs. The optional
pensionTypeinput (public or private) routes the pension stream to the correct treatment; public/employer-funded pensions receive the full exemption where a state grants it.
Social Security
As of the 2026 tax year, eight states still apply some tax to Social Security benefits (Colorado, Connecticut, Minnesota, Montana, New Mexico, Rhode Island, Utah, Vermont), each under its own statutory formula — a full exemption below an AGI threshold with a hard cliff above, a fixed partial inclusion, a ratable phase-out of the exemption, a phase-out credit, an age-plus-income test, or full federal conformity. West Virginia completes its phase-out to full exemption for 2026. The remaining 42 states and the District of Columbia do not tax Social Security. The engine owns this exemption: callers pass the federally-taxable benefit and the filer's age, and each state's real formula decides how much (if any) enters the state base.
Capital gains
Most states tax long-term capital gains at their ordinary rates. The engine also captures the exceptions:
- Flat-rate states (for example Pennsylvania) tax gains at the single statutory rate.
- A few states exempt investment income entirely (for example New Hampshire), so the ordinary/gain split changes the result.
- Washington levies a standalone capital-gains excise — 7% on long-term gains above a large standard deduction, plus an additional 2.9% above $1,000,000 of gain — despite having no income tax.
- Maryland adds a 2% capital-gains surcharge above a federal-AGI threshold; Massachusetts and California apply high-income surtaxes on top of the bracket tax (one inflation-indexed, one set by statute at a constant threshold).
- Montana taxes net long-term gains on its own two-rate schedule; Hawaii caps the tax on gains at an alternative rate; Vermont and New Mexico exclude a flat first slice of gain.
Federal-coupled bases and additional taxes
States that begin from federal taxable income are computed federal-first: the engine calculates the federal result, then hands the post-deduction federal taxable ordinary income and gains (and, where relevant, the year's federal tax liability) to the state engine, so conformity states inherit the real federal deduction stack rather than re-deriving a proxy. Two states allow a deduction for federal income tax paid (Alabama in full including the surtax, Oregon capped and phased out with income), and county/local income taxes that ride on the state taxable base (for example Indiana and Maryland) are supported through an optional localTaxRate input, clamped to a reasonable range.
Roth Conversion Optimizer
Two modes are supported:
- FIXED — convert a constant dollar amount each year in
[rothConvStartAge, rothConvEndAge). - BRACKET_FILL — convert up to the marginal federal bracket ceiling (e.g. the top of 12% or 22%). Amount varies annually with other income.
Conversions add to ordinary income in the year they occur, raising tax and potentially IRMAA tier. The simulator captures this interaction by re-running the full federal+state+Medicare pipeline per year.
Qualified Charitable Distributions (QCD)
For filers aged $\geq 70\tfrac{1}{2}$, up to $111,000 (2026 cap, inflation-indexed — up from $108,000 in 2025) of IRA distributions can be directed to charity and excluded from gross income. QCD reduces AGI, lowering both federal tax and the IRMAA premium tier. The simulator applies the QCD against the required minimum distribution first — a QCD satisfies the RMD without generating taxable income — then treats any remaining distribution normally.
Medicare-Specific Inflation (IRMAA)
Medicare premiums and IRMAA thresholds have historically outpaced core CPI by 1–3 percentage points. Users can decouple the Medicare inflation rate from the headline rate (medicareInflationRate). Defaults use the Medicare Board of Trustees projections; empirical calibration lives in backend/data/medicare/.
IRMAA Two-Year Lookback Projector (/irmaa-projector/)
The IRMAA bracket lookup is a step function in MAGI with a fixed two-year lag between the tax year and the Medicare premium year. The projector accepts a year-by-year MAGI schedule from the user, identifies the lookback MAGI for each premium year (premium year t uses MAGI from year t−2), and applies the 2026 CMS bracket table to produce the projected per-month surcharge plus annual totals. Both single and MFJ filing statuses are supported; for MFJ households where both spouses are Medicare-enrolled, the per-person surcharge is doubled. The Form SSA-44 life-changing-event flow is documented inline so users can identify qualifying situations.
The math is a deterministic table lookup with the 2-year offset and the optional "both spouses on Medicare" multiplier; there's no optimization here, only projection. The free tier offers a 3-year horizon; the PRO tier extends to 10 years and integrates with the bridge optimizer (below) for conversion-window timing.
ACA Marriage Penalty Calculator (/aca-marriage-penalty/)
The marriage penalty under the OBBBA-restored 400% FPL cliff arises because the household-of-two FPL ($84,600 in 2026) is roughly 1.35× the household-of-one threshold ($62,600), not 2×. A two-earner couple with $60k each crosses the cliff jointly but stays under it filing separately. The calculator enumerates 4–6 filing+coverage scenarios (MFJ both ACA, MFJ A-employer-B-ACA, unmarried both ACA, unmarried A-employer-B-ACA, MFJ A-Medicare-B-ACA, MFJ both Medicare) and ranks them by total annual cost (premium + federal tax + IRMAA where applicable).
State-specific Silver-benchmark premiums use the published KFF 2026 marketplace data anchored at age 40, scaled by the CMS 45 CFR 147.102 age-rating curve (3:1 from age 21 to 64). Medicaid expansion status is encoded for all 50 states + DC; non-expansion states trigger a coverage-gap detection when MAGI < 100% FPL. The scenario engine handles the constraint that Medicare-age (≥65) household members cannot be on ACA marketplace plans.
ACA Bridge Optimizer (/aca-bridge-optimizer/)
The bridge optimizer solves the joint multi-year decision problem: given a household's portfolio split (traditional / Roth / taxable), required annual cash-out for living expenses, chronic-condition healthcare cost band, target FPL ceiling, and state of residence, find the year-by-year Roth conversion amounts and withdrawal sequence that minimize lifetime cost (federal + state tax + healthcare net of subsidy + IRMAA from the 2-year lookback) over the bridge from current age to Medicare at 65.
Problem class. The decision space is up to 4 variables per year × 25 bridge years (100 decision variables max). The objective is non-convex, non-smooth, and includes cliff discontinuities at 400% FPL (full subsidy forfeiture), 138% FPL (Medicaid eligibility edge), and the six IRMAA bracket boundaries. Federal and state tax are piecewise-linear with kinks at bracket boundaries. The cash-flow constraint couples decisions across buckets within each year; the IRMAA constraint couples decisions across years via the 2-year lookback.
Solver architecture. Two tiers:
- Free tier — per-year greedy heuristic. Each year, the algorithm computes a fixed-point iteration over (taxable withdrawal, Roth withdrawal, traditional withdrawal, Roth conversion) until cash-flow, MAGI, healthcare cost, and tax all converge mutually (typically <8 iterations, contractive because higher conversion → higher tax → larger cash need → larger withdrawals → larger LTCG MAGI → shrunk headroom → smaller conversion). The greedy captures roughly 95% of the lifetime benefit of full joint optimization per FIRE-community backtests.
- PRO tier — joint nlopt ISRES + SBPLX refinement. Warm-started from the greedy result, the optimizer uses nlopt's ISRES (Improved Stochastic Ranking Evolution Strategy — gradient-free, handles non-smooth constraints) at high population, followed by a deterministic SBPLX local-refinement pass to tighten the result. Cliff discontinuities are handled via a smoothed quadratic penalty added to the objective. The final plan is guaranteed to be at least as good as the greedy warm-start (the optimizer falls back to greedy if it can't improve).
Healthcare model. Chronic-condition out-of-pocket bands are anchored to KFF Health System Tracker data (~$3k/yr for one mild condition, ~$8k/yr for 2–3 conditions, ~$18k/yr for 3+ severe). Premium subsidy follows the OBBBA-restored applicable-percentage curve (0% at ≤150% FPL, scaling to 8.5% at 400% FPL, cliff above). Medicaid (≤138% FPL in expansion states) and coverage-gap (≤100% FPL in non-expansion states) are detected and modeled separately.
State tax. Uses the same 51-jurisdiction engine as Section 25, with the user's MAGI split between ordinary income (other income + traditional withdrawal + conversion) and LTCG (taxable-account withdrawal × gain fraction). Most states tax LTCG at ordinary rates; a handful (e.g., NH) exempt investment income and the split matters.
Verification. The C implementation carries 35 unit tests covering cliff respect across many scenarios, infeasibility handling, money conservation (no money created or destroyed by the simulation), stochastic-run stability, naive-baseline domination, and state-tax variance. The frontend JS module carries an additional 56 tests on the greedy math. Both run as part of the deploy gate.
26. Randomized QMC & Wilson CI
Cranley-Patterson Scrambling
Unscrambled Sobol sequences are deterministic — two runs with the same inputs produce identical output and give no Monte Carlo standard-error estimate. With Sobol Scrambling enabled, each dimension is rotated by a random offset $r_d \sim U[0,1)$:
This preserves the low-discrepancy property while randomizing the realization (Cranley & Patterson 1976). Running $K$ independent scrambled replicates gives an unbiased estimate of the QMC error.
Wilson 95% Confidence Interval on Success Rate
With $N$ simulations and $k$ successes, the normal-approximation CI $\hat p \pm 1.96 \sqrt{\hat p(1-\hat p)/N}$ degrades badly when $\hat p$ is near 0 or 1. The Wilson score interval stays valid across the full range:
where $z = 1.96$. QuantCalc displays this CI next to every success-rate metric.
Pre-Computed Sobol Cache
At container-build time we generate a 10,000-sample × 6,480-dim Sobol cache using QuantLib's Joe-Kuo D7 direction numbers. Dimensions: 9 per month × 720 months (5 asset-return dimensions + 4 inflation-category dimensions), covering the widest model configuration.
27. Implementation Notes
For $N$ simulations over $T$ months with $n$ assets, random numbers needed: $N \times T \times n$. For 10,000 sims × 720 months × 5 assets = 36 million random numbers. Stochastic inflation adds up to $4 \times 720 \times N$ more when method #3 is active.
Optimizations: Pre-generate random numbers in batch, vectorized operations, pre-compute Cholesky factors (asset returns and inflation categories), fixed seed during optimization, OpenMP parallelization of the per-simulation loop.
28. References
- Glasserman, P. (2003). Monte Carlo Methods in Financial Engineering. Springer.
- Jorion, P. (2006). Value at Risk. McGraw-Hill.
- Nocedal, J. & Wright, S. (2006). Numerical Optimization. Springer.
- Kraft, D. (1988). "A software package for sequential quadratic programming." DFVLR-FB 88-28.
- Sobol, I.M. (1967). "On the distribution of points in a cube." USSR Comp. Math. & Math. Phys.
- Joe, S. & Kuo, F.Y. (2008). "Constructing Sobol sequences with better two-dimensional projections." SIAM J. Sci. Comput.
- Cranley, R. & Patterson, T.N.L. (1976). "Randomization of number theoretic methods for multiple integration." SIAM J. Numer. Anal.
- Hamilton, J.D. (1989). "A new approach to the economic analysis of nonstationary time series and the business cycle." Econometrica.
- Politis, D.N. & Romano, J.P. (1994). "The stationary bootstrap." J. American Statistical Association.
- Ang, A. & Piazzesi, M. (2003). "A no-arbitrage vector autoregression of term structure dynamics with macroeconomic and latent variables." J. Monetary Economics.
- Fama, E.F. & Gibbons, M.R. (1984). "A comparison of inflation forecasts." J. Monetary Economics.
- Bekaert, G. & Wang, X. (2010). "Inflation risk and the inflation risk premium." Economic Policy.
- Milevsky, M.A. (2020). Retirement Income Recipes in R. Springer.
- Wilson, E.B. (1927). "Probable inference, the law of succession, and statistical inference." JASA.
- US Bureau of Labor Statistics — CPI series CPIAUCSL, CPIMEDSL, CUSR0000SAE, CUSR0000SAH (FRED).
A. Editorial Standards
QuantCalc's articles and calculators are written and maintained by the QuantCalc Research team. The same engineering team that maintains the simulation backend also writes the public-facing research — there is no separate editorial layer paraphrasing technical content for a general audience.
Verification process
- Primary-source-first: every numerical fact (tax brackets, FPL thresholds, IRMAA tiers, RMD divisors, contribution limits) is verified against the originating government publication, not against a secondary source aggregator. Each article's "Primary sources cited" block links directly to the IRS, SSA, CMS, HHS, or congressional bill text it relies on.
- Computed against the backend: any worked example or scenario in an article is computed using the same C backend the calculators run on. If the math in the article disagrees with the calculator, the article gets corrected.
- Forecast inputs are publicly cited: capital-market expectations (return, volatility, correlation) are sourced from six named investment firms (BlackRock, JPMorgan, Vanguard, GMO, Schwab, Invesco) whose 2026 publications are linked in §5 above. We do not modify these except for the documented GMO real→nominal conversion.
- Update on rule change: when a tax-law or regulatory change is signed (e.g., the One Big Beautiful Bill Act of July 2025, the SECURE 2.0 Act of December 2022), affected articles are updated within 30 days. The "Last reviewed" date on each post reflects the most recent verification pass.
Review cadence
- Annual review — every article is reviewed at least once per calendar year for accuracy against the new tax-year brackets, FPL guidelines, and Medicare premium adjustments. The "Last reviewed" date stamp on each article shows the most recent pass.
- Event-triggered review — when a primary source releases new data (IRS Rev. Proc., CMS annual notice, HHS poverty guidelines, OBRA/OBBBA-class legislation), all affected articles are re-verified within 30 days.
- User-flagged corrections — readers can email [email protected] to flag a specific number; we investigate within 7 days and either correct or document why the existing figure stands.
What you will not find here
- Personalized financial advice. QuantCalc is an educational research tool. We do not know your tax situation, employer plan details, or risk tolerance. A scenario shown by the calculator is one of 10,000 possible paths, not a recommendation.
- Pay-to-play product reviews. When an article mentions a brokerage, fund family, or competing planning tool, we have no commercial relationship with them. There are no affiliate links in our content; the only revenue path is a one-time PRO unlock for our own calculator.
- Backdated edits hidden from readers. Material corrections are dated; the
dateModifiedfield in each article's JSON-LD reflects the actual file mtime, and "Last reviewed" dates appear in the post-meta strip.
Author
QuantCalc Research is the engineering and research team behind QuantCalc. The team's published methodology covers Monte Carlo simulation with quasi-Monte Carlo sampling (Sobol sequences), Cholesky-decomposed correlated returns, log-normal asset return modeling, regime-switching volatility, stochastic inflation with category-specific drift, IRS-compliant federal/state tax computation, and SECURE 2.0-aware RMD/IRMAA modeling. See sections 2-15 above for the full technical specification.
For questions, corrections, or research collaboration: [email protected].
Ready to run your own simulation?
QuantCalc runs this entire methodology in your browser — no account, no data collection.
Open QuantCalc →