Section A.2 Long-Term Returns
Weโll use the following function to compute long-term returns. It takes a start date and a duration, and computes two ratios:
-
The total price return based on actual annual returns.
-
The total price return if annual returns are clipped at 0 and 10โthat is, any negative returns are set to 0 and any returns above 10 are set to 10.
def compute_ratios(start=1993, duration=30):
end = start + duration
interval = annual.loc[start: end]
ratio = interval['Ratio'].prod()
low, high = 1.0, 1.10
clipped = interval['Ratio'].clip(low, high)
ratio_clipped = clipped.prod()
return start, end, ratio, ratio_clipped
With this function, we can replicate the analysis The Economist did with the S&P 500. Here are the results for the DJIA from the beginning of 1980 to the end of 2023.
$ compute_ratios(1980, 43)
(1980, 2023, 44.93751117788029, 15.356490985533199)
A buffer ETF over this period would have grown by a factor of more than 15 in nominal dollars, with no risk of loss. But an index fund would have grown by a factor of almost 45. So yeah, the ETF would have been a bad deal.
However, if we go back to the bad old days, an investor in 1900 would have been substantially better off with a buffer ETF held for 43 years.
$ compute_ratios(1900, 43)
(1900, 1943, 2.8071864303140583, 7.225624631784611)
It seems we can cherry-pick the data to make the comparison go either wayโso letโs see how things look more generally. Starting in 1886, weโll compute price returns for all 30-year intervals, ending with the interval from 1993 to 2023.
$ duration = 30
ratios = [compute_ratios(start, duration) for start in range(1886, 2024-duration)]
ratios = pd.DataFrame(ratios, columns=['Start', 'End', 'Index Fund', 'Buffer ETF'])
ratios.index = ratios['Start']
ratios.tail()
Start End Index Fund Buffer ETF
Start
1989 1989 2019 13.160027 6.532125
1990 1990 2020 11.116693 6.368615
1991 1991 2021 13.797643 7.005476
1992 1992 2022 10.460407 6.368615
1993 1993 2023 11.417232 6.724757
Hereโs what the returns look like for an index fund compared to a buffer ETF.
ratios['Index Fund'].plot()
ratios['Buffer ETF'].plot()
decorate(xlabel='Start year', ylabel='30-year price return')
The buffer ETF performs as advertised, substantially reducing volatility. But it has only occasionally been a good deal, and not in my lifetime.
According to ChatGPT, the primary reasons for strong growth in stock prices since the 1960s are โtechnological advancements, globalization, financial market innovation, and favorable monetary policiesโ. If you think these elements will generally persist in the future, a buffer ETF is probably not a good deal for you.
