/~learn/s/050bbe56
> 📅 2026-10-15 建立 | 板块:因子有效性检验 | 上游:反追高因子有效性检验
---
"5 个因子混池几乎全部不显著"是异质品种互相抵消的假象,不是因子无用。 按"价格由什么驱动"把池子切成 三域(权益 / 防御-固收红利 / 商品) 后,防御域里夏普、波动稳定性、估值锚立刻涌现强显著性(
但必须诚实说:分域后的对照回测全区间跑输旧口径,且"收益换回撤"的交换不划算——累计 +23.7% vs +39.3%、年化 4.1% vs 6.5%、夏普 0.36 vs 0.46,而平均回撤只改善 0.4pp(−16.6% vs −17.0%),且 2021/2026 平均回撤反而更差。
结论(2026-10-15 回退决定):方向有据、但当前实现不划算,已切回旧口径。 域层代码与开关保留为研究物(DOMAIN_ENABLED = False,默认关闭),等改进方案(如域权重随 regime 自适应)验证跑赢旧口径后再置 True。生产当前 = 纯 regime 权重 + 全池惩罚(multi_market_v4)。
---
第 1 期把 5 个因子放进同一个截面排名,Rank IC 全部
拆开看立刻不一样:防御-固收红利域里夏普 20 日 IC +0.0497(t=2.20)、波动稳定性 +0.0579(t=2.71)——都是 t>2 的强显著正。这说明因子不是没用,是没分对域用。
---
| 轴 | 切法 | 实现 | 用途 |
| ---- | ------ | ------ | ------ |
| 市场域(已有) | 按"在哪个市场交易" | regime.py::_classify_market(7 类:A股/美股/港股/其他跨境/防御/商品/REITs) | 决定用哪套 regime 基准向量 |
| 三域(本次新增) | 按"价格由什么驱动" | factor/domain.py::classify_domain | 决定因子权重与惩罚开关 |
两条轴都有"商品",但语义不同轴(一个是交易市场,一个是资产驱动逻辑),故 IC 统计里用 域· 前缀区分。
domain.py)| 域 | 判定 | 驱动逻辑 |
| ---- | ------ | --------- |
| 商品 | category == '商品' | 独立周期(与股债弱相关) |
| 防御-固收红利 | category ∈ {债券, 货币, REITs} 或 sub_category ∈ {红利, 红利低波, 自由现金流, 央企, 公用事业, 仓储物流, 产业园, 利率债, 信用债, 可转债} | 现金流 / NAV 锚定 → 均值回归 |
| 权益 | 其余(宽基 / 行业 / 主题 / 跨境股) | 盈利预期驱动 → 趋势/动量 |
> REITs 归防御的说明:本项目池内 3 只 REITs 均为中国基础设施 REITs(508056.SH 普洛斯仓储物流、508098.SH 京东仓储、508000.SH 张江产业园),价格由分红现金流 + NAV锚定、波动低于 A 股权益,与债券/红利同属"均值回归"气质。⚠️ 注意区分:美股权益型 REITs(如购物中心/办公 REITs)波动常高于宽基,若未来纳入需单独评估——本系统当前的"防御"是按因子气质定义,不是按波动率绝对值。
{'权益': 90, '防御-固收红利': 18, '商品': 3}
---
区间 2021-01-08 ~ 2026-09-04,274 个周五,20 日前向收益,单元格式 IC 均值(t 值)。
| 因子 | 域·权益 5/10/20日 | 域·防御-固收红利 5/10/20日 |
| ------ | ------------------ | ------------------------------ |
| 动量 | +0.0117(0.33) / +0.0157(0.33) / −0.0035(−0.18) | +0.0046(0.18) / +0.0084(0.35) / +0.0348(1.43) |
| 夏普 | +0.0036(0.17) / +0.0038(0.19) / −0.0153(−0.81) | +0.0284(1.28) / +0.0402(1.84) / +0.0497(2.20) ✅ |
| 反追高 | −0.0109(−0.60) / −0.0233(−1.27) / −0.0087(−0.46) | −0.0121(−0.56) / −0.0186(−0.89) / −0.0341(−1.60) |
| 稳定性 | +0.0017(0.09) / +0.0064(0.34) / −0.0079(−0.43) | +0.0311(1.47) / +0.0417(1.97) / +0.0579(2.71) ✅ |
| 估值锚 | −0.0121(−0.68) / −0.0188(−1.10) / −0.0165(−0.97) | −0.0204(−0.91) / −0.0359(−1.62) / −0.0571(−2.58) ✅ |
读法:
- 稳定性/夏普为正 → "低波动 = 未来更强",符合均值回归气质; - 估值锚显著为负 → 在该域"越贵反而越涨",说明估值锚不适合当防御域的选优依据; - 反追高为负 → 该域"超买的反而涨" → 反追高惩罚机制在该域方向是反的,必须关掉(与第 1 期分市场检验一致)。
---
DOMAIN_BASE_WEIGHTS)| 因子 | 权益域 | 防御-固收红利域 | 商品域 | 依据 |
| ------ | -------- | ---------------- | -------- | ------ |
| 动量 momentum | 0.25 | 0.20 | 0.25 | 防御域弱正(t1.43),小幅保留 |
| 夏普 sharpe | 0.15 | 0.30 | 0.15 | 防御域 t2.20 ↑↑ |
| 反追高 overbought_avoid | 0.20 | 0.05 | 0.20 | 防御域 t−1.60 ↓(且惩罚直接关闭) |
| 稳定性 vol_stability | 0.25 | 0.35 | 0.25 | 防御域 t2.71 ↑↑ |
| 估值锚 valuation | 0.15 | 0.10 | 0.15 | 防御域 t−2.58 ↓↓ |
> 权益/商品域因证据不足(权益全不显著、商品样本 <5),刻意沿用原 base_weights 不动,避免用噪声改权重。
---
EQUITY_MARKET_TILT)档2 只在权益域内按市场做乘数微调(幅度限制在 [0.7, 1.4]),理由是子市场证据弱(多数
| 市场 | 动量 | 夏普 | 反追高 | 稳定性 | 估值锚 | 证据方向 |
| ------ | ------ | ------ | -------- | -------- | -------- | --------- |
| A股 | 1.00 | 0.70 | 1.00 | 0.90 | 1.30 | 夏普负(t−0.8~−1.3)↓、估值略正↑ |
| 美股 | 0.70 | 1.00 | 1.40 | 0.90 | 1.00 | 反追高正(t1.2~1.5)↑、动量负↓ |
| 港股 | 0.70 | 0.90 | 1.30 | 0.80 | 1.30 | 反追高正、估值正、动量负 |
| 其他跨境 | 1.30 | 0.80 | 1.00 | 1.20 | 0.90 | 动量正(t0.8)↑、稳定性略正↑ |
---
w_final = normalize( 市场regime权重 × 域基准权重 × 权益内市场乘数 )
domonly)全区间最差(+14.2%),故 regime 层必须保留。factor_cols 缺项回退中性值。
PENALTY_DISABLED_DOMAINS)
overbought_penalty 是乘法惩罚项。因防御域反追高 IC 显著为负(惩罚在该域方向是反的),对防御域品种把惩罚乘数强制置 1.0(等价关闭惩罚),权益/商品域保留原惩罚。
---
区间 2021-01-08 ~ 2026-10-09(276 组),Top10 等权,逐周五调仓。 B = 旧口径(纯 regime 权重 + 全池惩罚);A = 各分域变体。
| 变体 | 累计 | 年化 | 夏普 | 最大回撤 | 平均回撤 | 胜率 | 平均重合 |
| ------ | ------ | ------ | ------ | --------- | ------------ | ------ | --------- |
regdom(分域) | +23.7% | 4.1% | 0.36 | −32.1% | −16.6% | 55.1% | 6.8/10 |
conservative(仅改防御域) | +19.9% | 3.5% | 0.32 | −31.8% | — | 55.8% | 7.2/10 |
domonly(丢 regime 权重) | +14.2% | 2.5% | 0.26 | −29.9% | — | 52.9% | 6.0/10 |
| B 旧口径(当前生产) | +39.3% | 6.5% | 0.46 | −34.4% | −17.0% | 55.8% | — |
> 平均回撤口径 = 净值相对历史高点的回撤序列取 mean(非最大值),同策略板块 Strategy.calculate_average_holding_drawdown,反映"全年平均处于水下多深";与"最大回撤"(区间最深一次)是两个不同问题。
分年(regdom vs B,含平均回撤):
| 年份 | A 累计 | B 累计 | A 夏普 | B 夏普 | A 平均回撤 | B 平均回撤 | 结论 |
| ------ | -------- | -------- | -------- | -------- | ----------- | ----------- | ------ |
| 2021 | −2.9% | +1.5% | −0.14 | 0.18 | −5.5% | −4.5% | 收益、回撤双输 |
| 2022 | −23.2% | −22.8% | −1.74 | −1.52 | −8.7% | −9.0% | 基本持平 |
| 2023 | +7.3% | +5.9% | 0.89 | 0.53 | −2.1% | −2.4% | 优 |
| 2024 | +9.8% | +12.4% | 0.93 | 0.87 | −4.2% | −5.0% | 收益差、回撤优 |
| 2025 | +31.7% | +30.4% | 1.87 | 1.60 | −3.4% | −4.9% | 优(夏普 +0.27、回撤改善 1.5pp) |
| 2026 | +6.9% | +14.6% | 0.83 | 1.29 | −2.4% | −2.2% | 收益、回撤双输 |
regdom 是三者最优(最高累计、最高夏普),domonly 最差 → regime 权重必须保留。> ⚠️ 不要只看全区间,也不要只看好年份。分域目前是"方向有据、幅度待调、性价比不划算",故已回退;2026 的拖累与"收益缩水"是首要待解问题。
---
| 文件 | 角色 |
| ------ | ------ |
selection/factor/domain.py | 单一事实源:三域分类、档1/档2 权重、惩罚开关、combine_weights();总开关 DOMAIN_ENABLED(默认 False) |
selection/selector/multi_factor_selector.py | 生产路径接入:multi_market 分支按 DOMAIN_ENABLED 门控——True 时按域调用 combine_weights 并按域关闭惩罚(multi_market_v5),False(当前生产)退化为纯 regime 权重 + 全池惩罚(multi_market_v4) |
selection/backtest/factor_ic_analysis.py | IC 分析改为 import 自 domain.py,消除重复定义(契约漂移) |
selection/backtest/compare_domain_ab.py | 对照回测(--variant regdom/domonly/conservative);内侧强制切换 DOMAIN_ENABLED 做 A/B,与生产默认解耦;含平均回撤指标 _avg_dd |
# selection/factor/domain.py
DOMAIN_ENABLED = False # 2026-10-15:分域口径全区间输给旧口径 → 生产暂不启用
False(当前生产):_last_weight_method = 'multi_market_v4',权重 = 纯市场 regime 权重,惩罚全池生效。True(研究用):_last_weight_method = 'multi_market_v5',权重 = regime × 域基准 × 权益内市场乘数,防御域关闭反追高惩罚。True。---
> 重启条件(回退后):域层要重新置 DOMAIN_ENABLED = True,必须先满足——全区间(或至少近 3 年)累计收益不再明显输给旧口径,且平均回撤至少改善 2~3pp(当前仅 0.4pp,属噪声量级)。改进后请重跑 compare_domain_ab.py 验证再切。
regime × base 相乘使权益域权重也变了(如 RANGING 下稳定性被抬、估值锚被压)。IC 证明权益域 5 因子全不显著,理论上没有理由动它——但消融显示"只改防御域"(conservative)反而更差,说明差异主要来自噪声/交互,需更长样本再判。---
# 分域 IC 矩阵(写 ic_summary.csv,含「域·」分组)
/usr/bin/env -u PYTHONHOME -u PYTHONPATH .venv/bin/python -u \
-m adata.aohan.quant.selection.backtest.factor_ic_analysis \
--start 2021-01-01 --horizons 5,10,20
# 分域对照回测(三变体)
for v in regdom domonly conservative; do
/usr/bin/env -u PYTHONHOME -u PYTHONPATH .venv/bin/python -u \
-m adata.aohan.quant.selection.backtest.compare_domain_ab \
--start 2021-01-01 --variant $v
done
结果落盘:adata/aohan/quant/selection/backtest/ic_results/
(ic_summary.csv / domain_ab_summary_{variant}.csv / domain_ab_series_{variant}.csv)。