问答交流

【其他】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)

回测结果:

{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}





~~放错了*(其实是代码错了*,~~以下是回测结果:

{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}

结果分析


先不管图上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、未来负相关性会延续多久?

后续的优化可以围绕这两点进行…我这只是抛砖引玉

我这小白光是造出这块砖就费了好几天时间- -

期待大佬们的思路。。

{link}