← 返回模块
4.2.3.4beta 可读 · 未来付费校验通过内容版本 2026-05-24

信号合成、堆叠与集成

4.2.3 · 信号评估与合成 · 量化全流程

周五上午,你在上海的一家 量化 私募 ——明汯、 幻方、 九坤、 灵均 风格 的 多 因子 私募。 L3 把 四 条 信号 正交化 完了: mom_12_1, book_to_market, gross_profitability, pead_sue 都 残差化 通过 了 IC_break_even 门槛。 桌面 上 还 没有 量产 复合 信号。 投决会 在 下午 2 点。 研究 主管 问 你: 「等 权重 简单 平均 行不行?」 在 沪海 2018-2022 样本内 IR 是 0.9; 在 2023 样本外 IR 是 0.85 ——可 用 但 还有 提升 空间。 你 还 在 试 Markowitz w = Σ^{-1} * IC: 样本内 IR 是 1.5, 样本外 暴跌 到 0.6 ——明显 过拟合。 Ledoit-Wolf 收 缩 Markowitz: 样本内 1.3, 样本外 1.1 ——shrinkage benefit 是 0.25 IR, 显著 高于 0.1 IR 门槛, 这 就 是 你 要 上线 的 复合。 本 课 是 整 个 4.2.3 craft 的 capstone: 怎 么 把 一 组 正交 信号 合 成 单 一 量产 评分, 怎 么 选 加 权 方案, 怎 么 防 过 拟 合。

五 种 合成 方法

业内 五 种 标准 加权 方案 在 这 个 顺序 上 适用 不同 数据 体 量:

(1) equal_weight (等 权重, w = (1/K, ..., 1/K)) ——稳 健 默认; 在 验证 集 长度 T < 5K 时 击败 Markowitz, 因 Markowitz 噪声 dominate optimisation gain;

(2) markowitz_optimal (Markowitz 最 优, w* = Σ^{-1} * IC) ——样本内 最 优 解; 没有 正则化 时 样本外 极 不 稳定;

(3) ledoit_wolf_shrinkage (Σ_shrunk = (1 - τ*) * Σ_sample + τ* * (tr(Σ_sample)/K) * I, w = Σ_shrunk^{-1} * IC) ——量产 默认, 适用 中 等 验证 集 长度;

(4) stacking (堆叠, 元 模型 ——线性 / ridge / LightGBM ——在 基 信号 的 out-of-fold 预测 上 训练) ——捕 捉 线性 加权 无法 表 达 的 非线性 交互;

(5) ensembling (集成, bagging 多 种子 + 跨 视界 model averaging + 跨 模型 家族 robust mean) ——多 层 防 御 过 拟 合。

规则: ​量产 复合 = (orthogonalise + combine + regime-check); T > 20K 时 默 认 对 称 Gram-Schmidt + Ledoit-Wolf 收 缩 Markowitz, T < 5K 时 默 认 对 称 Gram-Schmidt + 等 权重。​

五 元 复合 诊断 包

复合 信号 上 线 之前 携 带 五 个 诊断 数字:

(1) composite_ir_in_sample_vs_oos (样本内 vs 样本外 IR, gap > 50% 意 味 过 拟 合); (2) per_signal_weight_contribution_and_stability (每 条 信号 权 重 与 跨 验证 折 稳 定 性); (3) composite_turnover_and_break_even_ic (复合 必 须 在 复合 换 手率 下 满足 L2 break-even IC 门槛); (4) regime_conditional_composite_ic (牛市 / 熊市 / 高 波动 / 低 波动 ——单 regime 失效 的 复合 不 可 上 线); (5) shrinkage_benefit (收 缩 Markowitz vs 等 权重 的 样本外 IR 提升; > 0.1 IR 上线 收 缩 版, 否则 上线 等 权重)。

规则: ​任 何 缺 失 五 元 任一 的 复合 不 进入 4.4 组合 构造 步骤。​

Markowitz 与 收 缩 的 数学 形式

Markowitz 最 优 权 重 的 闭 形 解:

w=Σ1ICw^* = \Sigma^{-1} \cdot \mathrm{IC}

收 缩 协方差 的 Ledoit-Wolf 形式:

