[R-SIG-Finance] Attempting to switch between instruments in quantstrat

Erol Biceroglu erol.biceroglu at alumni.utoronto.ca
Sat Aug 13 06:26:41 CEST 2016


Hello,

I have another quantstrat-related question I was hoping someone could
help me with.

There's no error this time (at least I think), it's probably how I'm
setting it up, however any feedback would be greatly appreciated.

So, what I'm *trying* to do, is get quantstrat to chose an instrument
in mktdata to apply the rules to based on the value of a variable
(here **decileThreshold**).  The idea is, if **decileThreshold** is
equal to 2, I only want to trade the 2nd instrument and ignore the
first.  Thus, I load the indicator and signal as usual, and then add
*another* signal to check if the instrument equals
**decileThreshold**.  Lastly, I then combine the previous signals with
**sigFormula** (which combines **decileThreshold** with the
indicator-signal) to generate the buy-rule.

The buy-rule, in theory, is only executed if the rule-signal is true
AND if the "instrument is equal to the **decileThreshold** threshold".

I'm trying to pack it all into one set of code since I *eventually*
want to optimize the volatility of the instrument. (I've cut out a lot
of stuff and have included only the bare minimum).

applyIndicators and applySignals work if I supply my own mktdata
matrix, where I really just merge the instruments.

What confuses me, is why applyRules works on the first instrument,
when my **decileThreshold** value should only make it applicable to
the second instrument?

This is likely extremely confusing, so please let me know how I can
clarify my objective any further.

Worst case, for my "real code", I have a work-around that involves
running each instrument separately within a for-loop.  However, I was
hoping that I can get this to work so that I can leverage the
optimization functionality within quantstrat.

Any thoughts, comments, or feedback would be greatly appreciated.

Thank you,

Session Info:

> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.4 LTS

locale:
 [1] LC_CTYPE=en_CA.UTF-8       LC_NUMERIC=C
LC_TIME=en_CA.UTF-8
 [4] LC_COLLATE=en_CA.UTF-8     LC_MONETARY=en_CA.UTF-8
LC_MESSAGES=en_CA.UTF-8
 [7] LC_PAPER=en_CA.UTF-8       LC_NAME=C
LC_ADDRESS=C
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_CA.UTF-8
LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] quantstrat_0.9.1739           foreach_1.4.3
blotter_0.9.1695
[4] FinancialInstrument_1.2.0     quantmod_0.4-5
TTR_0.23-1
[7] PerformanceAnalytics_1.4.3541 xts_0.9.874
zoo_1.7-13

loaded via a namespace (and not attached):
[1] tools_3.3.1      codetools_0.2-14 grid_3.3.1       iterators_1.0.8
 lattice_0.20-33



MRE:
####################

library(xts)
library(PerformanceAnalytics)
library(quantmod)
library(TTR)
library(quantstrat)


getSymbols(Symbols = "SPY")
SPY <- SPY$SPY.Close

#create a more volatile copy
tmp <- diff(SPY)
tmp <- 1.5*tmp
SPY2 <- cumsum(rbind(SPY[1,],tmp[-1,]))
colnames(SPY2) <- "SPY2.Close"

#There we go...
# head(SPY)
# head(SPY2)

#Rename to fit into my "existing" code:
MAPortfolio1 <- SPY
MAPortfolio2 <- SPY2
rm(SPY,SPY2)
colnames(MAPortfolio1) <- "MAPortfolio1"
colnames(MAPortfolio2) <- "MAPortfolio2"


########################
# All this block does is loop through the instruments, and append a
constant vector to it
for(item in paste0("MAPortfolio",1:2)){
  tmp <- merge(get(item), rep(which(item ==
paste0("MAPortfolio",1:2)),nrow(get(item))))
  colnames(tmp) <- c(paste0(colnames(tmp)[1],".Close")
                     ,paste0("MAPortfolio",which(item ==
paste0("MAPortfolio",1:2)),".Ind")
  )
  command <- paste0("MAPortfolio",which(item ==
paste0("MAPortfolio",1:2))," <- ",quote(tmp))
  eval(parse(text = command))
}
rm(tmp)

# head(MAPortfolio1)
# head(MAPortfolio2)
#########################

startDate<-as.Date(index(MAPortfolio1)[1], format="%Y-%m-%d")
endDate<-as.Date(index(last(MAPortfolio1)), format="%Y-%m-%d")

currency("USD")


stock(primary_id = c("MAPortfolio1"),currency = "USD")
stock(primary_id = c("MAPortfolio2"),currency = "USD")

#name
maStrategy <-"MAStrategy"

#Date, one day before prices
strategyDate <- min(index(MAPortfolio1)) - 1

#*******************************
#Used to reset for testing
#rm.strat(maStrategy)
#rm(mktdata)
#*******************************

NumSh<-1
decileThreshold <- 2

maLag <- 5

if (!exists('.blotter')) .blotter <- new.env()
if (!exists('.strategy')) .strategy <- new.env()

#init portfolio and account
initPortf(name = maStrategy
          , symbols = as.list(paste0("MAPortfolio",1:2)) #as defined
in Financial instrument
          , initDate = strategyDate
)

initAcct(name = maStrategy
         ,portfolios = maStrategy
         ,initDate = strategyDate
         ,initEq = 1
)

#order book, and strategy
initOrders(portfolio = maStrategy
           , initDate = strategyDate
)

#position limits
addPosLimit(maStrategy, symbol = "MAPortfolio1", strategyDate, maxpos
= NumSh, longlevels = NumSh, minpos = 0)
addPosLimit(maStrategy, symbol = "MAPortfolio2", strategyDate, maxpos
= NumSh, longlevels = NumSh, minpos = 0)

strategy( maStrategy, store = TRUE)

