braverock / quantstrat

283 stars 114 forks source link

apply.paramset return empty results with doParallel/doSNOW #86

Open waileong94 opened 6 years ago

waileong94 commented 6 years ago

I am having problem with running apply.paramset with doParallel/doSnow, i have tried it in Windows 10 and Linux. Reproducible example as follow:


Sys.setenv(TZ = "UTC")

currency(c('USD'))

symbols <- "AAPL"
getSymbols(symbols)

stock(symbols, currency = "USD")

AAPL <- AAPL["2016/"]

init_date <- "2017-01-07"
start_date <- "2018-01-31"
end_date <- "2018-01-31"
init_equity <- 1e8 # $100,000,000
adjustment <- FALSE

portfolio.st <- "Luxor.Opt"  
account.st <- "Luxor.Opt"
strategy.st <- "Luxor.Opt"

rm.strat(name = portfolio.st)   

initPortf(name = portfolio.st, 
          symbols = symbols)

initAcct(name = account.st,
         portfolios = portfolio.st,
         initEq = init_equity)

initOrders(portfolio = portfolio.st,
           symbols = symbols)

strategy(strategy.st, store = TRUE) 

fastMA_custom2 = 12

slowMA_custom2 = 26

signalMA_custom2 = 9
maType="EMA"
MAforest = 3

forest <- function(x, fastMA_custom, slowMA_custom, signalMA_custom){
  step1 <- EMA(x,fastMA_custom)
  step2 <- EMA(x,slowMA_custom)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom)
  step5 <- step3-step4
  return(step5)
}

smaforest <- function(x){
  step1 <- EMA(x,fastMA_custom2)
  step2 <- EMA(x,slowMA_custom2)
  step3 <- step1-step2
  step4 <- EMA(step3,signalMA_custom2)
  step5 <- step3-step4
  step6 <- EMA(step5,MAforest)
  return(step6)
}

add.indicator(strategy = strategy.st,
              name ="forest",
              arguments = list(x=quote(Cl(mktdata)),
                               fastMA_custom = 12,
                               slowMA_custom = 26,
                               signalMA_custom = 9
              ),
              label="forest")

add.indicator(strategy=strategy.st,
              name ="smaforest",
              arguments = list(x=quote(Cl(mktdata))),
              label="smaforest")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "gte"),
           label = "long")

add.signal(strategy = strategy.st,
           name="sigCrossover",
           arguments = list(columns = c("forest", "smaforest"),
                            relationship = "lte"),
           label = "short")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "long",
                          sigval = TRUE,
                          orderqty = 100000,
                          ordertype = "market",
                          orderside = "long", 
                          TxnFees = -1, 
                          replace = FALSE),
         type = "enter",
         label = "EnterLONG")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(sigcol = "short",
                          sigval = TRUE,
                          orderqty = -100000,
                          ordertype = "market",
                          orderside = "short", 
                          replace = FALSE, 
                          TxnFees = -1
         ),
         type = "enter",
         label = "EnterSHORT")

add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "short", 
                          sigval = TRUE, 
                          orderside = "long", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2SHORT")

add.rule(strategy.st, 
         name = "ruleSignal", 
         arguments = list(sigcol = "long", 
                          sigval = TRUE, 
                          orderside = "short", 
                          ordertype = "market", 
                          orderqty = "all", 
                          TxnFees = -1, 
                          replace = TRUE), 
         type = "exit", 
         label = "Exit2LONG")

addPosLimit(portfolio.st, symbols[], timestamp=init_date, maxpos=500, minpos=0)

# applyStrategy(strategy.st, portfolio.st)
# 
# updatePortf(portfolio.st)
# tradeStats(portfolio.st, symbols)

