January 16, 2012
By

I’ve ordered Time Series Analysis and Its Applications: With R Examples (Springer Texts in Statistics) to help me up the time series in R learning curve. So far what I have seen it looks good. The author has a good page with the issues in R and time series.  The book should arrive by the end of the week.

In the meantime, I came across a trading strategy while reading an article provide on John Mauldin’s “Over My Shoulder” service (which I highly recommend).  The crux of it was that in the bear market that started with the tech bubble crash, a strategy of betting on mean reversion of the S&P500 generated significant returns.  Naturally I wanted to test.

Please note, I am not recommending anything that follows.  Do your homework and speak with an investment professional if you have questions.

The strategy is to go long the S&P500 when the market closes at a maximum over the previous 3 days.  Reverse the trade and go long when the market closes at the minimum over the previous 3 days.  ETFs make this strategy relatively easy to trade.  SPY will be our vehicle for being long the S&P500 and SH will be our vehicle for going short.

The SH began trading on 06/21/2006.  We focus our backtesting from that point until now.

Using the importSeries() function we previously created, get all the values for SPY and SH.

to   = “2012-01-14”
from = “2006-06-21”
spy = importSeries(“spy”,to=to,from=from)
sh  = importSeries(“sh”,to=to, from=from)
series = merge(spy,sh)[,c(“spy.Open”,“spy.Close”,“spy.Return”,
“sh.Open”,“sh.Close”,“sh.Return”)]

We need to create some additional timeSeries to hold

• Long/Short Flag — lets us know the current status of our holdings.
• Trade Flag — signals that we instituted a trade on this date.
• Strat.Returns — nominal return for the day with the strategy.
• Dollar Amount — a gross dollar value of the portfolio assuming a \$10,000 dollar value on 06/21/2006, and a \$2 transaction fee when we trade.
After we calculate the strategy we will also create a gross return series from the Dollar Amount series.
f = function(x) 0*x
ls = fapply(series[,1],FUN=f)
colnames(ls) = “long_short”
rets = fapply(series[,1],FUN=f)
colnames(rets) = “Strat.Return”
amt = rets
colnames(amt) = “DollarAmount”
amt[seq(1,3)] = 10000
We will loop from the 3rd day of the series until the end and calculate the values.
n = nrow(series)
for (i in seq(3,n)){
maxSpy = max(series[seq(i,i2),“spy.Close”])
minSpy = min(series[seq(i,i2),“spy.Close”])

#get the appropriate return
if (ls[i1] == 1){
rets[i] = series[i,“spy.Return”]
} else if (ls[i1] == 1){
rets[i] = series[i,“sh.Return”]
}

#change long/short as appropriate
if (maxSpy == series[i,“spy.Close”]){
ls[i] = 1
} else if (minSpy == series[i,“spy.Close”]){
ls[i] = 1
} else {
ls[i] = ls[i1]
}

#mark a trade if we did one
if (ls[i] != ls[i1]) trades[i] = 1

#Calculate the dollar amount
amt[i] = amt[i1]*exp(rets[i])
if (trades[i]) amt[i] = amt[i] 2
}
#Calculate gross returns
amt2 = returns(amt)
colnames(amt2) = “Strat.DollarReturns”
Next let’s output the annualized returns and CAPM statistics.  We will do this for the entire period as well as for each year.
#Merge all the series
series=merge(series,ls)
series = merge(series,rets)
series = merge(series,amt)
series = merge(series,amt2)
vars = c(“spy.Return”,“sh.Return”,“Strat.DollarReturns”)
series[1,vars] = 0
#Calculate the Annualized Statistics and the CAPM statistics
print(“Total”)
table.AnnualizedReturns(series[,vars])
table.CAPM(as.xts(series[,“Strat.Return”,drop=FALSE]),as.xts(series[,“spy.Return”,drop=FALSE]))
#Overall cumulative returns
png(“c:\\temp\\overall.png”)
chart.CumReturns(series[,vars],main=“Total Return”,legend.loc=“topleft”)
dev.off()

#Create the outputs for each year.
for (year in seq(2006,2011)){
start = paste(year,“-01-01”,sep=“”)
end = paste(year,“-12-31”,sep=“”)

title = paste(“Total Return “,year,sep=“”)
file = paste(“c:\\temp\\”,year,“.png”,sep=“”)

s = window(series,start=start, end=end)
png(file)
chart.CumReturns(s[,vars],main=title,legend.loc=“topleft”)
dev.off()

print(paste(year,“Returns”,sep=” “))
print(table.AnnualizedReturns(s[,vars]))
print(table.CAPM(as.xts(s[,“Strat.Return”,drop=FALSE]),as.xts(s[,“spy.Return”,drop=FALSE])))
}
 Total spy.Return sh.Return Strat.DollarReturns Annualized Return -0.0067 -0.0903 0.3535 Annualized Std Dev 0.2529 0.2512 0.2508 Annualized Sharpe (Rf=0%) -0.0263 -0.3593 1.4092
 Total Strat.Return to spy.Return Alpha 0.0013 Beta 0.1921 Beta+ 0.6830 Beta- -0.0803 R-squared 0.0374 Annualized Alpha 0.3990 Correlation 0.1934 Correlation p-value 0.0000 Tracking Error 0.7447 Active Premium 0.3694 Information Ratio 0.4960 Treynor Ratio 1.8885
So there seems to be something to this strategy.  The yearly return and CAPM tables are close to the total.  Some years are better than others.  I will leave it to you to create and study them (mostly to save space on here).
There are things to think of:
• It should be noted that this strategy is NOT tax efficient — any gains will be taxed at the short term capital gains rate.
• There were 411 trades.  A trade involves buying and selling, so 822 times would you be charged a brokerage fee.  I assumed 1 dollar per buy/sell — what is charged by Interactive Brokers.  Using someone like TD Ameritrade would cost FAR more.
• This also assumes that you can buy and sell at the market closing price.  Something that is possible, but slippage will occur.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...