前面小节中都使用分解流程方式一步一步实现回测,目的是为了更清晰的说明内部操作流程, 编码过程会显的有些复杂臃肿,但实际上在编写完成一个策略后只需要使用一行代码即abu.run_loop_back可以完成回测。 详细代码实现请阅读abu.run_loop_back()函数,下面使用run_loop_back()进行策略示例 - <font color="black" style="background-color: white;"># 设置初始资金数
- read_cash = 1000000
- # 设置选股因子,None为不使用选股因子
- stock_pickers = None
- # 买入因子依然延用向上突破因子
- buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak},
- {'xd': 42, 'class': AbuFactorBuyBreak}]
- # 卖出因子继续使用上一节使用的因子
- sell_factors = [
- {'stop_loss_n': 1.0, 'stop_win_n': 3.0,
- 'class': AbuFactorAtrNStop},
- {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},
- {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}
- ]
- # 择时股票池
- choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG',
- 'usTSLA', 'usWUBA', 'usVIPS']
- # 使用run_loop_back运行策略
- abu_result_tuple, kl_pd_manger = abu.run_loop_back(read_cash,
- buy_factors,
- sell_factors,
- stock_pickers,
- choice_symbols=choice_symbols,
- n_folds=2)</font>
复制代码如上代码abu.run_loop_back接口只需要买入策略序列,卖出策略序列等必要的用户参数,不再涉及AbuBenchmark,AbuCapital等对象的构建操作行为。 1. 度量的基本使用方法abu_result_tuple类型为AbuResultTuple对象,AbuMetricsBase类为abupy对回测结果进行度量的基础类,对于基于股票类型的
市场进行的回测可以直接使用,对于其它市场度量类有自己的专属类,如AbuMetricsFutures为对期货进行度量时使用,后面的章节示例期货回测时会示例使用。 首先通过AbuMetricsBase的参数进行结果度量,如下所示: - 输出的文字信息打印了胜率、获利期望、亏损期望、策略收益、买入成交比例等信息
- 第一图为策略收益与基准收益对照
- 第二图为策略收益线性拟合曲线
- 第三图为策略收益资金概率密度图‘
- <font style="background-color: white;"><font style="background-color: white;">metrics = AbuMetricsBase(*abu_result_tuple)
- metrics.fit_metrics()
- metrics.plot_returns_cmp()</font></font>
复制代码
买入后卖出的交易数量:67
买入后尚未卖出的交易数量:3
胜率:55.2239%
平均获利期望:14.1076%
平均亏损期望:-7.8008%
盈亏比:2.2102
策略收益: 48.3078%
基准收益: 15.0841%
策略年化收益: 24.1539%
基准年化收益: 7.5420%
策略买入成交比例:80.0000%
策略资金利用率比例:28.0706%
策略共执行504个交易日
2. 度量的可视化在AbuMetricsBase执行过程中对回测策略的 - 收益, 年化收益
- 胜率, 盈亏比
- 平均获利期望, 平均亏损期望
- 夏普比率, 信息比率
- 策略波动率, 阿尔法, 贝塔
....................
等度量值进行了计算,详情请阅读AbuMetricsBase源代码,关于这些度量值的基础知识请阅读《量化交易之路》中相关章节。 下面示例一些度量值的可视化: 如下代码通过plot_sharp_volatility_cmp()函数可视化策略与基准之间波动率和夏普比率关系:
- <font style="background-color: white;"><font style="background-color: white;">metrics.plot_sharp_volatility_cmp()</font></font>
复制代码
- <font style="background-color: white;"><font style="background-color: white;">alpha阿尔法:0.1899
- beta贝塔:0.1594
- Information信息比率:0.0423
- 策略Sharpe夏普比率: 1.8654
- 基准Sharpe夏普比率: 0.5012
- 策略波动率Volatility: 0.1090
- 基准波动率Volatility: 0.1689</font></font>
复制代码
- <font style="background-color: white;"><span style="color: rgb(0, 0, 0); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family:;" 0px;"="" normal;="" 245);="" 245,="" rgb(245,="" 2;="" pre-wrap;="" !important;="" inline="" none;="" 0px;="" 12px;="" sans-serif;="" new",="" courier=""><font style="background-color: white;">metrics.plot_effect_mean_day()</font></span></font>
复制代码
如下代码通过plot_effect_mean_day()函数可视化策略买入因子生效间隔天数, 统计买入因子的生效间隔,如图9-3所示。不同的类型的买入因子策略在生效周期上差别很大,组合不同特性的买入因子组成良好的买入策略很重要,但是要注意买入因子的组合不是组合的因子越多,优势越大,所有因子的组合、不光是优势的组合,同时也是劣势的组合。
- <font style="background-color: white;">metrics.plot_effect_mean_day()</font>
复制代码
- <font style="background-color: white;">因子平均生效间隔:16.7105263158</font>
复制代码
如下代码通过plot_keep_days()函数可视化策略持股天数: - [backcolor=white]metrics.plot_keep_days()[/backcolor]
复制代码- [backcolor=white]策略持股天数平均数: 45.429
- 策略持股天数中位数: 29.000[/backcolor]
复制代码
如下代码通过plot_sell_factors()函数可视化策略卖出因子生效分布情况:
- <font style="background-color: white;">metrics.plot_sell_factors()</font>
复制代码- <font style="background-color: white;">卖出生效因子分布:
- AbuFactorAtrNStop:stop_loss=1.0 18
- AbuFactorAtrNStop:stop_win=3.0 9
- AbuFactorCloseAtrNStop:close_atr_n=1.5 31
- AbuFactorPreAtrNStop:pre_atr=1.5 9
- dtype: int64</font>
复制代码
plot_max_draw_down()函数中实现了计算最大回撤并可视化:
- <font style="background-color: white;">metrics.plot_max_draw_down()</font>
复制代码
- <font style="background-color: white;">最大回撤: 0.065704
- 最大回测启始时间:2016-04-14, 结束时间2016-07-13, 共回测103775.665000</font>
复制代码
3. 扩展自定义度量类用户可以通过继承AbuMetricsBase,扩展度量值,以及添加其它的度量可视化方法。 如下代码示例子类通过实现: - 扩展_metrics_extend_stats方法,添加交易手续费变化曲线做为度量值
- 添加plot_commission度量可视化方法,可视化收益曲线和手续费曲线之前的关系
- <font style="background-color: white;">from abupy import ABuScalerUtil
- class MetricsDemo(AbuMetricsBase):
- """扩展自定义度量类示例"""
- def _metrics_extend_stats(self):
- """
- 子类可扩展的metrics方法,子类在此方法中可定义自己需要度量的值:
- 本demo示例交易手续费和策略收益之间的度量对比
- """
- commission_df = self.capital.commission.commission_df
- commission_df['commission'] = commission_df.commission.astype(float)
- commission_df['cumsum'] = commission_df.commission.cumsum()
- """
- eg:
- type date symbol commission cumsum
- 0 buy 20141024 usAAPL 19.04 19.04
- 0 buy 20141024 usAAPL 19.04 38.08
- 0 buy 20141029 usNOAH 92.17 130.25
- 0 buy 20141029 usBIDU 7.81 138.06
- 0 buy 20141029 usBIDU 7.81 145.87
- 0 buy 20141029 usVIPS 60.95 206.82
- """
- # 讲date转换为index
- dates_pd = pd.to_datetime(commission_df.date)
- commission = pd.DataFrame(index=dates_pd)
- """
- eg: commission
- 2014-10-24 19.04
- 2014-10-24 38.08
- 2014-10-29 130.25
- 2014-10-29 138.06
- 2014-10-29 145.87
- 2014-10-29 206.82
- 2014-11-03 265.82
- 2014-11-11 360.73
- """
- commission['cum'] = commission_df['cumsum'].values
- self.commission_cum = commission['cum']
- self.commission_sum = self.commission_cum[-1]
- def plot_commission(self):
- """
- 使用计算好的首先费cumsum序列和策略收益cumsum序列进行可视化对比
- 可视化收益曲线和手续费曲线之前的关系
- """
- print('回测周期内手续费共: {:.2f}'.format(self.commission_sum))
- # 使用缩放scaler_xy将两条曲线缩放到同一个级别
- x, y = ABuScalerUtil.scaler_xy(self.commission_cum, self.algorithm_cum_returns, type_look='look_max',
- mean_how=True)
- x.plot(label='commission')
- y.plot(label='algorithm returns')
- plt.legend(loc=2)
- plt.show()</font>
复制代码
上面代码的MetricsDemo类即完成了扩展自定义度量类的实现,它可以使用本前面使用的AbuMetricsBase中任何方法,
如metrics.plot_returns_cmp(),metrics.plot_max_draw_down()等等,它独有度量可视化方法plot_commission():
- <font style="background-color: white;">metrics = MetricsDemo(*abu_result_tuple)
- metrics.fit_metrics()
- metrics.plot_commission()</font>
复制代码
- <font style="background-color: white;">回测周期内手续费共: 4680.93</font>
复制代码
上面通过plot_commission方法中通过ABuScalerUtil.scaler_xy将两条曲线缩放到一个可视化级别上,可视化的目的是更直观的发现策略中的问题,度量值的意义即是提供发现问题的线索值,如上面两条曲线的走势,当策略收益曲线变缓的时候,手续费曲线应该也要随着变缓慢,如果出现两条曲线背离或者完全不跟随的情况,都代表交易策略有问题。 自定义度量类时也一定要以发现问题为目的,提供线索为手段进行度量类的个性化定制。 备注:关于ABuScalerUtil.scaler_xy等工具的使用在后面的章节会有示例讲解演示
|