# 概要:
在【策略编写系列六】中,详细的讲述了如何用Python语言编写出一个简单的双板块效应策略。本章内容讲解如何用Python语言编写出一个简单的多指数轮动策略,希望给有需要的同学提供一些帮助。内容主要分为:轮动策略介绍、构建简单多指数轮动策略、运用Python编写出策略、策略回测结果分析。
# 正文:
## 一、轮动策略介绍
在【系列六】中已经详细的讲到了板块轮动效应,当时整个策略的不完善之处在于板块太少,无法完全解释大盘的涨跌逻辑,因为本人在【系列七】中特意创建了一个多指数轮动策略,目的就是通过对大量指数的强弱判断,从而来解析整个大盘的上涨逻辑。
通俗的讲,每段时期的大盘涨跌逻辑都是有所不同的,比如:前段时间蓝筹股的上涨,这段时间周期股暴涨等等,说白了,每个时期的大盘在上涨过程中,总有一个板块或者是指数、行业是推动大盘上涨的,除非是在大牛市,每个行业、板块都在涨,但是都在涨的同时,必定有一个板块或者行业是涨幅最喜人的。从以上的逻辑,我们可以得出:多指数(行业)轮动策略可以最大程度上解释大盘的涨跌逻辑!
轮动策略的优势非常明显,在任何一段时间内,买入最强势的指数,而这个指数正是带动整个大盘上涨的核心力量。当然,策略中还会判断指数强弱,如果没有一个指数达到强势标准,则直接空仓。这也就是说,轮动策略本身就具备良好的风控措施,而且因为买入的是指数,其不需要考虑非系统性风险。
多指数轮动策略的重点在于以下四点:
一:必须具备足够多的指数,也就是这些指数包含很多行业、指数,这样可以在任何一个时期来解释大盘内在涨跌逻辑。
二:必须有一个严格的强弱判断逻辑,一个指数的表现如何量化成强弱关系并与其它指数进行对比。
三:确定调仓周期,策略应该是一个月调仓一次,还是一周调仓一次,或者其它,这个调仓逻辑与你选择指数的类型、数量有关。
四:确定持仓指数数量,当策略判断出各个指数的强弱并排序后,策略持仓最强表现的一个指数,还是前几个指数,这会直接影响到策略的最终结果。
## 二、构建多指数轮动策略
本章为了达到编写教学效果和策略逻辑完善,本人选取了9个指数ETF基金来解释大盘涨跌逻辑:159901 深100ETF,510050 50ETF,159915创业板ETF,510300 沪深300ETF,510500 500ETF,510180 180ETF,159902 中小板ETF,159905深红利ETF,150019银华锐进。
其次定义板块强弱,采用当日收盘价与20日前的收盘价进行涨跌幅计算,如果当日收盘价相对于20日前的收盘价是上涨的,则表明该板块较为强势,由于一共9个指数,选取其中最强的一个作为交易标的。如果出现9个指数都下跌,那么我们则空仓避险。
板块强弱的调仓周期为一月。
## 三、运用Python编写出策略
第一步:设置初始条件:
第二步:创建判断指数强弱的函数
1.def bankuai(account,data):
这行代码用来定义函数
2.df={'security':[],'qd':[]}
这行代码用来创建字典,security是键,[]放值
3.stocks=account.security
将初始条件中的9个指数植入stock
4.for i in stocks:
for in 循环函数,从stock中逐一取出指数
5.df['security'].append(i)
将取出的指数存放在security的键的[]中,
6.price = data.attribute_history(i, ['close'], 25, '1d')
获取历史数据函数,这里是25日收盘价,对象是取出的指数
7.p20=price['close'].iloc[-20]
获取20日前的收盘价
8.p1=price['close'].iloc[-1]
获取昨日收盘价
9.m=(p1-p20)/p20
计算昨日收盘价相对于20日前的涨跌幅。
10.df['qd'].append(m)
将计算结果植入 qd键的[]中。
11.df = pd.DataFrame(df).sort_values(by ='qd', ascending=False)
将字典转化成DataFrame的形式,并以 qd的值排降序。
12.x=df['qd'].iloc[0]
获取qd中值最大的那个
13.y=['123']
创建一个y,y=['123']
14.if x >0 :
if判断函数,判断x是否大于0
15.return df['security'].iloc[0]
如果大于0,则说明我们应该买入最强指数,由此输出函数结果为,最强指数
16.else:
如果不大于0 ,则说明我们应该空仓避险。
17.return y
输出函数结果为y
第三步:创建交易系统
1.def trade(account,data):
这行代码用来创建交易函数
2.n=bankuai(account,data)
将bankuai这个函数的结果植入n
3.d=len(n)
取n的长度
4.b=list(account.positions)
将持仓个股植入b
5.if d==1:
if判断函数,如果d是1,说明bankuai函数输出结果是 y ,应该空仓
6.if len(account.positions) > 0:
if判断函数,如果个股持仓数量大于0
7.for stock in list(account.positions):
从持仓个股冲逐一取出
8.order_target(stock, 0)
清仓持仓个股
9.else:
第5行代码不成立,也就是bankuai函数输出结果是9,应该买入最强指数
10.if n not in list(account.positions):
判断函数,如果买入的指数不是持仓指数
11.for stock in list(account.positions):
则先清仓,与7.8同理
12.order_target(stock, 0)
13.if len(account.positions) < 1:
if判断,如果个股持仓小于1,也就是已清仓就买对应的最强指数。
14.order_target_value(n, account.cash)
买入最强指数n,全仓。
第四步:扩张交易系统
1.def handle_data(account,data):
这行代码用来每日运行,来判断当初买入的最强指数是否变差了。
2.n=bankuai(account,data)
将bankuai函数的结果植入n
3.d=len(n)
取n的长度
4.b=list(account.positions)
将持仓个股形成列表,植入b
5.if d==1:
如果d等于1,说明bankuai函数输出结果为y,需要空仓避险
6.if len(account.positions) > 0:
如果持仓数量大于0
7.for stock in list(account.positions):
则清仓,同第三步的第7.8行代码同理
8.order_target(stock, 0)
## 四、策略回测结果分析。
三年回测结果图(按月调仓)
三年回测(按周调仓)
从回测结果看,按月调仓的收益明显高于按周调仓的收益,总体上9个指数能较好的解释大盘内在的涨跌逻辑,当然小伙伴可以直接复制我的代码,在开头添加更多的指数上去,还不动手试试>>>