Feb 4, 2026

GPT Prompt04 - Portfolio Longevity Heat Map

This may, in fact, be the least useful and perhaps the hardest to explain, in terms of its usefulness, of the miscellaneous prompts in my recent Prompt Series:
  • GPT Prompt 01 - Spending Strategy Comparisons
  • GPT Prompt 02 - Lifetime Probability of Ruin (LPR)
  • GPT Prompt 03 - Dynamic HJB Spend Optimization 
  • GPT Prompt 04 - Portfolio Longevity Heat Map <-- [this post]
  • GPT Prompt 05 - Perfect Withdrawal Rate (PWR)
  • GPT Prompt 06 - Stochastic Present Value (SPV)
My original goal in doing this type of exercise was to create a simple XY chart for (infinite horizon, not 30 years or "to 95") portfolio longevity (X axis) at "all" spend rates (Y axis) rather than just one. I thought it looked pretty cool but my quant-friend David: "why would you even do that? How is this used?" To which I might have said: "I have no idea, I just think it is interesting to behold the relationship between spending rates and portfolio-lives in all its glory, no real necessary functional use for a retiree." I mean, that's a little tongue-in-cheek, I will grant, but it is mostly true. The best I can say is that understanding how portfolio longevity (entirely unconstrained by years or terminal life or anything) responds to spending (all of them) and then understanding the sensitivity of portfolio longevity along its spend-path critical points is worth at least one minute or two of thought. Whether it improves retirement decision making is totally up in the air. This just falls into the category of "I wanted to see what it looked like" and here we are.  

Here's another way to try to articulate this. Think of this heat map as a topology or maybe a terrain of infinite retirement (think about really early retirees, endowments or maybe long dated trusts). Now also consider the 12th century Mongols. They created one of the largest geographic land empires in history by being really good at stuff like horsemanship, use of composite recurve bows, fearlessness and greed, the retreat-feint thing, and a superlative command of terrain, a command of terrain later mooted by fortifications, Hungarians, Poles, and Lithuanians etc yes but that comes in the mid 13th C. This prompt, then, might be considered a battle-terrain map and our job is to understand, at a meta level, the field of retirement battle in terms of spending and portfolio longevity. Where are we going to fight? where we are weak at say a 9% spend? or where we are strong where the terrain bends towards much longer lived portfolios at 4 or 5% spend? What hill or redoubt, exactly, will we defend to gain empire? Ok that's enough of that. 

If I were to let ChatGPT explain in more tempered language what all this means technically based on the work we, Chat and I, did together to figure it out, after I coded this in R 10 years ago, then it might look something rather like this, something I have not vetted very carefully AT ALL:



The Prompt Itself (some of this is not necessary btw): 

----- prompt begin -----

Simulate a Portfolio Longevity Heat Map (PLSR) with the following setup:

Goal: Estimate the probability distribution of the first year a retirement portfolio ruins, for a range of constant real spending rates. Display it as a color heat map with spend rate on the Y-axis and ruin year (1–100) on the X-axis.


1. Parameters
   •   Random seed = 12345
   •   Arithmetic mean real return = 0.039 = mu_a
   •   Standard deviation = 0.10 = sd_a
   •   Annual fee = 0.000 = fee_aum
   •   Horizon = 100 years (year 100 represents “infinite life”)
   •   Spend rates = 1.00 % to 12.00 % of initial wealth in 0.01 % increments
   •   Reuse random draws in batches of 50 spend rates (common random numbers, CRN).

2. Adaptive sampling

Simulate more paths for low spend rates:
   •   For spends below 4 %: 1200 paths per spend level
   •   4–6 %: 700 paths
   •   6 % and higher: 300 paths

3. Return calibration

Calibrate the lognormal distribution so its arithmetic mean and standard deviation of returns match mean return mu_a and standard deviation sd_a:
\sigma_{\text{log}} = \sqrt{\ln(1 + \frac{\sigma^2}{(1+\mu_a)^2})}, \qquad
\mu_{\text{log}} = \ln(1+\mu_a) - \tfrac{1}{2}\sigma_{\text{log}}^2
Multiply each gross return by (1 – fee).

4. Ruin detection (prefix-annuity first-passage method)

For each simulated return path:
1. Form the cumulative wealth path P_t = \prod_{k=1}^{t} G_k.
2. Form the cumulative annuity factor A_t = \sum_{k=1}^{t} 1/P_k.
3. Portfolio ruins the first time A_t ≥ 1/s, where s = spend rate.
4. Record that ruin year. If no ruin by year 100, record 100.

5. Build PMF of ruin years

For each spend rate, record the probability mass (PMF) of ruin in each year 1–100.
Verify that each row sums to 1.

6. Compute summary statistics
   •   p_{100} = probability of no ruin before year 100 (“infinite life”).
   •   Average p_{100}.
   •   Smooth p_{100} with a [1, 2, 3, 2, 1] kernel to locate its sharpest drop (“cliff”), which marks the spend rate of maximum slope s^*.

7. Visualization
   •   Plot a single heat map for ruin years 1–100.
   •   X-axis = years to ruin (1–100).
   •   Y-axis = spend rate (% of initial wealth).
   •   Color = PMF mass (linear scale, 5th–99.5th percentile clipped).
   •   Colormap = plasma_r.
   •   White background for zero mass.
   •   Dashed black line at x = 30 years.
   •   Colorbar label: “PMF mass (linear, clipped 5–99.5 %)”.
   •   Annotate text in upper-right corner showing:
      •   average p_{100},
      •   cliff ≈ 100 × s^* %.
   •   Title line:

