1955 & 1913 LETF Backtest

Leverage in markets is nothing new, but the forms and costs have certainly changed over time. In this post I wanted to model the importance of including borrowing costs in your analysis when deciding if leveraged ETFs (LETFs) are right for you.

In the next two charts you will see a log and a linear chart for the following:

  1. White: The total return of UPRO (an actual leveraged ETF).
  2. Green: The total return of the S&P 500 with dividends reinvested.
  3. Red: An estimate of a 3X leveraged ETF of the S&P 500 that only includes an expense ratio cost.
  4. Yellow: A 3X leveraged ETF that includes an expense ratio and estimates the cost of leverage using the 10 year treasury yield.
  5. Purple: A 3X leveraged ETF that includes an expense ratio and estimates the cost of leverage using the Fed Funds rate.
Log Scale 1. White is UPRO total return. 2. Green is SPXTR (S&P with dividends reinvested) 3. Red is 3X the monthly return of SPXTR with a 1% expense ratio 4. Yellow is 3X the monthly SPXTR return with leverage costs of 2 times the US 10 year yield and a 1% expense ratio. 5. Purple is 3X the monthly SPXTR return minus 2X (the Fed Funds Rate + 1%) minus 1% expense ratio.
Linear Scale. 1. White is UPRO total return. 2. Green is SPXTR (S&P with dividends reinvested) 3. Red is 3X the monthly return of SPXTR with a 1% expense ratio 4. Yellow is 3X the monthly SPXTR return with leverage costs of 2 times the US 10 year yield and a 1% expense ratio. 5. Purple is 3X the monthly SPXTR return minus 2X (the Fed Funds Rate + 1%) minus 1% expense ratio.

All three synthetic versions of UPRO may seem like reasonable estimates, but I don’t think this is the case. The red curve that does not include the cost of leverage is problematic. It overestimates the benefit of using leverage. In this timeframe when UPRO existed which is less than 15 years it is an okay estimate because the cost of leverage happened to be quite low at that time. However if we extend the backtests now to as far back as we have data on TradingView for the Fed Funds rate we will quickly see the problem.

Log Scale. 1. White or UPRO is no longer graphed as it is not available over this timeframe. 2. Green is SPXTR (S&P with dividends reinvested) 3. Red is 3X the monthly return of SPXTR with a 1% expense ratio 4. Yellow is 3X the monthly SPXTR return with leverage costs of 2 times the US 10 year yield and a 1% expense ratio. 5. Purple is 3X the monthly SPXTR return minus 2X (the Fed Funds Rate + 1%) minus 1% expense ratio.
Linear Scale. 1. White or UPRO is no longer graphed as it is not available over this timeframe. 2. Green is SPXTR (S&P with dividends reinvested) 3. Red is 3X the monthly return of SPXTR with a 1% expense ratio 4. Yellow is 3X the monthly SPXTR return with leverage costs of 2 times the US 10 year yield and a 1% expense ratio. 5. Purple is 3X the monthly SPXTR return minus 2X (the Fed Funds Rate + 1%) minus 1% expense ratio.

On the linear scale we can see that not graphing the cost of leverage leads to results that are dramatically unrealistic. If anyone is considering using leveraged ETFs they should be sure they understand the relationship between interest rates and the cost of leverage that they cause to the leveraged ETFs they use.

Going to 1913

The fed funds rate isn’t available prior to 1955 on tradingview but the 10 year US treasury yield is. Since we can see relativley similar results let’s now go back to 1913 with the synthetic version of a 3X leveraged ETF. I have intentionally used only monthly data up to now in order to allow going back to 1913. From 1913 to the 1950s only monthly data is available for SPX.

Log Scale. 1. White or UPRO is no longer graphed as it is not available over this timeframe. 2. Green is SPXTR (S&P with dividends reinvested) 3. Red is 3X the monthly return of SPXTR with a 1% expense ratio 4. Yellow is 3X the monthly SPXTR return with leverage costs of 2 times the US 10 year yield and a 1% expense ratio. 5. Purple is no longer available as the fedfunds rate data does not go back this far.

View, Track, and Copy My Trades Live

In addition to this blog you can follow a mixture of my live brokerage accounts and various strategies using the Strategies Page on my website. If you have the right brokerage account you can set it up to automatically copy my trading live. For more information check out the strategies page.

