[R-SIG-Finance] Parallelizing applyStrategy to multiple symbols

Atakan Okan atakanokan at outlook.com
Mon Mar 6 19:53:03 CET 2017


Hello,

I am trying to parallelize applyStrategy() to make it faster when applied to multiple symbols. The reproducible code below only contains 3 symbols thus it finishes fast however when I apply it to 100 symbols in an index, sequential computing takes a lot of time. What is the best way to accomplish this? Using foreach loop does not seem to work and couldn't find any info on stackexchange or the usual mailing lists. 

Thanks.

Atakan Okan

Code with applyStrategy (foreach is below this):

library(quantmod)
library(quantstrat)

symbols <- c("AAPL","GOOGL","MSFT")

getSymbols(Symbols = symbols, from = "2010-01-01")

currency('USD')
stock(symbols, currency="USD")

strategy.st <- "multiple_symbols_parallel_applystrategy"
rm.strat(strategy.st)                                                      
      
initPortf(strategy.st, symbols = symbols)
initAcct(strategy.st, portfolios=strategy.st, initEq=100000)
initOrders(portfolio=strategy.st)                          
strategy(strategy.st,store=TRUE)
                                           
rule.longenter  = TRUE  
rule.longexit   = TRUE  
rule.shortenter = TRUE 
rule.shortexit  = TRUE 

txn.model <- 0

add.indicator(strategy.st,  
              name = "MACD", 
              arguments = list(x=Cl(get(symbols))), 
              label='macd') 

add.signal(strategy.st,name="sigCrossover",
           arguments = list(columns=c("macd.macd","signal.macd"),
                            relationship="gt"),
           label="macd.gt.signal") 

add.signal(strategy.st,name="sigCrossover",
           arguments = list(columns=c("macd.macd","signal.macd"),
                            relationship="lt"),
           label="macd.lt.signal")

add.rule(strategy.st,
         name='ruleSignal',
         arguments = list(sigcol="macd.gt.signal",
                          sigval=TRUE,
                          prefer="Open", 
                          orderqty= 1000, 
                          #osFUN="osAllInLong",  
                          ordertype='market',
                          orderside='long',
                          orderset='ocolong',
                          TxnFees = txn.model),
         type='enter',
         label='longenter',
         enabled=FALSE
)

add.rule(strategy.st,
         name='ruleSignal',
         arguments = list(sigcol="macd.lt.signal",
                          sigval=TRUE,
                          prefer="Open", 
                          orderqty='all',
                          ordertype='market',
                          orderside='long',
                          orderset='ocolong',
                          TxnFees = txn.model),
         type='exit',
         label='longexit',
         enabled=FALSE
)


add.rule(strategy.st,
         name='ruleSignal',
         arguments = list(sigcol="macd.lt.signal",
                          sigval=TRUE,
                          prefer="Open", 
                          orderqty=-1000, 
                          #osFUN="osAllInShort",  
                          ordertype='market',
                          orderside='short',
                          orderset='ocoshort',
                          TxnFees = txn.model),
         type='enter',
         label='shortenter',
         enabled=FALSE
)

add.rule(strategy.st,
         name='ruleSignal',
         arguments = list(sigcol="macd.gt.signal",
                          sigval=TRUE,
                          prefer="Open", 
                          orderqty='all',
                          ordertype='market',
                          orderside='short',
                          orderset='ocoshort',
                          TxnFees = txn.model),
         type='exit',
         label='shortexit',
         enabled=FALSE
)

enable.rule(strategy.st,type="enter",label="longenter", enable = rule.longenter) 
enable.rule(strategy.st,type="exit",label="longexit", enable = rule.longexit)
enable.rule(strategy.st,type="enter",label="shortenter", enable = rule.shortenter) 
enable.rule(strategy.st,type="exit",label="shortexit", enable = rule.shortexit)
summary(getStrategy(strategy.st))                                              

applyStrategy( strategy=strategy.st , 
               portfolios=strategy.st,
               symbols = symbols,
               verbose=TRUE)
updatePortf(strategy.st)
updateAcct(strategy.st)
updateEndEq(strategy.st)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Code with foreach:

library(quantmod)
library(quantstrat)

