本文共 1370 字,大约阅读时间需要 4 分钟。
在阅读vnpy的样例代码可以发现,其主要逻辑都是在onbar(or ontick)中实现,这个和大部分基于股票回测的类似zipline等基本类似。但稍有差异的是onbar中首先会清空之前订单,也即是调用self.cancelAll()方法。
但是,在使用模板TargetPosTemplate时,系统提供样例MultiSignalStrategy却没做相同处理,看了下其实是在calculateTargetPos() self.setTargetPos(targetPos) self.trade() self.cancelAll()
但这么做其实有风险的,大部分时候如果仓位没变化不会调用这个方法的。但对于止损单来说,若采用随止损时却需要实时以最高价百分比下止损单,所以需要每个bar都调用cancelAll()进行旧止损订单清理。
= ArrayManager(size=100)
在系统样例中,可能会忽略,采用的都是默认值100,但如果回测时间需要很长的化就需要修改这个取值。 这个值会影响那些地方呢? 在样例策略中,有这么个共同点onbar(): if not am.inited: return
这里的am.inited就是指am中填充的数据是否足够,而足够就是由size=100来定义的。在初始化的数据填充足够后inited会变为True。
另外一个需要注意的地方是
initData = self.loadBar(self.initDays) 这里的self.initDays是天数,在bar为分钟等时,需要留意下,除240后填充到这里,避免初始化过多数据。还有就是在BacktestingEngine
self.strategy.inited = True self.output(u'策略初始化完成') self.strategy.trading = True
当am.inited被设置为True之后,如果self.strategy.trading=True会正常下单,否则的化虽然onbar执行逻辑正常,但是订单却不会被撮合。
理想的情况是我们需要240个分钟bar,则size=240,然后数据出事成功后,恰好am.inited=True,and ,trading = True但是实际可能不会那么凑巧。 建议回测时将initday设置偏小,比如需要360分钟bar,initday取(360/240)=1.5->1,然后初始结束后am.inited=False,回测引擎会继续执行后续的onbar填充am,直到am达到360才会执行onbar的后续业务相关逻辑。 这么做虽然会跳过一段时间,但是整体业务是顺的,不会出现应该下单的却找不到下单到哪里的诡异问题。纠正错误
上面思路没错,但会引起另一个问题,实盘时如果按照上面的思路回导致时间段跳过的问题,比如设定需要300个bar,那么由于initday设置的是1天,1天只有240个分钟bar,导致新的一天,60个bar用来积累数据了。 所以可能还是按照超额设定initday合理一些,避免实盘错过时间段。转载地址:http://bwfws.baihongyu.com/