###############################################
#add indicator
add.indicator(strategy = maStrategy
              , name = "EMA"
              , arguments = list(x =
quote(mktdata$MAPortfolio1.Close), n = quote(maLag))
              , label = "MAPortfolioma1"
)

add.indicator(strategy = maStrategy
              , name = "EMA"
              , arguments = list(x =
quote(mktdata$MAPortfolio2.Close), n = quote(maLag))
              , label = "MAPortfolioma2"
)
#################################################

#################################################
#MAPortfolio is greater than N-Lag Moving Average
add.signal(strategy = maStrategy
           , name = "sigComparison"
           , arguments = list(columns =
c("MAPortfolio1.Close","MAPortfolioma1")
                              , relationship = "gt"
           )
           , label = "MAPortfolio.gt.ma1"
)

add.signal(strategy = maStrategy
           , name = "sigComparison"
           , arguments = list(columns =
c("MAPortfolio2.Close","MAPortfolioma2")
                              , relationship = "gt"
           )
           , label = "MAPortfolio.gt.ma2"
)

#################################################

#MAPortfolio is less-than-equal-to N-Lag Moving Average
#################################################
add.signal(strategy = maStrategy
           , name = "sigComparison"
           , arguments = list(columns = c("MAPortfolio1.Close","MAPortfolioma1")
                              , relationship = "lte"
           )
           , label = "MAPortfolio.lte.ma1"
)

add.signal(strategy = maStrategy
           , name = "sigComparison"
           , arguments = list(columns = c("MAPortfolio2.Close","MAPortfolioma2")
                              , relationship = "lte"
           )
           , label = "MAPortfolio.lte.ma2"
)
#################################################

add.signal(strategy = maStrategy
           , name = "sigThreshold"
           , arguments = list(column = "MAPortfolio1.Ind"
                              , threshold = decileThreshold
                              , relationship = "eq"
           )
           , label = "MAPortfolio.dThresh1"
)

add.signal(strategy = maStrategy
           , name = "sigThreshold"
           , arguments = list(column = "MAPortfolio2.Ind"
                              , threshold = decileThreshold
                              , relationship = "eq"
           )
           , label = "MAPortfolio.dThresh2"
)
#################################################


#######
add.signal(strategy = maStrategy
           , name = "sigFormula"
           , arguments = list(formula = "MAPortfolio.dThresh1 == 1 &
MAPortfolio.gt.ma1 == 1")
           , label = "MAPortfolio.sig.buy1"
)

add.signal(strategy = maStrategy
           , name = "sigFormula"
           , arguments = list(formula = "MAPortfolio.dThresh1 == 1 &
MAPortfolio.lte.ma1 == 1")
           , label = "MAPortfolio.sig.sell1"
)
#######

#######
add.signal(strategy = maStrategy
           , name = "sigFormula"
           , arguments = list(formula = "MAPortfolio.dThresh2 == 1 &
MAPortfolio.gt.ma2 == 1")
           , label = "MAPortfolio.sig.buy2"
)

add.signal(strategy = maStrategy
           , name = "sigFormula"
           , arguments = list(formula = "MAPortfolio.dThresh2 == 1 &
MAPortfolio.lte.ma2 == 1")
           , label = "MAPortfolio.sig.sell2"
)
#######

#Entry and exit rules

#######
#buy MAPortfolio when above N-Lag Moving Average
add.rule(strategy = maStrategy
         , name = "ruleSignal"
         , arguments = list(sigcol = "MAPortfolio.sig.buy1"
                            , sigval = TRUE
                            , orderqty = NumSh
                            , ordertype = "market"
                            , orderside = NULL
                            , osFUN = "osMaxPos"
                            , symbol = "MAPortfolio1"
         )
         , type = "enter"
)

#sell MAPortfolio when above N-Lag Moving Average
add.rule(strategy = maStrategy
         , name = "ruleSignal"
         , arguments = list(sigcol = "MAPortfolio.sig.sell1"
                            , sigval = TRUE
                            , orderqty = "all"
                            , ordertype = "market"
                            , orderside = NULL
                            , osFUN = "osMaxPos"
                            , symbol = "MAPortfolio1"
         )
         , type = "exit"
)
#######

#######
#buy MAPortfolio when above N-Lag Moving Average
add.rule(strategy = maStrategy
         , name = "ruleSignal"
         , arguments = list(sigcol = "MAPortfolio.sig.buy2"
                            , sigval = TRUE
                            , orderqty = NumSh
                            , ordertype = "market"
                            , orderside = NULL
                            , osFUN = "osMaxPos"
                            , symbol = "MAPortfolio2"
         )
         , type = "enter"
)

#sell MAPortfolio when above N-Lag Moving Average
add.rule(strategy = maStrategy
         , name = "ruleSignal"
         , arguments = list(sigcol = "MAPortfolio.sig.sell2"
                            , sigval = TRUE
                            , orderqty = "all"
                            , ordertype = "market"
                            , orderside = NULL
                            , osFUN = "osMaxPos"
                            , symbol = "MAPortfolio2"
         )
         , type = "exit"
)
#######

mktdata <- merge(MAPortfolio1
                 , MAPortfolio2
)


applyIndicators(strategy = maStrategy, mktdata = mktdata)
applySignals(strategy = maStrategy, mktdata = mktdata)

#Why is this working, when decileThreshold == 2 ?
applyRules(portfolio = maStrategy
           , symbol = "MAPortfolio1"
           , strategy = maStrategy
           , mktdata = mktdata
           )


applyStrategy(strategy = maStrategy
              , portfolios = maStrategy
              #, mktdata = mktdata
)



#####################



Erol Biceroglu
erol.biceroglu at alumni.utoronto.ca



More information about the R-SIG-Finance mailing list