if(Sys.info()["sysname"] == "Windows") {
  library(doSNOW)
  cl <- makeCluster(4)
  registerDoSNOW(cl)
}
if(Sys.info()["sysname"] == "Linux") {
  library(doMC)
  registerDoMC(cores=4)
  #registerDoSEQ()
  getDoParWorkers()
}

symbols <- c("AAPL","GOOGL","MSFT")

sens.df <- foreach(sym = 1:length(symbols), 
                   .combine = 'rbind', 
                   .packages = c("quantstrat","quantmod")) %dopar% {

  getSymbols(Symbols = sym, from = "2010-01-01")
  
  currency('USD')
  stock(sym, currency="USD")
  
  strategy.st <- "multiple_symbols_parallel_applystrategy"
  rm.strat(strategy.st)                                                      
        
  initPortf(strategy.st, symbols = sym)
  initAcct(strategy.st, portfolios=strategy.st, initEq=100000)
  initOrders(portfolio=strategy.st)                          
  strategy(strategy.st,store=TRUE)
                                             
  rule.longenter  = TRUE  
  rule.longexit   = TRUE  
  rule.shortenter = TRUE 
  rule.shortexit  = TRUE 
  
  txn.model <- 0
  
  add.indicator(strategy.st,  
                name = "MACD", 
                arguments = list(x=Cl(get(sym))), 
                label='macd') 
  
  add.signal(strategy.st,name="sigCrossover",
             arguments = list(columns=c("macd.macd","signal.macd"),
                              relationship="gt"),
             label="macd.gt.signal") 
  
  add.signal(strategy.st,name="sigCrossover",
             arguments = list(columns=c("macd.macd","signal.macd"),
                              relationship="lt"),
             label="macd.lt.signal")
  
  add.rule(strategy.st,
           name='ruleSignal',
           arguments = list(sigcol="macd.gt.signal",
                            sigval=TRUE,
                            prefer="Open", 
                            orderqty= 1000, 
                            #osFUN="osAllInLong",  
                            ordertype='market',
                            orderside='long',
                            orderset='ocolong',
                            TxnFees = txn.model),
           type='enter',
           label='longenter',
           enabled=FALSE
  )
  
  add.rule(strategy.st,
           name='ruleSignal',
           arguments = list(sigcol="macd.lt.signal",
                            sigval=TRUE,
                            prefer="Open", 
                            orderqty='all',
                            ordertype='market',
                            orderside='long',
                            orderset='ocolong',
                            TxnFees = txn.model),
           type='exit',
           label='longexit',
           enabled=FALSE
  )
  
  
  add.rule(strategy.st,
           name='ruleSignal',
           arguments = list(sigcol="macd.lt.signal",
                            sigval=TRUE,
                            prefer="Open", 
                            orderqty=-1000, 
                            #osFUN="osAllInShort",  
                            ordertype='market',
                            orderside='short',
                            orderset='ocoshort',
                            TxnFees = txn.model),
           type='enter',
           label='shortenter',
           enabled=FALSE
  )
  
  add.rule(strategy.st,
           name='ruleSignal',
           arguments = list(sigcol="macd.gt.signal",
                            sigval=TRUE,
                            prefer="Open", 
                            orderqty='all',
                            ordertype='market',
                            orderside='short',
                            orderset='ocoshort',
                            TxnFees = txn.model),
           type='exit',
           label='shortexit',
           enabled=FALSE
  )
  
  enable.rule(strategy.st,type="enter",label="longenter", enable = rule.longenter) 
  enable.rule(strategy.st,type="exit",label="longexit", enable = rule.longexit)
  enable.rule(strategy.st,type="enter",label="shortenter", enable = rule.shortenter) 
  enable.rule(strategy.st,type="exit",label="shortexit", enable = rule.shortexit)
  summary(getStrategy(strategy.st))                                              
  
  applyStrategy( strategy=strategy.st , 
                 portfolios=strategy.st,
                 symbols = sym,
                 verbose=TRUE)
  updatePortf(strategy.st)
  updateAcct(strategy.st)
  updateEndEq(strategy.st)
  
  results.checkstrat <- data.frame(t(tradeStats(strategy.st)))
  
  return(results.checkstrat[,1])

}

if (Sys.info()["sysname"] == "Windows"){
  snow::stopCluster(cl)   #dosnow  windows
}



More information about the R-SIG-Finance mailing list