braverock / braverock/quantstrat

apply.paramset return empty results with doParallel/doSNOW

Open
#86 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
R
Stars
310
Forks
121
PR merge metrics
No merged PRs in 30d

Description

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

```library(quantstrat)

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):
``` myForestOptLabel 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
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
```

Contributor guide

Open the contributing guide

Research direction

Start with the apply.paramset call in the reproducible example and compare its sequential execution with the doSNOW-registered execution. Run the example and inspect resultsopt$tradeStats; done means parallel execution returns the same nonzero trade statistics as the sequential run.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
fintech-quant
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.