SlideShare a Scribd company logo
1 of 15
Download to read offline
Trading Code
Jiaxiang Li
Thanks so much to the developers of quantstrat 99% of this code comes from the demos in the quantstrat
package
Load the quantstrat-package and ggvis-package for html documents
rm(list=ls())
library(quantstrat)
## Loading required package: quantmod
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Version 0.4-0 included new data defaults. See ?getSymbols.
## Loading required package: blotter
## Loading required package: FinancialInstrument
## Loading required package: PerformanceAnalytics
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
## Loading required package: foreach
library(ggvis)
##
## Attaching package: 'ggvis'
## The following object is masked from 'package:quantmod':
##
## add_axis
Create initdate, from, and to charater strings
initdate <- "1999-01-01"
from <- "2003-01-01"
to <- "2016-12-31" #latest
Set the timezone to UTC
Sys.setenv(TZ = "UTC")
1
Set the currency to USD
currency("USD")
library(quantmod)
getSymbols("SPY", from = "2003-01-01", to = "2016-12-31", src = "yahoo", adjust = TRUE)
## As of 0.4-0, 'getSymbols' uses env=parent.frame() and
## auto.assign=TRUE by default.
##
## This behavior will be phased out in 0.5-0 when the call will
## default to use auto.assign=FALSE. getOption("getSymbols.env") and
## getOptions("getSymbols.auto.assign") are now checked for alternate defaults
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for more details.
## [1] "SPY"
Use the stock command to initialize SPY and set currency to USD
stock("SPY", currency = "USD")
## [1] "SPY"
# Define your trade size and initial equity
tradesize <- 100000
initeq <- 100000
Define the names of your strategy, portfolio and account
strategy.st <- "firststrat"
portfolio.st <- "firststrat"
account.st <- "firststrat"
Remove the existing strategy if it exists
rm.strat(strategy.st)
initialize the portfolio
initPortf(portfolio.st, symbols = "SPY", initDate = initdate, currency = "USD")
## [1] "firststrat"
initialize the account
initAcct(account.st, portfolios = portfolio.st, initDate = initdate, currency = "USD", initEq = initeq)
## [1] "firststrat"
initialize the orders
initOrders(portfolio.st, initDate = initdate)
store the strategy
strategy(strategy.st, store = TRUE)
Create a 200-day moving average
spy_ma <- SMA(x = Cl(SPY), n = 200)
Create an RSI with a 3 day lookback period
2
spy_rsi <- RSI(price = Cl(SPY), n = 3)
par(mfrow=c(2,1))
plot.ts(spy_ma)
plot.ts(spy_rsi)
Time
spy_ma
0 500 1000 1500 2000 2500 3000 3500
80
Time
spy_rsi
0 500 1000 1500 2000 2500 3000 3500
080
Plot the closing prices of SPY
plot(Cl(SPY))
# Overlay a 200-day SMA
lines(SMA(Cl(SPY), n = 200), col = "red")
3
Jan 02
2003
Jan 03
2005
Jan 03
2007
Jan 02
2009
Jan 03
2011
Jan 02
2013
Jan 02
2015
Dec 30
2016
100150200 Cl(SPY)
Is this a trend or reversion indicator?
"trend"
## [1] "trend"
plot the closing price of SPY
par(mfrow=c(2,1))
plot(Cl(SPY))
# plot the RSI 2
plot(RSI(Cl(SPY), n = 2))
4
Jan 02
2003
Jan 03
2005
Jan 03
2007
Jan 02
2009
Jan 03
2011
Jan 02
2013
Jan 02
2015
Dec 30
2016
100 Cl(SPY)
Jan 02
2003
Jan 03
2005
Jan 03
2007
Jan 02
2009
Jan 03
2011
Jan 02
2013
Jan 02
2015
Dec 30
2016
080
RSI(Cl(SPY), n = 2)
3.5 Implementing an indicator
## [1] "firststrat"
## [1] "firststrat"
## [1] "firststrat"
## [1] "firststrat"
## [1] "firststrat"
3.10 Apply the indicator
• use applyIndicators to test out your indicators
test <- applyIndicators(strategy = strategy.st, mktdata = OHLC(SPY))
• subset your data between Sep. 1 and Sep. 5 of 2013
test_subset <- test["2003-09-01/2003-09-05"]
test_subset
## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50
## 2003-09-02 77.47918 78.42442 77.02943 78.36344 NA 75.77683
## 2003-09-03 78.53876 79.04949 78.34819 78.79032 NA 75.85215
## 2003-09-04 78.59212 78.93516 78.33295 78.82844 NA 75.92670
## 2003-09-05 78.47016 78.93516 78.05852 78.38631 NA 76.00750
## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126
## 2003-09-02 95.35548 93.23960 89.68254
## 2003-09-03 96.59124 94.80571 84.92063
## 2003-09-04 96.70854 94.95093 61.90476
5
## 2003-09-05 60.49185 63.92274 43.65079
4. Signals
4.1 Signal or not?
test["2010-09-20/2010-09-20"]
## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50
## 2010-09-20 99.22294 100.6118 98.90649 100.392 97.32048 96.01428
## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126
## 2010-09-20 97.03421 95.32398 67.46032
test["2010-09-30/2010-09-30"]
## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50
## 2010-09-30 101.1304 101.7809 99.84703 100.3217 97.51358 96.89952
## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126
## 2010-09-30 46.74999 49.90234 19.84127
4.3 Using sigComparison
# add a sigComparison which specifies that SMA50 must be greater than SMA200, call it longfilter
add.signal(strategy.st, name = "sigComparison",
# we are interested in the relationship between the SMA50 and the SMA200
arguments = list(columns = c("SMA50", "SMA200"),
# particularly, we are interested when the SMA50 is greater than the SMA200
relationship = "gt"), # gt = greater than
# label this signal longfilter
label = "longfilter")
## [1] "firststrat"
4.4 Using sigCrossover
# add a sigCrossover which specifies that the SMA50 is less than the SMA200 and label it filterexit
add.signal(strategy.st, name = "sigCrossover",
# we're interested in the relationship between the SMA50 and the SMA200
arguments = list(columns = c("SMA50", "SMA200"),
# the relationship is that the SMA50 crosses under the SMA200
relationship = "lt"),
# label it filterexit
label = "filterexit")
## [1] "firststrat"
6
4.5 Using sigThreshold
# implement a sigThreshold which specifies that DVO_2_126 must be less than 20, label it longthreshold
add.signal(strategy.st, name = "sigThreshold",
# use the DVO_2_126 column
arguments = list(column = "DVO_2_126",
# the threshold is 20
threshold = 20,
# we want the oscillator to be under this value
relationship = "lt",
# we're interested in every instance that the oscillator is less than 20
cross = FALSE),
# label it longthreshold
label = "longthreshold")
## [1] "firststrat"
# add a sigThreshold signal to your strategy that specifies that DVO_2_126 must cross above 80 and label
add.signal(strategy.st, name = "sigThreshold",
# reference the column of DVO_2_126
arguments = list(column = "DVO_2_126",
# set a threshold of 80
threshold = 80,
# the oscillator must be greater than 80
relationship = "gt",
# we are interested only in the cross
cross = TRUE),
# label it thresholdexit
label = "thresholdexit")
## [1] "firststrat"
4.9 Combining signals
# add a sigFormula signal to your code specifying that both longfilter and longthreshold must be TRUE, l
add.signal(strategy.st, name = "sigFormula",
# specify that longfilter and longthreshold must be TRUE
arguments = list(formula = "longfilter & longthreshold",
# specify that cross must be TRUE
cross = TRUE),
7
# label it longentry
label = "longentry")
## [1] "firststrat"
add.signal(strategy.st, name = "sigFormula",
# specify that filterexit and thresholdexit must be TRUE
arguments = list(formula = "filterexit & thresholdexit",
# specify that cross must be TRUE
cross = TRUE),
# label it shortexit
label = "shortexit")
## [1] "firststrat"
test_init <- applyIndicators(strategy.st, mktdata = OHLC(SPY))
test <- applySignals(strategy = strategy.st, mktdata = test_init)
length(test)
## [1] 52875
summary(test)
## Index SPY.Open SPY.High SPY.Low
## Min. :2003-01-02 Min. : 57.55 Min. : 59.29 Min. : 56.83
## 1st Qu.:2006-07-03 1st Qu.: 93.94 1st Qu.: 94.53 1st Qu.: 93.29
## Median :2009-12-31 Median :112.61 Median :113.41 Median :111.56
## Mean :2010-01-01 Mean :124.77 Mean :125.48 Mean :124.01
## 3rd Qu.:2013-07-03 3rd Qu.:153.23 3rd Qu.:154.18 3rd Qu.:152.75
## Max. :2016-12-30 Max. :226.57 Max. :227.00 Max. :226.00
##
## SPY.Close SMA.SMA200 SMA.SMA50 EMA.RSI_3
## Min. : 57.69 Min. : 71.81 Min. : 64.4 Min. : 1.065
## 1st Qu.: 93.94 1st Qu.: 94.67 1st Qu.: 93.9 1st Qu.:35.255
## Median :112.60 Median :112.72 Median :112.3 Median :59.079
## Mean :124.79 Mean :123.76 Mean :124.5 Mean :56.134
## 3rd Qu.:153.25 3rd Qu.:145.91 3rd Qu.:152.5 3rd Qu.:77.974
## Max. :226.43 Max. :211.40 Max. :218.5 Max. :99.833
## NA's :199 NA's :49 NA's :3
## RSI_avg.RSI_3_4 DVO.DVO_2_126 longfilter filterexit
## Min. : 1.858 Min. : 0.7936 Min. :0.0000 Min. :1
## 1st Qu.:37.316 1st Qu.: 25.3968 1st Qu.:1.0000 1st Qu.:1
## Median :58.565 Median : 49.2064 Median :1.0000 Median :1
## Mean :56.011 Mean : 49.8085 Mean :0.7751 Mean :1
## 3rd Qu.:76.026 3rd Qu.: 73.8095 3rd Qu.:1.0000 3rd Qu.:1
## Max. :99.452 Max. :100.0000 Max. :1.0000 Max. :1
## NA's :4 NA's :126 NA's :199 NA's :3518
## longthreshold thresholdexit longentry shortexit
## Min. :0.0000 Min. :0.0000 Min. :0.000 Min. :0.0000
## 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.000 1st Qu.:0.0000
## Median :0.0000 Median :0.0000 Median :0.000 Median :0.0000
## Mean :0.1995 Mean :0.1162 Mean :0.084 Mean :0.0015
## 3rd Qu.:0.0000 3rd Qu.:0.0000 3rd Qu.:0.000 3rd Qu.:0.0000
8
## Max. :1.0000 Max. :1.0000 Max. :1.000 Max. :1.0000
## NA's :126 NA's :127 NA's :144 NA's :910
summary(test$shortexit)
## Index shortexit
## Min. :2003-01-02 Min. :0.0000
## 1st Qu.:2006-07-03 1st Qu.:0.0000
## Median :2009-12-31 Median :0.0000
## Mean :2010-01-01 Mean :0.0015
## 3rd Qu.:2013-07-03 3rd Qu.:0.0000
## Max. :2016-12-30 Max. :1.0000
## NA's :910
5 Rules
# add a rule that uses an osFUN to size an entry position
tradesize = 1e+05
add.rule(strategy = strategy.st, name = "ruleSignal",
arguments = list(sigcol = "longentry", sigval = TRUE, ordertype = 'market',
orderside = "long", replace = FALSE, prefer = "Open",
# set orderqty to 500
orderqty = 500,
# the tradeSize argument should be equal to tradesize (defined earlier)
tradeSize = tradesize,
# the maxSize argument should be equal to tradesize as well
maxSize = tradesize),
type = "enter")
## [1] "firststrat"
add.rule(strategy = strategy.st, name = "ruleSignal",
arguments = list(sigcol = "shortexit", sigval = TRUE, ordertype = 'market',
orderside = "long", replace = FALSE, prefer = "Open",
# set orderqty to 500
orderqty = 500,
# the tradeSize argument should be equal to tradesize (defined earlier)
tradeSize = tradesize,
# the maxSize argument should be equal to tradesize as well
maxSize = tradesize),
type = "exit")
## [1] "firststrat"
9
6. Analyzing results
6.1 Running the strategy
from chapter 6
# use applyStrategy() to apply your strategy. Save this to out
out <- applyStrategy(strategy = strategy.st, portfolios = portfolio.st)
# update your portfolio (portfolio.st)
updatePortf(portfolio.st)
daterange <- time(getPortfolio(portfolio.st)$summary)[-1]
# update your account (account.st)
updateAcct(account.st, daterange)
updateEndEq(account.st)
# what is the date of the last trade?
"2016-12-29"
6.2 Profit factor
portfolio.st
## [1] "firststrat"
# Get the tradeStats for your portfolio
tstats <- tradeStats(portfolio.st)
# Print the profit factor
tstats$Profit.Factor
## NULL
6.3 Percent positive
tstats
## NULL
6.4 Using chart.Posn()
# use chart.Posn to view your system's performance on SPY
chart.Posn(Portfolio = portfolio.st, Symbol = "SPY")
10
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Jan 02
2003
Jan 02
2004
Jan 03
2005
Jan 03
2006
Jan 03
2007
Jan 02
2008
Jan 02
2009
Jan 04
2010
Jan 03
2011
Jan 03
2012
Jan 02
2013
Jan 02
2014
Jan 02
2015
Jan 04
2016
Dec 30
2016
SPY 2003−01−02 / 2016−12−30
60
80
100
120
140
160
180
200
220
60
80
100
120
140
160
180
200
220
50
100
150
200
250
Positionfill 144000
0
50000
100000
150000
0
50000
100000
150000
0
50000
100000
150000
CumPL 13220349.21332
−5000000
0
5000000
10000000
15000000
−5000000
0
5000000
10000000
15000000
Drawdown −415173.81869
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
6.5 Adding an indicator to a chart.Posn() chart
# compute the SMA50
sma50 <- SMA(x = Cl(SPY), n = 50)
# compute the SMA200
sma200 <- SMA(x = Cl(SPY), n = 200)
# compute the DVO_2_126 with an navg of 2 and a percentlookback of 126
dvo <- DVO(HLC = HLC(SPY), navg = 2, percentlookback = 126)
# recreate the chart.Posn of the strategy from the previous exercise
chart.Posn(Portfolio = portfolio.st, Symbol = "SPY")
11
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Jan 02
2003
Jan 02
2004
Jan 03
2005
Jan 03
2006
Jan 03
2007
Jan 02
2008
Jan 02
2009
Jan 04
2010
Jan 03
2011
Jan 03
2012
Jan 02
2013
Jan 02
2014
Jan 02
2015
Jan 04
2016
Dec 30
2016
SPY 2003−01−02 / 2016−12−30
60
80
100
120
140
160
180
200
220
60
80
100
120
140
160
180
200
220
50
100
150
200
250
Positionfill 144000
0
50000
100000
150000
0
50000
100000
150000
0
50000
100000
150000
CumPL 13220349.21332
−5000000
0
5000000
10000000
15000000
−5000000
0
5000000
10000000
15000000
Drawdown −415173.81869
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
# overlay the SMA50 on your plot as a blue line
add_TA(sma50, on = 1, col = "blue")
12
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Jan 02
2003
Jan 02
2004
Jan 03
2005
Jan 03
2006
Jan 03
2007
Jan 02
2008
Jan 02
2009
Jan 04
2010
Jan 03
2011
Jan 03
2012
Jan 02
2013
Jan 02
2014
Jan 02
2015
Jan 04
2016
Dec 30
2016
SPY 2003−01−02 / 2016−12−30
60
80
100
120
140
160
180
200
220
60
80
100
120
140
160
180
200
220
50
100
150
200
250
Positionfill 144000
0
50000
100000
150000
0
50000
100000
150000
0
50000
100000
150000
CumPL 13220349.21332
−5000000
0
5000000
10000000
15000000
−5000000
0
5000000
10000000
15000000
Drawdown −415173.81869
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
50
100
150
200
250
# overlay the SMA200 on your plot as a red line
add_TA(sma200, on = 1, col = "red")
13
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Jan 02
2003
Jan 02
2004
Jan 03
2005
Jan 03
2006
Jan 03
2007
Jan 02
2008
Jan 02
2009
Jan 04
2010
Jan 03
2011
Jan 03
2012
Jan 02
2013
Jan 02
2014
Jan 02
2015
Jan 04
2016
Dec 30
2016
SPY 2003−01−02 / 2016−12−30
60
80
100
120
140
160
180
200
220
60
80
100
120
140
160
180
200
220
50
100
150
200
250
Positionfill 144000
0
50000
100000
150000
0
50000
100000
150000
0
50000
100000
150000
CumPL 13220349.21332
−5000000
0
5000000
10000000
15000000
−5000000
0
5000000
10000000
15000000
Drawdown −415173.81869
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
50
100
150
200
250
60
80
100
120
140
160
180
200
220
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Jan 02
2003
Jan 02
2004
Jan 03
2005
Jan 03
2006
Jan 03
2007
Jan 02
2008
Jan 02
2009
Jan 04
2010
Jan 03
2011
Jan 03
2012
Jan 02
2013
Jan 02
2014
Jan 02
2015
Jan 04
2016
Dec 30
2016
SPY 2003−01−02 / 2016−12−30
60
80
100
120
140
160
180
200
220
60
80
100
120
140
160
180
200
220
50
100
150
200
250
Positionfill 144000
0
50000
100000
150000
0
50000
100000
150000
0
50000
100000
150000
CumPL 13220349.21332
−5000000
0
5000000
10000000
15000000
−5000000
0
5000000
10000000
15000000
Drawdown −415173.81869
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
−1.4e+07
−1.2e+07
−1.0e+07
−8.0e+06
−6.0e+06
−4.0e+06
−2.0e+06
0.0e+00
50
100
150
200
250
60
80
100
120
140
160
180
200
220
dvo 30.95238
0
20
40
60
80
100
0
20
40
60
80
100
14
6.6 Cash Sharpe ratio
portpl <- .blotter$portfolio.firststrat$summary$Net.Trading.PL
SharpeRatio.annualized(portpl, geometric=FALSE)
## Net.Trading.PL
## Annualized Sharpe Ratio (Rf=0%) 0.4956742
# get instrument returns
instrets <- PortfReturns(portfolio.st)
# compute Sharpe ratio from returns
SharpeRatio.annualized(instrets, geometric = FALSE)
## SPY.DailyEndEq
## Annualized Sharpe Ratio (Rf=0%) 0.4957445
15

