介绍一款开源量化交易系统开发框架
1、VN.PY介绍
工欲善其事必先利其器,有一个好的回测框架,才能更好的验证自己的策略
vn.py是一套基于Python的开源量化交易系统开发框架,于2015年1月正式发布,在开源社区6年持续不断的贡献下一步步成长为全功能量化交易平台,目前国内外金融机构用户已经超过600家,包括:私募基金、证券自营和资管、期货资管和子公司、高校研究机构、自营交易公司、交易所、Token Fund等。
2、搭建回测环境
再好的策略也得经过历史数据的回测,才敢放心的去实盘
2.1、环境
Python 3.8.x
vnpy 2.30,在此特别感谢vnpy社区
MongoDB
2.2、安装
安装mongoDB
安装mongoD环境是为了存储数据,方便回测。
安装教程,参考:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
建库建表的语句
use admin
db.createUser({user:admin, pwd:xxxx, roles: [ { role: “userAdminAnyDatabase”, db: “admin”} ]})
use vnpy
db.createUser({ user: “root”, pwd: “xxxx”, roles: [{ role: “readWrite”, db: “vnpy” }] })安装vnpy
安装vnpy,别直接pip install vnpy, 因为pypi.org上的库已经好久没有更新了,所以用下面的安装方式
pip install git+https://github.com/vnpy/vnpy.git安装其他的包
成功安装vnpy后,还有部分包并没有成功安装,需要手动安装,如下:
pip install tzlocal
pip install plotly
pip install pymongo
pip install mongoengine
pip install quickfix3、项目结构说明
代码结构
├── README.md
├── .vntrader # 这个文件自己创建,默认是~/.vntrader/,但是为了编码方便,我会在项目创建这个目录(注意主要信息的泄露)
│ ├── cta_backtester_setting.json
│ ├── cta_strategy_data.json
│ ├── cta_strategy_setting.json
│ ├── data_recorder_setting.json
│ ├── database.db
│ ├── log
│ │ └── vt_20210522.log
│ ├── risk_manager_setting.json
│ └── vt_setting.json
└── vnpy_strategy
├── backtest_fixed_time.py # 运行回测
├── run_window.py # 通过图像界面操作
├── strategies # 自己写的量化策略,都在这个目录
│ └── simple_double_ma.py
└── utils # 工具类代码,都会放在这个目录
└── download_data_binance.py代码说明
使用VNPY创建自己的策略需要继承CtaTemplate, 下面也是官方一个简单均线策略,来对vn.py回测框架的熟悉。
双均线策略,指的是运用两条不同周期的移动平均线,即短周期移动平均线和长周期移动平均线的相对大小,研判买进与卖出时机的策略。由短周期均线自下向上穿越长周期均线,所形成的交点,称为金叉。当短周期均线自上而下穿越长周期均线,所形成的交点,称为死叉。
这样我们可以构建一个双均线策略:双均线金叉的时候,表明该币很强势,市场属于多头市场;反之,当出现死叉点时,市场属于空头市场。
class SimpleDoubleMA(CtaTemplate): “”“ 一个简单的双均线策略 ““” # 定义参数 fast_window = 10 slow_window = 20 # 定义变量 fast_ma0 = 0.0 fast_ma1 = 0.0 slow_ma0 = 0.0 slow_ma1 = 0.0 parameters = [“fast_window”, “slow_window”] variables = [“fast_ma0”, “fast_ma1”, “slow_ma0”, “slow_ma1”] def __init__(self, cta_engine: Any, strategy_name: str, vt_symbol: str, setting: dict): super().__init__(cta_engine, strategy_name, vt_symbol, setting) # K线合成器:从Tick合成分钟K线用, 这里合成轴线数据 self.bg_4_hour = BarGenerator(self.on_bar, 4, self.on_4hour_bar, Interval.HOUR) # 时间序列容器:计算技术指标用 self.am = ArrayManager() def on_init(self): self.write_log(“策略初始化”) # 加载10天的历史数据用于初始化回放 self.load_bar(20) def on_start(self): self.write_log(“策略启动”) # 通知图形界面更新(策略最新状态) # 不调用该函数则界面不会变化 self.put_event() def on_4hour_bar(self, bar: BarData): am = self.am am.update_bar(bar) # 若缓存的K线数量尚不够计算技术指标,则直接返回 if not self.am.inited: return # 计算快速均线 fast_ma = self.am.sma(self.fast_window, array=True) # T时刻的值 self.fast_ma0 = fast_ma[-1] # T-1时刻的值 self.fast_ma1 = fast_ma[-2] # 计算慢速均线 slow_ma = self.am.sma(self.slow_window, array=True) self.slow_ma0 = slow_ma[-1] self.slow_ma1 = slow_ma[-2] # 是否是金叉 cross_over = (self.fast_ma0 > self.slow_ma0) and (self.fast_ma1 < self.slow_ma1) # 是否是死叉 cross_below = (self.fast_ma0 < self.slow_ma0) and (self.fast_ma1 > self.slow_ma1) if cross_over: # 为了保证成交,在K线收盘价上加5发出限价单 price = bar.close_price + 5 # 当前无仓位,则直接开多 if self.pos == 0: self.buy(price, 1) # 当前持有空头仓位,则先平空,再开多 elif self.pos < 0: self.cover(bar.close_price, 1) self.buy(bar.close_price, 1) if cross_below: if self.pos == 0: self.short(bar.close_price, 1) elif self.pos > 0: self.sell(bar.close_price, 1) self.short(bar.close_price, 1) self.put_event() def on_stop(self): self.write_log(“策略停止”) self.put_event() def on_tick(self, tick: TickData): “”“ 通过该函数收到Tick推送。 :param tick: :return: ““” pass def on_bar(self, bar: BarData): “”“ 通过该函数收到新的1分钟K线推送。 :param bar: :return: ““” self.bg_4_hour.update_bar(bar) def on_order(self, order: OrderData): “”“ 通过该函数收到委托状态更新推送。 :param order: :return: ““” self.put_event() def on_trade(self, trade: TradeData): “”“ 通过该函数收到成交推送。 :param trade: :return: ““” self.put_event() def on_stop_order(self, stop_order: StopOrder): “”“ 通过该函数收到本地停止单推送。 :param stop_order: :return: ““” self.put_event()4、回测
回测之前,需要下载历史数据;如果配置了MongoDB,数据下载完成后可以在MongoDB查看
4.1、命令方式回测
python run_backtest.py回测结果
2021-05-24 23:18:06.187119 首个交易日:2017-09-05
2021-05-24 23:18:06.187126 最后交易日:2018-05-20
2021-05-24 23:18:06.187131 总交易日:258
2021-05-24 23:18:06.187137 盈利交易日:139
2021-05-24 23:18:06.187142 亏损交易日:117
2021-05-24 23:18:06.187151 起始资金:300,000.00
2021-05-24 23:18:06.187159 结束资金:300,969.58
2021-05-24 23:18:06.187165 总收益率:0.32%
2021-05-24 23:18:06.187170 年化收益:0.30%
2021-05-24 23:18:06.187177 最大回撤: -608.35
2021-05-24 23:18:06.187183 百分比最大回撤: -0.20%
2021-05-24 23:18:06.187188 最长回撤天数: 8
2021-05-24 23:18:06.187194 总盈亏:969.58
2021-05-24 23:18:06.187200 总手续费:101.55
2021-05-24 23:18:06.187208 总滑点:0.00
2021-05-24 23:18:06.187215 总成交金额:101,552.30
2021-05-24 23:18:06.187220 总成交笔数:171
2021-05-24 23:18:06.187226 日均盈亏:3.76
2021-05-24 23:18:06.187231 日均手续费:0.39
2021-05-24 23:18:06.187237 日均滑点:0.00
2021-05-24 23:18:06.187243 日均成交金额:393.61
2021-05-24 23:18:06.187250 日均成交笔数:0.6627906976744186
2021-05-24 23:18:06.187256 日均收益率:0.00%
2021-05-24 23:18:06.187262 收益标准差:0.02%
2021-05-24 23:18:06.187267 Sharpe Ratio:1.11
2021-05-24 23:18:06.187273 收益回撤比:1.60
2021-05-24 23:18:06.187780 策略统计指标计算完成4.2、图像界面方式回测
运行run_window.py文件,即可启动图像界面回测。启动成功后,整个界面如下所示。
python run_window.py图像界面回测结果如下:
回测之前,一定要先下载数据,有问题,可以多去看看官方的文档;
5、总结
VN.PY是国内开源社区比较成熟的回测框架,支持股票,期货,数字货币等;
简单看了下源码,代码结构清晰,容易上手;
适合业余者自己去专研,快速开启自己的量化之路。
所有代码均已上传到Github,以后的每一篇公众号的文章,涉及到的代码也会上传到这里。
谢谢大家的关注,后面会分享更多更有趣的策略,今天只是量化之路的开始。
https://github.com/mixbe/juejin_quant
发表回复