Σshrunk=(1τ)Σsample+τtr(Σsample)KI\Sigma_{\text{shrunk}} = (1 - \tau^*) \cdot \Sigma_{\text{sample}} + \tau^* \cdot \frac{\mathrm{tr}(\Sigma_{\text{sample}})}{K} \cdot I

Ledoit-Wolf 收 缩 Markowitz

Markowitz 在 样本内 是 IC 加 权 的 最 优 解: w* = Σ^{-1} * IC 最大化 IR = w^T * IC / sqrt(w^T * Σ * w)。 问 题: 协方差矩阵 Σ 在 短 验证 集 上 病 态 ——特征值 散布 极 宽, 最小 特征值 接近 零, 求 逆 后 权 重 极 端 (一 条 信号 50% 权 重, 另 一 条 -30%)。 样本外 噪声 dominate。

Ledoit-Wolf 2004 提 出 解析 收 缩 估 计 子: 把 样本 协方差 朝 一 个 良 态 目标 (单位 阵 乘 tr(Σ)/K) 收 缩, 收 缩 参数 τ* 由 MSE 最小化 解析 计算。 三 步:

(1) Sigma_sample = numpy.cov(ic_matrix.T) ——样 本 IC 协方差; (2) lw = sklearn.covariance.LedoitWolf().fit(ic_matrix) 然后 tau_star, Sigma_shrunk = lw.shrinkage_, lw.covariance_ ——解 析 收 缩 参 数 和 收 缩 协方差; (3) w_shrunk = numpy.linalg.solve(Sigma_shrunk, ic_mean_vector) ——正 则 化 后 的 Markowitz 权 重。

规则: ​收 缩 权 重 在 Markowitz 最 优 (τ=0) 与 等 权重 基线 (τ=1) 之 间 插 值。​

import numpy as np
import sklearn.covariance

def ledoit_wolf_markowitz(ic_matrix: np.ndarray) -> dict:
    # 1. 样本 协方差
    Sigma_sample = np.cov(ic_matrix.T)
    # 2. 解析 收 缩 估 计
    lw = sklearn.covariance.LedoitWolf().fit(ic_matrix)
    tau_star = lw.shrinkage_
    Sigma_shrunk = lw.covariance_
    # 3. 求 解 Sigma_shrunk @ w = ic_mean
    ic_mean = ic_matrix.mean(axis=0)
    weights = np.linalg.solve(Sigma_shrunk, ic_mean)
    cond_before = np.linalg.cond(Sigma_sample)
    cond_after = np.linalg.cond(Sigma_shrunk)
    return {'tau_star': tau_star, 'sigma_shrunk': Sigma_shrunk,
            'weights': weights, 'condition_number_before': cond_before,
            'condition_number_after': cond_after}

ledoit_wolf_markowitz 的 函数名、 参数 ic_matrix、 sklearn API sklearn.covariance.LedoitWolf, 以及 返回 字典 键, 在 中英 两 版 中 字 节 一 致; 仅 注 释 翻译。

Formula Explorer

Sigma_shrunk = (1 - tau) * Sigma + tau * trace_Sigma_over_K * I

Stacking ——元 模型 加 权

线 性 Markowitz 假 设 信号 与 收益 之 间 是 线 性 关 系。 LightGBM ranker 上 的 实际 量产 信号 通常 非 线 性: 极 端 值 的 边 际 贡 献 与 中 间 值 不 同, 信号 之 间 有 交 互 项 (动量 强 时 价 值 信号 反 而 弱)。 Stacking 用 一 个 元 模型 (linear / ridge / LightGBM) 学 习 这 些 非 线 性 关 系。 四 步:

(1) oof_predictions = purged_kfold_predict(base_signals, target_returns, n_folds=5, embargo=21) ——4.2.1 L2 的 净 化 K 折 ——产 出 每 条 基 信号 的 样 本 外 OOF 预 测; (2) meta_model = sklearn.linear_model.Ridge(alpha=1.0)lightgbm.LGBMRanker(...) ——元 模型, 业 内 私募 量产 通 常 是 lightgbm.LGBMRanker(objective='rank_xendcg'); (3) meta_model.fit(oof_predictions, target_returns) ——元 模型 在 OOF 预 测 上 训练; (4) composite_score = meta_model.predict(test_predictions) ——元 模型 在 测试 集 上 给 出 复合 评 分。

