学习笔记_vnpy实战培训day04_作业
使用第一堂课的作业,存入MongoDB的数据,对demo策略进行回测。
load数据到mongo并查看
直接使用现成数据吧
VN.PY附带了两份数据,一个是IF指数1分钟数据,一个是螺纹钢指数1分钟数据。在examples\CtaBacktesting目录下,csv格式的。
VN.PY已经帮我们准备好了。在框架的ctaHistoryData.py类中,已经实现好了。
执行:loadCsv,py就行了,2份csv数据就到mongo数据库中了
结果:
看看数据长什么样:
mongo
show dbs
use VnTrader_1Min_Db
show collections
db.IF0000.find().limit(1)
格式化后
{
"_id": ObjectId("5ca35134f688bd106b484671"),
"datetime": ISODate("2010-04-16T09:16:00Z"),
"close": 3468,
"date": "20100416",
"exchange": "",
"gatewayName": "",
"high": 3488,
"interval": "",
"low": 3450,
"open": 3450,
"openInterest": 0,
"rawData": null,
"symbol": "IF0000",
"time": "09:16:00",
"volume": "489",
"vtSymbol": "IF0000"
}
回测跑起来
examples\CtaBacktesting\runBacktesting.py
右键,run
结果:
跟踪查看策略的OnTick,OnOrder,OnTrade
去KkStrategy添加断点,不难发现对onstart,onstop,ontick,onbar,onTrade等KkStrategy都有实现,不妨都加上断点。
忽略一些init操作
重要的执行链如下
ctabackTestting.runBacktesting
self.loadHistoryData():读取数据库行情数据到self.dbCursor中
对于每个self.dbCursor的行情,执行newbar函数,那么newbar做了什么呢?
self.crossLimitOrder() # 先撮合限价单,撮合干了什么呢?
self.crossStopOrder() # 再撮合停止单
从订单列表中workingLimitOrderDict,寻找可成交的订单,将成交结果通知到self.strategy.onOrder(order)
self.strategy.onBar(bar) # 推送K线到策略中,推送干么什么事情
将小bar拼成大bar,并且攒够一个1bar则调用onXminBar方法,触发策略产生买卖信号(买卖指令)
self.updateDailyClose(bar.datetime, bar.close),干了什么?只是存储下
self.dailyResultDict[date] = DailyResult(date, price)
可以参考下面这个图理解,这个是非回测情况(比如实盘情况,系统调用流程)
回测情况下,系统调用流程
执行路径:1-2-3-4-6-7
回测引擎不断读取数据的中的bar信息(或者ticket,大部分回测是bar,为了加速,可能会牺牲准确性),调用newtick方法 (1)
newtick方法先执行撮合(2),撮合成功调用策略的onorder方法通知策略(3)这个路径完成,不会到4(图示有误差,改图太麻烦就不改了)
newtick方法执行撮合或者不需要撮合,上面的路径走完后会到4(也就是说2分拆为3和4,而不是2-3-4,图上不确切)
多个ticket会积累成bar,积累够bar后执行判断逻辑(5),达到开仓标准则调用6,发出订单
发出订单后被回测引擎接受,缓存到stopOrderDict(条件单)和workingOrderDict(普通限价单)中(7)
路径:7-2
含义是订单列表的订单会影响到第2步的撮合(这个不难理解,所谓撮合,就是撮合订单)
把策略改为5分钟级别,直接使用Bar数据进行回测
和上面一样的,区别在于多个ticker(orbar)l累计成一个大bar,然后修改方法updateBar,当积累5分钟的bar后调用一个5分钟大bar的函数self.onXminBar(self.xminBar)(self指BarGenerator)。
BarGenerator被策略持有,策略初始化时制定self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) ,这里self就是策略本身。
每次经过self.onBar*5=1分钟×5=5分钟的时间,就调用一次 self.onFiveBar(self.onBar×5所构成的大bar)
策略实现这个方法:self.onFiveBar(大bar),在里面生成买卖信号即可。