# Portfolio Symbol Num.Txns Num.Trades Net.Trading.PL Avg.Trade.PL Med.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses Std.Dev.Trade.PL Std.Err.Trade.PL Percent.Positive Percent.Negative Profit.Factor
# AAPL Luxor.Opt   AAPL      127         63       -45123.5    -28493.01     -46000.1        1328999      -1047001      10371975    -12167035           474783         59817.04         42.85714         57.14286     0.8524653
# Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity Min.Equity
# AAPL      384147.2      305999.5        -337973.2        -298000.6    -28493.01     -46000.1           474783         59817.04  -0.952672     -3182097        -0.01418043           1.13662          1.026842   985976.4   -2196121
# End.Equity
# AAPL   -45123.5

add.distribution(strategy.st,
                 paramset.label = "forestopt",  #The label we will use when we want to run this optimisation in paramset
                 component.type = "indicator", # The custom function is of indicator type (not other alternatives including signal or rule)
                 component.label = "forest", #this is the name of your custom function
                 variable = list(fastMA_custom = seq(8, 12, by = 2)),
                 label = "myForestOptLabel") #choose whatever you want
library(doSNOW)
# cl = makeCluster(2,type C= "SOCK")
# registerDoSNOW(cl)
resultsopt <- apply.paramset(strategy.st,
                             paramset.label = "forestopt",
                             portfolio.st = portfolio.st,
                             account.st = account.st, 
                             nsamples = 0)
# stopCluster(cl)

resultsopt$tradeStats

This is the result run in sequentiel(without having registerDoSnow):

1                8 Luxor.Opt.1   AAPL      113         56      2650885.5    47123.955    -34500.75        1405999      -1133001      13463971    -10825029         559261.7
2               10 Luxor.Opt.2   AAPL      121         60       -31124.3    -2701.052    -52500.75        1405999      -1133001      12520972    -12683035         553068.9
3               12 Luxor.Opt.3   AAPL      147         73      3143859.3    43656.611    -46000.10        2188999      -1047001      16946972    -13760039         596202.7
  Std.Err.Trade.PL Percent.Positive Percent.Negative Profit.Factor Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL
1         74734.49         44.64286         55.35714     1.2437815      538558.8      513998.9        -349194.5        -239001.0    47123.955    -34500.75         559261.7
2         71400.88         41.66667         58.33333     0.9872221      500838.9      386998.5        -362372.4        -259001.4    -2701.052    -52500.75         553068.9
3         69780.25         43.83562         56.16438     1.2316078      529592.9      309999.6        -335610.7        -308000.4    43656.611    -46000.10         596202.7
  Std.Err.Daily.PL  Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity Min.Equity End.Equity
1         74734.49  1.33760201     -2675006        0.990982974          1.542289          2.150614    4271893   -1122012  2650885.5
2         71400.88 -0.07752717     -3152090       -0.009874178          1.382111          1.494195    1351885   -1808107   -31124.3
3         69780.25  1.16240196     -3182097        0.987983397          1.577998          1.006491    3546860   -2196121  3143859.3

where as the following are the results with registerDoSNOW:

myForestOptLabel   Portfolio Symbol Num.Txns Num.Trades Total.Net.Profit Avg.Trade.PL Med.Trade.PL Std.Err.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses Std.Dev.Trade.PL Percent.Positive
1                8 Luxor.Opt.1      0        0          0                0            0            0                0              0             0             0            0                0                0
2               10 Luxor.Opt.2      0        0          0                0            0            0                0              0             0             0            0                0                0
3               12 Luxor.Opt.3      0        0          0                0            0            0                0              0             0             0            0                0                0
  Percent.Negative Profit.Factor Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio
1                0             0             0             0                0                0            0            0                0                0          0            0                  0                 0
2                0             0             0             0                0                0            0            0                0                0          0            0                  0                 0
3                0             0             0             0                0                0            0            0                0                0          0            0                  0                 0
  Med.WinLoss.Ratio Max.Equity Min.Equity End.Equity
1                 0          0          0          0
2                 0          0          0          0
3                 0          0          0          0

SessionInfo

R version 3.4.2 (2017-09-28)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 17.10

Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

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

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

