使用backtrader计算α,β,信息比例等回测指标。
参考:
https://www.r-bloggers.com/stock-trading-analytics-and-optimization-in-python-with-pyfolio-rs-performanceanalytics-and-backtrader/
https://teddykoker.com/2019/05/improving-cross-sectional-mean-reversion-strategy-in-python/
对于框架没有的指标,可以自建分析类,继承自backtrader.Analyzer,实现next()和stop()函数来计算指标,get_analysis()来获取分析结果。然后用addanalyzer()方法将分析类加载到cerebro对象里,这是一种轻量的做法,不需要在分析类里提供数据。
上面文章的作者是调用用R的PerformanceAnalytics库计算指标,我这没成功,搜了一下,用另一个python库,empyreal吧。
使用empyreal需要两个收益率序列,分别是策略的收益率和基准的收益率,这里的收益率是当前交易日相对前一交易日的收益率。对于策略收益率,可以向cerebro里添加TimeReturn分析器获得。
1 | self.__cerebro.addanalyzer(btay.TimeReturn, _name = "TR") |
在运行了回测以后获得策略收益率序列:
1 | self.__returns = pd.Series(self.__results[0].analyzers.TR.get_analysis()) |
基准策略的收益率序列呢?再建一个策略类吧。
1 | # 基准策略类,用于计算α,β等回测指标 |
再用前述方法计算收益率序列。
接着自己定义一个risk分析类。
1 | import empyrical as ey |
运行
OK,有点问题,夏普值Backtrader和empyrical的计算结果有差异,可能参数设置有差异吧。调试一下看看。
用这篇文章 https://www.cnblogs.com/bitquant/p/8432891.html 的数据和例子,用我的程序计算。
1 | if __name__ == "__main__": |
大部分结果跟文章里是一致的,但是阿尔法值文章里是0.7781,Calmar比率为207.1054,这两个值不对。
直接调用empyreal算一下看看。
1 | # 直接调用empyrical试试 |
阿尔法值还是不对,calmar值对了。先改计算calmar的程序。原来是我忘了调用我的类里面计算calmar的程序,加上去就对了。那么阿尔法值呢?
自己算一下:
1 | # 自己计算阿尔法值 |
算出来4.5,差别更大了。换篇文章看看。
http://www.imooc.com/article/293203
1 | # 自己计算阿尔法贝塔 |
1 | 计算结果 |
跟原文的结果一致。下面用empyreal算一下看看。
1 | # 用empyrical计算 |
贝塔值是一样的,阿尔法值差别就大了。
除一下两组阿尔法值:
1 | print(results2["alpha"]/results["alpha"]) |
并不一致。
经过不断试验,发现是参数的问题:
annualization = 1就完全一样啦。这个参数是设置收益率是多长时间间隔的收益率,1代表每天的收益率。
1 | alpha, beta = ey.alpha_beta(returns = stock_ret, factor_returns = mkt_ret, annualization = 1) |
再回测一下双均线策略
现在的问题就剩夏普值的计算了,这又是一个比较重要的数据。还是用一样的方法调试:自己实现一下计算夏普值,再跟empyrical计算的结果对比。
照这篇文章: https://zhuanlan.zhihu.com/p/61949367 的方法来。
1 | # 测试夏普值的计算 |
接下来再用empyrical算。
1 | # 用empyrical算 |
结果还是不对。还是参数问题?改改试试。
把上面程序作为基准的标普500换成固定的年化4%,设定
1 | risk_free = 0.04/252.0 |
empyrical计算程序设定risk_free参数
1 | # 用empyrical算 |
这下对了!说明empyrical算的没问题(废话!),现在来解决我回测中的计算夏普值差异的问题。
搜了一下backtrader的文档,例子里就有计算年化夏普值的程序,照着来吧:
https://www.backtrader.com/docu/analyzers/analyzers/
1 | # 计算年化夏普值,参考backtrader的文档 |
输出结果
还是一个不同于一个啊?再试试SharpeRatio_A分析器吧。
四个不同的结果……先用backtrader框架的数据吧。反正不同的策略对比用的是同一个计算方法。
代码地址还是: https://github.com/zwdnet/MyQuant/tree/master/47
主要修改了backtest.py文件。
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地