Profile
Income & Assets
CPF balances are informational — payouts modelled via CPF LIFE monthly
{{ mode === 'earliest' ? 'Target Spending' : 'Expenses' }}
{{ isSufficient ? 'Surplus at ' + resultLifeExpectancy : 'Shortfall at ' + resultLifeExpectancy }}
{{ fmt(Math.abs(surplusOrShortfall)) }}
Money Lasts Until
{{ moneyLastsUntilAge >= resultLifeExpectancy ? 'Age ' + resultLifeExpectancy + '+' : 'Age ' + moneyLastsUntilAge }}
Total Retirement Income
{{ fmt(totalRetirementIncome) }}
| Age | CPF LIFE | SRS | Other | Investment | Expenses | Net | Balance |
|---|---|---|---|---|---|---|---|
| {{ row.age }} | {{ fmt(disp(row.incomeSources.cpfLife, row.age)) }} | {{ fmt(disp(row.incomeSources.srs, row.age)) }} | {{ fmt(disp(row.incomeSources.other, row.age)) }} | {{ fmt(disp(row.incomeSources.investment, row.age)) }} | {{ fmt(disp(row.expenses.living + row.expenses.oneTime, row.age)) }} | {{ fmt(disp(row.net, row.age)) }} | {{ fmt(disp(row.cumulativeBalance, row.age)) }} |
| Expenses ↓ / Return → | {{ (rd >= 0 ? '+' : '') + (rd * 100) }}% |
|---|---|
| {{ (sensitivity.expenseDeltas[i] >= 0 ? '+' : '') + (sensitivity.expenseDeltas[i] * 100) }}% | {{ fmtShort(cell.surplusOrShortfall) }} |
Earliest Retirement Age
{{ earliestRetirementAge != null ? 'Age ' + earliestRetirementAge : 'Not by ' + resultLifeExpectancy }}
Years Until Retirement
{{ yearsUntilRetirement != null ? yearsUntilRetirement : '—' }}
Add'l Savings to Retire at 62
{{ savingsToRetireAt62 != null ? fmt(savingsToRetireAt62) + '/mo' : 'N/A' }}
| Target Age | Add'l Monthly Savings Needed | Shortfall at Current Plan |
|---|---|---|
| {{ g.targetAge }} | {{ g.monthlySavingsNeeded === 0 ? 'On track' : (g.monthlySavingsNeeded == null ? 'Not feasible' : fmt(g.monthlySavingsNeeded) + '/mo') }} | {{ g.shortfall > 0 ? fmt(g.shortfall) : '—' }} |
