gpt4 book ai didi

r - RQuantstrat代码中的while循环-如何使其更快?

转载 作者:行者123 更新时间:2023-12-04 18:13:47 24 4
gpt4 key购买 nike

在Quantstrat程序包中,我找到了applyRule函数运行缓慢的罪魁祸首之一,想知道编写while循环是否更有效率。任何反馈都将有所帮助。对于任何有经验的人,都可以将其包装到Parallel R中。

作为一种选择,会在一段时间内起作用吗?还是应该将这部分重写为新功能,例如ruleProc和nextIndex?我也想了解Rcpp,但这可能是一种努力。任何帮助和 build 性的建议将不胜感激?

   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
}

最佳答案

Garrett的答案的确指向了R-SIG-财务列表上的最后一个主要讨论,其中讨论了一个相关问题。

绝对是大部分时间花费在quantstrat中的applyRules函数上。

在此问题中复制的while循环代码是applyRules执行中与路径有关的部分。我相信所有这些内容都包含在文档中,但是我将简要回顾一下后代。

我们在applyRules内部构造了降维索引,因此我们不必观察每个时间戳并对其进行检查。我们仅注意到特定时间点,在这些时间点上,可以合理地预期该策略在订单簿上采取行动,或者可以合理地预期要完成的订单。

这是状态相关和路径相关的代码。在这种情况下,闲谈“矢量化”毫无意义。如果我需要了解市场的当前状态,订单簿和我的头寸,并且如果我的订单可以通过其他规则以时间相关的方式进行修改,那么我将看不到如何对这些代码进行矢量化处理。

从计算机科学的角度来看,这是一个状态机。我能想到的几乎每种语言的状态机通常都编写为while循环。这不是真正可以商谈或更改的。

该问题询问使用申请是否会有所帮助。 R中的apply语句是作为循环实现的,所以不,这无济于事。即使是并行应用程序(例如 mclapply foreach )也无济于事,因为这在代码的状态相关部分内。在不考虑状态的情况下评估不同的时间点没有任何意义。您会注意到,quantstrat的与状态无关的部分在可能的情况下都会进行矢量化处理,并且只占用很少的运行时间。

John的评论建议删除 ruleProc 中的for循环。 for循环所做的只是在此时检查与该策略关联的每个规则。该循环中唯一需要大量计算的部分是 do.call 以调用规则函数。 for循环的其余部分仅是查找和匹配这些函数的参数,并且从代码分析中根本不需要花费很多时间。在这里使用并行应用也没有多大意义,因为规则函数是按类型顺序应用的,因此取消或风险指令可以在新的进入指令之前应用。就像数学中有操作顺序,或者银行中有存款/取款处理顺序一样,quantstrat也有规则类型的评估顺序,如文档中所述。

为了加快执行速度,可以完成以下四项主要工作:

  • 编写一个非路径依赖的策略:代码支持此策略,并且可以通过这种方式对简单策略进行建模。在此模型中,您将编写一个自定义规则函数,当您认为应该填充时直接调用 addTxn 。它可能是在指示器/信号上运行的矢量化函数,并且应该非常快。
  • 预处理信号:如果状态机需要评估订单簿/规则/ Assets 组合的状态以查看是否需要执行某些操作的地方较少,那么速度的提高与信号的减少几乎成线性关系。这是大多数用户忽略的领域,他们编写的信号功能实际上并没有评估何时需要采取措施来修改仓位或订单。
  • 显式并行化分析问题的各个部分:我通常编写显式并行包装器以分离出不同的参数求值或符号求值,有关使用 foreach 的示例,请参见 applyParameter
  • 重写C/C++中applyRules内的状态机:欢迎打补丁,但请参阅Garrett发布的链接以获取更多详细信息。

  • 我可以向您保证,如果对信号生成功能稍加注意,大多数策略可以在报价数据上每个核心每天每个符号运行一分钟的核心分钟。不建议在笔记本电脑上运行大型回测。

    引用: quantstrat - applyRules

    关于r - RQuantstrat代码中的while循环-如何使其更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7712745/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com