前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vn.py源码解读(一、环境配置与回测初试)

vn.py源码解读(一、环境配置与回测初试)

作者头像
钱塘小甲子
发布2019-01-28 16:11:01
2.2K0
发布2019-01-28 16:11:01
举报

        近来忙于毕业找工作,也不知道能不能继续在量化界混了。周末比较闲,抽空研究了一下vn.py。有人说,为什么学那么多的回测平台呀。其实我个人觉得,做cta的话,两个回测平台还是要的,这样,当你的策略出现和你预计不符,而你有无法在代码逻辑层面找到问题的时候,你就可以用另外一个平台试一下,来看看到底是你的策略本身就不行,还是你的代码有着当前水平无法察觉的问题,甚至,可能回测平台本身存在一个bug。所以笔者之前学习的backtrader和pyalgotrade的目的就是这个,但是后续对于pyalgotrade没怎么用。前段时间看到vn.py和某Q开头的开源项目在网上开战,刚入门python的小朋友可能还不知道他们争论的是什么。

        闲话不说,总而言之,个人觉得,vn.py还是一个很不错的期货cta的平台,而且,不仅仅局限于回测,还可以直接当一个交易系统使用,整个代码框架也是相当不错的,只是似乎对刚入门的小朋友不是特别友好,入门级别的教程比较少。

1.安装mongodb

        vn.py用的数据库是mongdb,笔者也不知道为什么要这样,是为了速度么还是单纯表示与众不同的。说真的,笔者还是习惯用传统的sql数据库,不过还好,mongodb也入过门。怎么安装就不说了,安装好之后别忘了开启服务。

2.测试一下

        笔者使用的nv.py-1.7版本,本文主要介绍一下回测功能吧。在下载下来的文件夹下面有一个examples文件夹,里面有一个CtaBacktesting文件,里面有一个notebook,一个IF的分钟数据,还有三个python文件。

        我们先来运行一下loadCsv这个python文件,如果一切顺利的话,我们可以看到数据被写入mongdb的信息不断print出来。这个文件的功能就是告诉我们如何把数据存到数据库里。仔细看一下源码,其实可以发现,vn.py还是支持很多数据格式的,什么通达信上直接导到本地的数据啊之类的,功能还是很全的,很接地气。相对于国外的开源项目来说,基本都是要自己写数据格式处理程序的。有好处也有坏处吧。

        然后我们就可以打开notebook文件,然后不断运行就可以了。

        这里,笔者用DualThrust来作为例子讲解一下,毕竟这么经典的策略,大家很容易找到原理,也容易理解。

3.例子

        和别的回测项目一样,我们要现有一个回测的核心,在vn.py中叫做engine,引擎,还是比较好理解的。

代码语言:javascript
复制
engine = BacktestingEngine()

        然后自然的,就是进行一些设置了。

        设置的话,那么无非就是数据和回测方式。数据的话,设置是使用tick模式还是bar模式,笔者目前还没有研究tick模式,而且我们的数据也是分钟bar,所以选择BAR_MODE,然后就是设置数据库的名称,vn.py已经定义好了名称了,当然,我们可以按照我们的数据品种自己定义。

代码语言:javascript
复制
# 设置回测使用的数据
engine.setBacktestingMode(engine.BAR_MODE)    # 设置引擎的回测模式为K线
engine.setDatabase(MINUTE_DB_NAME, 'IF0000')  # 设置使用的历史数据库
engine.setStartDate('20120101')               # 设置回测用的数据起始日期
engine.setEndDate('20120201')
# 配置回测引擎参数
engine.setSlippage(0.2)     # 设置滑点为股指1跳
engine.setRate(0.3/10000)   # 设置手续费万0.3
engine.setSize(300)         # 设置股指合约大小 
engine.setPriceTick(0.2)    # 设置股指最小价格变动   
engine.setCapital(1000000)  # 设置回测本金

注:本文出现的大部分代码都是来自于vn.py的notebook文件里面自带的,并不是本人编写的。

接下来就是最核心的策略部分了。和很多开源平台一样,策略的封装就是一个类。

代码语言:javascript
复制
from vnpy.trader.app.ctaStrategy.strategy.strategyDualThrust import DualThrustStrategy

vn.py的作者已经写了一个DualThrust的策略了。

然后就是设置策略的参数,策略的参数是以字典形式传入的。

