繁体   English   中英

在R量子代码中循环 - 如何使其更快?

[英]While loop in R quantstrat code - how to make it faster?

在quantstrat包中,我找到了applyRule函数缓慢的主要罪魁祸首之一,并想知道是否有更高效的写入while循环。 任何反馈都会有所帮助。 任何人都可以将这部分包装成并行R.

作为一种选择,申请会有效吗? 或者我应该将此部分重新编写为新函数,例如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
}

加勒特的回答确实指出了关于R-SIG财务清单的最后一次重要讨论,其中讨论了相关问题。

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

在这个问题中复制的while循环代码是applyRules执行的路径依赖部分。 我相信所有这些都在文档中有所涉及,但我将简要回顾一下后代。

我们在applyRules中构建一个降维索引,这样我们就不必观察每个时间戳并检查它。 我们只注意到可以合理地预期策略可以在订单簿上执行的特定时间点,或者可以合理地预期订单被填补的特定时间点。

这是依赖于状态路径的代码。 在这种背景下,对“矢量化”的闲谈没有任何意义。 如果我需要知道市场的当前状态,订单和我的位置,如果我的订单可能会被其他规则以时间依赖的方式修改,我看不出这个代码是如何被矢量化的。

从计算机科学的角度来看,这是一台状态机。 我能想到的几乎所有语言的状态机通常都是以while循环编写的。 这不是真正可以谈判或改变的。

问题是否使用申请会有所帮助。 R中的apply语句实现为循环,所以不,它没有帮助。 即使是mclapplyforeach等并行应用也无济于事,因为这是代码中依赖于状态的部分。 在不考虑状态的情况下评估不同的时间点没有任何意义。 您将注意到,quantstrat的非状态相关部分尽可能地进行矢量化,并且占用的运行时间非常少。

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

为了加快执行速度,可以做四件事:

  1. 编写非路径依赖策略 :代码支持这一点,简单策略可以这种方式建模。 在这个模型中,您将编写一个自定义规则函数,当您认为应该填充时, 它会直接调用addTxn 它可能是一个操作指标/信号的矢量化函数,应该非常快。
  2. 预处理您的信号 :如果状态机需要评估订单簿/规则/组合的状态以查看是否需要执行某些操作,则速度增加几乎与信号减少呈线性关系。 这是大多数用户忽略的区域,写入信号功能并不真正评估何时可能需要修改位置或订单簿的操作。
  3. 显式并行化部分分析问题 :我通常明确地编写并行包装器以分离出不同的参数评估或符号评估,请参阅applyParameter以获取使用foreach的示例
  4. 在C / C ++中重写applyRules中的状态机 :欢迎补丁,但请看Garrett发布的链接以获取更多详细信息。

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

参考: quantstrat - applyRules

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM