Search code examples
rquantmodtradingback-testing

multiple tickers backtesting


I have built the following model which backtests only spy. My issue is that I want to apply this trading strategy to multiple tickers (e.g. both qqq and spy).

How do I do this? See below:

getSymbols("spy",from ="2000-01-01", to="2015-01-01")
SPY<-adjustOHLC(SPY)
rsi <- RSI(Cl(SPY),2)
smashort<-SMA(Cl(SPY),10)
smalong<-SMA(Cl(SPY),200)
adx<-ADX(HLC(SPY),10)
adx<-adx[,4]
close<-Cl(SPY)

signal<-ifelse(rsi<15 & close<smashort & smalong<close &adx>27,1,0)
for(i in 1:nrow(signal))
{signal<-ifelse(lag(signal)==1 & close<smashort,1,ifelse(rsi<15 & close<smashort & smalong<close & adx>27,1,0))}
signal<-lag(signal,1)
signal[is.na(signal)] <- 0
ret <- ROC(Cl(SPY))
ret[1] <- 0
equity<-exp(cumsum(ret*signal))
plot(equity)

Please see below for the multiple tickers version:

stockData <- new.env() #Make a new environment for quantmod to store data in
symbols = c("TLT", "USO")
getSymbols(symbols, src='yahoo',from = "2016-9-01",to = Sys.Date())
for(symbol in symbols){
  assign(symbol,adjustOHLC(get(symbol, pos=.GlobalEnv), symbol.name=symbol, 
                           adjust=c("split"), use.Adjusted=FALSE))
}

x <- list()
for (i in 1:length(symbols)) {
  x[[i]] <- get(symbols[i], pos=stockData)  # get data from stockData environment 
  x[[i]]$sma <-SMA(Cl(x[[i]]),10)
  x[[i]]$rsi <-RSI(Cl(x[[i]]),2)
  x[[i]]$close <-(Cl(x[[i]]))
  x[[i]]$signal<-ifelse(x[[i]]$rsi<15 & x[[i]]$close<x[[i]]$sma,1,0)
	
for(i in length(x[[i]]$signal))
{x[[i]]$signal<-ifelse(lag(x[[i]]$signal)==1 & x[[i]]$close<x[[i]]$sma,1,ifelse(x[[i]]$rsi<15 & x[[i]]$close<x[[i]]$sma,1,0))}


}


Solution

  • What you want to do can be easily done using quantstrat. See the demo folder in the package (See the RSI strategy in the demo folder), or google multiple tutorials online about it.

    devtools::install_github("braverock/quantstrat")
    

    In your code snippet, this section doesn't make sense as you are trying to loop over a vector operation:

    for(i in length(x[[i]]$signal))
    {x[[i]]$signal<-ifelse(lag(x[[i]]$signal)==1 & x[[i]]$close<x[[i]]$sma,1,ifelse(x[[i]]$rsi<15 & x[[i]]$close<x[[i]]$sma,1,0))}
    

    Also for(i in length(x[[i]]$signal)) simply returns i = length of vector. Maybe you wanted something like for(i in 1:NROW(x[[i]]$signal)).

    It looks like you want something like this:

    x <- list()
    for (i in 1:length(symbols)) {
        x[[i]] <- get(symbols[i], pos=stockData)  # get data from stockData environment 
        x[[i]]$sma <-SMA(Cl(x[[i]]),10)
        x[[i]]$rsi <-RSI(Cl(x[[i]]),2)
        x[[i]]$close <-(Cl(x[[i]]))
        x[[i]]$signal<-ifelse(x[[i]]$rsi<15 & x[[i]]$close<x[[i]]$sma,1,0)
        x[[i]]$signal2 <-ifelse(lag.xts(x[[i]]$signal) ==1 & x[[i]]$close<x[[i]]$sma,1,ifelse(x[[i]]$rsi<15 & x[[i]]$close<x[[i]]$sma,1,0))
    }