R - Loading External Indicators into Quantstrat

654 views Asked by At

I noticed that Quantstrat typically takes indicators that are based on price. However, I would like to load several indicators that have been externally calculated along with the price data. For instance, I have 2 extra columns in a csv file that contain my indicators (numbered 1-9). I want to generate a signal based on the numbers in these columns.

Thus far, I have been unable to get Quantstrat to read the columns in the csv file. I've attached my code below:

 library(quantmod)
 library(quantstrat)
 library(PerformanceAnalytics)
 library(foreach)
 library(FinancialInstrument)

 getSymbols("SPY", from = "2015-12-21", to = "2016-12-20", src = "yahoo", adjust =TRUE)

    read.csv("/Users/tylerdrust/Downloads/2016 Demark Indicators.csv", 
             stringsAsFactors = FALSE)

             Date   Open   High    Low  Close    Volume Adj.Close TD.Sell.Count TD.Buy.Count
1   12/21/15 201.41 201.88 200.09 201.67  99094300    197.43             0            0
2   12/22/15 202.72 203.85 201.55 203.50 111026200    199.22             0            0
3   12/23/15 204.69 206.07 204.58 206.02 110987200    201.69             0            0
4   12/24/15 205.72 206.33 205.42 205.68  48539600    201.36             0            0
5   12/28/15 204.86 205.26 203.94 205.21  65899900    200.90             1            0
6   12/29/15 206.51 207.79 206.47 207.40  92640700    203.04             2            0
7   12/30/15 207.11 207.21 205.76 205.93  63317700    201.60             0            1
8   12/31/15 205.13 205.89 203.87 203.87 102929500    199.58             0            2
9     1/4/16 200.49 201.03 198.59 201.02 222353500    196.79             0            3
10    1/5/16 201.40 201.90 200.05 201.36 110845800    197.13             0            4
11    1/6/16 198.34 200.06 197.60 198.82 152112600    194.64             0            5
12    1/7/16 195.33 197.44 193.59 194.05 213436100    189.97             0            6
13    1/8/16 195.19 195.85 191.58 191.92 209817200    187.89             0            7
14   1/11/16 193.01 193.41 189.82 192.11 187941300    188.07             0            8
15   1/12/16 193.82 194.55 191.14 193.66 172330500    189.59             0            9
16   1/13/16 194.45 194.86 188.38 188.83 221168900    184.86             0           10
17   1/14/16 189.55 193.26 187.66 191.93 240795600    187.90             1            0
18   1/15/16 186.77 188.76 185.52 187.81 314240200    183.86             0            1
19   1/19/16 189.96 190.11 186.20 188.06 195244400    184.11             0            2
20   1/20/16 185.03 187.50 181.02 185.65 286547800    181.75             0            3
21   1/21/16 186.21 188.87 184.64 186.69 195772900    182.77             0            4
22   1/22/16 189.78 190.76 188.88 190.52 168319600    186.51             1            0
23   1/25/16 189.92 190.15 187.41 187.64 130371700    183.70             0            1
24   1/26/16 188.42 190.53 188.02 190.20 141036800    186.20             1            0
25   1/27/16 189.58 191.56 187.06 188.13 185681700    184.18             2            0
26   1/28/16 189.96 190.20 187.16 189.11 143798800    185.13             0            1
27   1/29/16 190.02 193.88 189.88 193.72 210529300    189.65             1            0
28    2/1/16 192.53 194.58 191.84 193.65 136061600    189.58             2            0
29    2/2/16 191.96 191.97 189.54 190.16 182564900    186.16             3            0
30    2/3/16 191.41 191.78 187.10 191.30 205054900    187.28             4            0
31    2/4/16 190.71 192.75 189.96 191.60 139531800    187.57             0            1
32    2/5/16 190.99 191.67 187.20 187.95 180788300    184.00             0            2
33    2/8/16 185.77 186.12 182.80 185.42 191526700    181.52             0            3
34    2/9/16 183.36 186.94 183.20 185.43 184513100    181.53             0            4
35   2/10/16 186.41 188.34 185.12 185.27 148214100    181.38             0            5
36   2/11/16 182.34 184.10 181.09 182.86 219058900    179.02             0            6
37   2/12/16 184.96 186.65 183.96 186.63 127632400    182.71             1            0
38   2/16/16 188.77 189.81 187.63 189.78 120250700    185.79             2            0
39   2/17/16 191.16 193.32 191.01 192.88 136009500    188.83             3            0
40   2/18/16 193.20 193.27 191.72 192.09 102343000    188.05             4            0
41   2/19/16 191.17 192.18 190.45 192.00 114793000    187.96             5            0
42   2/22/16 193.87 194.95 193.79 194.78 103640300    190.69             6            0
43   2/23/16 194.00 194.32 192.18 192.32 111455300    188.28             0            1
44   2/24/16 190.63 193.53 189.32 193.20 150812200    189.14             1            0
45   2/25/16 193.73 195.55 192.83 195.54 110728300    191.43             2            0
46   2/26/16 196.57 196.68 194.90 195.09 129833700    190.99             3            0
47   2/29/16 195.11 196.23 193.33 193.56 125918100    189.49             4            0
48    3/1/16 195.01 198.21 194.45 198.11 141799700    193.95             5            0
49    3/2/16 197.74 199.06 197.25 199.00 102415000    194.82             6            0
50    3/3/16 198.79 199.80 198.11 199.78  95172200    195.58             7            0
51    3/4/16 200.01 201.35 199.03 200.43 129293600    196.22             8            0
52    3/7/16 199.34 201.07 199.25 200.59 100219000    196.37             9            0

  # Create initdate, from, and to charater strings
 initdate <- "2015-12-21"
 from <- "2015-12-22"
 to <- "2016-12-20"

 # Set the timezone to UTC
 Sys.setenv(TZ = "UTC")

 # Set the currency to USD 
 currency("USD")

 stock("SPY", currency = "USD")

 # 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")

