VeighNa量化社区
你的开源社区量化交易平台
Member
加入于:
帖子: 14
声望: 4

原文地址: https://blog.csdn.net/feivirus/article/details/100006132

第一节 参考

https://blog.csdn.net/qtlyx/column/info/30705
https://zhuanlan.zhihu.com/vn-py
https://www.jianshu.com/p/4beaf05fc585
https://blog.csdn.net/joinquantdata/article/details/86715029

安装:
mongod --config /usr/local/etc/mongod.conf
pip install --extra-index-url https://rquser:ricequant99@py.ricequant.com/simple/ rqdatac==1.0.0a35

第二节 架构

一.模块组成
(一).交易所及券商接口
vnpy.api包下,vnpy.trader.gateway包下,主要有
1.ctp:国内期货ctp接口. !
2.femas:
3.fxcm:
4.ib:盈透,港美股,外汇
5.ksgold
6.ksotp
7.lbank
8.lts
9.mini
10.xtp:中泰证券的股票,etf期权.!

(二).回测交易策略
在vnpy.trader.app.algoTrading, vnpy.trader.app.ctaStrategy包下.
(三).图形界面
在vnpy.trader包下.
(四).事件引擎
vnpy.event包下.

 

第四节 源码流程

一.启动
(一)启动逻辑.
入口代码在examples.VnTrader.run.py下面.
启动界面如下图所示:

1.调用vnpy.trader.ui.create_qapp()创建QApplication图形界面对象.
2.调用vnpy.event.engine.EventEngine类的构造函数创建事件引擎.
3.调用vnpy.trader.engine.MainEngine创建主引擎.在构造函数中,调用vnpy.event.engine.EventEngine.start()启动事件引擎.在该方法中主要是创建定时器线程,创建处理事件队列的线程.
4.添加vnpy.app.cta_strategy.CtaStrategyApp的CAT引擎到主引擎中,对应功能菜单中的CTA策略。
5.添加vnpy.app.cta_backtester.CtaBacktesterApp到主引擎中,对应功能菜单中的CTA回测.
6.添加vnpy.app.script_trader.ScriptTraderApp到主引擎中,对应功能菜单中的脚本策略。
7.添加vnpy.app.rpc_service.RpcServiceApp到主引擎中,对应功能菜单的RPC服务.
8.调用vnpy.trader.ui.mainwindow.MainWindow展示主界面.在这个方法中,调用init_ui()初始化界面,主要是初始化工具栏,菜单栏等.
在初始化菜单函数init_menu(),遍历主引擎中添加的所有app,比如CTA策略,CTA回测,脚本策略,RPC服务,每一个添加一个子菜单项.对应的每个子菜单的界面代码,是模块名加.ui包下的widget.py文件.比如CTA回测,就是vnpy.app.cta_backtester.ui包下的widget.py.

二.CTA回测
(一).准备阶段:
以分析DoubleMA Strategy的IF数据为例.
修改vnpy.trader.setting.py文件的米筐的用户名和密码.
选择时间段,点击下载数据。等待数据下载完,然后点击开始回测。看回测结果.
(二).回测页面初始化
由vnpy.app.cta_backtester.CtaBacktesterApp类来处理,对应的界面代码为vnpy.app.cta_backtester.ui.widget.BacktesterManager类.在该类的构造函数中依次执行
1.调用init_strategy_settings()获取各种交易策略,设置交易策略的默认参数.
2.调用init_ui()初始化界面,添加各个界面上的控件.比如合约符号,时间间隔,开始和结束时间,滑点,开始回测,下载数据,参数优化,委托记录,成交记录,每日盈亏,K线图表等按钮.如果是下载数据,进入BacktesterManager.start_downloading()方法.如果是开始回测,进入start_backtesting()方法.继续添加回测成交记录,回测委托记录,回测每日盈亏等结果的对话框.添加K线图的处理类cta_backtester.ui.widget.CandleChartDialog.
3.调用register_event()注册日志信号,回测完成信号,优化完成信号的处理函数。如果是回测完成,进入BacktesterManager.process_backtesting_finished_event()函数处理.
4.调用init_engine()方法初始化引擎,打印"初始化CTA回测引擎"的日志.日志也是作为事件来处理.创建vnpy.app.cta_strategy.backtesting.BacktestingEngine回测引擎类.调用init_rqdata()方法初始化rqdata米筐的sdk.
(三).下载数据
由vnpy.app.cta_backtester.ui.widget.BacktesterManager.start_downloading()方法处理.首先获取界面上输入的合约种类,合约周期,开始和结束时间.然后进入vnpy.app.cta_backtester.engine.BacktesterEngine.start_downloading()方法中,开启新线程下载.具体下载方法为vnpy.app.cta_backtester.engine.BacktesterEngine.run_downloading().主要逻辑是调用vnpy.trader.rqdata.RqdataClient.query_history()根据合约信息下载对应的K线数据.请求的接口是米筐的rqdatac.services.get_price.get_price()的sdk方法.下载完成后,调用vnpy.trader.database.database_sql.SqlManager.save_bar_data()保存K线数据.默认K线数据保存在SQLite数据库中.数据库的配置信息在vnpy/trader/setting.py中.默认路径在'/Users/feivirus/.vntrader/database.db'.
如下图所示:

(四).开始回测
回测结果如下图:

入口代码为vnpy.app.cta_backtester.ui.widget.BacktesterManager.start_backtesting()方法.获取界面配置的合约相关参数,弹窗vnpy.app.cta_backtester.ui.widget.BacktestingSettingEditor对话框,用户确认后,调用vnpy.app.cta_backtester.engine.BacktesterEngine.start_backtesting()开始回测,该方法开启新线程调用run_backtesting().此方法调用逻辑如下:
1.获取vnpy.app.cta_strategy.backtesting.BacktestingEngine类对象,传入界面参数.
2.调用vnpy.app.cta_strategy.backtesting.BacktestingEngine.load_data()方法加载数据.根据是bar模式还是tick模式,调用load_bar_data()和load_tick_data()加载数据到self.history_data的list中。默认bar模式,进入vnpy.app.cta_strategy.backtesting.load_bar_data(),调用vnpy.trader.database.database_sql.SqlManager.load_bar_data(),它通过peewee的orm库读取数据库.
3.调用vnpy.app.cta_strategy.backtesting.BacktestingEngine.run_backtesting()开始回测.
(1).根据bar还是tick模式,确认进入BacktestingEngine.new_bar()还是BacktestingEngine.new_tick()方法.
(2).进入vnpy.app.cta_strategy.strategies.double_ma_strategy.DoubleMaStrategy.on_init()初始化策略.进入vnpy.app.cta_strategy.template.CtaTemplate.load_bar()初始化加载.
(3).遍历历史K线数据,统计总天数.如果是一个月的分钟线,针对前10根K线(这块没看懂?),每一根K线都进入double_ma_strategy.DoubleMaStrategy.on_bar()方法处理。首先调用vnpy.trader.utility.ArrayManager.update_bar()更新当前K线信息.然后计算短期和长期均线价格,如果短期上穿长期均线,且当前仓位为0,则调用template.CtaTemplate.buy()方法下单买入.下单进入vnpy.app.cta_strategy.template.CtaTemplate.send_order()方法,回测期间该方法返回空.如果短期下穿长期均线,且当前仓位为0,调用vnpy.app.cta_strategy.template.CtaTemplate.short()做空.
(4).调用double_ma_strategy.DoubleMaStrategy.on_start()触发start事件.
(5).调用BacktestingEngine.new_bar()从第10根K线开始回放历史数据.该方法处理逻辑如下:
(5.1)调用BacktestingEngine.cross_limit_order()撮合本地限价单委托,将最新的行情K线或者TICK和策略之前下达的所有委托进行检查,如果能够撮合成交,则返回并记录数据。
(5.2)撮合本地停止单(条件单)委托.
(5.3)调用DoubleMaStrategy.on_bar(),该方法处理逻辑在前面3.(3)已经有介绍.
(5.4)调用BacktestingEngine.update_daily_close()处理每天收盘价后的统计计算逻辑,比如统计盈利交易日数,亏损交易日数.
4.调用BacktestingEngine.calculate_result()计算回测结果盈亏.遍历所有交易,计算当期pnl(profit and loss),turnover(交易量),commission(手续费佣金),slippage(滑点统计),总损益,净损益.
5.调用BacktestingEngine.calculate_statistics()计算策略的汇总统计指标,比如总天数,收益天数,最大回撤,净收益,平均日收益,总佣金,总滑点,总交易量,夏普比率等.
6.进入BacktesterManager.process_backtesting_finished_event()处理回撤结束事件,主要是把回测的结果值写到界面上.
(五).K线图表
入口代码为BacktesterManager.show_candle_chart().获取之前加载的数据库里面的bar数据。
1.调用CandleChartDialog.update_history(),调用vnpy.chart.manager.BarManager.update_history(),调用vnpy.chart.item.ChartItem.update_history()遍历所有K线,调用vnpy.chart.item.CandleItem._draw_bar_picture()通过QT画K线图.
2.获取所有交易记录,调用widget.CandleChartDialog.update_trades()在K线图上标记买卖记录.

Member
avatar
加入于:
帖子: 9
声望: 0

感谢分享,2.0以上的过程是不是跟之前1.x的版本有不同啊

Member
avatar
加入于:
帖子: 8
声望: 0

学习了,谢谢楼主

Member
avatar
加入于:
帖子: 8
声望: 0

很棒

Member
avatar
加入于:
帖子: 18
声望: 0

干货顶,国内的开发者和国外的开发者比起来其实还不是技术差距,可能还是开发规范性上,开源的把代码注释写的越详细,越有利于下一个版本的迭代出新

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】