【其他】ETF 二八轮动策略 (副本)
由bigquantofficial创建,最终由small_q 被浏览 80 用户
复现某论坛 「只取半瓢r」 老师的二八轮动策略
标的选择:
1、指数型ETF,计算各个etf的相关度,选走势最不相关的,最好是负相关的;
2、排除成立时间短,样本数据不够的科创版和国正2000;
3、引入走势相对独立的品种——黄金ETF。
(老师算出了各ETF2016年-2018年相关性,最后选出来3个相关度最小的:上证50ETF,创业板50ETF、黄金ETF)
\
调仓规则:
1、二八轮动常用趋势型的条件:比较3个ETF的20日涨幅,
当有20天涨幅大于0时,买入涨幅最大者,
当20日涨幅小于0时,空仓,或用债基代替现金;
2、调仓周期:5个交易日,以减低摩擦成本;
3、交易费用:0
\
回测时长:
5年,2018年1月1日至今
\
复现思路:
关键代码:
#ETF代码:
instrument_list="""159949.ZOF
510050.HOF
518880.HOF"""
def handle_data(context, data):
# 每隔 adjust_interval 天进行调仓
context.adjust_counter += 1
if context.adjust_counter % context.adjust_interval == 0:
# 获取今天的日期
today = data.current_dt.strftime('%Y-%m-%d')
# 获取今天的基金数据
today_df = df[df.date == today]
# 计算今天所有基金的20日收益率的最大值
max_return_instrument = today_df.loc[today_df['20日收益率'].idxmax()].instrument
# 判断要买入的基金是否已经持仓
if max_return_instrument not in [pos.symbol for pos in context.portfolio.positions]:
# 如果没有持仓,则卖出所有持仓
for pos in context.portfolio.positions:
context.order_target(context.symbol(pos.symbol), 0)
# 买入新的基金
context.order_target_percent(context.symbol(max_return_instrument), 1)
# 判断当前持仓的基金的20日收益率是否小于0
for pos in context.portfolio.positions:
instrument_return = today_df[today_df.instrument == pos.symbol]['20日收益率'].iloc[0]
if instrument_return < 0:
# 如果小于0,则卖出该基金
context.order_target(context.symbol(pos.symbol), 0)
回测结果:
~~放错了*(其实是代码错了*,~~以下是回测结果:
结果分析
先不管图上2022-01-04处凸出来的是什么鬼
可以看出,和老师帖子上给的结果基本一致
开始日期 | 结束日期 | 总收益 | 年化收益 | 夏普 | 最大回撤 | |
---|---|---|---|---|---|---|
我 | 2018年01月01日 | 2023年07月06日 | 182.97% | 21.66% | 0.78 | 33.15% |
只取半瓢r | 2018年01月01日 | 2023年5月27日 | 179.22% | 20.98% | 0.74 | 30.08% |
我就直接引用帖子原话了:
这样的成绩已经碾压很多公募基金了。
除了2018年大熊市是负收益之外,其余每年都是正收益,即使去年2022年熊市也有15.88%的收益,今年到周五(5月26日)为止收益率2.88%。
观察回测走势还可以看出,2020年前策略和沪深300走势几乎是同步的,没有明显的收益,2020年1月后,策略开始有明显的超额收益,是不是可以说明结构性市场是从2020年开始的呢?
\
优点:
1.由于本质上是趋势策略,可以有效躲避一些单边熊市达到控制回撤的效果。
2.策略简单,散户易操作,只需每周开盘时对比3个ETF的20天涨幅后即可进行交易,很多行情APP都可以实现
\
缺点:
1.由于是单标的满仓,导致策略的资金容量较小。
2.同样是因趋势策略,如果市场是震荡走势,则会出现来回买卖的情况,增大了交易摩擦。
\
他这个用计算相关性来决定轮动池的想法,很有启发性,
我想起了@Anthony老师直播复现花影林间因子时,也用了全市场相关性的计算:
每月月底,分别计算每只股票过去20天的t-intercept序列,与当期截面所有股票过去20天的t-intercept序列之间的相关系数的绝对值**(以2023年2月这一期为例,相关系数为正的部分约占88.3%,因此这一部分取绝对值的影响很小,但为了逻辑的一致性,我们依然取了绝对值),并取均值,记为该股票的“夜眠霜路”因子。
\
通过这种求相关系数的方式,将市场层面的信息与个股中长期的基本面信息剥离开。如果这一相关系数越大,就表明该股票的其他信息中,与其余所有股票的其他信息共同的部分越多(共同部分即市场信息),也就是说该股票的市场层面的信息,占其他信息的比重越大,即个股中长期的基本面信息占比就越小。因此这一因子值越大越好。
这种思路当然也可以用于基金
\
优化思路
原帖给出的思路:
从回测走势图可以看出,这个策略在2022年7月的时候创下最高收益191%,直到现在还没有创新高(当前179%,还回撤了11%),有什么方法可以优化呢?其实我前面为了回撤方便,省略了一些步骤,就是应该每年计算一次不同指数的相关性,更新相关度最小的标的。
贴主发现结果很好:
可以看出,2021年1月1日至2022年7月29日这1年半期间相关度最小的是上证50和国证2000,再算上黄金ETF,此时最新的基金池应该是上证50ETF+国证2000ETF+黄金ETF(刚好国证2000ETF是在2022年6月29日上市的,向后20天取20天涨幅数据)。
我们再次按新的基金池在2022年7月19日至今进行回测。
回测有令人惊讶的19.60%收益,不换标的前是-11%,相对收益达到30%。而最大回撤居然只有5%,夏普比率达到1.43。
再看看年度收益2022年下半年收益6.63%,2023年初至今在令股民异常难受的这半年里也有12.16%的收益,除去交易成本收益也非常可观了。
结论:
总的来说,在上市公司家数不断增加但场内新增资金跟不上的情况下,我认为结构性行情仍然会是当前且今后一段时间的基调,二八轮动策略也许该重新受到重视。
贴主说的相关度最小的,就是最负相关的,很好理解——一个越涨,另一个就越跌。
我们在一个轮动池中,卖出下跌趋势的,假如它们未来继续负相关,那么池中其它票就要上涨了,选开始涨的买入。
关键之处在于:
1、下跌趋势判断是否准确?
2、未来负相关性会延续多久?
后续的优化可以围绕这两点进行…我这只是抛砖引玉
我这小白光是造出这块砖就费了好几天时间- -
期待大佬们的思路。。