# initialize the account
initAcct(account.st, portfolios = portfolio.st, initDate = initdate, currency = "USD", initEq = initeq)

# initialize the orders
initOrders(portfolio.st, initDate = initdate)

# store the strategy
strategy(strategy.st, store = TRUE)



    add.signal(strategy.st, name = "sigThreshold", arguments = list(column ="TD.Buy.Count", 
               threshold = 8, relationship = "gt", cross = TRUE), label = "thresholdentry")
    [1] "firststrat"

    add.signal(strategy.st, name = "sigThreshold", arguments = list(column ="TD.Sell.Count", 
               threshold = 8, relationship = "gt", cross = TRUE), label = "thresholdexit")
    [1] "firststrat"

    add.rule(strategy.st, name = "ruleSignal", arguments = list(sigcol = "thresholdentry",
             sigval = TRUE, ordertype = "market", orderside = "long", replace = FALSE, prefer = "Open", osFUN = osMaxPos, tradeSize = tradesize, maxSize = tradesize), type = "enter")
    [1] "firststrat"

    add.rule(strategy.st, name = "ruleSignal", 
    arguments = list(sigcol = "thresholdexit", sigval = TRUE, orderqty = "all",   ordertype = "market", orderside = "long", replace = FALSE, prefer = "Open"),  type = "exit")

Any assistance that you can provide would be most appreciated.

1

There are 1 answers

2
Joshua Ulrich On

You need to read the file into an xts object. You can do this with read.zoo and as.xts.

library(quantstrat)