规则: ​当 基 信号 本 身 是 复 杂 模型 时 用 stacking; 元 模型 捕 捉 线 性 权 重 无 法 表 达 的 非 线 性 交 互。​ 净 化 K 折 的 21 日 embargo 在 沪深300 上 阻止 21 日 前瞻 收 益 的 OOF 预 测 看 到 训 练 集 信 息 ——4.2.1 L2 的 操 作 关 键。

集成 ——三 种 模 式

集成 是 复合 的 最 后 一 层 防 御:

(1) bagging_across_seeds ——训 练 K' = 5-20 个 不 同 种 子 的 基 ML 信号; 平 均 预 测; 方 差 减 少 ~ 1/K';

(2) model_averaging_across_horizons ——把 h = 1, h = 5, h = 21 上 的 信号 用 视界 特 定 权 重 (来自 L2 半 衰 期) 合 成;

(3) robust_mean_across_model_families ——公式驱动 复合、 事件驱动 复合、 ML 驱动 复合 的 中位数 / 截 尾 均值 作 为 顶 层 主 信号 输入。

规则: ​集成 层 是 过 拟 合 防 御 的 最 后 一 道; 量产 复合 = (orthogonalise + combine + ensemble) 三 层。​

复合 决 策 规 则

四 条 数据-体-量-条件 默 认:

(1) if T < 5K: ship equal_weight ——短 验证 集, Markowitz 噪 声 dominate; (2) if 5K <= T <= 20K: ship ledoit_wolf_shrinkage ——中 等 验证 集, 收 缩 安 全 插 值; (3) if T > 20K: ship markowitz_with_constraints ——长 验证 集, 加 多空 / 权 重 上限 / 杠 杆 约 束 的 Markowitz 解 稳定; (4) if shrinkage_benefit < 0.1_IR: prefer equal_weight ——更 简 单 的 复合 对 regime 变化 更 稳 健。

业内 私募 (明汯、 幻方、 九坤、 灵均、 鸣 石、 衍 复) 量产 复合 普 遍 组合 50-200 条 正交 信号, 复合 IR 在 1.0-1.5 样本外, 用 LightGBM stacking + bagging 跨 种 子 + Ledoit-Wolf 协方差 收 缩 ——业内 公 开 报告 描 述 的 流 水 与 上 述 完 全 一 致。

复合 构 造 函数

把 上 面 五 种 方法 dispatch 进 一 个 接 口:

import numpy as np
import sklearn.covariance, sklearn.linear_model

def construct_composite(orthogonal_signals: np.ndarray, forward_returns: np.ndarray,
                       method: str = 'ledoit_wolf') -> dict:
    T, K = orthogonal_signals.shape
    if method == 'equal_weight':
        weights = np.ones(K) / K
    elif method == 'markowitz':
        # 1. 样本 IC 协方差 与 样本 平均 IC
        ic_matrix = orthogonal_signals * forward_returns[:, None]
        Sigma = np.cov(ic_matrix.T)
        ic_mean = ic_matrix.mean(axis=0)
        # 2. w = Σ^{-1} * IC
        weights = np.linalg.solve(Sigma, ic_mean)
    elif method == 'ledoit_wolf':
        ic_matrix = orthogonal_signals * forward_returns[:, None]
        lw = sklearn.covariance.LedoitWolf().fit(ic_matrix)
        ic_mean = ic_matrix.mean(axis=0)
        weights = np.linalg.solve(lw.covariance_, ic_mean)
    elif method == 'stacking':
        ridge = sklearn.linear_model.Ridge(alpha=1.0).fit(orthogonal_signals, forward_returns)
        weights = ridge.coef_
    # 3. 复合 评分 与 样本内 IR
    composite_score = orthogonal_signals @ weights
    in_sample_ir = composite_score.mean() / composite_score.std() * np.sqrt(12)
    return {'weights': weights, 'composite_score': composite_score,
            'in_sample_ir': in_sample_ir, 'oos_ir': None}

