
Synopsis
This document utilizes the “QuantMod”, and “PerformanceAnalytics”, R packages for Backtesting of Automated Trading Stategies.
Working Directory, and Required Packages
library(RCurl)
library(xts)
library(zoo)
library(quantmod)
library(PerformanceAnalytics)
library(rugarch)
library(knitr)
Downloading Stock Ticker Data from Yahoo Finances
ticker_lookup <- getSymbols("TWTR", auto.assign=F,
from="2014-01-01", to="2016-01-01")
ticker_lookup2 <- as.data.frame(cbind(ticker_lookup[,1], ticker_lookup[,2], ticker_lookup[,3], ticker_lookup[,4], ticker_lookup[,5], ticker_lookup[,6]))
ticker_data <- as.data.frame(cbind(date = rownames(ticker_lookup2), ticker_lookup2))
colnames(ticker_data) <- c("date","open","high ","low ","close ","volume ","adjusted")
rownames(ticker_data) <- NULL
Trading Strategy Backtest
daysSinceHigh <- function(x, n){
apply(embed(x, n), 1, which.max)-1
}
myStrat <- function(x, nHold=100, nHigh=200) {
position <- ifelse(daysSinceHigh(x, nHigh)<=nHold,1,0)
c(rep(0,nHigh-1),position)
}
getSymbols('TWTR', from='2011-01-01')
## [1] "TWTR"
myStock <- Cl(TWTR)
myPosition <- myStrat(myStock,40,45)
bmkReturns <- dailyReturn(myStock, type = "arithmetic")
myReturns <- bmkReturns*Lag(myPosition,1)
myReturns[1] <- 0
names(bmkReturns) <- 'TWTR'
names(myReturns) <- 'Me'
Trading Strategy Backtest Charts
charts.PerformanceSummary(cbind(bmkReturns,myReturns))

Performance <- function(x) {
cumRetx = Return.cumulative(x)
annRetx = Return.annualized(x, scale=252)
sharpex = SharpeRatio.annualized(x, scale=252)
winpctx = length(x[x > 0])/length(x[x != 0])
annSDx = sd.annualized(x, scale=252)
DDs <- findDrawdowns(x)
maxDDx = min(DDs$return)
maxLx = max(DDs$length)
Perf = c(cumRetx, annRetx, sharpex, winpctx, annSDx, maxDDx, maxLx)
names(Perf) = c("Cumulative Return", "Annual Return","Annualized Sharpe Ratio",
"Win %", "Annualized Volatility", "Maximum Drawdown", "Max Length Drawdown")
return(Perf)
}
cbind(Me=Performance(myReturns),TWTR=Performance(bmkReturns))
## Me TWTR
## Cumulative Return -0.4560617 -0.5574610
## Annual Return -0.1936313 -0.2503363
## Annualized Sharpe Ratio -0.4312546 -0.4436876
## Win % 0.4968553 0.4914530
## Annualized Volatility 0.4489952 0.5642175
## Maximum Drawdown -0.7053375 -0.8088937
## Max Length Drawdown 483.0000000 680.0000000
Test Strategy
testStrategy <- function(myStock, nHold=100, nHigh=200) {
myPosition <- myStrat(myStock,nHold,nHigh)
bmkReturns <- dailyReturn(myStock, type = "arithmetic")
myReturns <- bmkReturns*Lag(myPosition,1)
myReturns[1] <- 0
names(bmkReturns) <- 'TWTR'
names(myReturns) <- 'Me'
charts.PerformanceSummary(cbind(bmkReturns,myReturns))
cbind(Me=Performance(myReturns),Index=Performance(bmkReturns))
}
getSymbols('TWTR', from='2014-01-01')
## [1] "TWTR"
testStrategy(na.omit(TWTR),40,45)

## Me Index
## Cumulative Return -0.5258818 -0.6943077
## Annual Return -0.2428592 -0.3571290
## Annualized Sharpe Ratio -0.8411437 -0.6497178
## Win % 0.4077670 0.4849850
## Annualized Volatility 0.2887249 0.5496679
## Maximum Drawdown -0.6016240 -0.7969565
## Max Length Drawdown 599.0000000 675.0000000
SMA (Simple Moving Average) Strategy Backtest
tickerData.xts <- xts(as.numeric(Cl(ticker_data)),
order.by=as.Date(ticker_data$date))
tickerData.z = zoo(x=Cl(ticker_data), order.by=as.Date(ticker_data$date))
prices <- tickerData.xts[,1]
CCI20 <- CCI(prices, 20)
RSI3 <- RSI(prices, 3)
DEMA10 <- DEMA(prices, n = 10, v = 1, wilder = FALSE)
DEMA10c <- prices - DEMA10
DEMA10c <- DEMA10c/.0001
buy.signal <- ifelse(RSI3 < 30 & CCI20 > -290 & CCI20 < -100 & DEMA10c > -40 & DEMA10c < 750, 1, NA)
sell.signal <- ifelse(DEMA10c > 5 & DEMA10c < 200 & CCI20 > 100 & CCI20 < 500 & RSI3 > 10, -1 ,NA)
sma <- SMA(tickerData.xts, n=1)
sig <- Lag(ifelse(sma$SMA < buy.signal, 1, -1))
retSMA <- ROC(tickerData.xts) * sig
SMA Backtest Results
SMA Backtest Charts
plot(sma)