Resources

Below I have provided you with a link to the chart. You can zoom in our out and the chart should recalculate to what time frame you want to see. You can also use the excel file to see the data or you can take the code below and build on it.

https://www.tradingview.com/chart/oJyPPDp7/


//@version=5
//US SPX as security
//For each item the start period can only be about a year after that asset starts
//Stocks and Gold 1 Jan 1872
//Houseing
//https://www.tradingview.com/blog/en/pine-script-and-charts-become-better-acquainted-32927/

indicator(title="Demo History, Lev, Active", shorttitle="Public Demo 3X Cost Examination", overlay=true, timeframe="", timeframe_gaps=true)
StartTime = input.time(timestamp("1 May 1913"), title="Start Comparison Calc")
//StartTime = input.time(timestamp(chart.left_visible_bar_time), title="Start Comparison Calc")
//Price Function x days ago
priceXDaysAgo(numDays,PriceItem) =>
targetTimestamp = time - numDays*60*60*24*1000

// Declare a result variable with a "void" value
float result = if false
1

// We'll scan backwards through the preceding bars to find the first bar
// earlier than X days ago (it might be a little greater than X days if
// there was a break in trading: weekend, public holiday, etc.)
for i = 1 to 1000
if time[i] < targetTimestamp
result := PriceItem[i]
break
result
//
// Save the `open` of the leftmost visible bar.
var float chartOpen = na
if time == chart.left_visible_bar_time
chartOpen := open

//var leverageFee = input(Title= "Leverage Annual Cost %" ,2)
var chartStartTime = time
var SPXfilterTime = time



//Asset Data
UnderlyingClose = close
SPX_close = request.security('SPX', timeframe.period,close)
div = request.security('QUANDL:MULTPL/SP500_DIV_YIELD_MONTH',timeframe.period, close)
goldclose = request.security('TVC:GOLD',timeframe.period, close)
HouseClose = request.security('FRED:MSPUS',timeframe.period, close)
US10Yclose = request.security('TVC:US10Y',timeframe.period, close)
FEDFUNDSclose = request.security('FRED:FEDFUNDS',timeframe.period, close)

//Most Recent available data
float MostRecentDiv = 0
MostRecentDiv:=nz(div,nz(MostRecentDiv[1]))
float MostRecentSPX = 0
MostRecentSPX:=nz(SPX_close,nz(MostRecentSPX[1],4.5))
float MostRecentGold = 0
MostRecentGold:=nz(goldclose,nz(MostRecentGold[1],4.5))
float MostRecentHouse = 0
MostRecentHouse:=nz(HouseClose,nz(MostRecentHouse[1],4.5))
float MostRecent10Y = 0
MostRecent10Y:=nz(US10Yclose,nz(MostRecent10Y[1],4.5))
float MostRecentFEDFUNDS = 0
MostRecentFEDFUNDS:=nz(FEDFUNDSclose,nz(MostRecentFEDFUNDS[1],4.5))
float MostRecentUnderlying = 0
MostRecentUnderlying:=nz(UnderlyingClose,nz(MostRecentUnderlying[1],4.5))


//Period of dividend yield
time_between_bars = time_close-time_close[1]
days_between_bars = time_between_bars/24/60/60/1000
dailyDivYield = (math.pow(1+MostRecentDiv/100,1/365.25)-1)
PeriodDivYield = math.pow(1+dailyDivYield,days_between_bars)-1
//Need to find how to have SPXTR_PRICE on first bar be SPX bar. Then have it build from there.

//Growth Start
float UnderlyingGrowth = chartOpen
float SPXTR_Growth = chartOpen
float SPX_Growth = chartOpen
float Gold_Growth = chartOpen
float House_Growth = chartOpen
float B10Y_Growth = chartOpen
float MixGrowth = chartOpen
float LevMixGrowth = chartOpen
float ActLevMixGrowth = chartOpen
float levStocksGrowth = chartOpen
float levStocks10YGrowth = chartOpen
float levStocksFEDFundsGrowth = chartOpen
float ActiveMixNoLevGrowth=chartOpen
float levStocksGrowthwithborrow = chartOpen
float Active3XStocksGrowth = chartOpen
//Bond Price Calculation MostRecent10Y
MostRecentYield10Y = MostRecent10Y/100
Pv10Y = math.pow(1+MostRecentYield10Y,10)
YieldPeriod = MostRecentYield10Y/(365/days_between_bars)
float BondReturn = 0
float GoldReturn = 0
float SPXTRReturn = 0
float levstocksRETURN = 0
float levstocks10YRETURN = 0
float levstocksFEDFUNDSRETURN = 0