More Related Content

Similar to Trading on SPY

Forecasting Revenue With Stationary Time Series Models
Forecasting Revenue With Stationary Time Series ModelsForecasting Revenue With Stationary Time Series Models
Forecasting Revenue With Stationary Time Series ModelsGeoffery Mullings
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings imtiazalijoono
 
The Ring programming language version 1.9 book - Part 93 of 210
The Ring programming language version 1.9 book - Part 93 of 210The Ring programming language version 1.9 book - Part 93 of 210
The Ring programming language version 1.9 book - Part 93 of 210Mahmoud Samir Fayed
 
Python 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptxPython 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptxTseChris
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorNeeraj Kaushik
 
Estimating Beta For A Portfolio Of Stocks
Estimating Beta For A Portfolio Of StocksEstimating Beta For A Portfolio Of Stocks
Estimating Beta For A Portfolio Of StocksGeoffery Mullings
 
Data manipulation and visualization in r 20190711 myanmarucsy
Data manipulation and visualization in r 20190711 myanmarucsyData manipulation and visualization in r 20190711 myanmarucsy
Data manipulation and visualization in r 20190711 myanmarucsySmartHinJ
 
The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196Mahmoud Samir Fayed
 
Regression and Classification with R
Regression and Classification with RRegression and Classification with R
Regression and Classification with RYanchang Zhao
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194Mahmoud Samir Fayed
 
