Skip to content

设计:周频动量 ETF 轮动 + 多层风控

2026-06-24。每周一调仓,全市场 ETF 池,风险调整动量选股 + 四层风控。仅研究学习,不构成投资建议。

1. 目标与总览

每周一在全市场流动性 top-N 的 ETF 里,用风险调整动量选最强的 ≤10 只、风险平价分仓;再叠四层风控,趋势走坏时逐级降险直至空仓避险,余额转入避险 sleeve(债券/货币 ETF)。

信号全部用上一交易日(上周五)收盘前数据,周一收盘执行,无未来函数。

上周五收盘数据
[0] 池子(PIT)    全市场场内ETF → 名称分类 → 成交额top-N → 近63日日均成交额>门槛
[1] 进攻·相对动量  score = 过去L日收益 / 过去L日波动 (跳过近skip日)
[2] 选择          全池降序取 top-10,同类别最多 cap 只 → 候选篮子
[3] 风控A·趋势过滤  剔除 score≤0 或 价<200日线 → 幸存篮子(可能<10,甚至0)
[4] 仓位·风险平价  幸存标的 risk_parity_weights 定权(单只上限) → 进攻权重
[5] 风控B·波动率目标  σ_p=组合近期波动 → scale=min(1, σ_target/σ_p),进攻权重整体×scale
[6] 风控C·回撤熔断  策略净值回撤>10% → 强制最低仓位,直到趋势过滤(市场)重新转正才回场
余额(1−进攻仓位) → 避险sleeve:动量最高且>0的债券ETF,否则货币ETF/现金
→ run_rebalance_backtest(整手/佣金/weight-band/sweep_code)

四层风控各管一个失效模式:A 系统性熊市(整体撤离)、B 波动放大(降仓)、C 尾部黑天鹅(硬熔断)、风险平价(单标的不主导组合风险)。

2. 定稿决策

  • 风控 B:连续波动率目标(非二元 risk-on/off)。scale = min(1, σ_target/σ_p),不加杠杆(上限 1)。
  • 风控 C:熔断阈值 −10%;触发后强制避险,等趋势过滤重新转正(市场基准价 > 200 日线)才回场——不是固定冷却周数。
  • 进攻:风险调整动量(收益/波动)。持仓 top-10 + 每类 cap 只。权重风险平价。
  • 池子:全市场动态池(成交额 top-N,复用 build_universe_all)。
  • 节奏:每周一(自然周首个交易日,休市顺延)。

3. 模块与接口

新建 src/quant/strategy/momentum_rotation.py(纯函数,3.8 安全,可单测)

  • risk_adjusted_momentum(prices, asof, lookback=60, skip=5) -> Series 每列:窗口内日收益均值 / 日收益标准差(类 Sharpe 动量),跳过近 skip 日。
  • select_top_capped(scores, categories, n=10, cap=2) -> list[str] 按分降序取至 n,单类别不超过 cap。
  • trend_filter(prices, asof, candidates, scores, ma_window=200) -> list[str] 保留 score>0price[asof] > MA(ma_window) 的标的(绝对动量 + 均线)。
  • vol_target_scale(weights, returns, asof, target_vol, vol_window=60, max_leverage=1.0) -> float 用近期协方差算组合年化波动 σ_p;min(max_leverage, target_vol/σ_p)
  • class CircuitBreaker(threshold=0.10):状态机。 step(nav, regime_on) -> defensive: bool。维护净值高点;回撤≤−threshold→tripped; tripped 且 regime_on→解除;返回是否强制避险。
  • class MomentumRotationStrategy:持有 config + 熔断状态,__call__(date, nav) -> {code: weight}, 组合上面各层 + risk_parity_weights + 避险 sleeve 选择。

复用

run_rebalance_backtestrisk_parity_weightsbuild_universe_all+_categorizeAShareCostModel/涨跌停、metrics、TushareFundSource

小改 src/quant/backtest/portfolio.py

run_rebalance_backtestweight_fn 可选接收当前净值:若其签名参数 ≥2,则调用 weight_fn(date, nav_now),否则保持 weight_fn(date)向后兼容(现有月度脚本不受影响), 以便熔断层读到策略自身回撤。

新建 scripts/run_momentum_rotation.py

取数(全市场ETF) → 每周一调仓日 → 跑策略 → 消融(完整四层 / 仅相对动量 / 逐层开关) → 基准(沪深300买入持有、全池等权) → 指标 + 净值/回撤/仓位暴露图 + 报告。

4. 参数默认(全部可配)

参数默认
动量回看 L / 跳过 skip60 / 5 交易日
波动窗口60 日
池规模 / 流动性门槛成交额 top-100 / 近63日日均>3000万
持仓数 / 类内上限10 / 2
风险平价权重界[5%, 20%]
趋势过滤score>0 且 价>200日线
波动率目标年化 11%
熔断 / 回场−10% / 市场基准>200日线
成本 / 换手带佣金万三、无印花、weight-band 1%

5. 回测与验证

  • 消融:完整四层 vs 仅相对动量 vs 逐层开关,量化每层贡献。
  • 基准:沪深300 买入持有 + 全池等权。
  • 指标:年化/波动/夏普/最大回撤/换手/在场率(% 周处于进攻)。
  • 产出:净值图 + 回撤图 + 仓位暴露时序图。
  • 单测:逐层纯函数 + 熔断状态机(合成数据,3.8 本地可跑)。

6. 非目标(YAGNI)

不做:日内/分钟级、加杠杆(vol target 上限 1)、个股、机器学习信号、实盘下单对接。