construct_composite 的 函数名、 参数 orthogonal_signals / forward_returns / method、 method 值 equal_weight / markowitz / ledoit_wolf / stacking, 以及 返回 字典 键, 在 中英 两 版 中 字 节 一 致; 仅 注 释 翻译。

走 通 的 例子 ——四 信号 复合

把 L3 输出 的 四 条 正交 信号 (mom_12_1_orth, book_to_market_orth, gross_profitability_orth, pead_sue_orth) 在 沪深300 universe 上 2018-2022 样本内 / 2023 样本外 走 一 遍:

(1) 等 权重 w = (0.25, 0.25, 0.25, 0.25): 样本内 IR ≈ 0.95, 样本外 IR ≈ 0.85;

(2) 无 约 束 Markowitz: 样本内 IR ≈ 1.50, 样本外 IR ≈ 0.55, 协方差矩阵 Σ 条件 数 ≈ 200 ——病 态;

(3) Ledoit-Wolf 收 缩 Markowitz: τ* ≈ 0.4-0.7 (沪深300 验证 集 短, 收 缩 较 高), 样本内 IR ≈ 1.30, 样本外 IR ≈ 1.10, 协方差矩阵 收 缩 后 条件 数 ≈ 8 ——良 态;

(4) shrinkage benefit = 1.10 - 0.85 = 0.25 IR, > 0.1 IR 门槛 ——上 线 收 缩 Markowitz 复合;

(5) 复合 诊断: 样本内-vs-样本外 gap 是 (1.30 - 1.10) / 1.30 ≈ 15%, 远 低 于 50% 门槛; 每 条 信号 权 重 (动量 ≈ 0.32, 价 值 ≈ 0.18, 质量 ≈ 0.20, PEAD ≈ 0.30 ——PEAD 因 正交 IC 高 得 到 高 权 重); 复合 月度 单 边 换手率 ≈ 90% (低 于 单 信号 ——正交化 + 收 缩 平 滑 信号 序列), 在 10 bp 往返 TC 下 break-even IC ≈ 0.015 (实 际 复合 IC ≈ 0.06, 远 高 于); regime-conditional 复合 IC 在 牛市 / 熊市 / 高 波动 / 低 波动 四 个 桶 中 都 > 0.04 ——通 过 regime check。 复合 进入 4.4 组合 构造。

过 拟 合 与 deflated-Sharpe 修 正 的 实 操 注 解

私募 业 内 每 年 跑 通 1000+ 候 选 信号 走 这 个 评估 流 水, 在 每 个 复合 上 跑 100+ 变化 ——不 同 正交化 方法、 不 同 协方差 收 缩 估 计 子、 不 同 stacking 元 模型、 不 同 bagging 计 数、 不 同 特 征 子 集、 不 同 前瞻 收 益 视 界。 每 个 变化 都 在 4.2.1 L3 的 试 验 计 数 器 上 加 一, 累 计 多 重 检 验 inflation 可 以 显 著。 deflated-Sharpe-ratio 修 正 (Bailey & López de Prado 2014) 提 供 一 个 试 验 数 与 IR 分 布 高 阶 矩 的 闭 形 罚 项; 在 写 报告 把 复合 IR 上 报 投决会 之 前 应 用 这 个 修 正。