Efficient equity portfolios using mean variance optimisation in R
Efficient equity portfolios using mean variance optimisation in REfficient equity portfolios using mean variance optimisation in R
Efficient equity portfolios using mean variance optimisation in RGregg Barrett
 
Peterson_-_Machine_Learning_Project
Peterson_-_Machine_Learning_ProjectPeterson_-_Machine_Learning_Project
Peterson_-_Machine_Learning_Projectjpeterson2058
 
lecture7.ppt
lecture7.pptlecture7.ppt
lecture7.pptEdFeranil
 
Market Basket Analysis in R
Market Basket Analysis in RMarket Basket Analysis in R
Market Basket Analysis in RRsquared Academy
 

Similar to Trading on SPY (20)

Forecasting Revenue With Stationary Time Series Models
Forecasting Revenue With Stationary Time Series ModelsForecasting Revenue With Stationary Time Series Models
Forecasting Revenue With Stationary Time Series Models
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings
 
The Ring programming language version 1.9 book - Part 93 of 210
The Ring programming language version 1.9 book - Part 93 of 210The Ring programming language version 1.9 book - Part 93 of 210
The Ring programming language version 1.9 book - Part 93 of 210
 
Python 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptxPython 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptx
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
Estimating Beta For A Portfolio Of Stocks
Estimating Beta For A Portfolio Of StocksEstimating Beta For A Portfolio Of Stocks
Estimating Beta For A Portfolio Of Stocks
 
