Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
This post will introduce my up and coming IKReporting package, and functions that compute and plot rolling returns, which are useful to compare recent performance, since simply looking at two complete equity curves may induce sample bias (EG SPY in 2008), which may not reflect the state of the markets going forward.
In any case, the motivation for this package was brought about by one of my readers, who has reminded me in the past of the demand for the in-the-ditches work of pretty performance reports. This package aims to make creating such thing as painless as possible, and I will be updating it rapidly in the near future.
The strategy in use for this post will be Flexible Asset Allocation from my IKTrading package, in order to celebrate the R/Finance lightning talk I’m approved for on FAA, and it’ll be compared to SPY.
Here’s the code:
require(IKTrading) require(quantmod) require(PerformanceAnalytics) options("getSymbols.warning4.0"=FALSE) symbols <- c("XLB", #SPDR Materials sector "XLE", #SPDR Energy sector "XLF", #SPDR Financial sector "XLP", #SPDR Consumer staples sector "XLI", #SPDR Industrial sector "XLU", #SPDR Utilities sector "XLV", #SPDR Healthcare sector "XLK", #SPDR Tech sector "XLY", #SPDR Consumer discretionary sector "RWR", #SPDR Dow Jones REIT ETF "EWJ", #iShares Japan "EWG", #iShares Germany "EWU", #iShares UK "EWC", #iShares Canada "EWY", #iShares South Korea "EWA", #iShares Australia "EWH", #iShares Hong Kong "EWS", #iShares Singapore "IYZ", #iShares U.S. Telecom "EZU", #iShares MSCI EMU ETF "IYR", #iShares U.S. Real Estate "EWT", #iShares Taiwan "EWZ", #iShares Brazil "EFA", #iShares EAFE "IGE", #iShares North American Natural Resources "EPP", #iShares Pacific Ex Japan "LQD", #iShares Investment Grade Corporate Bonds "SHY", #iShares 1-3 year TBonds "IEF", #iShares 3-7 year TBonds "TLT" #iShares 20+ year Bonds ) from="2003-01-01" #SPDR ETFs first, iShares ETFs afterwards if(!"XLB" %in% ls()) { suppressMessages(getSymbols(symbols, from="2003-01-01", src="yahoo", adjust=TRUE)) } prices <- list() for(i in 1:length(symbols)) { prices[[i]] <- Cl(get(symbols[i])) } prices <- do.call(cbind, prices) colnames(prices) <- gsub("\.[A-z]*", "", colnames(prices)) faa <- FAA(prices = prices, riskFreeName = "SHY", bestN = 6, stepCorRank = TRUE) getSymbols("SPY", from="1990-01-01") comparison <- merge(faa, Return.calculate(Cl(SPY)), join='inner') colnames(comparison) <- c("FAA", "SPY")
And now here’s where the new code comes in:
This is a simple function for computing running cumulative returns of a fixed window. It’s a quick three-liner function that can compute the cumulative returns over any fixed period near-instantaneously.
"runCumRets" <- function(R, n = 252) { cumRets <- cumprod(1+R) rollingCumRets <- cumRets/lag(cumRets, k = n) - 1 return(rollingCumRets) }
So how does this get interesting? Well, with some plotting, of course.
Here’s a function to create a plot of these rolling returns.
"plotCumRets" <- function(R, n = 252, ...) { cumRets <- runCumRets(R = R, n = n) cumRets <- cumRets[!is.na(cumRets[,1]),] chart.TimeSeries(cumRets, legend.loc="topleft", main=paste(n, "day rolling cumulative return"), date.format="%Y", yaxis=FALSE, ylab="Return", auto.grid=FALSE) meltedCumRets <- do.call(c, data.frame(cumRets)) axisLabels <- pretty(meltedCumRets, n = 10) axisLabels <- round(axisLabels, 1) axisLabels <- axisLabels[axisLabels > min(axisLabels) & axisLabels < max(axisLabels)] axis(side=2, at=axisLabels, label=paste(axisLabels*100, "%"), las=1) }
While the computation is done in the first line, the rest of the code is simply to make a prettier plot.
Here’s what the 252-day rolling return comparison looks like.
require(IKReporting) plotCumRets(comparison)
So here’s the interpretation: assuming that there isn’t too much return degradation in the implementation of the FAA strategy, it essentially delivers most of the upside of SPY while doing a much better job protecting the investor when things hit the fan. Recently, however, seeing as to how the stock market has been on a roar, there’s a slight bit of underperformance over the past several years.
However, let’s look at a longer time horizon — the cumulative return over 756 days.
plotCumRets(comparison, n = 756)
With the following result:
This offers a much clearer picture–essentially, what this states is that over any 756-day period, the strategy has not lost money, ever, unlike SPY, which would have wiped out three years of gains (and then some) at the height of the crisis. More recently, as the stock market is in yet another run-up, there has been some short-term (well, if 756 days can be called short-term) underperformance, namely due to SPY having some historical upward mobility.
On another unrelated topic, some of you (perhaps from Seeking Alpha) may have seen the following image floating around:
This is a strategy I have collaborated with Harry Long from Seeking Alpha on. While I’m under NDA and am not allowed to discuss the exact rules of this particular strategy, I can act as a liaison for those that wish to become a client of ZOMMA, LLC. While the price point is out of the reach of ordinary retail investors (the price point is into the six figures), institutions that are considering licensing one of these indices can begin by sending me an email at ilya.kipnis@gmail.com. I can also set up a phone call.
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.