Custom Indicator and apply.paramset problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Custom Indicator and apply.paramset problem

Atakan Okan
Hi again,

As a followup to my custom indicator question:
Although I have successfully implemented it based on your suggestions and ran it via applyStrategy; optimizing parameters of a strategy with the same custom indicator via apply.paramset does not seem to work on Windows using the package doSNOW, despite the fact that I have run apply.paramset on a different strategy with parallelization with doSNOW but without any custom indicators.

Any help is appreciated, thank you :) 

Atakan Okan

The reproducible code:

library(quantmod)
library(quantstrat)
library(TTR)


Sys.setenv(TZ = "UTC")                            


.strategy <- new.env()
.blotter  <- new.env()                             


#Data
getSymbols("AAPL")


#Stock
symbol.name = "AAPL" 
tick.size = 0.01
currency('USD')
stock(symbol.name, currency="USD", multiplier=1,tick_size= tick.size)


initialEquity = 100000 
port.acct.currency <- "USD"


strategy.st <- 'Custom_Prob'
rm.strat(strategy.st)                                                      


initDate = as.character(as.Date(index(AAPL[1])-1))
initPortf(strategy.st, symbol.name, initDate=initDate, currency =
            port.acct.currency) 
initAcct(strategy.st, portfolios=strategy.st,
         initDate=initDate,
         initEq=initialEquity, currency = port.acct.currency)
initOrders(portfolio=strategy.st,initDate=initDate)
strategy(strategy.st,store=TRUE)
summary(getStrategy(strategy.st))                                          




#MACD W1 indicator
MACD_W1 <- function(mktdata=quote(mktdata),
                    nFast = 12,
                    nSlow = 26,
                    nSig = 9)
{
  y <- eval(parse(text = symbol.name))
  y <- to.weekly(y)
  y <- Cl(y)
  y <- MACD(y,
            nFast = nFast,
            nSlow = nSlow,
            nSig = nSig,
            maType = "EMA")
  y <- cbind(mktdata, y[paste(first(index(mktdata)),
                              last(index(mktdata)), 
                              sep = "/")])
  if (anyNA(y[,1])){                          
    y <- y[-which(is.na(y[,1])),]
  }
  y <- na.locf(y)
  y <- y[,c((ncol(y)-1),ncol(y))]
  y





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


add.indicator(strategy.st,
              name = "MACD_W1",
              arguments = list(mktdata=quote(mktdata)))


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.signal(strategy.st, name="sigFormula", 
           arguments=list(columns=c("macd.MACD_W1.ind", "signal.MACD_W1.ind"), 
                          formula="(macd.MACD_W1.ind > signal.MACD_W1.ind)", 
                          cross=FALSE), 
           label="LongCond.W1")


add.signal(strategy.st, name="sigFormula", 
           arguments=list(columns=c("macd.macd", "signal.macd","LongCond.W1"), 
                          formula="(macd.gt.signal == 1) & (LongCond.W1 == 1)", 
                          cross=FALSE), 
           label="macd.gt.signal.w1")


add.rule(strategy.st,
         name='ruleSignal',
         arguments = list(sigcol="macd.gt.signal.w1",
                          sigval=TRUE,
                          prefer="Open", 
                          orderqty= 100, 
                          ordertype='market',
                          orderside='long',
                          orderset='ocolong',
                          TxnFees = 0),
         type='enter',
         label='longenter',
         enabled=TRUE
)


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 = 0),
         type='exit',
         label='longexit',
         enabled=TRUE
)


macdFastMARange <- seq(2,12,by=5)
macdSlowMARange <- seq(12,24,by=6)
macdSignalRange <- seq(5,15,by=5)


paramset.label.name <- "macd_opt"


add.distribution(strategy.st,
                 paramset.label = paramset.label.name,
                 component.type = 'indicator',
                 component.label = "macd",
                 variable = list( nFast = macdFastMARange ), 
                 label = "macdFastMARANGE")


add.distribution(strategy.st,
                 paramset.label = paramset.label.name,
                 component.type = 'indicator',
                 component.label = "macd",
                 variable = list( nSlow = macdSlowMARange ),
                 label = "macdSlowMARANGE")


add.distribution(strategy.st,
                 paramset.label = paramset.label.name,
                 component.type = 'indicator',
                 component.label = "macd",
                 variable = list( nSig = macdSignalRange ),
                 label = "macdSignalRANGE")


add.distribution.constraint(strategy.st,
                            paramset.label = paramset.label.name,
                            distribution.label.1 = 'macdFastMARANGE',
                            distribution.label.2 = 'macdSlowMARANGE',
                            operator = '<',
                            label = 'FastMA<SlowMA')


#Single Core - Works
#applyStrategy(strategy=strategy.st,portfolios=strategy.st, verbose=TRUE)
#updatePortf(strategy.st)
#updateAcct(strategy.st)
#updateEndEq(strategy.st)