第 二 个 操 作 注 解: 单 次 收 缩 Markowitz 跑 出 的 每 条 信号 权 重 在 跨 验证 折 上 不 稳 定, 即 使 复合 IR 是 稳 定 的。 某 条 信号 在 第 一 折 拿 权 重 0.30、 第 二 折 0.10 但 始 终 正 值 是 稳 健 贡献; 某 条 信号 第 一 折 0.30、 第 二 折 -0.20 ——无 论 样本内 IR 多 高, 它 都 危 险。 per_signal_weight_contribution_and_stability 诊 断 抓 的 就 是 这 个 ——跨 折 权 重 标 准 差 与 均 值 同 时 报 告。 沪深300 上 验证 集 短 (后-2015 约 2400 个 交易 日, 月度 调仓 约 120 个 调仓 期), 折 数 通 常 是 5, 每 折 24 个 调仓 期 ——足 以 算 权 重 稳 定 性 但 也 足 以 暴 露 不 稳 定 信号 的 异 常 摆 动。 业 内 普 遍 用 5 折 是 一 个 经验 经 济 取 舍, 不 是 理 论 最 优。 量产 私募 (明汯、 幻方、 九坤) 公开 报告 中 描述 的 复合 构造 流 水 通 常 包 括: 在 训 练 集 上 跑 100+ 信号 通 过 L3 正交化 与 因 子 中 性 化, 然后 在 验证 集 上 通 过 LightGBM 元 模型 做 stacking, 跨 5-20 个 随 机 种 子 做 bagging, 跨 多 个 视 界 (h=1, h=5, h=21) 做 model averaging ——这 是 业 内 公 开 的 量产 复合 构造 标 准 流 水, 与 学 术 文 献 描 述 完 全 一 致 但 在 实 际 部 署 上 工程 化 更 深。

与 4.4 的 衔接 与 模块 结 束

L4 是 整 个 4.2.3 craft 的 capstone, 也 是 整 个 subject 4.2 alpha research 的 闭 环。 4.2.1 教 你 怎 么 设 计 一 个 诚 实 的 研究 实验 (预 注 册、 样本内 / 样本外 分 割、 多 重 检验 修正、 净 化 K 折); 4.2.2 教 你 怎 么 构 造 信号 (DSL、 公式驱动 / 事件驱动 / ML 驱动 三 个 信号 家族、 标 准 化 流 水); 4.2.3 教 你 怎 么 评估 与 合 成 (IC / IR / Grinold-Kahn / 衰 减 / 换 手 / 容 量 / 正交化 / 复合)。 三 个 模块 加 起 来: 你 现 在 可 以 接 到 一 个 alpha 研究 任务 ——构 造 K 条 候选 信号、 每 条 跑 L1 + L2 诊断、 通过 L3 正交化 与 因 子 中 性 化 把 它 们 残 差 化、 在 L4 用 收 缩 Markowitz 或 stacking 合 成 复合, 然后 把 复合 评 分 交 给 4.4 portfolio construction 转 成 实 际 持 仓。 多 重 检验 inflation 在 整 个 研 究 流 程 上 用 4.2.1 L3 的 deflated-Sharpe 修 正 调 整; 实 际 backtest 与 transaction cost 全 套 framework 在 4.5; risk model 在 4.4.2; 因 子 zoo 与 academic 因子 模型 文 献 在 4.3.1。

课程 组件 (Lesson components)

​Inline-code 列表 五 种 经典 合 成 方法​​:

  1. equal_weight (w = (1/K, ..., 1/K), 稳 健 默 认);
  2. markowitz_optimal (w* = Σ^{-1} * IC, 样本内 最 优);
  3. ledoit_wolf_shrinkage (Σ_shrunk = (1 - τ*) * Σ_sample + τ* * (tr(Σ_sample)/K) * I);
  4. stacking (元 模型 ——linear / ridge / LightGBM);
  5. ensembling (bagging + 跨 视界 model averaging + robust mean)。

量产 复合 = (orthogonalise + combine + regime-check)。

​Inline-code 列表 五 元 复合 诊断 包​​: composite_ir_in_sample_vs_oos (gap > 50% 过 拟 合)、 per_signal_weight_contribution_and_stabilitycomposite_turnover_and_break_even_icregime_conditional_composite_ic (牛市 / 熊市 / 高 波动 / 低 波动)、 shrinkage_benefit (> 0.1 IR 上 线 收 缩 版)。

​Inline-code 列表 Ledoit-Wolf 收 缩 三 步​​: Sigma_sample = numpy.cov(ic_matrix.T)lw = sklearn.covariance.LedoitWolf().fit(ic_matrix)w_shrunk = numpy.linalg.solve(Sigma_shrunk, ic_mean_vector)

​Inline-code 列表 stacking 四 步​​: oof_predictions = purged_kfold_predict(base_signals, target_returns, n_folds=5, embargo=21)meta_model = sklearn.linear_model.Ridge(alpha=1.0)lightgbm.LGBMRanker(...)meta_model.fit(oof_predictions, target_returns)composite_score = meta_model.predict(test_predictions)

