|
|
|
|
移动端

2.4.1 itertools的使用

《量化交易之路:用Python做股票量化分析》第2章量化语言——Python,第2部分(第2~6章)主要讲解了量化交易需要的基础知识及相关工具,如Python语言、NumPy、pandas、数据可视化及量化数学等知识,适合完全没有任何编程经验的读者从头开始阅读。本节为大家介绍itertools的使用。

作者:阿布来源:机械工业出版社|2017-10-19 16:40

技术沙龙 | 6月30日与多位专家探讨技术高速发展下如何应对运维新挑战!


2.4  性能效率

2.4.1  itertools的使用

标准库中的itertools提供了很多生成循环器的工具,其中很重要的用途是生成集合中所有可能方式的元素排列或组合。在量化数据处理中经常需要使用itertools来完成数据的各种排列组合以寻找最优参数。

  1. import itertools 

(1)permutations()函数,考虑顺序组合元素,示例如下:

  1. items = [1, 2, 3]  
  2. for item in itertools.permutations(items):  
  3.     print(item) 

输出如下:

  1. (1, 2, 3)  
  2. (1, 3, 2)  
  3. (2, 1, 3)  
  4. (2, 3, 1)  
  5. (3, 1, 2)  
  6. (3, 2, 1) 

(2)combinations()函数,不考虑顺序,不放回数据,示例如下:

  1. for item in itertools.combinations(items, 2):  
  2.     print(item) 

输出如下:

  1. (1, 2)  
  2. (1, 3)  
  3. (2, 3) 

(3)combinations_with_replacement()函数,不考虑顺序,有放回数据,示例如下:

  1. for item in itertools.combinations_with_replacement(items, 2):  
  2.     print(item) 

输出如下:

  1. (1, 1)  
  2. (1, 2)  
  3. (1, 3)  
  4. (2, 2)  
  5. (2, 3)  
  6. (3, 3) 

(4)product()函数,笛卡尔积。

product()函数与上述方法最大的不同点是:其针对多个输入序列进行排列组合,示例如下:

  1. ab = ['a', 'b']  
  2. cd = ['c', 'd']  
  3. # 针对ab、cd两个集合进行排列组合  
  4. for item in itertools.product(ab, cd):  
  5. print(item) 

输出如下:

  1. ('a', 'c')  
  2. ('a', 'd')  
  3. ('b', 'c')  
  4. ('b', 'd') 

在量化中通过参数组合来寻找最优参数时一般都会使用笛卡尔积,本节将重点示例。

下面继续刚才的回测实例,使用itertools.product(笛卡尔积)求出TradeStrategy2的最优参数,即求出下跌幅度买入阀值(s_buy_change_threshold)与买入股票后持有天数(s_keep_stock_threshold)如何取值,可以让策略最终盈利最大化。

首先将2.3节修改TradeStrategy2策略基础参数并执行回测的代码抽象出一个函数calc(),该函数的输入参数有两个,分别是持股天数和下跌买入阀值;输出返回值为3个,分别是盈亏情况、输入的持股天数和下跌买入阀值。

  1. def calc(keep_stock_threshold, buy_change_threshold):  
  2.     """  
  3.     :param keep_stock_threshold: 持股天数  
  4.     :param buy_change_threshold: 下跌买入阀值  
  5.     :return: 盈亏情况,输入的持股天数, 输入的下跌买入阀值  
  6.     """  
  7.     # 实例化TradeStrategy2  
  8.     trade_strategy2 = TradeStrategy2()  
  9.     # 通过类方法设置买入后持股天数  
  10.     TradeStrategy2.set_keep_stock_threshold(keep_stock_threshold)  
  11.     # 通过类方法设置下跌买入阀值  
  12.     TradeStrategy2.set_buy_change_threshold(buy_change_threshold)  
  13.     # 进行回测  
  14.     trade_loop_back = TradeLoopBack(trade_days, trade_strategy2)  
  15.     trade_loop_back.execute_trade()  
  16.     # 计算回测结果的最终盈亏值profit  
  17.     profit = 0.0 if len(trade_loop_back.profit_array) == 0 else \  
  18.         reduce(lambda a, b: a + b, trade_loop_back.profit_array)  
  19.     # 返回值profit和函数的两个输入参数  
  20.     return profit, keep_stock_threshold, buy_change_threshold  
  21. # 测试,使用2.3节使用的参数  
  22. calc(20, -0.08) 

输出如下:

  1. (0.31900000000000006, 20, -0.08) 

笛卡尔积求最优属于有限参数范围内求最优的问题,即将有限个参数形成集合,多个有限集合进行笛卡尔积,寻找问题的最优参数。下面通过range()函数使具体参数形成有限集合,示例如下:

  1. #range集合:买入后持股天数从2~30天,间隔两天  
  2. keep_stock_list = range(2, 30, 2)  
  3. print '持股天数参数组:{}'.format(keep_stock_list)  
  4. # 下跌买入阀值从-0.05到-0.15,即从5%下跌到15%  
  5. buy_change_list = [buy_change / 100.0 for buy_change in  
  6.                    range(-5, -16, -1)]  
  7. print '下跌阀值参数组:{}'.format(buy_change_list) 

输出如下:

  1. 持股天数参数组:[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]  
  2. 下跌阀值参数组:[-0.05, -0.06, -0.07, -0.08, -0.09, -0.1, -0.11, -0.12, -0.13, -0.14, -0.15] 

通过对多个有限集合进行笛卡尔积,使用上面封装的函数clac()分别将各个组合参数代入,计算参数对应的最终盈利结果,将结果加入result序列,示例如下:

  1. result = []  
  2. for keep_stock_threshold, buy_change_threshold in itertools.product(  
  3.         keep_stock_list, buy_change_list):  
  4.     # 使用calc()函数计算参数对应的最终盈利,结果加入result序列  
  5.     result.append(calc(keep_stock_threshold, buy_change_threshold))  
  6. print '笛卡尔积参数集合总共结果为:{}个'.format(len(result)) 

输出如下:

  1. 笛卡尔积参数集合总共结果为:154个 

下面使用sorted(result)将结果序列排序:

  1. # [::-1]将整个排序结果反转,反转后盈亏收益从最高向低开始排序  
  2. # [:10]取出收益最高的前10个组合查看  
  3. sorted(result)[::-1][:10] 

输出如下:

  1. [(0.5790000000000001, 28, -0.1),  
  2.  (0.519, 26, -0.1),  
  3.  (0.5019999999999999, 28, -0.05),  
  4.  (0.4770000000000001, 24, -0.1),  
  5.  (0.4660000000000001, 22, -0.1),  
  6.  (0.45100000000000007, 16, -0.09),  
  7.  (0.44999999999999996, 20, -0.06),  
  8.  (0.44800000000000006, 28, -0.07),  
  9.  (0.437, 28, -0.13),  
  10.  (0.437, 28, -0.14)] 

从输出结果中可以看出,持股天数等于28天、下跌阀值等于-0.1的组合盈亏收益最高,达到57.9%。当然这个结果只是在keep_stock_list与buy_change_list给定的参数中排列组合最优的参数,不代表绝对最优。

类似本节寻找最优的参数问题,在“第9章量化系统——度量与优化”中将详细讲解,其他寻找最优参数的方法会在“第6章量化工具——数学”中详细讲解。

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Linux安全体系分析与编程

本书选择经典的开放源代码,全面系统地分析了Linux安全机制。本书共有17章,前10章着重介绍了Linux操作系统的安全机制及实现方法,阐述了公...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