R: Backtesting a trading strategy. Beginners to quantmod and R

MichiZH picture MichiZH · Jun 6, 2013 · Viewed 11.9k times · Source

I'm very new to R and trying to backtest a strategy I've programmed already in WealthLab.

Several stuff I don't understand (and it doesn't work obviously:)

  1. I don't get the Close Prices nicely into a vector...or some kind of vector but it starts with structure and I don't really understand what this function does. Thats why my series[,1] call probably doesn't work.

  2. n <- nrow(series) doesn't work either, but I need that for the Loop

So I guess if I get These 2 questions answered my strategy should work...I'm very thankful for any help..R seems quite complicated even with programming experience in other languages

#rm(list = ls(all = TRUE))

#import data, default is yahoo
require(quantmod)
series <- getSymbols('AAPL',from='2013-01-01')
#generate HLOC series
close <- Cl(AAPL)
open <- Op(AAPL)
low <-Lo(AAPL)
high <- Hi(AAPL)

#setting parameters
lookback <- 24 #24 days ago
startMoney <- 10000


#Empty our time series for position and returns
f <- function(x) 0 * x

position <- apply(series[,1],FUN=f)
colnames(position)="long_short"

returns <- apply(series[,1],FUN=f)
colnames(returns)="Returns"

trades = returns
colnames(trades)="Trades"

amount = returns
colnames(amount) = "DollarAmount"
amt[seq(1,lookback)] = startMoney


#Calculate all the necessary values in a loop with our trading strategy
n <- nrow(series)

for(i in seq(lookback+1,n)){
  #get the return
  if(position[i-1] == 1){
    #we were long
    returns[i] = close[i]/close[i-1] - 1
  } else if(position[i-1] == -1){
    #we were short
    returns[i] = close[i-1]/close[i] - 1
  }


  #long/short position
  if(open[i-lookback]<open[i] && low[i-1] < open[i]){
    #go long
    position[i] = 1    
  } else if(open[i-lookback]>open[i] && high[i-1] > open[i]){
    # go short
    position[i] = -1
  } else {
    position[i] = position[i-1]
  }

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

  #Calculate the dollar amount
  amount[i] = amount[i-1]*exp(returns[i])
  if(trades[i]) amount[i] = amount[i] - 2
}

Answer

haki picture haki · Jul 2, 2013

Starting with the second question

> s <- getSymbols('SPY')
> nrow(s)
NULL
> class(s)
[1] "character"
> s.data <- get(s)
> class(s.data)
[1] "xts" "zoo"
> nrow(s.data)
[1] 1635

So if you want to work on the actual xts object you need to use get.

About your first question - i don't think you really need to pull the data as a vector - the xts object is an array indexed by date and it's easy to work with. If you still want to get the data you can use

closing.prices <- coredata(Cl(s))

Now, to get you started with simple back testing of strategies i will suggest working in the following steps

define your strategy. 2. create an array or add a column to your xts object that will represent your position for each day. 1 for long, 0 for no position and -1 for short (later on you can play with the number for leverage). 3. multiply each days return with the position and you'll get your strategy return vector. 4. examine the results - my recommendation is PerformanceAnalytics.

simple strategy - buy when close over SMA20 , sell under

library(quantmod)
library(PerformanceAnalytics)

s <- get(getSymbols('SPY'))["2012::"]
s$sma20 <- SMA(Cl(s) , 20)
s$position <- ifelse(Cl(s) > s$sma20 , 1 , -1)
myReturn <- lag(s$position) * dailyReturn(s)
charts.PerformanceSummary(cbind(dailyReturn(s),myReturn))

and this is what you'll get

enter image description here