​Inline-code 列表 三 种 集成 模 式​​: bagging_across_seeds (5-20 种 子 平 均, 方 差 减少 1/K')、 model_averaging_across_horizons (h=1, 5, 21)、 robust_mean_across_model_families (公式驱动 + 事件驱动 + ML 驱动 三 个 顶 层 输入)。

​Inline-code 列表 四 条 复合 决 策 规 则​​: if T < 5K: ship equal_weightif 5K <= T <= 20K: ship ledoit_wolf_shrinkageif T > 20K: ship markowitz_with_constraintsif shrinkage_benefit < 0.1_IR: prefer equal_weight

两 个 fenced python 块: construct_composite 函数 (五 种 方法 dispatch) 和 ledoit_wolf_markowitz 函数 (协方差 收 缩 + Markowitz 求 解)。

L4 用 到 的 词汇: 组合优化 (portfolio optimization, Markowitz 是 经典 解); 协方差矩阵 (Markowitz 与 收 缩 的 核 心 对 象); 特征值 (协方差 良 态 性 与 病 态 性 由 特 征 值 散 布 决 定); 特征分解 (PCA 与 谱 分 析); Barra 模型 (因 子 模型 的 商 业 实 现); 因子模型 (合 成 前 的 因 子 中 性 化 引 用); 信息比率 (L4 的 头条 指 标); 夏普比率 (复合 与 long-short 组合 的 IR-Sharpe 等 价 性); Alpha 衰减 (跨 验证 集 的 复合 IR 衰减); 交易成本 (复合 换 手率 的 break-even IC 约 束)。

练习

Exercise

给 定 一 个 orthogonal_signals_df (以 (date, symbol) 为 MultiIndex, 四 列 由 L3 对 称 Gram-Schmidt 正交化 产 出: mom_12_1_orth, book_to_market_orth, gross_profitability_orth, pead_sue_orth) 和 一 个 returns_df (以 (date, symbol) 为 MultiIndex, 列 fwd_21d_return), 在 沪深300 universe 上。 用 2018-2022 作 为 样本内 窗 口, 2023 作 为 样本外 窗 口。

(i) 算 等 权重 复合 (w = (0.25, 0.25, 0.25, 0.25)); 报 告 样本内 IR 与 样本外 IR。

(ii) 算 无 约 束 Markowitz 复合 (w* = Σ^{-1} * IC, ΣIC 在 样本内 窗 口 估 计); 报 告 样本内 IR、 样本外 IR、 与 Σ 的 条件 数。

(iii) 用 sklearn.covariance.LedoitWolf 算 Ledoit-Wolf 收 缩 Markowitz 复合; 报 告 最 优 τ*、 样本内 IR、 样本外 IR、 与 收 缩 后 Σ_shrunk 的 条件 数。

(iv) 算 shrinkage benefit = 收 缩 Markowitz 样本外 IR 减 等 权重 样本外 IR; 判 断 量产 复合 应 该 是 收 缩 Markowitz (如 果 shrinkage benefit > 0.1 IR) 还 是 等 权重 (否 则)。

(v) 算 复合 诊断 包 ——样本内-vs-样本外 gap、 每 条 信号 权 重、 在 TC = 10 bps 下 的 复合 换 手率 与 break-even IC、 牛市 / 熊市 / 高 波动 / 低 波动 桶 上 的 regime-conditional 复合 IC。 判 断 复合 是否 可 以 上 4.4 portfolio construction。

提示
等 权重 IR 是 (composite.mean() / composite.std()) * sqrt(12); Markowitz w = numpy.linalg.solve(np.cov(ic_matrix.T), ic_matrix.mean(axis=0)); Σ 条件 数 是 numpy.linalg.cond(Sigma), 大 值 (> 50) 警 示 病 态。
提示
Ledoit-Wolf: lw = sklearn.covariance.LedoitWolf().fit(ic_matrix); tau_star = lw.shrinkage_; weights = numpy.linalg.solve(lw.covariance_, ic_mean); shrinkage benefit > 0.1 IR 是 上 线 收 缩 版 的 门槛。