This document utilizes the “QuantMod”, and “PerformanceAnalytics”, R packages for Backtesting of Automated Trading Stategies, and Holt-Winters Filtering for Price Prediction.
# Set Working Directory
# setwd(" ")
# Required Packages
# if (!require("quantmod")) { install.packages("quantmod"); require("quantmod") }
# if (!require("PerformanceAnalytics")) { install.packages("PerformanceAnalytics"); require("PerformanceAnalytics") }
# if (!require("rgl")) { install.packages("rgl"); require("rgl") }
# if (!require("rugarch")) { install.packages("rugarch"); require("rugarch") }
library(RCurl)
library(xts)
library(zoo)
library(tseries)
library(forecast)
library(quantmod) # data, plotting, quant modelling
library(PerformanceAnalytics) # performance and risk management
library(knitr)
# Import Original data
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
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'
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.4741291 -0.5721604
## Annual Return -0.2042218 -0.2604865
## Annualized Sharpe Ratio -0.4538231 -0.4605472
## Win % 0.4947146 0.4899713
## Annualized Volatility 0.4500032 0.5656021
## Maximum Drawdown -0.7053375 -0.8088937
## Max Length Drawdown 479.0000000 676.0000000
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.7044616
## Annual Return -0.2441119 -0.3668884
## Annualized Sharpe Ratio -0.8429806 -0.6657829
## Win % 0.4077670 0.4833837
## Annualized Volatility 0.2895819 0.5510632
## Maximum Drawdown -0.6016240 -0.7969565
## Max Length Drawdown 595.0000000 671.0000000
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))
# Specify the prices and store our models
prices <- tickerData.xts[,1]
# Create indicator
sma <- SMA(tickerData.xts, n=1)
# Calculate the indicators we need for our strategy
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)
# Construct trading rule
sig <- Lag(ifelse(sma$SMA < buy.signal, 1, -1))
# The trading rules/equity curve
retSMA <- ROC(tickerData.xts) * sig
chartSeries(ticker_lookup, theme = chartTheme('white'),
TA=c(addVo(),addBBands(), addMACD()))
ticker_dataTS <- ts(ticker_data$close, start=c(2014, 1, 1), end=c(2016, 1, 1), frequency=250)
plot.ts(ticker_dataTS, col="blue", main="Time Series of TWTR")
# Seasonal decomposition
fit <- stl(ticker_dataTS, s.window="period")
plot(fit, main="Seasonal Decomposition of TWTR")
monthplot(ticker_dataTS, col="green", main="Month Plot of TWTR, Seasonal Adjustment")
seasonplot(ticker_dataTS, main="Season Plot of TwTR, Seasonal Adjustment")
# simple exponential - models level
fit <- HoltWinters(ticker_dataTS, beta=FALSE, gamma=FALSE)
plot(fit, main="Holt-Winters Filtering, Models Level")
# double exponential - models level and trend
fit <- HoltWinters(ticker_dataTS, gamma=FALSE)
plot(fit, main="Holt-Winters Filtering, Models Level + Trend")
# triple exponential - models level, trend, and seasonal components
fit <- HoltWinters(ticker_dataTS)
plot(fit, main="Holt-Winters Filtering, Models Level + Trend + Seasonal Components")
# predict next three future values
TWTRForecast <- forecast(fit, 20)
plot(TWTRForecast, main="TWTR Price Forecast (20 Days) from Holt-Winters Filtering")