if time > StartTime
UnderlyingGrowth := (MostRecentUnderlying/nz(MostRecentUnderlying[1],MostRecentUnderlying))*nz(UnderlyingGrowth[1],UnderlyingGrowth)
SPX_Growth := (MostRecentSPX/nz(MostRecentSPX[1],MostRecentSPX))*nz(SPX_Growth[1],SPX_Growth)
SPXTR_Growth := (MostRecentSPX/nz(MostRecentSPX[1],MostRecentSPX)+nz(PeriodDivYield))*nz(SPXTR_Growth[1],SPXTR_Growth)
Gold_Growth := (MostRecentGold/nz(MostRecentGold[1],MostRecentGold))*nz(Gold_Growth[1],Gold_Growth)
House_Growth := (MostRecentHouse/nz(MostRecentHouse[1],MostRecentHouse))*nz(House_Growth[1],House_Growth)
B10Y_Growth := ((nz(Pv10Y[1],Pv10Y)-Pv10Y)/nz(Pv10Y[1],Pv10Y)+1+YieldPeriod)*nz(B10Y_Growth[1],B10Y_Growth)
BondReturn := B10Y_Growth/nz(B10Y_Growth[1],B10Y_Growth)-1
GoldReturn := Gold_Growth/nz(Gold_Growth[1],Gold_Growth)-1
SPXTRReturn := SPXTR_Growth/nz(SPXTR_Growth[1],SPXTR_Growth)-1

MixGrowth := nz(MixGrowth[1],MixGrowth)*(1+BondReturn/3 + GoldReturn/3 + SPXTRReturn/3)
LevMixGrowth := nz(LevMixGrowth[1],LevMixGrowth)*(1+BondReturn + GoldReturn + SPXTRReturn-US10Yclose*2/100/12) // it does have 3x leverage because each is at full


/////////
levstocksRETURN := levStocksGrowth/nz(levStocksGrowth[1],levStocksGrowth)-1
levStocksGrowth := nz(levStocksGrowth[1],levStocksGrowth)*(1 + SPXTRReturn*3.0-1.0/100/12)
levStocks10YGrowth := nz(levStocks10YGrowth[1],levStocks10YGrowth)*(1 + SPXTRReturn*3.0-US10Yclose*2.0/100/12-1.0/100.0/12.0)
levStocksFEDFundsGrowth := nz(levStocksFEDFundsGrowth[1],levStocksFEDFundsGrowth)*(1 + SPXTRReturn*3.0-(FEDFUNDSclose+1.00)*2.00/100.0/12.0-1.0/100.0/12.0)

plot(UnderlyingGrowth, title="Selected Asset", color=color.white)
plot(SPXTR_Growth, title="S&P with DRIP", color=color.green)
plot(levStocksGrowth, title="3X Stocks - Exp Ratio", color=color.red)
plot(levStocks10YGrowth, title="3X Stocks - EXp Ratio and 10Y x 2", color=color.yellow)
plot(levStocksFEDFundsGrowth, title="3X Stocks - (Exp Ratio & 2x(Fedfunds + 1%))", color=color.purple)

Follow My Trading

For more information on how you can follow my own trading and results subscribe to my blog, check out the strategies page, or check out my brokerage performance reports.

Disclaimer

This is not investment advice for you. This website is designed to talk about investments but it is not designed to give you personalized investment advice. This site contains generic information that does not have the capability of taking your personal risk tolerance, goals, assets, or other factors into account. Therefore, this site and all of its related content is for entertainment, informational, and educational purposes only.

The owner of PatienceToInvest.com is also a trade leader on Collective2.com. We may receive compensation by promoting some collective2 strategies over others. Should you decide to make or avoid any investments or use any service due to the information on this site or related information you assume full responsibility and risks and will not hold howiinvest.com it’s associated sites or its owners responsible. You also acknowledge investing is risky and can result in the loss of all your capital and even more than your original capital in some cases.

Leave a comment