algorithmdivs
algorithmdivsalgorithmdivs
algorithmdivs
 
algorithmdivs
algorithmdivsalgorithmdivs
algorithmdivs
 
Data manipulation and visualization in r 20190711 myanmarucsy
Data manipulation and visualization in r 20190711 myanmarucsyData manipulation and visualization in r 20190711 myanmarucsy
Data manipulation and visualization in r 20190711 myanmarucsy
 
Useful c programs
Useful c programsUseful c programs
Useful c programs
 
The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196The Ring programming language version 1.7 book - Part 93 of 196
The Ring programming language version 1.7 book - Part 93 of 196
 
Regression and Classification with R
Regression and Classification with RRegression and Classification with R
Regression and Classification with R
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194
 
Performance
PerformancePerformance
Performance
 
Efficient equity portfolios using mean variance optimisation in R
Efficient equity portfolios using mean variance optimisation in REfficient equity portfolios using mean variance optimisation in R
Efficient equity portfolios using mean variance optimisation in R
 
Peterson_-_Machine_Learning_Project
Peterson_-_Machine_Learning_ProjectPeterson_-_Machine_Learning_Project
Peterson_-_Machine_Learning_Project
 
Quality Python Homework Help
Quality Python Homework HelpQuality Python Homework Help
Quality Python Homework Help
 