other attached packages:
 [1] doSNOW_1.0.16              snow_0.4-2                 iterators_1.0.9            quantstrat_0.14.3          foreach_1.4.4              blotter_0.14.2             PerformanceAnalytics_1.5.2
 [8] FinancialInstrument_1.3.1  quantmod_0.4-13            TTR_0.23-3                 xts_0.10-2                 zoo_1.8-1                 

loaded via a namespace (and not attached):
[1] quadprog_1.5-5   lattice_0.20-35  codetools_0.2-15 MASS_7.3-47      grid_3.4.2       curl_3.2         boot_1.3-20      tools_3.4.2      compiler_3.4.2  
braverock commented 6 years ago

@waileong94 is there a reason you are using the older snow and registerDoSNOW rather than the newer parallel and doParallel package with registerDoParallel ?

If I use the parallel package, things run as expected for me:

> registerDoParallel()
> resultsopt <- apply.paramset(strategy.st,
+                              paramset.label = "forestopt",
+                              portfolio.st = portfolio.st,
+                              account.st = account.st, 
+                              nsamples = 0)
> resultsopt$tradeStats
  myForestOptLabel   Portfolio Symbol Num.Txns Num.Trades Net.Trading.PL Avg.Trade.PL Med.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses
1                8 Luxor.Opt.1   AAPL      113         56      2650885.5    47123.955    -34500.75        1405999      -1133001      13463971    -10825029
2               10 Luxor.Opt.2   AAPL      121         60       -31124.3    -2701.052    -52500.75        1405999      -1133001      12520972    -12683035
3               12 Luxor.Opt.3   AAPL      147         73      3143859.3    43656.611    -46000.10        2188999      -1047001      16946972    -13760039
  Std.Dev.Trade.PL Std.Err.Trade.PL Percent.Positive Percent.Negative Profit.Factor Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade
1         559261.7         74734.49         44.64286         55.35714     1.2437815      538558.8      513998.9        -349194.5        -239001.0
2         553068.9         71400.88         41.66667         58.33333     0.9872221      500838.9      386998.5        -362372.4        -259001.4
3         596202.7         69780.25         43.83562         56.16438     1.2316078      529592.9      309999.6        -335610.7        -308000.4
  Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL  Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity
1    47123.955    -34500.75         559261.7         74734.49  1.33760201     -2675006        0.990982974          1.542289          2.150614    4271893
2    -2701.052    -52500.75         553068.9         71400.88 -0.07752717     -3152090       -0.009874178          1.382111          1.494195    1351885
3    43656.611    -46000.10         596202.7         69780.25  1.16240196     -3182097        0.987983397          1.577998          1.006491    3546860
  Min.Equity End.Equity
1   -1122012  2650885.5
2   -1808107   -31124.3
3   -2196121  3143859.3

> sessionInfo()
R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 17.10

Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
 [6] LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

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

other attached packages:
 [1] doParallel_1.0.11          iterators_1.0.9            pander_0.6.1               knitr_1.20                 quantstrat_0.14.3         
 [6] foreach_1.4.4              blotter_0.14.2             PerformanceAnalytics_1.5.2 FinancialInstrument_1.3.1  quantmod_0.4-13           
[11] TTR_0.23-3                 xts_0.10-2                 zoo_1.8-1                 

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.16     quadprog_1.5-5   lattice_0.20-35  codetools_0.2-15 digest_0.6.15    MASS_7.3-49      grid_3.4.4       curl_3.2         boot_1.3-20     
[10] tools_3.4.4      yaml_2.1.19      compiler_3.4.4  
waileong94 commented 6 years ago

It works now with doparallel and without makecluster in Ubuntu, but i still couldn't get it working in windows.

braverock commented 6 years ago

You'll need to be more specific about what error you're seeing. It works for me in Windows.

jaymon0703 commented 5 years ago

hi @waileong94 can you please confirm if this is working for you when using latest version of quantstrat, v0.16.1? keen to close this issue if it is. thanks!