There are a number of sites that market their signals as great indicators for outperforming the market, let me highlight how careful one needs to be when looking at backtests.

In the strategy I am about to show you we create a ratio between the S&P 500 and the Dow and we trigger a signal to buy the market when the current ratio is above the rolling mean ratio. I will include the code at the bottom for those who want to understand the details, but the table and chart will illustrate my point. A further important point that I must emphasize and will continue to highlight is that I look at risk-adjusted returns as my proxy for out-performance.

So lets begin:

Rplot06 2015-01-15_1532

Yes Sir you beauty, we have here a 24yr backtest where our model handily outperforms a buy and hold with a Sharpe Ratio of 0.32 vs 0.22. So should we bet the farm on this baby? Not so fast I say, lets look at this strategy over some more data, in the table below we look at performance from 1950 a lengthy 64yrs.


What we see here, is underperformance; so it is very important when considering a model to ensure that the starting date isn’t cherry picked. In this illustration there are very few parameters, and we only tweaked the date. Many people pushing automated models love to “curve-fit” parameters to satisfy the backtest with no basis of reality.

Here is the R code for those that are interested:

getSymbols("^GSPC", from= "1900-01-01")
sp500.weekly <- GSPC[endpoints(GSPC, "weeks"),6]
sp500rets<- ROC(sp500.weekly, type = "discrete", n = 1)
DJ<- read.csv('', colClasses=c('Date'='Date'))
date<- DJ$Date
values<- DJ[,2]
DJ_xts<- as.xts(values, = as.Date(date, "%d/%m/%Y"))
dj.weekly <- DJ_xts[endpoints(DJ_xts, "weeks"),1]
djrets<- ROC(dj.weekly, type = "discrete", n = 1)
data<- merge(sp500.weekly,dj.weekly)
data.sub = data['1950-02-05::']
ratio<- data.sub[,1]/data.sub[,2]
ave.ratio<- rollapply(ratio,20,mean)
lead.lag<- ifelse(ratio >= ave.ratio, "Lead", "Lag")
# filtered results investing in S&P500 with the signal
ma_sig <- Lag(ifelse(lead.lag=="Lead", 1, 0))
ma_ret <- sp500rets * ma_sig
dowtimer<- cbind(ma_ret,sp500rets) # or
colnames(dowtimer) = c('SPX/DJI-Timer','Buy&Hold')
table.AnnualizedReturns(dowtimer, Rf= 0.04/52)
charts.PerformanceSummary(dowtimer, Rf = 0.04/52, main="SPX/DJI Timer",geometric=FALSE)

Created by Pretty R at

3 thoughts on “DOW SIGNALS

  1. So if the weekly return is greater than the SMA of 20 weeks of weekly returns, enter, else exit?

    If you haven’t yet been acquainted with it, I highly recommend the TTR package in addition to performanceAnalytics.

    -Ilya (author of quantStrat TradeR)


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s