chartSeries(ticker_lookup, theme = chartTheme('white'),
TA=c(addVo(),addBBands(), addMACD()))

retdrawDowns <- table.Drawdowns(retSMA, top=10)
kable(retdrawDowns)
2014-05-12 |
2014-05-12 |
NA |
-0.0573 |
2 |
1 |
NA |
retReturns <- table.CalendarReturns(retSMA); retReturns
## Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Lag.1
## 2014 NA NA NA 3.7 -5.7 NA NA NA NA NA NA NA -2.2
## 2015 NA NA NA NA NA NA NA NA NA NA NA NA NA
retDownsideRisk <- table.DownsideRisk(retSMA)
kable(retDownsideRisk)
Semi Deviation |
0.0335 |
Gain Deviation |
NA |
Loss Deviation |
NA |
Downside Deviation (MAR=210%) |
0.0464 |
Downside Deviation (Rf=0%) |
0.0405 |
Downside Deviation (0%) |
0.0405 |
Maximum Drawdown |
0.0573 |
Historical VaR (95%) |
-0.0526 |
Historical ES (95%) |
-0.0573 |
Modified VaR (95%) |
-0.0898 |
Modified ES (95%) |
-0.0907 |
charts.PerformanceSummary(retSMA)

DVI Strategy Backtest
getSymbols('MSFT', from='2011-01-01')
## [1] "MSFT"
dvi <- DVI(Cl(MSFT))
sig <- Lag(ifelse(dvi$e1 < 0.5, 1, -1))
Trading_Strategy_Returns <- ROC(dvi$e1)*sig
Trading_Strategy_Returns <- ROC(Cl(MSFT))*sig
plot(Trading_Strategy_Returns)

retdrawDowns <- table.Drawdowns(Trading_Strategy_Returns, top=10)
kable(retdrawDowns)
2015-10-02 |
2016-01-29 |
2016-04-20 |
-0.2303 |
138 |
82 |
56 |
2015-04-20 |
2015-04-28 |
2015-08-21 |
-0.1586 |
88 |
7 |
81 |
2014-09-22 |
2014-11-13 |
2015-01-27 |
-0.1435 |
88 |
39 |
49 |
2013-10-25 |
2013-11-06 |
2014-02-03 |
-0.1287 |
68 |
9 |
59 |
2016-05-26 |
2016-08-11 |
NA |
-0.1141 |
73 |
54 |
NA |
2012-09-07 |
2012-10-25 |
2012-11-12 |
-0.0985 |
45 |
35 |
10 |
2015-02-12 |
2015-03-12 |
2015-04-10 |
-0.0982 |
40 |
20 |
20 |
2013-04-24 |
2013-05-06 |
2013-07-19 |
-0.0946 |
61 |
9 |
52 |
2013-03-12 |
2013-04-10 |
2013-04-22 |
-0.0806 |
29 |
21 |
8 |
2012-06-11 |
2012-06-20 |
2012-07-06 |
-0.0656 |
19 |
8 |
11 |
retReturns <- table.CalendarReturns(Trading_Strategy_Returns); retReturns
## Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec MSFT.Close
## 2011 NA NA NA NA NA NA NA NA NA NA NA NA NA
## 2012 NA NA NA NA NA 2.2 -0.2 1.6 -0.9 3.4 1.2 0.6 8.2
## 2013 -1.7 0.5 0.0 1.2 0.4 -0.5 -0.5 0.4 0.9 -0.3 1.4 -0.3 1.3
## 2014 -2.6 1.2 1.0 1.0 -1.5 0.4 -0.7 1.2 -1.0 -1.9 1.7 1.2 -0.1
## 2015 -3.9 0.5 0.1 0.0 0.8 0.7 -0.4 -4.0 0.8 1.4 -1.6 1.5 -4.3
## 2016 0.7 3.3 -0.6 -0.1 0.3 0.0 0.2 -0.2 0.1 NA NA NA 3.6
retDownsideRisk <- table.DownsideRisk(Trading_Strategy_Returns)
kable(retDownsideRisk)
Semi Deviation |
0.0104 |
Gain Deviation |
0.0114 |
Loss Deviation |
0.0105 |
Downside Deviation (MAR=210%) |
0.0145 |
Downside Deviation (Rf=0%) |
0.0098 |
Downside Deviation (0%) |
0.0098 |
Maximum Drawdown |
0.2303 |
Historical VaR (95%) |
-0.0206 |
Historical ES (95%) |
-0.0321 |
Modified VaR (95%) |
-0.0192 |
Modified ES (95%) |
-0.0192 |
charts.PerformanceSummary(Trading_Strategy_Returns)
