by @eschen42 (https://github.com/eschen42)
Version 0.1.3 - 5 February 2026
This is not financial advice, of course. This code is provided AS IS, with no guarantee that the calculations are correct or that the results are reliable for any particular purpose. If you don't fully understand what to do with this code or the results, pay a professional to get guidance; you'll probably be very glad that you did.
Typical retirement planning tools use "Monte Carlo simulations" to estimate a "probability of success" in funding a retirement, but a complementary tool esists: the "funded ratio".
According to https://retirementresearcher.com/funded-ratio-vs-monte-carlo-simulations-whats-the-best-way-to-plan-for-retirement/:
The Funded Ratio is a straightforward, actionable starting point [for assessing retirement readiness]. It’s particularly appealing for its simplicity and conservative nature, especially for retirees who value clear metrics.
Monte Carlo Simulations are better suited for individuals with more complex financial plans or for those who want to explore “what-if” scenarios, such as variable spending strategies.
I see value in reviewing the funded ratio at the beginning of each year of retirement when deciding how much to spend.
Before diving into the details of how to compute the funded ratio, it is important to note that this description in the next subsection is very dense because it is intended to be more useful for a computer than for a human. A much more user-friendly presentation of the principles underlying this approach to computed a funded ratio may be found:
- (for planning retirement income and spending generally) in Wade Pfau's Retirement Planning Guidebook, ISBN 9781945640209. https://www.google.com/books/edition/Retirement_Planning_Guidebook/sM2uEQAAQBAJ
- (for the funded ratio specifically) at https://retirementresearcher.com/understanding-funded-ratio/.
- Note that that link has at times offerred a 7-day trial membership of the Retirement Researcher Academy, which has a highly sophisticated Funded Ratio calculation tool. It may make sense, however, to deepen understanding of the funded ratio itself before starting the free trial so that you can make the most of the opportunity.
This document provides a brief summary of how to calculate the funded ratio using a programming language called SQL, specifically SQL version implemented by SQLite3 https://sqlite.org/. An SQL programmer can fairly easily add to model any additional income and expense streams that may be needed.
Why SQL might be desirable as an approach:
- "Because I like the declarative approach taken by the SQL language."
- "Because I want to learn to use the SQL language."
- "I want to see and review the formulas that are computing my results."
- "My circumstances are different and I need to take into account different assumptions from the author of the spreadsheet. Also, I hate copying and pasting and inserting cells in a spreadsheet when I am trying to adapt it to do the calculation that I want. I perfer taking a more formulaic approach."
Alternative approaches not using SQL:
- Join Retirement Researcher (see above) and use their tool.
- If it's still available, try out a spreadsheet such as the "AOC Funded Ratio Calculator" linked from https://alloptionsconsidered.com/2022/09/30/reviewing-the-retirement-planning-guidebook-part-1-risa-profiles-and-the-funded-ratio/ (about half-way down the page under the title "Every Good Calculator Needs an Equally Good Spreadsheet".
- Search the web for "retirement funded ratio spreadsheet".
- Figure how to code it yourself in your favorite procedural language.
As applied to retirement spending, the funded ratio is calculated as the present value of all liquid assets over the present value of all liabilities not covered by "reliable income" (such as annuities).
Consider a scenario of a couple at the beginning of retirement (the parameters are presented below). In brief, the couple is funding retirement from available resources: social security, a guaranteed annuity, an investment portfolio, and home equity. Results are adjusted for inflation ("real dollars") to reflect actual "spending power". Results further assume a very conservative rate of return on investments.
| funded | year | calendar | elder | younger | budget | premium | soc_sec | annuity | distribution | dividends | portfolio | house | pv_annuity | pv_distribution |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.89 | 1 | 2026 | 62 | 60 | -120000.0 | -40000 | 0 | 38000.0 | 122000.0 | 81000.0 | 2000000.0 | 500000.0 | 279276.84 | 2804829.55 |
| 0.9 | 2 | 2027 | 63 | 61 | -118320.0 | -40000 | 5633 | 37073.17 | 115613.83 | 77404.39 | 1911219.51 | 503750.0 | 241276.84 | 2682829.55 |
| 0.91 | 3 | 2028 | 64 | 62 | -116663.52 | -40000 | 8450 | 36168.95 | 112044.57 | 74006.74 | 1827326.9 | 507528.13 | 204203.67 | 2567215.72 |
| 0.92 | 4 | 2029 | 65 | 63 | -115030.23 | -30000 | 8450 | 35286.78 | 101293.45 | 70698.74 | 1745647.87 | 511334.59 | 168034.72 | 2455171.15 |
| 0.93 | 5 | 2030 | 66 | 64 | -113419.81 | -20000 | 8450 | 34426.12 | 90543.69 | 67765.52 | 1673222.6 | 515169.6 | 132747.94 | 2353877.7 |
| 0.94 | 6 | 2031 | 67 | 65 | -111831.93 | -20000 | 8450 | 33586.46 | 89795.47 | 65212.68 | 1610189.69 | 519033.37 | 98321.82 | 2263334.01 |
| 0.95 | 7 | 2032 | 68 | 66 | -110266.28 | -20000 | 8450 | 32767.28 | 89049.0 | 62650.81 | 1546933.56 | 522926.12 | 64735.36 | 2173538.54 |
| 0.96 | 8 | 2033 | 69 | 67 | -108722.56 | -20000 | 59210 | 31968.08 | 37544.48 | 60079.69 | 1483449.14 | 526848.07 | 31968.08 | 2084489.54 |
| 0.98 | 9 | 2034 | 70 | 68 | -107200.44 | -20000 | 76130 | 0 | 51070.44 | 59504.75 | 1469253.02 | 530799.43 | 0 | 2046945.06 |
| 0.99 | 10 | 2035 | 71 | 69 | -105699.63 | -20000 | 76130 | 0 | 49569.63 | 58386.67 | 1441646.18 | 534780.43 | 0 | 1995874.62 |
| 1.0 | 11 | 2036 | 72 | 70 | -104219.84 | -20000 | 76130 | 0 | 48089.84 | 57310.99 | 1415086.07 | 538791.28 | 0 | 1946304.99 |
| 1.02 | 12 | 2037 | 73 | 71 | -102760.76 | -20000 | 76130 | 0 | 46630.76 | 56277.5 | 1389568.02 | 542832.21 | 0 | 1898215.15 |
| 1.03 | 13 | 2038 | 74 | 72 | -101322.11 | -20000 | 76130 | 0 | 45192.11 | 55286.05 | 1365087.57 | 546903.45 | 0 | 1851584.39 |
| 1.05 | 14 | 2039 | 75 | 73 | -99903.6 | -20000 | 76130 | 0 | 43773.6 | 54336.44 | 1341640.5 | 551005.23 | 0 | 1806392.28 |
| 1.06 | 15 | 2040 | 76 | 74 | -98504.95 | -20000 | 76130 | 0 | 42374.95 | 53428.52 | 1319222.77 | 555137.77 | 0 | 1762618.68 |
| 1.08 | 16 | 2041 | 77 | 75 | -97125.88 | -20000 | 76130 | 0 | 40995.88 | 52562.14 | 1297830.58 | 559301.3 | 0 | 1720243.73 |
| 1.1 | 17 | 2042 | 78 | 76 | -95766.12 | -20000 | 76130 | 0 | 39636.12 | 51737.14 | 1277460.33 | 563496.06 | 0 | 1679247.85 |
| 1.11 | 18 | 2043 | 79 | 77 | -94425.39 | -20000 | 76130 | 0 | 38295.39 | 50953.4 | 1258108.63 | 567722.28 | 0 | 1639611.73 |
| 1.13 | 19 | 2044 | 80 | 78 | -93103.44 | -20000 | 76130 | 0 | 36973.44 | 50210.78 | 1239772.33 | 571980.2 | 0 | 1601316.34 |
| 1.15 | 20 | 2045 | 81 | 79 | -91799.99 | -20000 | 76130 | 0 | 35669.99 | 49509.16 | 1222448.46 | 576270.05 | 0 | 1564342.9 |
| 1.17 | 21 | 2046 | 82 | 80 | -90514.79 | -20000 | 76130 | 0 | 34384.79 | 48848.44 | 1206134.27 | 580592.08 | 0 | 1528672.91 |
| 1.19 | 22 | 2047 | 83 | 81 | -93049.2 | -20000 | 76130 | 0 | 36919.2 | 48228.5 | 1190827.24 | 584946.52 | 0 | 1494288.12 |
| 1.21 | 23 | 2048 | 84 | 82 | -95654.58 | -20000 | 76130 | 0 | 39524.58 | 47499.05 | 1172816.14 | 589333.62 | 0 | 1457368.92 |
| 1.23 | 24 | 2049 | 85 | 83 | -98332.91 | -20000 | 76130 | 0 | 42202.91 | 46655.63 | 1151990.84 | 593753.62 | 0 | 1417844.34 |
| 1.26 | 25 | 2050 | 86 | 84 | -101086.23 | -20000 | 76130 | 0 | 44956.23 | 45693.62 | 1128237.62 | 598206.77 | 0 | 1375641.43 |
| 1.28 | 26 | 2051 | 87 | 85 | -103916.65 | -20000 | 76130 | 0 | 47786.65 | 44608.28 | 1101439.03 | 602693.32 | 0 | 1330685.2 |
| 1.31 | 27 | 2052 | 88 | 86 | -106826.31 | -20000 | 76130 | 0 | 50696.31 | 43394.69 | 1071473.81 | 607213.52 | 0 | 1282898.55 |
| 1.34 | 28 | 2053 | 89 | 87 | -109817.45 | -20000 | 76130 | 0 | 53687.45 | 42047.78 | 1038216.77 | 611767.62 | 0 | 1232202.24 |
| 1.37 | 29 | 2054 | 90 | 88 | -112892.34 | -20000 | 76130 | 0 | 56762.34 | 40562.31 | 1001538.63 | 616355.88 | 0 | 1178514.79 |
| 1.41 | 30 | 2055 | 91 | 89 | -116053.32 | -20000 | 76130 | 0 | 59923.32 | 38932.89 | 961305.95 | 620978.55 | 0 | 1121752.45 |
| 1.45 | 31 | 2056 | 92 | 90 | -119302.82 | -20000 | 76130 | 0 | 63172.82 | 37153.93 | 917381.0 | 625635.89 | 0 | 1061829.13 |
| 1.5 | 32 | 2057 | 93 | 91 | -122643.29 | -20000 | 76130 | 0 | 66513.29 | 35219.67 | 869621.57 | 630328.16 | 0 | 998656.31 |
| 1.56 | 33 | 2058 | 94 | 92 | -126077.31 | -20000 | 76130 | 0 | 69947.31 | 33124.18 | 817880.93 | 635055.62 | 0 | 932143.02 |
| 1.63 | 34 | 2059 | 95 | 93 | -129607.47 | -20000 | 76130 | 0 | 73477.47 | 30861.31 | 762007.61 | 639818.54 | 0 | 862195.71 |
| 1.71 | 35 | 2060 | 96 | 94 | -133236.48 | -20000 | 76130 | 0 | 77106.48 | 28424.74 | 701845.32 | 644617.18 | 0 | 788718.24 |
| 1.81 | 36 | 2061 | 97 | 95 | -136967.1 | -20000 | 76130 | 0 | 80837.1 | 25807.93 | 637232.76 | 649451.81 | 0 | 711611.76 |
| 1.94 | 37 | 2062 | 98 | 96 | -140802.18 | -20000 | 76130 | 0 | 84672.18 | 23004.14 | 568003.5 | 654322.7 | 0 | 630774.66 |
| 2.11 | 38 | 2063 | 99 | 97 | -144744.64 | -20000 | 76130 | 0 | 88614.64 | 20006.43 | 493985.81 | 659230.12 | 0 | 546102.48 |
| 2.36 | 39 | 2064 | 100 | 98 | -148797.49 | -20000 | 76130 | 0 | 92667.49 | 16807.6 | 415002.54 | 664174.35 | 0 | 457487.84 |
| 2.74 | 40 | 2065 | 101 | 99 | -152963.82 | -20000 | 55680 | 0 | 117283.82 | 13400.27 | 330870.88 | 669155.66 | 0 | 364820.35 |
| 3.62 | 41 | 2066 | 102 | 100 | -157246.81 | -20000 | 55680 | 0 | 121566.81 | 8968.77 | 221451.05 | 674174.33 | 0 | 247536.53 |
| 6.24 | 42 | 2067 | 103 | 101 | -161649.72 | -20000 | 55680 | 0 | 125969.72 | 4301.02 | 106198.06 | 679230.64 | 0 | 125969.72 |
where columns are as follows:
| column | description |
|---|---|
| funded | the "funded ratio" as of year; this is (portfolio + house) / pv_distribution |
| year | how many years into retirement is the current year (starting with 1) |
| calendar | calendar year to which year corresponds |
| elder | age of elder member of couple |
| younger | age of younger member of couple |
| budget | amount to spend in year, in excess of healthcare premiums |
| premium | amount to spend in year for healthcare premiums |
| soc_sec | expected total income (i.e., for both partners) from Social Security for year |
| annuity | "reliable income" from an annuity for year |
| distribution | amount that must be distributed from portfolio during year to meet expenses |
| dividends | expected dividends from portfolio, assuming a conservative rate of return |
| portfolio | expected value of portfolio after addition of dividends and removal of dstribution |
| house | home equity, assuming modest growth |
| pv_annuity | present value of all predicted forthcoming distributions from the annuity; note that this is not included in the funded ratio |
| pv_distribution | present value of all predicted forthcoming distributions from the portfolio |
Notes:
- Control of discretionary spending is the single greatest lever to control success in funding a retirement! Never lose sight of that fact as you plan. This exercise is based on the absurd assumption that spending will be constant, which is extremely unlikely.
- An "annuitized annuity" is an income stream akin to Social Security. These income streams are not "liquid" (i.e., assets that can be traded), so they only affects the funded ratio indirectly be reducing the amount that must be distributed from the portfolio to fund expenses. I am not sufficiently conversant to explain why this is the correct way to handle annuitized annuities; for further information, one might search the web for something like "why should annuitized annuities not be included as part of assets when calculating of the funded ratio for retirement?".
As applied to retirement spending, the funded ratio is calculated as the present value of all assets over the present value of all liabilities. The approach to computing the taken here may be described as follows:
- For simplicity, computations are usually modeled using "real" dollars, i.e., assuming zero inflation.
- All amounts are expressed in terms of the value of a dollar in the "reference year" (typically the starting year).
- For example, one might be computing present value in the year 2024; then all projections might be expressed in 2024 dollars.
- Projected results for future years in nominal dollars can be estimated by multiplying the projected amount by the expected CPI (Consumer Price Index) for the projected year divided by the CPI for the reference year.
- This is not necessary for computing the funded ratio; it's only for viewing results of the analysis in nominal dollars.
- All amounts are expressed in terms of the value of a dollar in the "reference year" (typically the starting year).
- Computing the present value for "reliable income" (guaranteed or known income streams) and known expenses is trivial.
- Estimating the present value of other assets such as a home or business.
- Uncertain streams such as expenses may be projected.
- During retirement, spending generally decreases with decreasing physical ability but eventually increases as medical expenses increase ("Go go years; slow go years; no go years"). https://retirementresearcher.com/retirement-spending-smile/
- The Retirement Researcher approach to the Funded Ratio breaks down the future value of expenses several ways:
- Longevity (i.e., essential) expenses; this implicitly includes taxes and requires liquidity
- Lifestyle (i.e., discretionary) expenses
- Long-term care expenses
- Legacy (i.e., what remains in the estate after expenses stop the death of the spender(s))
- A cruder approach is to lump longevity and lifestyle expenses into a single figure for each year and pay for long-term care and legacy out of the assets remaining near the end of life.
- I suggest shaping the smile as decreasing the yearly budget by 1.4% per year from age 65 until age 83 and, thereafter, increasing the budget by 2.8% each year.
- Investment returns are dependent on portfolio size. This should be computed last:
- Investment returns have to take into account distributions from the portfolio.
- The principal value of the portfolio should never be allowed to be "depleted" below zero for the computations to make sense.
- The real principal value of the portfolio at the beginning of a year is equal to the real principal value for the previous year plus the real returns (dividends and interest) produced by the investments minus the real distributions for the year.
- Use an estimated "discount rate" to estimate the real return for the portfolio.
- "Discount rate" is a term of art that names a variable used by the present value calculation.
- For simplicity, and to be conservative, it is best to estimate the "discount rate" (i.e., the rate of return for the portfolio) as
the real rate of return.
- Arguably, the best approach is to use the going rate for 10-year TIPS (Treasury Inflation-Protected Securities)
- See https://www.fa-mag.com/news/using-tips-to-reveal-a-retirement-plan-s-funded-ratio-73360.html for the argument why this is the case.
- 10-year TIPS is the so-called "risk-free asset". "For long-term investors, an inflation-indexed long-term bond is actually less risky than cash." (Campbell, John Y. Strategic Asset Allocation: Portfolio Choice for Long-Term Investors. https://www.nber.org/reporter/fall-2000/strategic-asset-allocation-portfolio-choice-long-term-investors)
- You can estimate this rate as the going rate for 10-year Treasury bonds minus your estimate for the rate of inflation.
- At the risk of making a circular statement, the market's estimate of the inflation rate for the next ten years is the difference between the going rate for 10-year Treasury bonds and the going rate for 10-year TIPS.
- Arguably, the best approach is to use the going rate for 10-year TIPS (Treasury Inflation-Protected Securities)
Consider the following scenario:
- A married couple are aged 63 and 61 in year 1 of retirement, which begins on January 1, 2026.
- Social Security Income (approximate results are from https://opensocialsecurity.com/)
- Both have retired and do not intend to earn wages again.
- The plan will assume that both will live to be 101 years old.
- The 63 year old has a SocialSecurity PIA of 4000 and plans to claim Social Security at age 69, i.e., in year 9 of retirement.
- The 61 year old has a SocialSecurity PIA of 1000 and plans to claim Social Security at age 62, i.e., in year 2 of retirement.
- When the older spouse turns 69, the younger spouse will switch to the spousal benefit.
- Thus, the couple's Social Security income (without cost-of-living adjustments) will be:
- in year 1, $0;
- in year 2, $5633 (in year 1 dollars);
- in years 3-6, $8450 (in year 1 dollars);
- in year 7, $59,210 (in year 1 dollars);
- in years 8-38, $76,130 (in year 1 dollars);
- in years 40-41, $55,680 (in year 1 dollars).
- The couple has purchased and annitized an annuity (such as a MYGA, a "Multi-Year Guaranteed Annuity") paying 38,000 for years 1-8 (not inflation-adjusted) to bridge between initiation of retirement and the maximum annual income from Social Security.
- It is important to contrast the cost of doing so with the cost of a QLAC (Qualified Longevity Annuity Contract) that starts paying when they are in their mid 80's.
- The couple's investment portfolio starts at $2,000,000 in year 1.
- The discount rate is assumed to be 1.6% in real (inflation-adjusted) terms.
- Whatever remains in the investment portfolio at the end of one year, after distributions have been taken to meet expenses, is assumed to grow by the discount rate and becomes the balance of the investment portfolio at the beginning of the next year.
- The couple owns a $500,000 house.
- The real value of the house is expected to grow 1% per year.
- The couple expects to spend (excluding healthcare premiums and long-term care):
- $120,000 (in year 1 dollars) in year 1;
- a real (not inflation-adjusted) decrease of 1.4% for each year for years 2-20;
- a real (not inflation-adjusted) increase of 2.8% for each year for years 21-40.
- The decreased spending after one spouse passes away is assumed to be spent on long-term care of the other spouse.
- The couple expects to spend on healthcare premiums (but excluding long-term care):
- $40,000 (in year 1 dollars) in years 1-3;
- $30,000 (in year 1 dollars) in year 4;
- $20,000 (in year 1 dollars) in years 5-41.
----- Set parameters to establish the cash flows necessary to compute funded ratio
----------------------------------------------------------------------------------
.parameter clear
.parameter init
-- first year of retirement
.parameter set @retireStart 2026
-- start and demise ages of couple members
.parameter set @elderStart 62
.parameter set @youngerStart 60
.parameter set @elderDemise 101
.parameter set @youngerDemise 101
-- initial assets
.parameter set @house 500000
.parameter set @portfolioFirst 2000000
-- initial budget - everything (including taxes) excepting healthcare premiums
.parameter set @budgetBase -120000
-- health premiums in addition to budgetBase
-- - age to trainsition to Medicare
.parameter set @premiumCutover 65
-- - premium before either is on medicare
.parameter set @premiumEarly -40000
-- - premium when first is on Medicare
.parameter set @premiumMiddle -30000
-- - premium when both are on Medicare
.parameter set @premiumLate -20000
-- real discount rate, e.g., the 30-day yield for VTP
-- https://investor.vanguard.com/investment-products/etfs/profile/vtp
.parameter set @discountRate 0.0155
-- inflation rate, e.g., although I expect it to be 2.5%, I could use the Fed's 2% target
.parameter set @inflation 0.025
-- somewhat conservative real discount rate for real estate
-- Tune for local market; perhaps knock off 25 basis points for safety
.parameter set @homeDiscountRate 0.0075
-- Social Security parameters
.parameter set @ssFirstTransitionYear 2
.parameter set @ssFirstTransitionAmnt 5633
.parameter set @ssFirstInterimAmnt 8450
.parameter set @ssSecondTransitionYear 8
.parameter set @ssSecondTransitionAmnt 59210
.parameter set @ssMaximumAmnt 76130
.parameter set @ssSurvivorYear 39
.parameter set @ssSurvivorAmnt 55680
-- allowance or annuity for bridge to Social Security
.parameter set @annuity 38000
.parameter set @annuityStart 62
.parameter set @annuityEnd 70
-- configure "retirement spending smile"
.parameter set @smileShrink 0.986
.parameter set @smileGrow 1.028
.parameter set @smileCutover 83
INSERT INTO temp.sqlite_parameters (key, value) VALUES (
'@horizon',
(select max(@elderDemise - @elderStart + 1, @youngerDemise - @youngerStart + 1))
);
INSERT INTO temp.sqlite_parameters (key, value) VALUES (
'@elderPremiumCutover',
(select @premiumCutover - @elderStart)
);
INSERT INTO temp.sqlite_parameters (key, value) VALUES (
'@youngerPremiumCutover',
(select @premiumCutover - @youngerStart)
);
UPDATE temp.sqlite_parameters
SET value = @smileCutover - @elderStart
WHERE key = '@smileCutover';
UPDATE temp.sqlite_parameters
SET value = @premiumCutover - @elderStart
WHERE key = '@premiumCutover';
UPDATE temp.sqlite_parameters
SET value = 1 + @annuityStart - @elderStart
WHERE key = '@annuityStart';
UPDATE temp.sqlite_parameters
SET value = @annuityEnd - @elderStart
WHERE key = '@annuityEnd';
-- rate at which real value of annuity payment shrinks each year
INSERT INTO temp.sqlite_parameters (key, value) VALUES (
'@annuityShrink',
(select 1 + @inflation)
);
----- Create the tables to compute funded ratio for each year
----------------------------------------------------------------------------------
-- create initial temporary table of cash flows, excluding dividends
DROP TABLE IF EXISTS temp.flow;
CREATE TEMP TABLE flow AS
WITH RECURSIVE years(y) AS (
SELECT 1
UNION ALL
SELECT y + 1 FROM years WHERE y < @horizon
)
SELECT
y AS year,
y - 1 + @retireStart AS calendar,
@elderStart + y - 1 AS elder,
@youngerStart + y - 1 AS younger,
CASE
WHEN y <= @smileCutover
THEN ROUND(@budgetBase * POWER(@smileShrink, y - 1), 2)
ELSE
ROUND(
@budgetBase * POWER(@smileShrink, @smileCutover - 1) *
POWER(@smileGrow, y - @smileCutover),
2)
END AS budget,
CASE
WHEN y <= @elderPremiumCutover
THEN @premiumEarly
WHEN y < @youngerPremiumCutover
THEN @premiumMiddle
ELSE @premiumLate
END AS premium,
CASE
WHEN y < @ssFirstTransitionYear THEN 0
WHEN y = @ssFirstTransitionYear THEN @ssFirstTransitionAmnt
WHEN y > @ssFirstTransitionYear AND y < @ssSecondTransitionYear THEN @ssFirstInterimAmnt
WHEN y = @ssSecondTransitionYear THEN @ssSecondTransitionAmnt
WHEN y > @ssSecondTransitionYear AND y <= @ssSurvivorYear THEN @ssMaximumAmnt
ELSE @ssSurvivorAmnt
END AS soc_sec,
CASE
WHEN y < @annuityStart THEN 0
WHEN y >= @annuityStart AND y <= @annuityEnd
THEN ROUND(@annuity * POWER(@annuityShrink, @annuityStart - y), 2)
ELSE 0
END AS annuity
FROM years
ORDER BY y;
-- create temporary table to compute dividends and distributions
-- and to update portfolio and house values
DROP TABLE IF EXISTS temp.scenario;
CREATE TEMP TABLE scenario AS
WITH RECURSIVE scen AS (
-- seed row for year = 1
SELECT
f.year,
f.calendar,
f.elder,
f.younger,
f.budget,
f.premium,
f.soc_sec,
f.annuity,
(-(f.budget + f.premium + f.soc_sec + f.annuity)) AS distribution,
ROUND((@inflation + @discountRate) * @portfolioFirst, 2)
AS dividends,
ROUND(@portfolioFirst, 2) AS portfolio,
ROUND(@house, 2) AS house
FROM
flow f
WHERE f.year = 1
UNION ALL
-- recursive step: build year = previous.year + 1
SELECT
f.year,
f.calendar,
f.elder,
f.younger,
f.budget,
f.premium,
f.soc_sec,
f.annuity,
ROUND(-(f.budget + f.premium + f.soc_sec + f.annuity), 2)
AS distribution,
-- this year's dividends are approximately the nominal discount rate times
-- last year's portfolio plus dividends minus distribution,
-- adjusted for inflation
ROUND((@inflation + @discountRate) *
(Z.portfolio + Z.dividends - Z.distribution) / (1 + @inflation), 2)
AS dividends,
-- this year's portfolio is approximately
-- last year's portfolio plus dividends minus distribution,
-- adjusted for inflation
ROUND((Z.portfolio + Z.dividends - Z.distribution) / (1 + @inflation), 2)
AS portfolio,
-- note that home value has its own discount rate
ROUND(Z.house * (1 + @homeDiscountRate), 2) AS house
FROM
flow f JOIN scen Z ON f.year = Z.year + 1
)
SELECT * FROM scen ORDER BY year DESC;
-- create table to compute funded ratio and entabulate results for each year
DROP TABLE IF EXISTS funded_ratio;
CREATE TABLE funded_ratio AS
WITH RECURSIVE fnddrt AS (
-- seed row for year = @horizon
SELECT
ROUND((s.house + s.portfolio) / s.distribution, 2) AS funded,
s.year,
s.calendar,
s.elder,
s.younger,
s.budget,
s.premium,
s.soc_sec,
s.annuity,
s.distribution,
s.dividends,
s.portfolio,
s.house,
s.annuity AS pv_annuity,
s.distribution AS pv_distribution
FROM scenario s
WHERE s.year = @horizon
UNION ALL
-- recursive step
SELECT
ROUND((s.house + s.portfolio) / (Y.pv_distribution + s.distribution), 2)
AS funded,
s.year,
s.calendar,
s.elder,
s.younger,
s.budget,
s.premium,
s.soc_sec,
s.annuity,
s.distribution,
s.dividends,
s.portfolio,
s.house,
Y.pv_annuity + s.annuity AS pv_annuity,
Y.pv_distribution + s.distribution AS pv_distribution
FROM scenario s JOIN fnddrt Y ON Y.year = s.year + 1
)
SELECT * FROM fnddrt ORDER BY year;At this point, the query
SELECT * FROM funded_ratio ORDER BY year;will show the funded ratio for each year at the end of each column. The result of this query for the parameters chosen for this scenario are presented above.
Also, at this point,
.parameter listwould show:
@annuity 38000
@annuityEnd 8
@annuityShrink 1.025
@annuityStart 1
@budgetBase -120000
@discountRate 0.0155
@elderDemise 101
@elderPremiumCutover 3
@elderStart 62
@homeDiscountRate 0.0075
@horizon 42
@house 500000
@inflation 0.025
@portfolioFirst 2000000
@premiumCutover 3
@premiumEarly -40000
@premiumLate -20000
@premiumMiddle -30000
@retireStart 2026
@smileCutover 21
@smileGrow 1.028
@smileShrink 0.986
@ssFirstInterimAmnt 8450
@ssFirstTransitionAmnt 5633
@ssFirstTransitionYear 2
@ssMaximumAmnt 76130
@ssSecondTransitionAmnt 59210
@ssSecondTransitionYear 8
@ssSurvivorAmnt 55680
@ssSurvivorYear 39
@youngerDemise 101
@youngerPremiumCutover 5
@youngerStart 60
and
SELECT 'main' AS schema, name, sql FROM sqlite_schema WHERE type = 'table'
UNION ALL
SELECT 'temp' AS schema, name, sql FROM temp.sqlite_schema WHERE type = 'table';would show:
| schema | name | sql |
|---|---|---|
| main | funded_ratio | CREATE TABLE funded_ratio( |
| funded, | ||
| year, | ||
| calendar, | ||
| elder, | ||
| younger, | ||
| budget, | ||
| premium, | ||
| soc_sec, | ||
| annuity, | ||
| distribution, | ||
| dividends, | ||
| portfolio, | ||
| house, | ||
| pv_annuity, | ||
| pv_distribution | ||
| ) | ||
| temp | sqlite_parameters | CREATE TABLE sqlite_parameters( |
| key TEXT PRIMARY KEY, | ||
| value | ||
| ) WITHOUT ROWID | ||
| temp | flow | CREATE TABLE flow( |
| year, | ||
| calendar, | ||
| elder, | ||
| younger, | ||
| budget, | ||
| premium, | ||
| soc_sec, | ||
| annuity | ||
| ) | ||
| temp | scenario | CREATE TABLE scenario( |
| year, | ||
| calendar, | ||
| elder, | ||
| younger, | ||
| budget, | ||
| premium, | ||
| soc_sec, | ||
| annuity, | ||
| distribution, | ||
| dividends, | ||
| portfolio, | ||
| house | ||
| ) |