增加回测滑点计算和限价单撮合价格计算

This commit is contained in:
chenxy123 2016-02-28 21:52:08 +08:00
parent 7d9e054db3
commit bc1ce0372a
2 changed files with 45 additions and 4 deletions

View File

@ -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接口基本覆盖了国内所有常规交易品种股票、期货、期权具体包括
* CTPvn.ctp
* 飞马vn.femas
* LTSvn.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!!!**

View File

@ -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')