#DoSNOW Parallel on Windows - Does Not Work 
library(doSNOW)
library(parallel)
paramsetenv <- new.env()
cl <- snow::makeCluster(detectCores(), type = "SOCK")   
registerDoSNOW(cl)                                      
results <- apply.paramset(strategy.st,
                          paramset.label=paramset.label.name,
                          portfolio=strategy.st, 
                          account=strategy.st,
                          nsamples=0,
                          verbose = TRUE,
                          audit=paramsetenv,
                          calc = "slave")
snow::stopCluster(cl)   

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Custom Indicator and apply.paramset problem

braverock
You didn't tell the list what error you see when you try running your code.

You should probably use doParallel on Windows, and not load snow and
parallel both.  The socket cluster code in the parallel package came
from snow, and they share the same function names, so you could have
namespace collisions with both loaded.

Your most likely problem is that you did not export your custom function
to the cluster workers using .exports in the apply.paramsets call or
clusterExport before calling apply.paramsets.

Regards,

Brian


On 02/25/2017 02:11 PM, Atakan Okan wrote:

> Hi again,
>
> As a followup to my custom indicator question:
> Although I have successfully implemented it based on your suggestions and ran it via applyStrategy; optimizing parameters of a strategy with the same custom indicator via apply.paramset does not seem to work on Windows using the package doSNOW, despite the fact that I have run apply.paramset on a different strategy with parallelization with doSNOW but without any custom indicators.
>
> Any help is appreciated, thank you :)
>
> Atakan Okan
>
> The reproducible code:
>
> library(quantmod)
> library(quantstrat)
> library(TTR)
>
>
> Sys.setenv(TZ = "UTC")
>
>
> .strategy <- new.env()
> .blotter  <- new.env()
>
>
> #Data
> getSymbols("AAPL")
>
>
> #Stock
> symbol.name = "AAPL"
> tick.size = 0.01
> currency('USD')
> stock(symbol.name, currency="USD", multiplier=1,tick_size= tick.size)
>
>
> initialEquity = 100000
> port.acct.currency <- "USD"
>
>
> strategy.st <- 'Custom_Prob'
> rm.strat(strategy.st)
>
>
> initDate = as.character(as.Date(index(AAPL[1])-1))
> initPortf(strategy.st, symbol.name, initDate=initDate, currency =
>             port.acct.currency)
> initAcct(strategy.st, portfolios=strategy.st,
>          initDate=initDate,
>          initEq=initialEquity, currency = port.acct.currency)
> initOrders(portfolio=strategy.st,initDate=initDate)
> strategy(strategy.st,store=TRUE)
> summary(getStrategy(strategy.st))
>
>
>
>
> #MACD W1 indicator
> MACD_W1 <- function(mktdata=quote(mktdata),
>                     nFast = 12,
>                     nSlow = 26,
>                     nSig = 9)
> {
>   y <- eval(parse(text = symbol.name))
>   y <- to.weekly(y)
>   y <- Cl(y)
>   y <- MACD(y,
>             nFast = nFast,
>             nSlow = nSlow,
>             nSig = nSig,
>             maType = "EMA")
>   y <- cbind(mktdata, y[paste(first(index(mktdata)),
>                               last(index(mktdata)),
>                               sep = "/")])
>   if (anyNA(y[,1])){
>     y <- y[-which(is.na(y[,1])),]
>   }
>   y <- na.locf(y)
>   y <- y[,c((ncol(y)-1),ncol(y))]
>   y
> }
>
>
>
>
> add.indicator(strategy.st,
>               name = "MACD",
>               arguments = list(x=Cl(AAPL)),
>               label='macd')
>
>
> add.indicator(strategy.st,
>               name = "MACD_W1",
>               arguments = list(mktdata=quote(mktdata)))
>
>
> 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.signal(strategy.st, name="sigFormula",
>            arguments=list(columns=c("macd.MACD_W1.ind", "signal.MACD_W1.ind"),
>                           formula="(macd.MACD_W1.ind > signal.MACD_W1.ind)",
>                           cross=FALSE),
>            label="LongCond.W1")
>
>
> add.signal(strategy.st, name="sigFormula",
>            arguments=list(columns=c("macd.macd", "signal.macd","LongCond.W1"),
>                           formula="(macd.gt.signal == 1) & (LongCond.W1 == 1)",
>                           cross=FALSE),
>            label="macd.gt.signal.w1")
>
>
> add.rule(strategy.st,
>          name='ruleSignal',
>          arguments = list(sigcol="macd.gt.signal.w1",
>                           sigval=TRUE,
>                           prefer="Open",
>                           orderqty= 100,
>                           ordertype='market',
>                           orderside='long',
>                           orderset='ocolong',
>                           TxnFees = 0),
>          type='enter',
>          label='longenter',
>          enabled=TRUE
> )
>
>
> 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 = 0),
>          type='exit',
>          label='longexit',
>          enabled=TRUE
> )
>
>
> macdFastMARange <- seq(2,12,by=5)
> macdSlowMARange <- seq(12,24,by=6)
> macdSignalRange <- seq(5,15,by=5)
>
>
> paramset.label.name <- "macd_opt"
>
>
> add.distribution(strategy.st,
>                  paramset.label = paramset.label.name,
>                  component.type = 'indicator',
>                  component.label = "macd",
>                  variable = list( nFast = macdFastMARange ),
>                  label = "macdFastMARANGE")
>
>
> add.distribution(strategy.st,
>                  paramset.label = paramset.label.name,
>                  component.type = 'indicator',
>                  component.label = "macd",
>                  variable = list( nSlow = macdSlowMARange ),
>                  label = "macdSlowMARANGE")
>
>
> add.distribution(strategy.st,
>                  paramset.label = paramset.label.name,
>                  component.type = 'indicator',
>                  component.label = "macd",
>                  variable = list( nSig = macdSignalRange ),
>                  label = "macdSignalRANGE")
>
>
> add.distribution.constraint(strategy.st,
>                             paramset.label = paramset.label.name,
>                             distribution.label.1 = 'macdFastMARANGE',
>                             distribution.label.2 = 'macdSlowMARANGE',
>                             operator = '<',
>                             label = 'FastMA<SlowMA')
>
>
> #Single Core - Works
> #applyStrategy(strategy=strategy.st,portfolios=strategy.st, verbose=TRUE)
> #updatePortf(strategy.st)
> #updateAcct(strategy.st)
> #updateEndEq(strategy.st)
>
>
>
>
> #DoSNOW Parallel on Windows - Does Not Work
> library(doSNOW)
> library(parallel)
> paramsetenv <- new.env()
> cl <- snow::makeCluster(detectCores(), type = "SOCK")
> registerDoSNOW(cl)
> results <- apply.paramset(strategy.st,
>                           paramset.label=paramset.label.name,
>                           portfolio=strategy.st,
>                           account=strategy.st,
>                           nsamples=0,
>                           verbose = TRUE,
>                           audit=paramsetenv,
>                           calc = "slave")
> snow::stopCluster(cl)
>
> _______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.
>