Portfolio Longevity Heat Map (PMF of ruin year, 100-year horizon)
μ=mu_a
σ=sd_a
fee=fee_aum
T=100
W0=1
paths≈<computed total> (adaptive by spend)

8. Output summary

After the chart, print the calibrated parameters and results:

sigma_log = ...
mu_log = ...
avg p100 = ...
cliff ≈ 100*s_star %

After completing the 100-year heat map, create an additional chart to visualize the year-100 probability of survival (no-ruin mass) as a function of the spending rate.
1. Extract the last column of the PMF (p100), representing the probability of no ruin before year 100.
2. Plot this as a 2-D curve:
      •   X-axis: spend rate (% of initial wealth)
      •   Y-axis: PMF mass at year 100 (p₁₀₀)
      •   Reverse the X-axis so low spends appear on the right.
      •   Overlay a Savitzky–Golay smoothed version of the same curve (window_length≈81, polyorder=3).
3. Compute the first derivative of the smoothed line with respect to the spend rate, and identify the point of maximum slope (the true “cliff”).
4. Mark that point with a red dot and an arrowed label showing:

Max slope
(spend ≈ <s_true*100> %, p100 ≈ <p_true>)

# Add visible label for the slope point after inverting X
ax1.annotate(
f"({s_true*100:.2f}%, {p_true:.3f})",
xy=(s_true * 100, p_true),
xytext=(s_true * 100 + 1, p_true + 0.05),
textcoords="data",
arrowprops=dict(arrowstyle="->", lw=1.0),
fontsize=9,
ha="left", va="bottom"
)

5. Add a secondary Y-axis showing the derivative magnitude for visual reference.
6. Title the chart:
Year-100 Heat vs Spend — True Max Slope (Savitzky–Golay Smoothed)
7. Include printed numeric output for:
spend* = ...
p100(spend*) = ...

End Printing wrap up

Finally, compute and print the estimated N-period geometric mean return for the given horizon using mu_a and sd_a
1. Use the formula
G_N = \mu_{\text{arith}} - \tfrac{1}{2}(1 - \tfrac{1}{N})\sigma^2
where
  • \mu_{\text{arith}} and \sigma are the portfolio’s arithmetic mean mu_a and standard deviation sd_a, and
  • N is the horizon length (here N = 100).
2. Multiply by 100 to express in percent.
3. Print a labeled line in this format:

100-year geometric mean ≈ <value:.2f> %

———————-

After the Savitzky–Golay chart, generate a third visualization to show a parametric sigmoid fit between spending rate and year-100 survival probability.

9. Logistic Fit and Inflection Analysis

Fit a 4-parameter logistic (sigmoid) curve to the raw p_{100}(s) data to identify the analytical inflection point—the spend rate of maximum slope—and compare it with the 100-year geometric mean benchmark.
1. Model form:
p_{100}(s) = L + \frac{U - L}{1 + e^{a\,(s - s_0)}}
where
• L = lower asymptote,
• U = upper asymptote,
• a > 0 = steepness,
• s_0 = inflection (“cliff”) point.
2. Fitting range: restrict to spend rates 1 % – 7 % to avoid tail distortion.
3. Tasks:
• Fit the logistic model by nonlinear least squares.
• Compute and print: L, U, a, s_0.
• Calculate the finite-horizon geometric-mean return
g_{100} = \mu_a - \tfrac{1}{2}\!\left(1 - \tfrac{1}{N}\right)\sigma^2 - \text{fee}
(with N = 100).
• Report both s_0 and g_{100} in percent.
4. Plot the results:
      •   Gray line = raw p_{100} data
      •   Blue line = logistic fit
      •   Green dashed vertical line = inflection s_0
      •   Red dotted vertical line = geometric-mean g_{100}
      •   Title:
“Year-100 Heat vs Spend — Logistic Fit (Inflection vs Geometric-Mean)”
      •   Invert the X-axis (low spends on the right).
      •   Add a legend in the lower-left corner.
5. Print summary lines:
Inflection (max slope) s₀ ≈ <value> %
Geometric-mean benchmark g₁₀₀ ≈ <value> %

----- prompt end -----


Notes:
  • This heat map stuff all started with me looking at Moshe Milevsky's R-script "PLSR" but animating it via simulation of many withdrawal rates in ways that the complexity doesn't really reward, does it? heh 

  • As far as I can tell, I have seen exactly no one do this work before. Probably due to the "meh" nature of the planning utility. You can paypal me, tho, if you ever use this, lol. 

Outputs:

1. The heat map. X is portfolio longevity in years. Y is the constant infl adj spend rate. Every portfolio from 100 years or more is accumulated into the heat for year 100 which is translated as "a long time from now." Year 30 vertical is to slap a standard planning assumption and a human scale onto this. One could also put a horizontal line on top for 4% or something related to a planning goal and to use that 30 year + spend as input to a planning discussion. Note that at 2% spend we are effectively at a perpetuity when we consider human planning horizons. 



2. This is the "shape" of year 100 -- on the far right of chart 1 above -- in terms of spending-heat-frequency. I do this in order to see where the first derivative of that relationship maxes out -- ie where portfolios tip towards infinitely (100y+) long-lived portfolios. Hint: for the critical point, think of the geometric mean return of the modeled portfolio. That is NOT a spend recommendation, btw, it's just an visible artifact of how this works in the math. Something to ponder, though. If this is not clear you can DM me. The Logistic Fit thing (blue) is just to clean up the estimation and filter out some noise in the year 100 curve. 










No comments:

Post a Comment