这是个好问题。如果您查看applyStrategy,您会发现循环中的每个符号都是独立运行的——独立运行。您可能想查看applyStrategy.rebalancing,它执行以下形式的嵌套循环:
for(i in 2:length(pindex)){
#the proper endpoints for each symbol will vary, so we need to get
#them separately, and subset each one
for (symbol in symbols){
#sret<-ret[[portfolio]]
这意味着它会循环一段时间戳,然后循环遍历每个符号,这就是您想要符号之间进行交互时所需要的(applyStrategy 只需执行一个 for 符号,然后是一个内部按时间戳循环,因此您'永远不会进行互动)在公平方面。
当我第一次开始使用 quantstrat 时,我最初也有同样的挫败感。我的解决方案是将applyStrategy.rebalancing 修改为(较慢的)双循环,对于每个时间戳,然后是每个符号的内部循环。
是的,这意味着您无法在 quantstrat 中直接准确计算投资组合 PL。因此,不能直接进行诸如开仓等当前投资组合权益的头寸之类的事情。 (但您可以根据需要修改代码来执行此操作)。
为什么 quantstrat 默认会这样?作者会给你很好的理由。简而言之,我的观点是(在与作者进行了一些简短讨论之后),如果一个信号具有预测能力,并在策略中为您提供优势,那么无论您以后如何将其与其他符号组合,它都会起作用。 quantstrat 是关于识别与您传递给它的 mktdata 相关的信号是否良好。
从逻辑上讲,如果一个信号在每个符号级别上都很好,那么它在投资组合级别上也可能没问题(如果不是更好,则投资组合 PL 更平滑)。 quantstrat 当前的方法将为您提供一个合理的近似值,即投资组合 PL 的样子,但不是真正的“复合回报”意义上的。为此,您需要根据当前的投资组合 PL 扩展您的头寸(如上所述,这在 applyStrategy 中是不可能的)。仅对每个符号运行策略的这种简化也使模拟变得非常非常快。请注意,您可以在 applyStrategy 中引入与其他符号的静态交互,方法是向与其他符号相关的符号数据添加额外的列(例如成对交易等)。
归根结底,回测结果总是对现实交易的简化,因此没有很大的动力去获得非常准确地预测利润/交易收入的“超级”准确回测结果。