lecture7.ppt
lecture7.pptlecture7.ppt
lecture7.ppt
 
Market Basket Analysis in R
Market Basket Analysis in RMarket Basket Analysis in R
Market Basket Analysis in R
 
C Arrays.ppt
C Arrays.pptC Arrays.ppt
C Arrays.ppt
 

Trading on SPY

  • 1. Trading Code Jiaxiang Li Thanks so much to the developers of quantstrat 99% of this code comes from the demos in the quantstrat package Load the quantstrat-package and ggvis-package for html documents rm(list=ls()) library(quantstrat) ## Loading required package: quantmod ## Loading required package: xts ## Loading required package: zoo ## ## Attaching package: 'zoo' ## The following objects are masked from 'package:base': ## ## as.Date, as.Date.numeric ## Loading required package: TTR ## Version 0.4-0 included new data defaults. See ?getSymbols. ## Loading required package: blotter ## Loading required package: FinancialInstrument ## Loading required package: PerformanceAnalytics ## ## Attaching package: 'PerformanceAnalytics' ## The following object is masked from 'package:graphics': ## ## legend ## Loading required package: foreach library(ggvis) ## ## Attaching package: 'ggvis' ## The following object is masked from 'package:quantmod': ## ## add_axis Create initdate, from, and to charater strings initdate <- "1999-01-01" from <- "2003-01-01" to <- "2016-12-31" #latest Set the timezone to UTC Sys.setenv(TZ = "UTC") 1
  • 2. Set the currency to USD currency("USD") library(quantmod) getSymbols("SPY", from = "2003-01-01", to = "2016-12-31", src = "yahoo", adjust = TRUE) ## As of 0.4-0, 'getSymbols' uses env=parent.frame() and ## auto.assign=TRUE by default. ## ## This behavior will be phased out in 0.5-0 when the call will ## default to use auto.assign=FALSE. getOption("getSymbols.env") and ## getOptions("getSymbols.auto.assign") are now checked for alternate defaults ## ## This message is shown once per session and may be disabled by setting ## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for more details. ## [1] "SPY" Use the stock command to initialize SPY and set currency to USD stock("SPY", currency = "USD") ## [1] "SPY" # Define your trade size and initial equity tradesize <- 100000 initeq <- 100000 Define the names of your strategy, portfolio and account strategy.st <- "firststrat" portfolio.st <- "firststrat" account.st <- "firststrat" Remove the existing strategy if it exists rm.strat(strategy.st) initialize the portfolio initPortf(portfolio.st, symbols = "SPY", initDate = initdate, currency = "USD") ## [1] "firststrat" initialize the account initAcct(account.st, portfolios = portfolio.st, initDate = initdate, currency = "USD", initEq = initeq) ## [1] "firststrat" initialize the orders initOrders(portfolio.st, initDate = initdate) store the strategy strategy(strategy.st, store = TRUE) Create a 200-day moving average spy_ma <- SMA(x = Cl(SPY), n = 200) Create an RSI with a 3 day lookback period 2
  • 3. spy_rsi <- RSI(price = Cl(SPY), n = 3) par(mfrow=c(2,1)) plot.ts(spy_ma) plot.ts(spy_rsi) Time spy_ma 0 500 1000 1500 2000 2500 3000 3500 80 Time spy_rsi 0 500 1000 1500 2000 2500 3000 3500 080 Plot the closing prices of SPY plot(Cl(SPY)) # Overlay a 200-day SMA lines(SMA(Cl(SPY), n = 200), col = "red") 3
  • 4. Jan 02 2003 Jan 03 2005 Jan 03 2007 Jan 02 2009 Jan 03 2011 Jan 02 2013 Jan 02 2015 Dec 30 2016 100150200 Cl(SPY) Is this a trend or reversion indicator? "trend" ## [1] "trend" plot the closing price of SPY par(mfrow=c(2,1)) plot(Cl(SPY)) # plot the RSI 2 plot(RSI(Cl(SPY), n = 2)) 4
  • 5. Jan 02 2003 Jan 03 2005 Jan 03 2007 Jan 02 2009 Jan 03 2011 Jan 02 2013 Jan 02 2015 Dec 30 2016 100 Cl(SPY) Jan 02 2003 Jan 03 2005 Jan 03 2007 Jan 02 2009 Jan 03 2011 Jan 02 2013 Jan 02 2015 Dec 30 2016 080 RSI(Cl(SPY), n = 2) 3.5 Implementing an indicator ## [1] "firststrat" ## [1] "firststrat" ## [1] "firststrat" ## [1] "firststrat" ## [1] "firststrat" 3.10 Apply the indicator • use applyIndicators to test out your indicators test <- applyIndicators(strategy = strategy.st, mktdata = OHLC(SPY)) • subset your data between Sep. 1 and Sep. 5 of 2013 test_subset <- test["2003-09-01/2003-09-05"] test_subset ## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50 ## 2003-09-02 77.47918 78.42442 77.02943 78.36344 NA 75.77683 ## 2003-09-03 78.53876 79.04949 78.34819 78.79032 NA 75.85215 ## 2003-09-04 78.59212 78.93516 78.33295 78.82844 NA 75.92670 ## 2003-09-05 78.47016 78.93516 78.05852 78.38631 NA 76.00750 ## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126 ## 2003-09-02 95.35548 93.23960 89.68254 ## 2003-09-03 96.59124 94.80571 84.92063 ## 2003-09-04 96.70854 94.95093 61.90476 5
  • 6. ## 2003-09-05 60.49185 63.92274 43.65079 4. Signals 4.1 Signal or not? test["2010-09-20/2010-09-20"] ## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50 ## 2010-09-20 99.22294 100.6118 98.90649 100.392 97.32048 96.01428 ## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126 ## 2010-09-20 97.03421 95.32398 67.46032 test["2010-09-30/2010-09-30"] ## SPY.Open SPY.High SPY.Low SPY.Close SMA.SMA200 SMA.SMA50 ## 2010-09-30 101.1304 101.7809 99.84703 100.3217 97.51358 96.89952 ## EMA.RSI_3 RSI_avg.RSI_3_4 DVO.DVO_2_126 ## 2010-09-30 46.74999 49.90234 19.84127 4.3 Using sigComparison # add a sigComparison which specifies that SMA50 must be greater than SMA200, call it longfilter add.signal(strategy.st, name = "sigComparison", # we are interested in the relationship between the SMA50 and the SMA200 arguments = list(columns = c("SMA50", "SMA200"), # particularly, we are interested when the SMA50 is greater than the SMA200 relationship = "gt"), # gt = greater than # label this signal longfilter label = "longfilter") ## [1] "firststrat" 4.4 Using sigCrossover # add a sigCrossover which specifies that the SMA50 is less than the SMA200 and label it filterexit add.signal(strategy.st, name = "sigCrossover", # we're interested in the relationship between the SMA50 and the SMA200 arguments = list(columns = c("SMA50", "SMA200"), # the relationship is that the SMA50 crosses under the SMA200 relationship = "lt"), # label it filterexit label = "filterexit") ## [1] "firststrat" 6
  • 7. 4.5 Using sigThreshold # implement a sigThreshold which specifies that DVO_2_126 must be less than 20, label it longthreshold add.signal(strategy.st, name = "sigThreshold", # use the DVO_2_126 column arguments = list(column = "DVO_2_126", # the threshold is 20 threshold = 20, # we want the oscillator to be under this value relationship = "lt", # we're interested in every instance that the oscillator is less than 20 cross = FALSE), # label it longthreshold label = "longthreshold") ## [1] "firststrat" # add a sigThreshold signal to your strategy that specifies that DVO_2_126 must cross above 80 and label add.signal(strategy.st, name = "sigThreshold", # reference the column of DVO_2_126 arguments = list(column = "DVO_2_126", # set a threshold of 80 threshold = 80, # the oscillator must be greater than 80 relationship = "gt", # we are interested only in the cross cross = TRUE), # label it thresholdexit label = "thresholdexit") ## [1] "firststrat" 4.9 Combining signals # add a sigFormula signal to your code specifying that both longfilter and longthreshold must be TRUE, l add.signal(strategy.st, name = "sigFormula", # specify that longfilter and longthreshold must be TRUE arguments = list(formula = "longfilter & longthreshold", # specify that cross must be TRUE cross = TRUE), 7
  • 8. # label it longentry label = "longentry") ## [1] "firststrat" add.signal(strategy.st, name = "sigFormula", # specify that filterexit and thresholdexit must be TRUE arguments = list(formula = "filterexit & thresholdexit", # specify that cross must be TRUE cross = TRUE), # label it shortexit label = "shortexit") ## [1] "firststrat" test_init <- applyIndicators(strategy.st, mktdata = OHLC(SPY)) test <- applySignals(strategy = strategy.st, mktdata = test_init) length(test) ## [1] 52875 summary(test) ## Index SPY.Open SPY.High SPY.Low ## Min. :2003-01-02 Min. : 57.55 Min. : 59.29 Min. : 56.83 ## 1st Qu.:2006-07-03 1st Qu.: 93.94 1st Qu.: 94.53 1st Qu.: 93.29 ## Median :2009-12-31 Median :112.61 Median :113.41 Median :111.56 ## Mean :2010-01-01 Mean :124.77 Mean :125.48 Mean :124.01 ## 3rd Qu.:2013-07-03 3rd Qu.:153.23 3rd Qu.:154.18 3rd Qu.:152.75 ## Max. :2016-12-30 Max. :226.57 Max. :227.00 Max. :226.00 ## ## SPY.Close SMA.SMA200 SMA.SMA50 EMA.RSI_3 ## Min. : 57.69 Min. : 71.81 Min. : 64.4 Min. : 1.065 ## 1st Qu.: 93.94 1st Qu.: 94.67 1st Qu.: 93.9 1st Qu.:35.255 ## Median :112.60 Median :112.72 Median :112.3 Median :59.079 ## Mean :124.79 Mean :123.76 Mean :124.5 Mean :56.134 ## 3rd Qu.:153.25 3rd Qu.:145.91 3rd Qu.:152.5 3rd Qu.:77.974 ## Max. :226.43 Max. :211.40 Max. :218.5 Max. :99.833 ## NA's :199 NA's :49 NA's :3 ## RSI_avg.RSI_3_4 DVO.DVO_2_126 longfilter filterexit ## Min. : 1.858 Min. : 0.7936 Min. :0.0000 Min. :1 ## 1st Qu.:37.316 1st Qu.: 25.3968 1st Qu.:1.0000 1st Qu.:1 ## Median :58.565 Median : 49.2064 Median :1.0000 Median :1 ## Mean :56.011 Mean : 49.8085 Mean :0.7751 Mean :1 ## 3rd Qu.:76.026 3rd Qu.: 73.8095 3rd Qu.:1.0000 3rd Qu.:1 ## Max. :99.452 Max. :100.0000 Max. :1.0000 Max. :1 ## NA's :4 NA's :126 NA's :199 NA's :3518 ## longthreshold thresholdexit longentry shortexit ## Min. :0.0000 Min. :0.0000 Min. :0.000 Min. :0.0000 ## 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.000 1st Qu.:0.0000 ## Median :0.0000 Median :0.0000 Median :0.000 Median :0.0000 ## Mean :0.1995 Mean :0.1162 Mean :0.084 Mean :0.0015 ## 3rd Qu.:0.0000 3rd Qu.:0.0000 3rd Qu.:0.000 3rd Qu.:0.0000 8
  • 9. ## Max. :1.0000 Max. :1.0000 Max. :1.000 Max. :1.0000 ## NA's :126 NA's :127 NA's :144 NA's :910 summary(test$shortexit) ## Index shortexit ## Min. :2003-01-02 Min. :0.0000 ## 1st Qu.:2006-07-03 1st Qu.:0.0000 ## Median :2009-12-31 Median :0.0000 ## Mean :2010-01-01 Mean :0.0015 ## 3rd Qu.:2013-07-03 3rd Qu.:0.0000 ## Max. :2016-12-30 Max. :1.0000 ## NA's :910 5 Rules # add a rule that uses an osFUN to size an entry position tradesize = 1e+05 add.rule(strategy = strategy.st, name = "ruleSignal", arguments = list(sigcol = "longentry", sigval = TRUE, ordertype = 'market', orderside = "long", replace = FALSE, prefer = "Open", # set orderqty to 500 orderqty = 500, # the tradeSize argument should be equal to tradesize (defined earlier) tradeSize = tradesize, # the maxSize argument should be equal to tradesize as well maxSize = tradesize), type = "enter") ## [1] "firststrat" add.rule(strategy = strategy.st, name = "ruleSignal", arguments = list(sigcol = "shortexit", sigval = TRUE, ordertype = 'market', orderside = "long", replace = FALSE, prefer = "Open", # set orderqty to 500 orderqty = 500, # the tradeSize argument should be equal to tradesize (defined earlier) tradeSize = tradesize, # the maxSize argument should be equal to tradesize as well maxSize = tradesize), type = "exit") ## [1] "firststrat" 9
  • 10. 6. Analyzing results 6.1 Running the strategy from chapter 6 # use applyStrategy() to apply your strategy. Save this to out out <- applyStrategy(strategy = strategy.st, portfolios = portfolio.st) # update your portfolio (portfolio.st) updatePortf(portfolio.st) daterange <- time(getPortfolio(portfolio.st)$summary)[-1] # update your account (account.st) updateAcct(account.st, daterange) updateEndEq(account.st) # what is the date of the last trade? "2016-12-29" 6.2 Profit factor portfolio.st ## [1] "firststrat" # Get the tradeStats for your portfolio tstats <- tradeStats(portfolio.st) # Print the profit factor tstats$Profit.Factor ## NULL 6.3 Percent positive tstats ## NULL 6.4 Using chart.Posn() # use chart.Posn to view your system's performance on SPY chart.Posn(Portfolio = portfolio.st, Symbol = "SPY") 10
  • 11. 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 Jan 02 2003 Jan 02 2004 Jan 03 2005 Jan 03 2006 Jan 03 2007 Jan 02 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Jan 02 2014 Jan 02 2015 Jan 04 2016 Dec 30 2016 SPY 2003−01−02 / 2016−12−30 60 80 100 120 140 160 180 200 220 60 80 100 120 140 160 180 200 220 50 100 150 200 250 Positionfill 144000 0 50000 100000 150000 0 50000 100000 150000 0 50000 100000 150000 CumPL 13220349.21332 −5000000 0 5000000 10000000 15000000 −5000000 0 5000000 10000000 15000000 Drawdown −415173.81869 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 6.5 Adding an indicator to a chart.Posn() chart # compute the SMA50 sma50 <- SMA(x = Cl(SPY), n = 50) # compute the SMA200 sma200 <- SMA(x = Cl(SPY), n = 200) # compute the DVO_2_126 with an navg of 2 and a percentlookback of 126 dvo <- DVO(HLC = HLC(SPY), navg = 2, percentlookback = 126) # recreate the chart.Posn of the strategy from the previous exercise chart.Posn(Portfolio = portfolio.st, Symbol = "SPY") 11
  • 12. 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 Jan 02 2003 Jan 02 2004 Jan 03 2005 Jan 03 2006 Jan 03 2007 Jan 02 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Jan 02 2014 Jan 02 2015 Jan 04 2016 Dec 30 2016 SPY 2003−01−02 / 2016−12−30 60 80 100 120 140 160 180 200 220 60 80 100 120 140 160 180 200 220 50 100 150 200 250 Positionfill 144000 0 50000 100000 150000 0 50000 100000 150000 0 50000 100000 150000 CumPL 13220349.21332 −5000000 0 5000000 10000000 15000000 −5000000 0 5000000 10000000 15000000 Drawdown −415173.81869 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 # overlay the SMA50 on your plot as a blue line add_TA(sma50, on = 1, col = "blue") 12
  • 13. 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 Jan 02 2003 Jan 02 2004 Jan 03 2005 Jan 03 2006 Jan 03 2007 Jan 02 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Jan 02 2014 Jan 02 2015 Jan 04 2016 Dec 30 2016 SPY 2003−01−02 / 2016−12−30 60 80 100 120 140 160 180 200 220 60 80 100 120 140 160 180 200 220 50 100 150 200 250 Positionfill 144000 0 50000 100000 150000 0 50000 100000 150000 0 50000 100000 150000 CumPL 13220349.21332 −5000000 0 5000000 10000000 15000000 −5000000 0 5000000 10000000 15000000 Drawdown −415173.81869 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 50 100 150 200 250 # overlay the SMA200 on your plot as a red line add_TA(sma200, on = 1, col = "red") 13
  • 14. 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 Jan 02 2003 Jan 02 2004 Jan 03 2005 Jan 03 2006 Jan 03 2007 Jan 02 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Jan 02 2014 Jan 02 2015 Jan 04 2016 Dec 30 2016 SPY 2003−01−02 / 2016−12−30 60 80 100 120 140 160 180 200 220 60 80 100 120 140 160 180 200 220 50 100 150 200 250 Positionfill 144000 0 50000 100000 150000 0 50000 100000 150000 0 50000 100000 150000 CumPL 13220349.21332 −5000000 0 5000000 10000000 15000000 −5000000 0 5000000 10000000 15000000 Drawdown −415173.81869 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 50 100 150 200 250 60 80 100 120 140 160 180 200 220 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 Jan 02 2003 Jan 02 2004 Jan 03 2005 Jan 03 2006 Jan 03 2007 Jan 02 2008 Jan 02 2009 Jan 04 2010 Jan 03 2011 Jan 03 2012 Jan 02 2013 Jan 02 2014 Jan 02 2015 Jan 04 2016 Dec 30 2016 SPY 2003−01−02 / 2016−12−30 60 80 100 120 140 160 180 200 220 60 80 100 120 140 160 180 200 220 50 100 150 200 250 Positionfill 144000 0 50000 100000 150000 0 50000 100000 150000 0 50000 100000 150000 CumPL 13220349.21332 −5000000 0 5000000 10000000 15000000 −5000000 0 5000000 10000000 15000000 Drawdown −415173.81869 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 −1.4e+07 −1.2e+07 −1.0e+07 −8.0e+06 −6.0e+06 −4.0e+06 −2.0e+06 0.0e+00 50 100 150 200 250 60 80 100 120 140 160 180 200 220 dvo 30.95238 0 20 40 60 80 100 0 20 40 60 80 100 14
  • 15. 6.6 Cash Sharpe ratio portpl <- .blotter$portfolio.firststrat$summary$Net.Trading.PL SharpeRatio.annualized(portpl, geometric=FALSE) ## Net.Trading.PL ## Annualized Sharpe Ratio (Rf=0%) 0.4956742 # get instrument returns instrets <- PortfReturns(portfolio.st) # compute Sharpe ratio from returns SharpeRatio.annualized(instrets, geometric = FALSE) ## SPY.DailyEndEq ## Annualized Sharpe Ratio (Rf=0%) 0.4957445 15