# -*- encoding:utf-8 -*-from __future__ import print_functionimport matplotlib.pyplot as pltimport seaborn as snsimport numpy as npimport warnings# noinspection PyUnresolvedReferencesimport abu_local_envimport abupyfrom abupy import AbuMetricsBasefrom abupy import AbuFactorBuyBreakfrom abupy import AbuFactorAtrNStopfrom abupy import AbuFactorPreAtrNStopfrom abupy import AbuFactorCloseAtrNStop# run_loop_back等一些常用且最外层的方法定义在abu中from abupy import abuwarnings.filterwarnings('ignore')sns.set_context(rc={'figure.figsize': (14, 7)})# 使用沙盒数据,目的是和书中一样的数据环境abupy.env.enable_example_env_ipython()# 设置选股因子,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}]"""第九章 量化系统——度量与优化abu量化系统github地址:https://github.com/bbfamily/abu (您的star是我的动力!)abu量化文档教程ipython notebook:https://github.com/bbfamily/abu/tree/master/abupy_lecture"""def sample_91(show=True):"""9.1 度量的基本使用方法:return:"""# 设置初始资金数read_cash = 1000000# 择时股票池choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG','usTSLA', 'usWUBA', 'usVIPS']# 使用run_loop_back运行策略abu_result_tuple, kl_pd_manager = abu.run_loop_back(read_cash,buy_factors,sell_factors,stock_pickers,choice_symbols=choice_symbols, n_folds=2)metrics = AbuMetricsBase(*abu_result_tuple)metrics.fit_metrics()if show:metrics.plot_returns_cmp()return metricsdef sample_922():"""9.2.2 度量的可视化:return:"""metrics = sample_91(show=False)metrics.plot_sharp_volatility_cmp()plt.show()def sharpe(rets, ann=252):return rets.mean() / rets.std() * np.sqrt(ann)print('策略sharpe值计算为={}'.format(sharpe(metrics.algorithm_returns)))metrics.plot_effect_mean_day()plt.show()metrics.plot_keep_days()plt.show()metrics.plot_sell_factors()plt.show()metrics.plot_max_draw_down()plt.show()"""9.3 基于grid search寻找因子最优参数"""stop_win_range = np.arange(2.0, 4.5, 0.5)stop_loss_range = np.arange(0.5, 2, 0.5)sell_atr_nstop_factor_grid = {'class': [AbuFactorAtrNStop],'stop_loss_n': stop_loss_range,'stop_win_n': stop_win_range}close_atr_range = np.arange(1.0, 4.0, 0.5)pre_atr_range = np.arange(1.0, 3.5, 0.5)sell_atr_pre_factor_grid = {'class': [AbuFactorPreAtrNStop],'pre_atr_n': pre_atr_range}sell_atr_close_factor_grid = {'class': [AbuFactorCloseAtrNStop],'close_atr_n': close_atr_range}def sample_931():"""9.3.1 参数取值范围:return:"""print('止盈参数stop_win_n设置范围:{}'.format(stop_win_range))print('止损参数stop_loss_n设置范围:{}'.format(stop_loss_range))print('暴跌保护止损参数pre_atr_n设置范围:{}'.format(pre_atr_range))print('盈利保护止盈参数close_atr_n设置范围:{}'.format(close_atr_range))def sample_932(show=True):"""9.3.2 参数进行排列组合:return:"""from abupy import ABuGridHelpersell_factors_product = ABuGridHelper.gen_factor_grid(ABuGridHelper.K_GEN_FACTOR_PARAMS_SELL,[sell_atr_nstop_factor_grid, sell_atr_pre_factor_grid, sell_atr_close_factor_grid])if show:print('卖出因子参数共有{}种组合方式'.format(len(sell_factors_product)))print('卖出因子组合0形式为{}'.format(sell_factors_product[0]))buy_bk_factor_grid1 = {'class': [AbuFactorBuyBreak],'xd': [42]}buy_bk_factor_grid2 = {'class': [AbuFactorBuyBreak],'xd': [60]}buy_factors_product = ABuGridHelper.gen_factor_grid(ABuGridHelper.K_GEN_FACTOR_PARAMS_BUY, [buy_bk_factor_grid1, buy_bk_factor_grid2])if show:print('买入因子参数共有{}种组合方式'.format(len(buy_factors_product)))print('买入因子组合形式为{}'.format(buy_factors_product))return sell_factors_product, buy_factors_productdef sample_933():"""9.3.3 GridSearch寻找最优参数:return:"""from abupy import GridSearchread_cash = 1000000choice_symbols = ['usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG','usTSLA', 'usWUBA', 'usVIPS']sell_factors_product, buy_factors_product = sample_932(show=False)grid_search = GridSearch(read_cash, choice_symbols,buy_factors_product=buy_factors_product,sell_factors_product=sell_factors_product)from abupy import ABuFileUtil"""注意下面的运行耗时大约1小时多,如果所有cpu都用上的话,也可以设置n_jobs为 < cpu进程数,一边做其它的一边跑"""# 运行GridSearch n_jobs=-1启动cpu个数的进程数scores, score_tuple_array = grid_search.fit(n_jobs=-1)"""针对运行完成输出的score_tuple_array可以使用dump_pickle保存在本地,以方便修改其它验证效果。"""ABuFileUtil.dump_pickle(score_tuple_array, '../gen/score_tuple_array')print('组合因子参数数量{}'.format(len(buy_factors_product) * len(sell_factors_product)))print('最终评分结果数量{}'.format(len(scores)))best_score_tuple_grid = grid_search.best_score_tuple_gridAbuMetricsBase.show_general(best_score_tuple_grid.orders_pd, best_score_tuple_grid.action_pd,best_score_tuple_grid.capital, best_score_tuple_grid.benchmark)def sample_934():"""9.3.4 度量结果的评分:return:"""from abupy import ABuFileUtilscore_fn = '../gen/score_tuple_array'if not ABuFileUtil.file_exist(score_fn):print('../gen/score_tuple_array not exist! please execute sample_933 first!')return"""直接读取本地序列化文件"""score_tuple_array = ABuFileUtil.load_pickle(score_fn)from abupy import WrsmScorer# 实例化一个评分类WrsmScorer,它的参数为之前GridSearch返回的score_tuple_array对象scorer = WrsmScorer(score_tuple_array)print('scorer.score_pd.tail():\n', scorer.score_pd.tail())# score_tuple_array[658]与grid_search.best_score_tuple_grid是一致的sfs = scorer.fit_score()# 打印前15个高分组合print('sfs[::-1][:15]:\n', sfs[::-1][:15])def sample_935_1():"""9.3.5_1 不同权重的评分: 只考虑投资回报来评分:return:"""from abupy import ABuFileUtilscore_fn = '../gen/score_tuple_array'if not ABuFileUtil.file_exist(score_fn):print('../gen/score_tuple_array not exist! please execute sample_933 first!')return"""直接读取本地序列化文件"""score_tuple_array = ABuFileUtil.load_pickle(score_fn)from abupy import WrsmScorer# 实例化WrsmScorer,参数weights,只有第二项为1,其他都是0,# 代表只考虑投资回报来评分scorer = WrsmScorer(score_tuple_array, weights=[0, 1, 0, 0])# 返回排序后的队列scorer_returns_max = scorer.fit_score()# 因为是倒序排序,所以index最后一个为最优参数best_score_tuple_grid = score_tuple_array[scorer_returns_max.index[-1]]# 由于篇幅,最优结果只打印文字信息AbuMetricsBase.show_general(best_score_tuple_grid.orders_pd,best_score_tuple_grid.action_pd,best_score_tuple_grid.capital,best_score_tuple_grid.benchmark,only_info=True)# 最后打印出只考虑投资回报下最优结果使用的买入策略和卖出策略print('best_score_tuple_grid.buy_factors, best_score_tuple_grid.sell_factors:\n', best_score_tuple_grid.buy_factors,best_score_tuple_grid.sell_factors)def sample_935_2():"""9.3.5_2 不同权重的评分: 只考虑胜率:return:"""from abupy import ABuFileUtilscore_fn = '../gen/score_tuple_array'if not ABuFileUtil.file_exist(score_fn):print('../gen/score_tuple_array not exist! please execute sample_933 first!')return"""直接读取本地序列化文件"""score_tuple_array = ABuFileUtil.load_pickle(score_fn)from abupy import WrsmScorer# 只有第一项为1,其他都是0代表只考虑胜率来评分scorer = WrsmScorer(score_tuple_array, weights=[1, 0, 0, 0])# 返回按照评分排序后的队列scorer_returns_max = scorer.fit_score()# index[-1]为最优参数序号best_score_tuple_grid = score_tuple_array[scorer_returns_max.index[-1]]AbuMetricsBase.show_general(best_score_tuple_grid.orders_pd,best_score_tuple_grid.action_pd,best_score_tuple_grid.capital,best_score_tuple_grid.benchmark,only_info=False)# 最后打印出只考虑胜率下最优结果使用的买入策略和卖出策略print('best_score_tuple_grid.buy_factors, best_score_tuple_grid.sell_factors:\n', best_score_tuple_grid.buy_factors,best_score_tuple_grid.sell_factors)"""9.4 资金限制对度量的影响如下内容不能使用沙盒环境, 建议对照阅读:abu量化文档-第十九节 数据源第20节 美股交易UMP决策"""def sample_94_1():"""9.4_1 下载市场中所有股票的6年数据,如果没有运行过abu量化文档-第十九节 数据源:中使用腾讯数据源进行数据更新,需要运行如果运行过就不要重复运行了:"""from abupy import EMarketTargetType, EMarketSourceType, EDataCacheType# 关闭沙盒数据环境abupy.env.disable_example_env_ipython()abupy.env.g_market_source = EMarketSourceType.E_MARKET_SOURCE_txabupy.env.g_data_cache_type = EDataCacheType.E_DATA_CACHE_CSV# 首选这里预下载市场中所有股票的6年数据(做5年回测,需要预先下载6年数据)abu.run_kl_update(start='2011-08-08', end='2017-08-08', market=EMarketTargetType.E_MARKET_TARGET_US)def sample_94_2(from_cache=False):"""9.4_2 使用切割训练集测试集模式,且生成交易特征,回测训练集交易数据, mac pro顶配大概下面跑了4个小时:return:"""# 关闭沙盒数据环境abupy.env.disable_example_env_ipython()from abupy import EMarketDataFetchMode# 因为sample_94_1下载了预先数据,使用缓存,设置E_DATA_FETCH_FORCE_LOCALabupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_FORCE_LOCAL# 回测生成买入时刻特征abupy.env.g_enable_ml_feature = True# 回测将symbols切割分为训练集数据和测试集数据abupy.env.g_enable_train_test_split = True# 下面设置回测时切割训练集,测试集使用的切割比例参数,默认为10,即切割为10份,9份做为训练,1份做为测试,# 由于美股股票数量多,所以切割分为4份,3份做为训练集,1份做为测试集abupy.env.g_split_tt_n_folds = 4from abupy import EStoreAbuif from_cache:abu_result_tuple = \abu.load_abu_result_tuple(n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='train_us')else:# 初始化资金200万,资金管理依然使用默认atrread_cash = 5000000# 每笔交易的买入基数资金设置为万分之15abupy.beta.atr.g_atr_pos_base = 0.0015# 使用run_loop_back运行策略,因子使用和之前一样,# choice_symbols=None为全市场回测,5年历史数据回测# 不同电脑运行速度差异大,mac pro顶配大概下面跑了4小时# choice_symbols=None为全市场回测,5年历史数据回测abu_result_tuple, _ = abu.run_loop_back(read_cash,buy_factors, sell_factors,stock_pickers,choice_symbols=None,start='2012-08-08', end='2017-08-08')# 把运行的结果保存在本地,以便之后分析回测使用,保存回测结果数据代码如下所示abu.store_abu_result_tuple(abu_result_tuple, n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='train_us')print('abu_result_tuple.action_pd.deal.value_counts():\n', abu_result_tuple.action_pd.deal.value_counts())metrics = AbuMetricsBase(*abu_result_tuple)metrics.fit_metrics()metrics.plot_returns_cmp(only_show_returns=True)def sample_94_3(from_cache=False, show=True):"""9.4_3 使用切割好的测试数据集快,mac pro顶配大概下面跑了半个小时:return:"""# 关闭沙盒数据环境abupy.env.disable_example_env_ipython()from abupy import EMarketDataFetchMode# 因为sample_94_1下载了预先数据,使用缓存,设置E_DATA_FETCH_FORCE_LOCALabupy.env.g_data_fetch_mode = EMarketDataFetchMode.E_DATA_FETCH_FORCE_LOCALabupy.env.g_enable_train_test_split = False# 使用切割好的测试数据abupy.env.g_enable_last_split_test = True# 回测生成买入时刻特征abupy.env.g_enable_ml_feature = Truefrom abupy import EStoreAbuif from_cache:abu_result_tuple_test = \abu.load_abu_result_tuple(n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='test_us')else:read_cash = 5000000abupy.beta.atr.g_atr_pos_base = 0.007choice_symbols = Noneabu_result_tuple_test, kl_pd_manager_test = abu.run_loop_back(read_cash,buy_factors, sell_factors, stock_pickers,choice_symbols=choice_symbols, start='2012-08-08',end='2017-08-08')abu.store_abu_result_tuple(abu_result_tuple_test, n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='test_us')print('abu_result_tuple_test.action_pd.deal.value_counts():\n', abu_result_tuple_test.action_pd.deal.value_counts())metrics = AbuMetricsBase(*abu_result_tuple_test)metrics.fit_metrics()if show:metrics.plot_returns_cmp(only_show_returns=True)return metricsdef sample_94_4(from_cache=False):"""满仓乘数9.4_4 《量化交易之路》中通过把初始资金扩大到非常大,但是每笔交易的买入基数却不增高,来使交易全部都成交,再使用满仓乘数的示例,由于需要再次进行全市场回测,比较耗时。下面直接示例通过AbuMetricsBase中的transform_to_full_rate_factor接口将之前的回测结果转换为使用大初始资金回测的结果:return:"""metrics_test = sample_94_3(from_cache=True, show=False)from abupy import EStoreAbuif from_cache:test_us_fr = abu.load_abu_result_tuple(n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='test_us_full_rate')# 本地读取后使用AbuMetricsBase构造度量对象,参数enable_stocks_full_rate_factor=True, 即使用满仓乘数test_frm = AbuMetricsBase(test_us_fr.orders_pd, test_us_fr.action_pd, test_us_fr.capital, test_us_fr.benchmark,enable_stocks_full_rate_factor=True)test_frm.fit_metrics()else:test_frm = metrics_test.transform_to_full_rate_factor(n_process_kl=4, show=False)# 转换后保存起来,下次直接读取,不用再转换了from abupy import AbuResultTupletest_us_fr = AbuResultTuple(test_frm.orders_pd, test_frm.action_pd, test_frm.capital, test_frm.benchmark)abu.store_abu_result_tuple(test_us_fr, n_folds=5, store_type=EStoreAbu.E_STORE_CUSTOM_NAME,custom_name='test_us_full_rate')"""使用test_frm进行度量结果可以看到所有交易都顺利成交了,策略买入成交比例:100.0000%,但资金利用率显然过低,它导致基准收益曲线和策略收益曲线不在一个量级上,无法有效的进行对比"""AbuMetricsBase.show_general(test_frm.orders_pd,test_frm.action_pd, test_frm.capital, test_frm.benchmark, only_show_returns=True)"""转换出来的test_frm即是一个使用满仓乘数的度量对象,下面使用test_frm直接进行满仓度量即可"""print(type(test_frm))test_frm.plot_returns_cmp(only_show_returns=True)# 如果不需要与基准进行对比,最简单的方式是使用plot_order_returns_cmpmetrics_test.plot_order_returns_cmp()"""其它市场的回测, A股市场回测全局设置请阅读abu量化文档相关章节"""if __name__ == "__main__":sample_91()# sample_922()# sample_931()# sample_932()# 耗时操作# sample_933()# sample_934()# sample_935_1()# sample_935_2()# sample_94_1()# sample_94_2()# sample_94_2(from_cache=True)# sample_94_3()# sample_94_3(from_cache=True)# sample_94_4()# sample_94_4(from_cache=True)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。