The ZOMMA Warthog Index
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Harry Long posted another article on SeekingAlpha. As usual, it’s another “looks amazing at first glance, and winds up being disappointing compared to first impressions, but is still worth talking about” types of strategies. So here’s the strategy:
Rebalance annually:
50% XLP, 15% GLD, 35% TLT — aka a variation of the stocks/bonds portfolio, just with some gold added in. The twist is the idea that XLP is less risky than SPY. The original article, written by Harry Long, can be found here.
This strategy is about as simple as they come, and is tested just as easily in R.
Here’s the original replication:
require(PerformanceAnalytics) require(quantmod) getSymbols("XLP", from="1990-01-01") getSymbols("GLD", from="1990-01-01") getSymbols("TLT", from="1990-01-01") prices <- cbind(Ad(XLP), Ad(GLD), Ad(TLT)) prices <- prices[!is.na(prices[, 2]),] rets <- Return.calculate(prices) warthogRets <- Return.portfolio(rets, weights=c(.5, .15, .35), rebalance_on = "years") getSymbols("SPY", from="1990-01-01") SPYrets <- Return.calculate(Ad(SPY)) comparison <- merge(warthogRets, SPYrets, join='inner') charts.PerformanceSummary(comparison)
And the resulting replicated (approximately) equity curve:
So far, so good.
Now, let’s put the claim of outperforming over an entire cycle to the test.
years <- apply.yearly(comparison, Return.cumulative) years <- years[-1,] #remove 2004 years sum(years[,1] > years[,2])/nrow(years) sapply(years, mean)
And here’s the output:
> years portfolio.returns SPY.Adjusted 2005-12-30 0.07117683 0.04834811 2006-12-29 0.10846819 0.15843582 2007-12-31 0.14529234 0.05142241 2008-12-31 0.05105269 -0.36791039 2009-12-31 0.03126667 0.26344690 2010-12-31 0.14424559 0.15053339 2011-12-30 0.20384853 0.01897321 2012-12-31 0.07186807 0.15991238 2013-12-31 0.04234810 0.32309145 2014-12-10 0.16070863 0.11534450 > sum(years[,1] > years[,2])/nrow(years) [1] 0.5 > sapply(years, mean) portfolio.returns SPY.Adjusted 0.10302756 0.09215978
So, even with SPY’s 2008 in mind, this strategy seems to break even on a year-to-year basis, and the returns are slightly better, which I suppose should be par for the course for a backtest against SPY through the recession.
Now, let’s just remove that one year and see how things stack up:
years <- years[-4,] #remove 2008 sapply(years, mean)
And we obtain the following results:
> sapply(years, mean) portfolio.returns SPY.Adjusted 0.1088025 0.1432787
In short, the so-called outperformance is largely sample-dependent on the S&P having a terrible year. Beyond that, things don’t look so stellar for the strategy.
Lastly, anytime anyone makes a claim about a strategy outperforming a benchmark, one very, very easy test to do is to simply look at the equity curve of a “market neutral” strategy that shorts the benchmark against the strategy, and see if that looks like an equity curve one would be comfortable holding. Here are the results:
diff <- comparison[,1] - comparison[,2] charts.PerformanceSummary(diff, main="short SPY against portfolio")
And the resulting equity curve of the outperformance:
Basically, ever since the crisis passed, the strategy has been flat to underperforming against SPY.
To hammer the point, let’s look at the equity curves from 2009 onwards.
#strategy against SPY post-crisis charts.PerformanceSummary(comparison["2009::"])
With the result:
To its credit, the strategy’s equity curve is certainly a smoother ride. At the same time, the underperformance is clear as well. I suppose this makes sense as a portfolio invested 35% in bonds should expect to underperform a portfolio fully invested in equities on an absolute returns basis. Nevertheless, a far cry from the marketing the strategy has received in the original article.
Now, as I did before, in It’s Amazing How Well Dumb Things Get Marketed, I’m going to backtest this strategy as far as I can using proxies from Quandl for gold and bonds, by going directly to the futures. Refer to that post to see that the proxies are relatively decent for the ETFs. In this case, I switched from adjusted to close prices, but the concept should still hold.
require(IKTrading) goldFutures <- quandClean(stemCode = "CHRIS/CME_GC", verbose = TRUE) thirtyBond <- quandClean(stemCode="CHRIS/CME_US", verbose = TRUE) longPrices <- cbind(Cl(XLP), Cl(goldFutures), Cl(thirtyBond)) longRets <- Return.calculate(longPrices) longRets <- longRets[!is.na(longRets[,1]),] names(longRets) <- c("XLP", "Gold", "Bonds") longWarthog <- Return.portfolio(longRets, weights=c(.5, .15, .35), rebalance_on = "years") longComparison <- merge(longWarthog, SPYrets, join='inner') charts.PerformanceSummary(longComparison)
And here’s the resultant equity curve comparison:
So, the idea that the strategy outperforms SPY? It seems to be due to SPY’s horrendous performance in 2008, which is a once-in-several-decades event. As you can see, if you started from XLP’s inception to approximately 2005, the strategy was actually in drawdown for all those years.
Let’s look at the risk/reward metrics for this timeframe:
stats <- rbind(Return.annualized(longComparison), maxDrawdown(longComparison), SharpeRatio.annualized(longComparison), Return.annualized(longComparison)/maxDrawdown(longComparison) ) rownames(stats)[4] <- "Return Over MaxDD" stats
And the results:
> stats portfolio.returns SPY.Adjusted Annualized Return 0.0409267 0.05344120 Worst Drawdown 0.2439091 0.55186722 Annualized Sharpe Ratio (Rf=0%) 0.4846184 0.26295594 Return Over MaxDD 0.1677949 0.09683706
To its credit, the strategy has a better return to risk profile than SPY does, which I hope would be the case for any backtest going up against SPY with 2008 in mind. Nevertheless, I feel there was definitely a veneer of marketing in the original presentation. Overall, the strategy has a bit of merit as a defensive play, but in all honesty, looking at the return over max drawdown, I think there are ways to do better.
Thanks for reading.
NOTE: I am a freelance consultant in quantitative analysis on topics related to this blog. If you have contract or full time roles available for proprietary research that could benefit from my skills, please contact me through my LinkedIn here.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.