代码语言:javascript
复制
# 在引擎中创建策略对象
d = {}                     # 策略参数配置
engine.initStrategy(DualThrustStrategy, d)    # 创建策略对象
# 运行回测
engine.runBacktesting()          # 运行回测

上面的d就是。至于有什么参数,则与策略类的编写有关。

4.策略类

整个DualThrust的实现就不说了,大家可以去文件里面找怎么实现的。主要说一下框架吧。

代码语言:javascript
复制
    # 参数列表,保存了参数的名称
    paramList = ['name',
                 'className',
                 'author',
                 'vtSymbol',
                 'k1',
                 'k2']    

在类里面,定义了参数表。我们知道,DualThrust如果只考虑前面一天的价格的话,也就是N为1的话,其实参数就是两个,上轨K和下轨K,也就是这里的K1和K2,大家修改上面的参数字典d就可以了。不传参数的话,当然就是默认参数。

然后就是所有事件驱动类型的回测框架都会有的那个触发函数了,也就是我们所有逻辑的核心。

代码语言:javascript
复制
    def onBar(self, bar):
        print 'on_bar method'
        print bar.datetime.date()
        """收到Bar推送(必须由用户继承实现)"""
        # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
        for orderID in self.orderList:
            self.cancelOrder(orderID)
        self.orderList = []

        # 计算指标数值
        self.barList.append(bar)
        
        if len(self.barList) <= 2:
            return
        else:
            self.barList.pop(0)
        lastBar = self.barList[-2]
        
        # 新的一天
        if lastBar.datetime.date() != bar.datetime.date():
            # 注意,这段代码其实只在改变日期那一天执行一次
            # 如果已经初始化
            if self.dayHigh:
                self.range = self.dayHigh - self.dayLow
                self.longEntry = bar.open + self.k1 * self.range
                self.shortEntry = bar.open - self.k2 * self.range           
                
            self.dayOpen = bar.open
            self.dayHigh = bar.high
            self.dayLow = bar.low

            self.longEntered = False
            self.shortEntered = False
        else:
            self.dayHigh = max(self.dayHigh, bar.high)
            self.dayLow = min(self.dayLow, bar.low)

        # 尚未到收盘
        if not self.range:
            return

        if bar.datetime.time() < self.exitTime:
            if self.pos == 0:
                if bar.close > self.dayOpen:
                    if not self.longEntered:
                        vtOrderID = self.buy(self.longEntry, self.fixedSize, stop=True)
                        self.orderList.append(vtOrderID)
                else:
                    if not self.shortEntered:
                        vtOrderID = self.short(self.shortEntry, self.fixedSize, stop=True)
                        self.orderList.append(vtOrderID)
    
            # 持有多头仓位
            elif self.pos > 0:
                self.longEntered = True

                # 多头止损单
                vtOrderID = self.sell(self.shortEntry, self.fixedSize, stop=True)
                self.orderList.append(vtOrderID)
                
                # 空头开仓单
                if not self.shortEntered:
                    vtOrderID = self.short(self.shortEntry, self.fixedSize, stop=True)
                    self.orderList.append(vtOrderID)
                
            # 持有空头仓位
            elif self.pos < 0:
                self.shortEntered = True

                # 空头止损单
                vtOrderID = self.cover(self.longEntry, self.fixedSize, stop=True)
                self.orderList.append(vtOrderID)
                
                # 多头开仓单
                if not self.longEntered:
                    vtOrderID = self.buy(self.longEntry, self.fixedSize, stop=True)
                    self.orderList.append(vtOrderID)  
            
        # 收盘平仓
        else:
            if self.pos > 0:
                vtOrderID = self.sell(bar.close * 0.99, abs(self.pos))
                self.orderList.append(vtOrderID)
            elif self.pos < 0:
                vtOrderID = self.cover(bar.close * 1.01, abs(self.pos))
                self.orderList.append(vtOrderID) 
 
        # 发出状态更新事件
        self.putEvent()

       在vn.py中叫onBar这个函数。逻辑还是很简单的。

        总而言之,这是一个不错的工具,二DualThrust其实也是一个相对不错的策略,和还有一个也是日内交易的策略,忘记叫啥了,不但简单,而且效果巨好。后期如果找到工作了,还在量化界混的话,写个教程,如何在树莓派上跑几个这样的策略,然后放在印钱(血本无归)。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年11月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.安装mongodb
  • 2.测试一下
  • 3.例子
  • 4.策略类
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档