上一篇文章里,我作为一个量化小白,花了不少篇幅拆解了社区大佬的小市值策略——五道风控防线、九项年报排雷、动态持仓调节……拆完之后我有一个很直观的感受:这套策略的内核是"活得久",靠的是极致风控 + 小市值弹性。
但最近两个月盯盘下来,我发现一个问题:ETF行情太好了。
纳指ETF、黄金ETF、港股互联网ETF……这些标的动辄月涨10%+,而且波动远小于小市值个股。我手里的小市值策略虽然在A股震荡行情里能吃到肉,但碰到「市场整体偏弱、ETF板块性行情轮动」的阶段,就会显得力不从心——小市值在休息,ETF在狂飙,两边接不上。
于是我开始在社区里大量翻阅ETF轮动相关的帖子和策略,学习各位大佬的思路。看了十几篇帖子之后,我萌生了一个想法:能不能把小市值和ETF轮动组合起来,搞一个"双核引擎"?
说实话,ETF轮动这块我是完完全全的新手。下面文章里涉及的ETF池子构建、动量打分、滤波器选择等,都是我在社区里反复学习、参考了多位大佬的策略和文章后,慢慢拼凑理解出来的。如果有理解不到位的地方,还请各位前辈多多指教?
小市值负责在A股弹性行情里捕捉超额;ETF轮动负责在板块行情里追趋势。两个引擎交替发力,互相补位——我给它起了个名字:「双龙出海」。
一、为什么要加ETF?先看数据说话
单跑小市值策略,5年30倍,年化收益极高,但有一个问题:回撤集中在大盘系统性下跌的阶段。当大盘暴跌时,小市值股票的跌幅往往比大盘还狠。
而ETF轮动策略有一个天然优势:它可以在全球资产中切换。A股不行就切港股ETF,港股不行就切纳指ETF,纳指也不行就直接买货币基金(银华日利 511880)躺平。
加上ETF之后效果怎么样?我跑了2021年至今的回测,结果直接把我看傻了:
| 指标 | 双龙出海(小市值+ETF) | 基准(沪深300) |
|---|---|---|
| 总收益 | 4632.93%(约47倍) | -9.11% |
| 年化收益 | 112.53% | — |
| 最大回撤 | 15.50% | — |
| 夏普比率 | 4.589 | — |
| 索提诺比率 | 7.535 | — |
| 胜率 | 56.7% | — |
| 盈亏比 | 2.505 | — |
| 阿尔法 | 1.115 | — |
| 贝塔 | 0.502 | — |
5年47倍,年化112%,最大回撤才15.5%——对比上一篇纯小市值的"5年30倍17回撤",收益从30倍提升到47倍,回撤反而从17%降到了15.5%。
说白了就是:加了ETF引擎之后,不仅赚得更多了,还更稳了。这不就是"既要又要"的最佳答案么?
| 维度 | 纯小市值 | 小市值 + ETF轮动 |
|---|---|---|
| 进攻性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 防守性 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 行情适应性 | A股弹性行情 | 全市场+全球资产 |
| 空仓时的机会成本 | 高(只能买货币ETF) | 低(自动切到强势ETF) |
核心逻辑:小市值是矛,ETF轮动是盾——双核协同,攻守兼备。
二、架构设计:两个子账户,各管各的
双核策略的架构其实不复杂,核心就是子账户隔离:
总资金 100%
├── 子账户0:小市值策略(50%)
│ └── 每周二调仓,选中证1000最小市值股票
└── 子账户1:五福ETF轮动(50%)
└── 每日午后轮动,从100+只ETF中挑最强的1只
聚宽提供了 set_subportfolios 的功能,可以把一个账户拆成两个独立子账户,各自有独立的持仓和资金,互不干扰:
set_subportfolios([
SubPortfolioConfig(cash=小市值资金, type='stock'), # 子账户0
SubPortfolioConfig(cash=ETF资金, type='stock'), # 子账户1
])
这样做的好处是:
- 策略之间完全隔离:小市值止损不会影响ETF持仓,反之亦然
- 资金分配清晰:各占50%,不会出现一边吃掉另一边资金的情况
- 独立记录收益:可以分别看两个策略各自的表现,方便归因分析
三、ETF轮动引擎拆解(站在大佬肩膀上)
小市值部分的逻辑我在上一篇已经拆过了,这里重点讲ETF轮动部分。
先说声感谢:ETF轮动这块我参考了社区里很多大佬的策略和思路,包括ETF池子的构建方式、动量打分的数学方法、震荡期切换机制等。我做的更多是「学习→理解→整合」的工作,算不上什么原创,更像是一个学习笔记。如果哪位大佬看到觉得某个模块眼熟,那大概率就是从您那学来的?
3.1 ETF池子:固定池 + 动态池,双池合并
ETF轮动的第一个难题是:从哪些ETF里选?
我学习到的一个很聪明的做法——固定池 + 动态池合并:
- 固定池(108只):手工精选的优质ETF,覆盖黄金、白银、纳指、恒生、各行业板块等
- 动态池(全市场扫描):每天从全市场ETF中自动筛选流动性达标的头部标的,去重后取行业最强的那一只
关键过滤逻辑:
- 剔除宽基指数ETF(沪深300、中证500等——这些不是行业轮动标的)
- 剔除债券/货币类ETF(短融、国债、可转债等——这些不是趋势标的)
- 流动性门槛:日均成交额低于全市场ETF均值/20000的,直接淘汰
- 行业去重:同行业多只ETF时,只保留成交额最高的那一只
最终合并出约100-150只ETF的"作战池"。
3.2 动量打分:拉普拉斯滤波 + 高斯滤波
ETF轮动最核心的问题是:怎么判断哪只ETF最强?
策略用的是加权线性回归 + 数学滤波器的组合方案:
动量得分计算(25日回看):
1. 对收盘价取对数
2. 用加权最小二乘法拟合趋势线(近期数据权重更高)
3. 斜率年化 → 年化收益率
4. 计算R²(拟合优度)→ 趋势稳定度
5. 动量得分 = 年化收益率 × R²
说人话就是:涨得快还涨得稳的ETF,得分最高。
但这还不够。策略额外加了两层数学滤波器,用来判断"该不该现在买":
| 滤波器 | 用途 | 触发条件 |
|---|---|---|
| 拉普拉斯滤波(正常期使用) | 平滑价格,识别趋势 | 价格 > 滤波值 且 斜率 > 0.002 |
| 高斯滤波(震荡期使用) | 更强的降噪,更保守 | 价格 > 滤波值 且 斜率 > 0.002 |
正常行情用拉普拉斯(灵敏一点,抓趋势),震荡行情切高斯(保守一点,少挨打)。两个滤波器自动切换,这个设计很巧妙。
3.3 震荡期自动切换:市场的"红绿灯"
策略有一套完整的"红绿灯"机制来判断当前是正常期还是震荡期:
进入震荡期(亮红灯)——满足任一条件:
- 沪深300的乖离率(BIAS)> 8%(涨太多了,有回调风险)
- RSI从70以上回落到65以下(超买后开始回落)
- 当天触发了止损(市场可能在变差)
退出震荡期(亮绿灯)——满足任一条件:
- 从近20日低点反弹超过4%
- 回撤收窄 + 多个复苏信号连续出现
- 震荡期持续超过20个交易日(强制退出,不能永远观望)
还有一个冷却期设计:每次红绿灯切换后,3个交易日内不允许再次切换,防止频繁反复。
3.4 多层过滤漏斗
从作战池到最终买入,要过七道关:
100+只ETF
→ 动量得分过滤(0 ≤ 得分 ≤ 5)
→ R²过滤(> 0.4,趋势不稳的排除)
→ 成交量过滤(量比 <1.8,异常放量的排除)
→ 短期风控(近3天没有单日跌 > 3%)
→ 溢价率过滤(可选,防止QDII高溢价陷阱)
→ 动态滤波过滤(正常期/震荡期分别用不同滤波器)
→ 最终只选1只!
没错,最终只持有1只ETF。这是一个非常激进但也非常纯粹的设计——全仓轮动,不分散。因为分散在ETF轮动里反而是稀释收益,不如集中火力追最强的那个。
3.5 分钟级止损:最后的保险丝
ETF策略还有一个分钟级的止损机制(every_bar 频率运行):
- 固定止损:当前价格跌破成本价的95%时,立刻卖出
- 日内跌幅止损(可选):如果当天相对昨收跌超过5%,也立刻卖出
触发止损后会标记 stop_loss_triggered_today,在午后13:10的检查中自动触发进入震荡期——止损不仅是保护本金,还会触发策略整体进入防守姿态。
四、双核协同的几个关键细节
4.1 资金分配
当前是简单的50:50平分。但我在想,未来可以根据市场状态动态调整——比如A股弹性好的时候多给小市值,ETF板块轮动强的时候多给ETF。这是一个可以继续优化的方向。
4.2 独立收益记录
策略每日收盘后会分别记录两个子策略的累计收益率,方便做归因分析。用 record() 函数输出到回测图表上,可以直观看到两条收益曲线。
def record_daily_performance(context):
for i, strategy_key in enumerate(['strategy1', 'strategy2']):
sub_portfolio = context.subportfolios[i]
cumulative_return = (sub_portfolio.total_value / initial_cash - 1) * 100
# 记录到图表
record(小市值=小市值收益率, 五福ETF=ETF收益率)
4.3 滑点和佣金的差异化设置
很多人忽略的一个细节——股票和ETF的交易成本是不一样的:
set_slippage(FixedSlippage(0.002), type="stock") # 股票:固定滑点
set_slippage(PriceRelatedSlippage(0.0001), type="fund") # ETF:比例滑点
# 股票佣金:万0.85,卖出还有千分之0.5的印花税
# ETF佣金:万0.5,无印花税
ETF的交易成本天然比股票低很多,这也是ETF轮动策略能频繁调仓的基础。
五、一个小白的学习感悟
- 不要只盯一个赛道。小市值再好,碰到风格切换也会歇菜。加一个ETF轮动引擎,相当于给自己多开了一个全球化的战场。
- 站在巨人肩膀上学得更快。ETF轮动这一整套逻辑,如果让我从零开始写,可能半年都写不出来。但社区里有那么多大佬无私分享代码和思路,我做的只是把不同的模块学懂、拼到一起。聚宽社区的开源氛围真的很好,感谢每一位分享策略的前辈。
- 数学滤波器很有意思。拉普拉斯、高斯这些信号处理领域的工具,用到金融数据上效果很好。作为小白第一次接触这些概念,说实话还没有完全吃透,后面还要继续啃论文和代码。
- 震荡期切换是ETF轮动的灵魂。没有这个机制,ETF轮动在震荡行情里会被反复打脸。有了红绿灯+冷却期,策略才能在"追趋势"和"认怂"之间优雅切换。
- 子账户隔离是个好设计。让两个策略各管各的,不争抢资金,不相互干扰。简单粗暴但有效。
- 最后还是那句话:风控是一切的基础。不管是小市值的五道防线,还是ETF的分钟级止损,核心都是同一个信仰——先活着,再赚钱。
六、实战检验
说得再好不如跑起来看。我已经把这套「小市值+ETF轮动_双龙出海」策略上传到了 9db量化竞技场,用真实模拟盘每天跑。
欢迎围观、拍砖。在9db上可以看到每天的交易记录、持仓变化、收益曲线。比回测更真实,因为是每天实时跑的——好不好,跑几周就知道了。
也欢迎大家去看看其他大佬的策略表现,和自己的策略做个对比。量化这条路,闭门造车不如多看多学。
作为一个刚入门的量化小白,文中很多理解可能不够深入甚至有偏差,欢迎各位大佬在评论区指正。也特别感谢社区里那些无私分享策略和思路的前辈们,没有你们的开源精神,就没有这篇学习笔记。
免责声明:以上内容仅为个人学习记录,不构成任何投资建议。股市有风险,投资需谨慎。