--
Brian G. Peterson
http://braverock.com/brian/
Ph: 773-459-4973
IM: bgpbraverock

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Custom Indicator and apply.paramset problem

Atakan Okan
In reply to this post by Atakan Okan
Thanks for the quick reply Brian,

The error reads as follows:

error calling combine function:
<simpleError in fun(result.1, result.2, result.3, result.4, result.5, result.6,     result.7, result.8, result.9, result.10, result.11, result.12,     result.13, result.14, result.15, result.16, result.17, result.18,     result.19, result.20, result.21, result.22, result.23, result.24): attempt to select less than one element in OneIndex>


After switching to doParallel, the error message stays the same. How should I export my custom function to the cluster workers using .exports though? Just add it as an argument to apply.paramset()? Took a quick look at the apply.paramset() source code but couldn't figure out how to pass the .exports argument to it.

Thanks,

Atakan

The new parallel code (all other bits are the same):

#DoParallel on Windows - Does Not Work
library(doParallel)
library(parallel)
paramsetenv <- new.env()
cl <- makeCluster(detectCores())
registerDoParallel(cl, cores=detectCores())                                      
results <- apply.paramset(strategy.st,
                          paramset.label=paramset.label.name,
                          portfolio=strategy.st,
                          account=strategy.st,
                          nsamples=0,
                          verbose = TRUE,
                          audit=paramsetenv,
                          calc = "slave")
stopCluster(cl)
   
_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Custom Indicator and apply.paramset problem

Atakan Okan
Firstly, I tried to pass the .exports argument in apply.paramset, but produced an error like "formal argument ".exports" matched by multiple actual arguments"

So tried changing the code of apply.paramset using trace("apply.paramset",edit=TRUE) where I added my custom indicator MACD_W1 to the .exports arguments so that it looks like this:
.export = c(env.functions,  symbols, "MACD_W1")

When I run the code now I get a different error:

error calling combine function:
<simpleError in results[[r$portfolio.st]] <- r: attempt to select less than one element in OneIndex>




From: Atakan Okan <[hidden email]>
Sent: Saturday, February 25, 2017 11:47 PM
To: [hidden email]
Subject: Custom Indicator and apply.paramset problem
   
Thanks for the quick reply Brian,

The error reads as follows:

error calling combine function:
<simpleError in fun(result.1, result.2, result.3, result.4, result.5, result.6,     result.7, result.8, result.9, result.10, result.11, result.12,     result.13, result.14, result.15, result.16, result.17, result.18,     result.19, result.20, result.21, result.22,  result.23, result.24): attempt to select less than one element in OneIndex>


After switching to doParallel, the error message stays the same. How should I export my custom function to the cluster workers using .exports though? Just add it as an argument to apply.paramset()? Took a quick look at the apply.paramset() source code but couldn't  figure out how to pass the .exports argument to it.

Thanks,

Atakan

The new parallel code (all other bits are the same):

#DoParallel on Windows - Does Not Work
library(doParallel)
library(parallel)
paramsetenv <- new.env()
cl <- makeCluster(detectCores())
registerDoParallel(cl, cores=detectCores())                                     
results <- apply.paramset(strategy.st,
                          paramset.label=paramset.label.name,
                          portfolio=strategy.st,
                          account=strategy.st,
                          nsamples=0,
                          verbose = TRUE,
                          audit=paramsetenv,
                          calc = "slave")
stopCluster(cl)

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.