前言
一个完整的量化交易系统离不开人机交互功能的应用,特别是在回测阶段,我们需要不断更改参数因子、更换交易策略以应对当前的市场。因此创建完整的、功能键全的GUI用户界面至关重要。
市面上也出现了很多相关的平台,比如米筐Ricequant,聚宽Joinquant,掘金Myquant,优矿Uqer,镭矿Raquant,果仁网,Factors, 宽帮Bigquant, 国泰安,同花顺量化,WIND量化,天软等等。
不过这些通用的回测平台并不能满足个性化的风格需求。于是我们亲自动手搭建了一个本地的量化回测平台。
什么是事件型回测框架
前几期我们搭建了自定义的量化回测框架【搭建系统|想把聚宽本地化吗?一起来创建GUI版的自定义量化回测平台】,这个版本仍然是矢量化回测架构。矢量化回测有它的优势,同样也存在劣势。
我们直接对比来看下两种回测方式的优缺点。
矢量型 | 事件型 | |
数据处理负荷 | 需要在全部交易数据基础上生成信号 | 可以用迭代方式逐个处理交易数据 |
数据处理效率 | 矢量化的数据处理是非常高效的 | for循环级别的处理相对会慢的多 |
实盘贴近程度 | 一次拿到全部数据容易出现未来函数 | 逐个bar给交易数据,贴近实盘 |
实现复杂度 | 就像写表达式一样处理,代码量少 | 复杂许多,因此比较容易出错 |
灵活程度 | 一样的逻辑去处理才能体现矢量化优势 | 可以在分支中增加很多判断,比如涨停板、除权等情况的判断 |
现在市面上倒是有好些事件型的开源量化框架,经过一番的了解和试验,其中的一款backtrader框架相对来说功能完善、扩展灵活、资料也详细,比较适合集成在本地的Python股票量化交易系统中。
如何集成backtrader
backtrader框架使用起来是蛮方便的,使用方法在官方文档上介绍的挺详细。我在掘金小册课程中也提取了一些关键点来介绍。效果图如下所示:
此处我们是集成起来搭建一个基于backtrader的本地回测系统。接下来我们概述下我们主要作的一些改动点。
大体分为两步:
创建一个策略,创建一个策略类,这个类要继承自backtrader.Strategy,然后就可以自定义里面的方法。
策略类中有一个类属性params,用于定义一些在策略中可调参数值
backtrader.indicators内置了许多指标的计算方法,比如移动平均线、MACD、RSI等等,使用时只需要实例化策略中会使用到的技术指标即可
next函数中编写交易策略,也就是进入市场和退出市场的逻辑
创建一个策略决策引擎(原文是Cerebro,这里我用决策这个词)
把定义的策略注入到决策引擎之中
把行情数据注入到决策引擎之中
可视化方式反馈回测结果
此处关于cerebro设置的几个参数,我们通过GUI配置下去,比如手续费、初始资金、交易规模、回测周期等等。
回测的数据格式为PandasData,我们通过API接口下载后,经过转换后使用。
可视化部分会稍微复杂些,因为我们在wxPython中嵌入了matplotlib,所以后端是更改过的,基本上backtrader的绘图就废了。
话说回来,自带的绘图风格我其实也也不是很喜欢,于是就把回测过程中的一些log信息收集下来,二次制作一个绘图函数。
来看下效果图:
从log信息中收集到的关键数据有:收盘价序列、收益序列、买入信号序列、卖出信号序列。
收集下来后,把收盘价绘制为line;买入和卖出为annotate;收益则分成两部分处理,一部分是单次的盈亏用bar表示,另一部分是累积的收益用line表示。
动态修改参数
之前实现的回测过程中,策略是固定在程序文件中的,当我们要修改策略代码的时候需要停止程序,然后再次运行。
能不能直接在线修改策略代码呢?本期我们在此基础上作了以下改进:
1 点击策略列表后 会打开对应的文件
2 在线修改文件中的代码,修改后点击保存
3 点击回测时会重新加载策略函数
策略列表做了一些优化,之前是显示了策略的参数,点击时候仅仅是把参数传递到回测交易信号模块中,这里我们直接关联到了策略的代码,点击之后就会打开py文件,如下图所示:
这一步我们用了wxpython的TextCtrl控件去显示py文件内容(虽然没有pycharm显示那么人性化,但是可以进行简单的代码修改)。
可以注意到在策略列表里面的函数那列,如果没有定义策略的话要在对应的集合中填写未定义,如下所示:
self.colleges = {
u'经典策略': [
{'名称': u'N日突破', '类型': u'趋势', '函数': u'未定义'},
{'名称': u'动能转换', '类型': u'趋势','函数': u'未定义'},
{'名称': u'KDJ峰谷', '类型': u'波动','函数': u'未定义'},
{'名称': u'均线交叉', '类型': u'趋势','函数': u'dua_ma_strategy'}],
u'自定义策略': [
{'名称': u'yx-zl-1', '类型': u'基本面','函数': u'FinanceDatStrategy'},
{'名称': u'yx-zl-2', '类型': u'趋势','函数': u'未定义'},
{'名称': u'yx-zl-3', '类型': u'波动','函数': u'未定义'}]
}
不过可以放心的是,点击的策略如果没有定义函数,我们也做了对话框的提示,如下所示:
修改代码后,点击保存,这样就可以把代码重新回写到py文件中去。
到这一步都算比较简单的,稍有点麻烦的是如何让修改完的代码起作用。
这里涉及到两个小技巧,一个是reload模块的用法,另一个是把字符串转换为函数的方法。每次修改完成后,动态加载下模块,这样即可。
接下来我们展示下效果和操作的方法。
1. 点击策略 —> 修改策略的N1参数 —> 点击保存 —> py文件对应更改。
2. 点击回测 —> 按照最新修改的策略代码执行回测,可以多尝试几次看下是否符合预期。
财务指标策略
以上的展示都是基于双均线策略的,也就是短期均线和长期均线金叉/死叉来进行择时。
建立股票量化策略时,除了使用量价数据计算技术指标型的策略之外,也应该结合个股基本面数据,把它们作为因子加入到策略模型中。将技术面和基本面指标结合起来制定股票量化策略会更有效果。
接下来我们用一个财务数据相关的策略来展示下操作的方法和效果。——通过换手率、市盈率这些涉及到基本面的指标去建立股票择时策略。
1)获取财务数据
我用了我书里介绍的baostock的query_history_k_data_plus()接口。这个接口里面返回的数据类型有我们所要的换手率、滚动市盈率之类的基本面指标。建立的数据结构如下所示:
然后我们要理解换手率、滚动市盈率的含义和用法。
换手率指标是反映市场交易活跃程度最重要的指标,等于某一段时期内的成交量/发行总股数×100%。
对应个股走势的不同阶段,换手率体现的含义也并不相同。比如在底部阶段,某只股票的换手率突然上升,可能意味着有投资者在大量买进,股价可能会随之上扬。如果某只股票持续上涨了一个时期后,换手率又迅速上升,则可能意味着一些获利者要套现,股价可能会下跌。
滚动市盈率表示某只股票每股当天市价与每股盈利的比率,用倍数来表示。运用市盈率指标的比例值,可以估量股票的投资价值,或者在不同的公司之间进行比较。
2)编写策略
了解这两个指标之后,我们开始制定量化策略。
策略逻辑是当该股换手率和市盈率同时处于历史低区域内买入股票,当该股换手率或者市盈率其中一个处于历史高区域内卖出股票。高低区域的阈值我们可以通过统计算法得到。
编写策略在Code_for_strategy.py文件中,方法和backtrader一样。写完后要在策略列表接口中定义名称。
3)回测策略
接下来我们用水晶光电近一年的行情数据来回测这个策略。
我们先选择单独的backtrade框架来回测。如下所示:
此处我们初始资金为100000,最终的总资金为189756.99,净收益为89756.99。不过此处我们只是单纯的用了财务指标,并未添加趋势指标进行叠加分析。实际中需要多个类别的指标共同作用,这样效果会更佳。
这个策略添加到量化小工具之后就可以回测了。
操作流程:点击策略 —> 修改策略的参数 —> 点击保存 —> py文件对应更改 —> 设置回测参数 —> 点击回测 —> 按照最新修改的策略代码执行回测。
左侧的表格显示了回测评估指标,这里提到了最终资金、回撤幅度等等,实际上backtrader内置了很多回测指标,都可以扩展到表格中显示。
最后
本次代码的更改是在往期代码的基础上迭代而成(已上传知识星球)。大家可以留意版本号,利用Pycharm的代码比较功能查看更改的地方(知识星球3-6 如何用Pycharm对文件内容比较)。
加入知识星球获取完整代码
点击【阅读原文】查看目录
更多量化交易内容扫码加入星球!—————————————————元宵大师的量化交易书籍开售!!京东、当当、天猫有售!!加我微信了解详情
微信关注:‘元宵大师带你用Python量化交易’