# read indicators data
indicators <- read.zoo(header = TRUE, as.is = TRUE,
                       index.column = 1, format = "%m/%d/%y", text = "
        Date   Open   High    Low  Close    Volume Adj.Close TD.Sell.Count TD.Buy.Count
1   12/21/15 201.41 201.88 200.09 201.67  99094300    197.43             0            0
2   12/22/15 202.72 203.85 201.55 203.50 111026200    199.22             0            0
3   12/23/15 204.69 206.07 204.58 206.02 110987200    201.69             0            0
4   12/24/15 205.72 206.33 205.42 205.68  48539600    201.36             0            0
5   12/28/15 204.86 205.26 203.94 205.21  65899900    200.90             1            0
6   12/29/15 206.51 207.79 206.47 207.40  92640700    203.04             2            0
7   12/30/15 207.11 207.21 205.76 205.93  63317700    201.60             0            1
8   12/31/15 205.13 205.89 203.87 203.87 102929500    199.58             0            2
9     1/4/16 200.49 201.03 198.59 201.02 222353500    196.79             0            3
10    1/5/16 201.40 201.90 200.05 201.36 110845800    197.13             0            4
11    1/6/16 198.34 200.06 197.60 198.82 152112600    194.64             0            5
12    1/7/16 195.33 197.44 193.59 194.05 213436100    189.97             0            6
13    1/8/16 195.19 195.85 191.58 191.92 209817200    187.89             0            7
14   1/11/16 193.01 193.41 189.82 192.11 187941300    188.07             0            8
15   1/12/16 193.82 194.55 191.14 193.66 172330500    189.59             0            9
16   1/13/16 194.45 194.86 188.38 188.83 221168900    184.86             0           10
17   1/14/16 189.55 193.26 187.66 191.93 240795600    187.90             1            0
18   1/15/16 186.77 188.76 185.52 187.81 314240200    183.86             0            1
19   1/19/16 189.96 190.11 186.20 188.06 195244400    184.11             0            2
20   1/20/16 185.03 187.50 181.02 185.65 286547800    181.75             0            3
21   1/21/16 186.21 188.87 184.64 186.69 195772900    182.77             0            4
22   1/22/16 189.78 190.76 188.88 190.52 168319600    186.51             1            0
23   1/25/16 189.92 190.15 187.41 187.64 130371700    183.70             0            1
24   1/26/16 188.42 190.53 188.02 190.20 141036800    186.20             1            0
25   1/27/16 189.58 191.56 187.06 188.13 185681700    184.18             2            0
26   1/28/16 189.96 190.20 187.16 189.11 143798800    185.13             0            1
27   1/29/16 190.02 193.88 189.88 193.72 210529300    189.65             1            0
28    2/1/16 192.53 194.58 191.84 193.65 136061600    189.58             2            0
29    2/2/16 191.96 191.97 189.54 190.16 182564900    186.16             3            0
30    2/3/16 191.41 191.78 187.10 191.30 205054900    187.28             4            0
31    2/4/16 190.71 192.75 189.96 191.60 139531800    187.57             0            1
32    2/5/16 190.99 191.67 187.20 187.95 180788300    184.00             0            2
33    2/8/16 185.77 186.12 182.80 185.42 191526700    181.52             0            3
34    2/9/16 183.36 186.94 183.20 185.43 184513100    181.53             0            4
35   2/10/16 186.41 188.34 185.12 185.27 148214100    181.38             0            5
36   2/11/16 182.34 184.10 181.09 182.86 219058900    179.02             0            6
37   2/12/16 184.96 186.65 183.96 186.63 127632400    182.71             1            0
38   2/16/16 188.77 189.81 187.63 189.78 120250700    185.79             2            0
39   2/17/16 191.16 193.32 191.01 192.88 136009500    188.83             3            0
40   2/18/16 193.20 193.27 191.72 192.09 102343000    188.05             4            0
41   2/19/16 191.17 192.18 190.45 192.00 114793000    187.96             5            0
42   2/22/16 193.87 194.95 193.79 194.78 103640300    190.69             6            0
43   2/23/16 194.00 194.32 192.18 192.32 111455300    188.28             0            1
44   2/24/16 190.63 193.53 189.32 193.20 150812200    189.14             1            0
45   2/25/16 193.73 195.55 192.83 195.54 110728300    191.43             2            0
46   2/26/16 196.57 196.68 194.90 195.09 129833700    190.99             3            0
47   2/29/16 195.11 196.23 193.33 193.56 125918100    189.49             4            0
48    3/1/16 195.01 198.21 194.45 198.11 141799700    193.95             5            0
49    3/2/16 197.74 199.06 197.25 199.00 102415000    194.82             6            0
50    3/3/16 198.79 199.80 198.11 199.78  95172200    195.58             7            0
51    3/4/16 200.01 201.35 199.03 200.43 129293600    196.22             8            0
52    3/7/16 199.34 201.07 199.25 200.59 100219000    196.37             9            0
")
indicators <- as.xts(indicators)

Then the easiest thing to do is merge the indicator data with your market price data.

# get data for same interval as indicators
getSymbols("SPY", from = start(indicators), to = end(indicators), adjust = TRUE)

# merge indicators with data
SPY <- merge(SPY, indicators[, c("TD.Sell.Count", "TD.Buy.Count")])

Now you can setup your strategy. Note that you do not need to set initDate (and can actually create problems for yourself if you set it incorrectly), and you need to set a position limit using addPosLimit if you want to use osMaxPos. I also reduced the threshold from 8 to 6 to get one entry and one exit signal.

# Set the timezone to UTC
Sys.setenv(TZ = "UTC")

# Set the currency to USD 
currency("USD")
stock("SPY", currency = "USD")

# 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")

# initialize the account
initAcct(account.st, portfolios = portfolio.st, initEq = initeq)

# initialize the orders
initOrders(portfolio.st)

# set position limits
addPosLimit(portfolio.st, "SPY", start(SPY), 100)

# store the strategy
strategy(strategy.st, store = TRUE)

add.signal(strategy.st, name = "sigThreshold",
           arguments = list(column = "TD.Buy.Count",
                            threshold = 6,
                            relationship = "gt",
                            cross = TRUE),
           label = "thresholdentry")

add.signal(strategy.st, name = "sigThreshold",
           arguments = list(column = "TD.Sell.Count",
                            threshold = 6,
                            relationship = "gt",
                            cross = TRUE),
           label = "thresholdexit")

add.rule(strategy.st, name = "ruleSignal",
         arguments = list(sigcol = "thresholdentry",
                          sigval = TRUE,
                          ordertype = "market",
                          orderside = "long",
                          orderqty = 100,
                          replace = FALSE,
                          prefer = "Open",
                          osFUN = osMaxPos,
                          tradeSize = tradesize,
                          maxSize = tradesize),
         type = "enter")

add.rule(strategy.st, name = "ruleSignal",
         arguments = list(sigcol = "thresholdexit",
                          sigval = TRUE,
                          orderqty = "all",
                          ordertype = "market",
                          orderside = "long",
                          replace = FALSE,
                          prefer = "Open"),
         type = "exit")

applyStrategy(strategy.st, portfolio.st)
# [1] "2016-01-11 00:00:00 SPY 100 @ 193.009995"
# [1] "2016-03-04 00:00:00 SPY -100 @ 200.009995"