From bc1ce0372a8be2cf26bfb6c2ed6b70fa1e8e202f Mon Sep 17 00:00:00 2001 From: chenxy123 Date: Sun, 28 Feb 2016 21:52:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=9E=E6=B5=8B=E6=BB=91?= =?UTF-8?q?=E7=82=B9=E8=AE=A1=E7=AE=97=E5=92=8C=E9=99=90=E4=BB=B7=E5=8D=95?= =?UTF-8?q?=E6=92=AE=E5=90=88=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +++++++++++++++++++++- vn.trader/ctaAlgo/ctaBacktesting.py | 27 ++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3e680307..cdb53a34 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ### Quick Start 对于大部分用户来说,无需自行编译API接口,可以直接使用vn.trader进行交易和策略开发: + 1. 准备一台Windows 7 64位系统的电脑 2. 安装[Anaconda](http://www.continuum.io/downloads):下载Python 2.7 32位版本,**注意必须是32位** @@ -45,12 +46,19 @@ 截止2016年2月15日,vn.py项目在Github上收获了583个Star和362个Fork,且已有6位贡献者提交了代码。项目的用户包括:私募基金,证券自营、资管,期货公司,高校的金融研究院系,个人投资者等,机构用户加起来至少20多家(和作者交流过的)。 **总结一下项目当前取得的进展** + 1. 较为丰富的Python交易和数据API接口,基本覆盖了国内所有常规交易品种(股票、期货、期权),具体包括: + * CTP(vn.ctp) + * 飞马(vn.femas) + * LTS(vn.lts) + * 金仕达黄金(vn.ksgold) + * 金仕达期权(vn.ksotp) + * 通联数据(vn.datayes) 2. 简洁易用的事件驱动引擎(vn.event),作为事件驱动型交易程序的核心 @@ -58,8 +66,11 @@ 3. 针对如何使用API和事件驱动引擎开发交易程序的示例(vn.demo) 4. 开箱即用的实盘交易平台vn.trader(相比之下vn.demo仅建议学习用),整合了多种交易接口,并针对具体策略算法和功能开发提供了简洁易用的API,功能应用举例: + * 同时登录多个交易接口,在一套界面上监控多种市场的行情和多种资产账户的资金、持仓、委托、成交情况 + * 支持跨市场套利(CTP期货和LTS证券)、境内外套利(CTP期货和IB外盘)、多市场数据整合实时预测走势(CTP的股指期货数据、IB的外盘A50数据、Wind的行业指数数据)等策略应用 + * CTA策略引擎模块,在保持易用性的同时,允许用户针对CTA类策略运行过程中委托的报撤行为进行细粒度控制(降低交易滑点、实现高频策略) 5. [官网](http://vnpy.org)和[知乎专栏](http://zhuanlan.zhihu.com/vn-py),内容目前主要是《Python量化交易平台开发教程系列》,以及vn.py项目进展的更新 @@ -69,19 +80,28 @@ **展望一下项目2016年的计划** 代码方面: + 1. 完善飞创、易盛等相对小众接口的添加,这块将由社区驱动,作者主要负责代码检查和管理 + 2. 整理vn.py项目中API的具体版本号,保证封装接口的对应,这点已经有多位用户提起过,项目初期没有做详细记录所以很多API的版本号一时都较难对上 + 3. Linux上API的编译以及vn.trader支持 + 4. 基于VirtualBox的vn.py开发环境镜像,解决部分用户反映项目初期不知该如何搭建开发环境的问题,这个镜像会由官方长期维护下去 文章方面: -1. 作者自己作为交易员的成长经历(这一年来收到好多人关于如何成为Quant、建议看什么书、怎么选学校等类似的问题,与其零散的回答不如介绍下自己的一些经历给大家参考可能更有帮助) +1.作者自己作为交易员的成长经历(这一年来收到好多人关于如何成为Quant、建议看什么书、怎么选学校等类似的问题,与其零散的回答不如介绍下自己的一些经历给大家参考可能更有帮助) + 2. vn.trader的使用教程(目前基本除了代码里的注释什么都没有...) + 3. 将ta-lib(技术分析)和quantlib(金融工程和量化)整合到vn.trader中应用的教程,解决目前策略开发过程中技术指标和量化函数缺乏的问题 + 4. 一套关于开发基于股指交易ETF期权的CTA策略的教程(股指期货短时间内还看不到恢复的希望,咱得另谋出路) 社区方面: + 1. 重新建设官方网站,目前使用的是托管在Github Pages上的Hexo静态博客,一来功能比较有限,二来有些用户反映Github时不时会被墙,考虑基于Flask重建一个托管在国内的官网 + 2. 有用户提出建设互动性更强的网站作为交流平台(如论坛或者知乎Q&A类似的模式),这点在考虑中,主要制约因素是作者参与的时间,可能考虑和更多的资深用户合作是个好主意? **最后,2016年,Happy Trading!!!** diff --git a/vn.trader/ctaAlgo/ctaBacktesting.py b/vn.trader/ctaAlgo/ctaBacktesting.py index 9f65eedc..69060680 100644 --- a/vn.trader/ctaAlgo/ctaBacktesting.py +++ b/vn.trader/ctaAlgo/ctaBacktesting.py @@ -44,6 +44,8 @@ class BacktestingEngine(object): self.strategy = None # 回测策略 self.mode = self.BAR_MODE # 回测模式,默认为K线 + self.slippage = 0 # 回测时假设的滑点 + self.dbClient = None # 数据库客户端 self.dbCursor = None # 数据库指针 @@ -251,9 +253,11 @@ class BacktestingEngine(object): if self.mode == self.BAR_MODE: buyCrossPrice = self.bar.low # 若买入方向限价单价格高于该价格,则会成交 sellCrossPrice = self.bar.high # 若卖出方向限价单价格低于该价格,则会成交 + bestCrossPrice = self.bar.open # 在当前时间点前发出的委托可能的最优成交价 else: buyCrossPrice = self.tick.lastPrice sellCrossPrice = self.tick.lastPrice + bestCrossPrice = self.tick.lastPrice # 遍历限价单字典中的所有限价单 for orderID, order in self.workingLimitOrderDict.items(): @@ -274,7 +278,16 @@ class BacktestingEngine(object): trade.vtOrderID = order.orderID trade.direction = order.direction trade.offset = order.offset - trade.price = order.price + + # 以买入为例: + # 1. 假设当根K线的OHLC分别为:100, 125, 90, 110 + # 2. 假设在上一根K线结束(也是当前K线开始)的时刻,策略发出的委托为限价105 + # 3. 则在实际中的成交价会是100而不是105,因为委托发出时市场的最优价格是100 + if buyCross: + trade.price = min(order.price, bestCrossPrice) + else: + trade.price = max(order.price, bestCrossPrice) + trade.volume = order.totalVolume trade.tradeTime = str(self.dt) trade.dt = self.dt @@ -401,7 +414,8 @@ class BacktestingEngine(object): # 当前多头交易为平空 else: entryTrade = shortTrade.pop(0) - pnl = (trade.price - entryTrade.price) * trade.volume * (-1) + # 滑点对于交易而言永远是不利的方向,因此每笔交易开平需要减去两倍的滑点 + pnl = (trade.price - entryTrade.price - self.slippage * 2) * trade.volume * (-1) pnlDict[trade.dt] = pnl # 空头交易 else: @@ -411,7 +425,7 @@ class BacktestingEngine(object): # 当前空头交易为平多 else: entryTrade = longTrade.pop(0) - pnl = (trade.price - entryTrade.price) * trade.volume + pnl = (trade.price - entryTrade.price - self.slippage * 2) * trade.volume pnlDict[trade.dt] = pnl # 然后基于每笔交易的结果,我们可以计算具体的盈亏曲线和最大回撤等 @@ -463,6 +477,10 @@ class BacktestingEngine(object): """发送策略更新事件,回测中忽略""" pass + #---------------------------------------------------------------------- + def setSlippage(self, slippage): + """设置滑点""" + self.slippage = slippage if __name__ == '__main__': @@ -477,6 +495,9 @@ if __name__ == '__main__': # 设置引擎的回测模式为K线 engine.setBacktestingMode(engine.BAR_MODE) + # 设置滑点 + engine.setSlippage(0.2) # 股指1跳 + # 设置回测用的数据起始日期 engine.setStartDate('20100416')