【发布时间】:2011-12-04 11:50:07
【问题描述】:
在 quantstrat 包中,我找到了导致 applyRule 函数运行缓慢的主要原因之一,并想知道编写 while 循环是否更有效率。任何反馈都会有所帮助。对于任何有将此部分包装到 Parallel R 中的经验的人。
作为一个选项 apply 会起作用吗?或者我应该把这部分重新写成新的函数,比如ruleProc和nextIndex?我也在研究 Rcpp,但这可能是一个问题。非常感谢任何帮助和建设性建议?
while (curIndex) {
timestamp = Dates[curIndex]
if (isTRUE(hold) & holdtill < timestamp) {
hold = FALSE
holdtill = NULL
}
types <- sort(factor(names(strategy$rules), levels = c("pre",
"risk", "order", "rebalance", "exit", "enter", "entry",
"post")))
for (type in types) {
switch(type, pre = {
if (length(strategy$rules[[type]]) >= 1) {
ruleProc(strategy$rules$pre, timestamp = timestamp,
path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
symbol = symbol, ruletype = type, mktinstr = mktinstr)
}
}, risk = {
if (length(strategy$rules$risk) >= 1) {
ruleProc(strategy$rules$risk, timestamp = timestamp,
path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
symbol = symbol, ruletype = type, mktinstr = mktinstr)
}
}, order = {
if (length(strategy$rules[[type]]) >= 1) {
ruleProc(strategy$rules[[type]], timestamp = timestamp,
path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
symbol = symbol, ruletype = type, mktinstr = mktinstr,)
} else {
if (isTRUE(path.dep)) {
timespan <- paste("::", timestamp, sep = "")
} else timespan = NULL
ruleOrderProc(portfolio = portfolio, symbol = symbol,
mktdata = mktdata, timespan = timespan)
}
}, rebalance = , exit = , enter = , entry = {
if (isTRUE(hold)) next()
if (type == "exit") {
if (getPosQty(Portfolio = portfolio, Symbol = symbol,
Date = timestamp) == 0) next()
}
if (length(strategy$rules[[type]]) >= 1) {
ruleProc(strategy$rules[[type]], timestamp = timestamp,
path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
symbol = symbol, ruletype = type, mktinstr = mktinstr)
}
if (isTRUE(path.dep) && length(getOrders(portfolio = portfolio,
symbol = symbol, status = "open", timespan = timestamp,
which.i = TRUE))) {
}
}, post = {
if (length(strategy$rules$post) >= 1) {
ruleProc(strategy$rules$post, timestamp = timestamp,
path.dep = path.dep, mktdata = mktdata, portfolio = portfolio,
symbol = symbol, ruletype = type, mktinstr = mktinstr)
}
})
}
if (isTRUE(path.dep))
curIndex <- nextIndex(curIndex)
else curIndex = FALSE
}
【问题讨论】:
-
我怀疑这个问题是
while所固有的,但无论while内部发生什么。您的代码似乎没有做任何事情 - 没有赋值或返回值。因此,由于ruleProc的副作用,您必须运行它。如果副作用之一是您在其他地方分配值,我将首先重构它。根据我的经验,在结果列表中使用lapply和do.call通常比使用[<-进行选择性分配更快。 -
如果您发布了每个底层数据结构的玩具示例,那么我认为
for可以被矢量化。此外,nextIndex和ruleProc等函数也需要公开。只有在那之后,才能有人对while循环做出良好的评估。 -
好的,刚刚查看了这段代码...尝试先将 ruleProc 向量化。事实上,如果
ruleProc是这个代码非常慢的一个例子,那么你几乎不需要思考就可以轻松实现大幅加速。通过ruleProc并将所有内容移出包含整个函数的巨大for循环。很多。如果你不能自己做那部分,然后发布它进行矢量化。但请先行动。 -
我在下面提供了一个答案,如果 OP 能接受,那就太好了。我还将在这里提供一个评论,这实际上是一个我没有时间测试的假设。我怀疑 applyRules 中的状态机代码可以通过使用 R 2.13.0 引入的 compiler 包显着加快。这可用于对 quantstrat 中的部分/全部 applyRules 函数进行字节编译。
标签: r while-loop quantstrat