abu 发表于 2019-11-2 23:01:22

量化投资:第6节 回测结果的度量

前面小节中都使用分解流程方式一步一步实现回测,目的是为了更清晰的说明内部操作流程, 编码过程会显的有些复杂臃肿,但实际上在编写完成一个策略后只需要使用一行代码即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()函数可视化策略持股天数:metrics.plot_keep_days()策略持股天数平均数: 45.429
策略持股天数中位数: 29.000

如下代码通过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    symbolcommissioncumsum
            0   buy 20141024    usAAPL19.04   19.04
            0   buy 20141024    usAAPL19.04   38.08
            0   buy 20141029    usNOAH92.17   130.25
            0   buy 20141029    usBIDU7.81    138.06
            0   buy 20141029    usBIDU7.81    145.87
            0   buy 20141029    usVIPS60.95   206.82
      """
      # 讲date转换为index
      dates_pd = pd.to_datetime(commission_df.date)
      commission = pd.DataFrame(index=dates_pd)
      """
            eg: commission
            2014-10-2419.04
            2014-10-2438.08
            2014-10-29130.25
            2014-10-29138.06
            2014-10-29145.87
            2014-10-29206.82
            2014-11-03265.82
            2014-11-11360.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等工具的使用在后面的章节会有示例讲解演示





页: [1]
查看完整版本: 量化投资:第6节 回测结果的度量