第32节 策略有效性的验证
作者: 阿布
阿布量化版权所有 未经允许 禁止转载
abu量化系统github地址 (欢迎+star)
上一节讲解资金仓位管理与买入策略搭配的示例,本节讲解策有效性的验证。
首先导入本节需要使用的abupy中的模块:
本节大多数内容无法使用沙盒数据运行,需要下载缓存,百度云地址如下:
csv格式美股,A股,港股,币类,期货6年日k数据 密码: gvtr
1. UI界面: Grid Search寻找策略最优参数
30,31两节都使用了abupy内置的一个长短线买入策略AbuDownUpTrend,策略默认的参数实现如下:
- 寻找长线下跌的股票,比如一个季度(4个月)整体趋势为下跌趋势
- 短线走势上涨的股票,比如一个月整体趋势为上涨趋势
- 最后使用海龟突破的xd日突破策略作为策略最终买入信号
上面策略描述的‘一个季度(4个月)’,‘xd日突破’都是策略的默认参数,通过改变设置因子的默认参数可以修改值,而且做为判断趋势是否为上涨下跌的趋势拟合角度阀值也是可以设置的,如下将策略修改为:
- 寻找长线下跌的股票,过去120个交易日整体趋势为下跌趋势
- 短线走势上涨的股票,过去30个交易日整体趋势为上涨趋势
- 最后使用30日突破策略作为策略最终买入信号
- 判定趋势是否为上涨下跌的拟合角度值为+-4
代码示例如下:
"""
买入策略使用AbuDownUpTrend:
短线基数xd=30: 30个交易日整体趋势为上涨趋势, 长线下跌乘数基数, 海龟突破的30日突破
长线乘数past_factor=4: xd * 4 = 30 * 4 = 120 过去120个交易日整体趋势为下跌趋势
趋势角度阀值down_deg_threshold: 判定趋势是否为上涨下跌的拟合角度值为+-4
"""
buy_factors = [{'class': AbuDownUpTrend, 'xd': 30, 'past_factor': 4, 'down_deg_threshold': -4}]
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}]
# 开始回测
_, _ = run_loo_back(us_choice_symbols, only_info=True)
买入后卖出的交易数量:16
买入后尚未卖出的交易数量:0
胜率:43.7500%
平均获利期望:14.7855%
平均亏损期望:-6.2479%
盈亏比:2.1803
所有交易收益比例和:0.4727
所有交易总盈亏和:249346.0300
从回测结果中可以看到最终收益为正值,由于使用较高的止盈位,偏倚重盈亏比值,胜率不高,最终策略是否应该使用这组参数,即最优参数的选择在‘第7节-寻找策略最优参数和评分’中讲解过,这里不过多赘述,只示例更简洁的接口使用以及ui操作。
首先示例ui界面的操作使用WidgetGridSearch,如下:
备注:
- ui具体操作步骤在之后的视频教程中详细示例
- 更多界面操作请直接运行abupy/abupy_ui/文件夹下的界面功能文件
# 直接启动grid search界面
WidgetGridSearch()()
2. 代码实现Grid Search寻找策略最优参数
如下可以使用GridSearch.grid_search寻找买入AbuDownUpTrend策略参数:
- 短线基数'xd': [20, 30, 40]
- 长线乘数'past_factor': [3, 4, 5]
- 趋势角度阀值'down_deg_threshold': [-2, -3, -4]
寻找卖出AbuFactorAtrNStop策略参数:
- 止损atr倍数stop_loss_n:[0.5, 1.0, 1.5]
- 止盈atr倍数stop_win_n:[0.5, 1.0, 2.0, 3.0]
buy_factors = {'class': AbuDownUpTrend, 'xd': [20, 30, 40],
'past_factor': [3, 4, 5], 'down_deg_threshold': [-2, -3, -4]}
sell_factors = [{'class': AbuFactorAtrNStop, 'stop_loss_n': [0.5, 1.0, 1.5],
'stop_win_n': [0.5, 1.0, 2.0, 3.0]},
]
# 使用类方法GridSearch.grid_search进行最优参数查找
scores, score_tuple_array = GridSearch.grid_search(us_choice_symbols, buy_factors, sell_factors)
最佳买入因子参数组合:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]
最佳卖出因子参数组合:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]
****************************************************************************************************
买入后卖出的交易数量:8
买入后尚未卖出的交易数量:2
胜率:100.0000%
平均获利期望:7.4020%
平均亏损期望:0.0000%
盈亏比:0.0000
所有交易收益比例和:0.5922
所有交易总盈亏和:830148.8000
上述最优结果输出为对所有参数评分结果的最优结果,由于策略的苛刻买入条件导致整体交易数量少,所以很多时候需要根据top n的输出结果来进行筛选使用的最优参数。
使用show_top_score_metrics多显示一些最优结果,top_cnt为正数时显示评分最高的参数组合及回测结果,top_cnt为负数时相反,如下top_cnt=3显示度量结果最好的3组参数组合及回测结果:
GridSearch.show_top_score_metrics(scores, score_tuple_array, top_cnt=3)
买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]
卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]
买入后卖出的交易数量:8
买入后尚未卖出的交易数量:2
胜率:100.0000%
平均获利期望:7.4020%
平均亏损期望:0.0000%
盈亏比:0.0000
所有交易收益比例和:0.5922
所有交易总盈亏和:830148.8000
买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]
卖出策略:[{'stop_loss_n': 1.5, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]
买入后卖出的交易数量:8
买入后尚未卖出的交易数量:2
胜率:100.0000%
平均获利期望:7.4020%
平均亏损期望:0.0000%
盈亏比:0.0000
所有交易收益比例和:0.5922
所有交易总盈亏和:830148.8000
买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -4}]
卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]
买入后卖出的交易数量:7
买入后尚未卖出的交易数量:1
胜率:100.0000%
平均获利期望:7.8207%
平均亏损期望:0.0000%
盈亏比:0.0000
所有交易收益比例和:0.5475
所有交易总盈亏和:740741.1400
如下top_cnt=-1显示度量结果最差的回测参数组合及回测结果:
GridSearch.show_top_score_metrics(scores, score_tuple_array, top_cnt=-1)
买入策略:[{'past_factor': 3, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 30, 'down_deg_threshold': -4}]
卖出策略:[{'stop_loss_n': 1.5, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 3.0}]
买入后卖出的交易数量:6
买入后尚未卖出的交易数量:1
胜率:-100.0000%
平均获利期望:0.0000%
平均亏损期望:-19.4947%
盈亏比:0.0000
所有交易收益比例和:-1.1697
所有交易总盈亏和:-1319405.8000
3 交叉相关性策略验证
通过gird search可以暂时选定策略的参数,但是进一步验证策略的有效性,普适性就需要扩大策略的回测范围以及symbol数量,可以使用全市场对策略进行多年的历史回测来验证策略的有效性,但更推荐使用abupy中内置的交叉相关性策略验证模块,它整体思路如下:
- 选择一个市场中所有的symbol,计算所有的symbol与大盘指标的相关系数值
- 根据计算出的相关系数值将全市场中的symbol切分成多个组
- 依次从各个symbol相关系数组中多次进行抽取几个symbol进行历史交易策略回测
- 合并计算所有相关系数组的交易回测度量结果,进行输出
- 合并计算每一个相关系数组中多次进行抽取的symbol的交易回测度量结果,进行输出
abupy中内置的AbuCrossVal实现了上述功能,下面为使用示例:
首先使用上面grid search结果的top1参数组合进行验证:
- 买入策略:[{'past_factor': 3, 'xd': 30, 'down_deg_threshold': -4}]
- 卖出策略:[{'stop_loss_n': 1.5, 'stop_win_n': 3.0}]
代码如下所示:
# 交叉相关性策略验证只支持本地非沙盒数据模式
abupy.env.disable_example_env_ipython()
# 使用上面grid search结果的top1参数组合进行验证
buy_factors = [{'class': AbuDownUpTrend, 'down_deg_threshold': -2, 'past_factor': 5, 'xd': 20}]
sell_factors = [{'stop_loss_n': 1, 'stop_win_n': 0.5,
'class': AbuFactorAtrNStop},
{'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},
{'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]
cross_val = AbuCrossVal()
cross_val.fit(buy_factors, sell_factors, cv=10)
所有交叉验证交易度量结果如下:
买入后卖出的交易总数量:1945
胜率:63.6504%
平均获利期望:5.4986%
平均亏损期望:-8.9359%
盈亏比:1.3633
所有交易收益比例和:3.2719
所有交易总盈亏和:8013432.8000
与大盘相关度范围:(-0.983, 0.0585]验证结果如下:
买入后卖出的交易总数量:118
胜率:55.9322%
平均获利期望:7.0492%
平均亏损期望:-17.2657%
盈亏比:1.2400
所有交易收益比例和:-2.0740
所有交易总盈亏和:-1575194.6300
与大盘相关度范围:(0.0585, 0.123]验证结果如下:
买入后卖出的交易总数量:163
胜率:52.7607%
平均获利期望:7.0947%
平均亏损期望:-9.5202%
盈亏比:1.0002
所有交易收益比例和:-1.2498
所有交易总盈亏和:-653173.8900
与大盘相关度范围:(0.197, 0.266]验证结果如下:
买入后卖出的交易总数量:180
胜率:61.6667%
平均获利期望:6.8414%
平均亏损期望:-10.3985%
盈亏比:1.2672
所有交易收益比例和:0.2082
所有交易总盈亏和:549301.5200
与大盘相关度范围:(0.544, 0.982]验证结果如下:
买入后卖出的交易总数量:173
胜率:76.3006%
平均获利期望:3.2808%
平均亏损期望:-5.5625%
盈亏比:2.1738
所有交易收益比例和:2.0364
所有交易总盈亏和:3690507.2200
与大盘相关度范围:(0.123, 0.197]验证结果如下:
买入后卖出的交易总数量:174
胜率:54.5977%
平均获利期望:5.5889%
平均亏损期望:-10.6108%
盈亏比:0.7840
所有交易收益比例和:-2.9575
所有交易总盈亏和:-3593232.6200
与大盘相关度范围:(0.41, 0.469]验证结果如下:
买入后卖出的交易总数量:212
胜率:67.9245%
平均获利期望:4.3265%
平均亏损期望:-7.4523%
盈亏比:1.7431
所有交易收益比例和:1.1322
所有交易总盈亏和:1125995.4000
与大盘相关度范围:(0.469, 0.544]验证结果如下:
买入后卖出的交易总数量:219
胜率:67.1233%
平均获利期望:4.2240%
平均亏损期望:-6.0844%
盈亏比:1.4474
所有交易收益比例和:1.8658
所有交易总盈亏和:3026834.9100
与大盘相关度范围:(0.266, 0.314]验证结果如下:
买入后卖出的交易总数量:224
胜率:62.5000%
平均获利期望:6.5416%
平均亏损期望:-10.4021%
盈亏比:1.1344
所有交易收益比例和:0.3893
所有交易总盈亏和:538029.9900
与大盘相关度范围:(0.314, 0.362]验证结果如下:
买入后卖出的交易总数量:228
胜率:69.2982%
平均获利期望:5.2076%
平均亏损期望:-7.6170%
盈亏比:1.5337
所有交易收益比例和:2.7967
所有交易总盈亏和:3560297.7700
与大盘相关度范围:(0.362, 0.41]验证结果如下:
买入后卖出的交易总数量:254
胜率:62.5984%
平均获利期望:5.6700%
平均亏损期望:-8.3927%
盈亏比:1.2261
所有交易收益比例和:1.1247
所有交易总盈亏和:1344067.1300
上最终输出为
- 合并计算所有相关系数组的交易回测度量结果
- 合并计算每一个相关系数组中多次进行抽取的symbol的交易回测度量结果
- 由于涉及随机抽取所以这里每次的运行结果都会不一样
有效性判定需要根据整体策略的风格来判断:
上面的激进风格的止盈止损设置,止盈位倍数(1) < 止损位倍数(0.5),且值偏低:
- 代表交易策略整体风格为均值回复类型
- 需要交叉相关性分组结果的高胜率,盈亏比可以偏低
- 注意很多组的平均获利期望都比平均亏损期望低。
普适性的判定需要在有效性的基础上针对不同相关性组进行判定:
- 上面回测结果中所有相关性回测组的胜率都大于55%, 一定程度代表普适性很好
- 一般10组中有7组以上符合判定就可以认为策略良好。
上面的运行结果由于使用随机抽取的原因每一次的运行结果都不同,所以可以多运行几次,也可以切换不同的交易市场进行验证。
上面验证策略使用了低止盈位形成的整体策略风格为均值回复,如果要构建整体策略风格为趋势跟踪需要比较高的止盈位,但上面使用
GridSearch.show_top_score_metrics
输出前top个结果都是均值回复类型的策略参数,可以使用
GridSearch.show_top_constraints_metrics
限制top的排序结果,比如下面的示例要求止盈位stop_win_n的值为3.0的情况下上面所有度量结果的排序top,代码如下所示:
def constraints(scores, score_tuple_array, top_cnt):
result_top = []
for sc_ind in scores.index:
for sell_factor in score_tuple_array[sc_ind].sell_factors:
if 'stop_win_n' in sell_factor and sell_factor['stop_win_n'] == 3.0:
result_top.append(score_tuple_array[sc_ind])
if len(result_top) >= top_cnt:
return result_top
return result_top
# top_cnt=1:输出stop_win_n=3.0下最好的参数组合度量结果
GridSearch.show_top_constraints_metrics(constraints, scores, score_tuple_array, top_cnt=1)
买入策略:[{'past_factor': 4, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -4}]
卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 3.0}]
买入后卖出的交易数量:3
买入后尚未卖出的交易数量:2
胜率:66.6667%
平均获利期望:47.5159%
平均亏损期望:-23.5175%
盈亏比:5.2488
所有交易收益比例和:0.7151
所有交易总盈亏和:1006187.3100
上面带参数限制条件的输出即为止盈位为3.0情况下的最好度量结果以及参数组合。
下面将带参数限制条件的top1参数组合进行相关交叉验证:
- 买入策略:[{'past_factor': 4, 'xd': 20, 'down_deg_threshold': -4}]
- 卖出策略:[{'stop_loss_n': 1.0, 'stop_win_n': 3.0}]
代码以及运行结果如下所示:
# grid search结果的带参数限制条件的top1参数
buy_factors = [{'class': AbuDownUpTrend, 'down_deg_threshold': -3, 'past_factor': 4, 'xd': 20}]
# 限制条件为stop_win_n值为3.0
sell_factors = [{'stop_loss_n': 1.5, 'stop_win_n': 3.0,
'class': AbuFactorAtrNStop},
{'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},
{'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]
cross_val.fit(buy_factors, sell_factors, cv=10)
所有交叉验证交易度量结果如下:
买入后卖出的交易总数量:1328
胜率:48.8705%
平均获利期望:9.6774%
平均亏损期望:-8.7472%
盈亏比:2.1089
所有交易收益比例和:1.0916
所有交易总盈亏和:8305731.2200
与大盘相关度范围:(-0.983, 0.0585]验证结果如下:
买入后卖出的交易总数量:75
胜率:37.3333%
平均获利期望:10.0744%
平均亏损期望:-14.9680%
盈亏比:0.7145
所有交易收益比例和:-4.1668
所有交易总盈亏和:-3601348.9600
与大盘相关度范围:(0.0585, 0.123]验证结果如下:
买入后卖出的交易总数量:101
胜率:36.6337%
平均获利期望:9.3515%
平均亏损期望:-10.3681%
盈亏比:0.6095
所有交易收益比例和:-3.4743
所有交易总盈亏和:-3219578.7800
与大盘相关度范围:(0.123, 0.197]验证结果如下:
买入后卖出的交易总数量:108
胜率:50.0000%
平均获利期望:12.2473%
平均亏损期望:-12.8210%
盈亏比:1.2057
所有交易收益比例和:-0.3560
所有交易总盈亏和:44971.2800
与大盘相关度范围:(0.544, 0.982]验证结果如下:
买入后卖出的交易总数量:120
胜率:62.5000%
平均获利期望:6.3188%
平均亏损期望:-4.0046%
盈亏比:8.9209
所有交易收益比例和:3.0121
所有交易总盈亏和:5099296.6300
与大盘相关度范围:(0.197, 0.266]验证结果如下:
买入后卖出的交易总数量:126
胜率:42.8571%
平均获利期望:15.3035%
平均亏损期望:-9.5645%
盈亏比:2.0687
所有交易收益比例和:3.0370
所有交易总盈亏和:4552595.3600
与大盘相关度范围:(0.41, 0.469]验证结果如下:
买入后卖出的交易总数量:137
胜率:51.0949%
平均获利期望:9.0096%
平均亏损期望:-8.3197%
盈亏比:2.4406
所有交易收益比例和:0.7406
所有交易总盈亏和:1408590.9800
与大盘相关度范围:(0.266, 0.314]验证结果如下:
买入后卖出的交易总数量:164
胜率:41.4634%
平均获利期望:10.6555%
平均亏损期望:-10.2247%
盈亏比:0.8248
所有交易收益比例和:-2.6424
所有交易总盈亏和:-3668550.9500
与大盘相关度范围:(0.469, 0.544]验证结果如下:
买入后卖出的交易总数量:149
胜率:55.7047%
平均获利期望:6.7706%
平均亏损期望:-5.3619%
盈亏比:1.8350
所有交易收益比例和:2.0410
所有交易总盈亏和:3239663.5600
与大盘相关度范围:(0.362, 0.41]验证结果如下:
买入后卖出的交易总数量:170
胜率:50.0000%
平均获利期望:8.7658%
平均亏损期望:-7.9418%
盈亏比:1.3457
所有交易收益比例和:0.6577
所有交易总盈亏和:1701122.0400
与大盘相关度范围:(0.314, 0.362]验证结果如下:
买入后卖出的交易总数量:178
胜率:53.3708%
平均获利期望:9.3338%
平均亏损期望:-7.9238%
盈亏比:1.4177
所有交易收益比例和:2.2426
所有交易总盈亏和:2748970.0600
上面的整体风格的止盈止损设置,止盈位倍数(3.0) >> 止损位倍数(1.0),止盈位偏高:
- 代表交易策略整体风格为趋势跟踪类型
- 总体交叉验证交易度量胜率低于50%符合趋势跟踪风格,
- 所有平均获利期望 > 平均亏损期望低。
- 有一组相关回测组的胜率以及盈亏比都偏低导致收益总盈亏为负值
为保证策略的有效,可以多次运行进行验证。
fit运行后所有的交易回测结果都可以使用show_cross_val_se进行查看,通过start,end参数设置游标,如下示例:
cross_val.show_cross_val_se(start=8, end=10)
回测symbol:['usPVTD' 'usNQP' 'usLXP-C' 'usHTF' 'usEVHC' 'usEGT' 'usCIZN' 'usDGICB'
'usMPB' 'usDTUL']
回测symbol与大盘相关度范围:(-0.983, 0.0585]
买入后卖出的交易数量:5
买入后尚未卖出的交易数量:0
胜率:40.0000%
平均获利期望:7.0152%
平均亏损期望:-8.2043%
盈亏比:1.0766
所有交易收益比例和:-0.0238
所有交易总盈亏和:15266.0900
回测symbol:['usAMRS' 'usHBANP' 'usSIEB' 'usNXJ' 'usKTN' 'usSD' 'usTDI' 'usTCI'
'usXPLR' 'usNYMX']
回测symbol与大盘相关度范围:(-0.983, 0.0585]
买入后卖出的交易数量:15
买入后尚未卖出的交易数量:0
胜率:26.6667%
平均获利期望:15.7032%
平均亏损期望:-19.8829%
盈亏比:0.4019
所有交易收益比例和:-1.5590
所有交易总盈亏和:-1278037.9400
4. 人工分析比人工智能要聪明, 懂事
除了上述最终度量结果做为策略最终有效性,普适性的判别标准外,还可以把上面相关交叉验证回测的所有交易都通过可视化接口保存在本地,然后一个一个的查看交易的买入点与卖出点,排查策略是否存在问题,以及是否存在改进方案等。
可以使用plot_all_cross_val_orders接口对交叉验证回测的所有交易进行保存,保存结果如下所示:
备注:再次强调:对交易策略结果的人工分析,注重分析失败的结果以及是否存在改进方案,改进方案是否会引进新的问题是非常重要的,不要排斥人工, 人工分析比人工智能要聪明, 懂事。
cross_val.plot_all_cross_val_orders()
保存完成后,快照将保存在~/abu/data/save_png下当前日期的文件夹中,可使用如下命令直接打开查看:
if abupy.env.g_is_mac_os:
!open $abupy.env.g_project_data_dir
else:
!echo $abupy.env.g_project_data_dir
5. UI界面: 交叉相关性策略验证
与寻找最优参数类似,可以使用WidgetCrossVal进行界面操作进行交叉相关性策略验证,如下:
备注:
- ui具体操作步骤在之后的视频教程中详细示例
- 更多界面操作请直接运行abupy/abupy_ui/文件夹下的界面功能文件
WidgetCrossVal()()
abu量化文档目录章节
- 择时策略的开发
- 择时策略的优化
- 滑点策略与交易手续费
- 多支股票择时回测与仓位管理
- 选股策略的开发
- 回测结果的度量
- 寻找策略最优参数和评分
- A股市场的回测
- 港股市场的回测
- 比特币,莱特币的回测
- 期货市场的回测
- 机器学习与比特币示例
- 量化技术分析应用
- 量化相关性分析应用
- 量化交易和搜索引擎
- UMP主裁交易决策
- UMP边裁交易决策
- 自定义裁判决策交易
- 数据源
- A股全市场回测
- A股UMP决策
- 美股全市场回测
- 美股UMP决策
更多关于abu量化系统请关注微信公众号: abu_quant