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

信号衰减、换手率与容量

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

周三下午,你在上海的一家 量化 私募。L1 走通了 12-1 动量 的 IC 与 IR 报告,头条 数字 是 月度 rank IC ≈ 0.03、 IR ≈ 0.5。 在 投决会 上 提交 前,合规 与 交易 部门 同时 提了 三 个 问题:这个 IC 在 多 长 视界 上 仍然 有效? 月度 跑 一遍 会 产生 多大 换手率? 等到 私募 规模 上到 5 亿 元 RMB,这条 信号 还能 不能 用? 这 三 个 问题 不能 靠 一个 IC 数字 回答——它们 是 单 信号 评估 的 时间规模 维度。 本课 教 你 怎么 答:衰减 曲线 与 半衰期、 换手率 与 break-even IC、 容量 与 平方根 冲击 模型——加 起来 是 L1 IC 包 之外 的 三 个 额外 诊断,合 在 一起 才 让 一条 信号 可 上线 评议。

L2 的 三 元 诊断

L1 给 一条 信号 一个 视界 的 IC 与 IR; L2 把 视界 扩展 为 多个 视界 并 引入 换手率 与 容量。 三 元 诊断 的 顺序 是 固定 的:(1) decay_curve IC(h) 在 h ∈ {1, 5, 21, 63, 252} 日 上,带 half_life 作为 摘要; (2) turnover(单 边 每 期、 年化、 附 现实 交易成本 下 的 break_even_ic); (3) capacity(用 平方根 冲击 模型 计算,带 AUM-at-which-IR-drops-50% 基准)。

规则:​​每个 信号 在 L1 IC 包 之外,必须 携带 时间 与 规模 三 元 诊断;缺 任一 项,无法 在 组合 中 定 仓位。​

衰减 曲线

衰减 曲线 的 五 个 标准 视界 是 h = 1, h = 5, h = 21, h = 63, h = 252 个 交易日。 在 沪深300 universe 上 取 12-1 动量 信号,在 每个 视界 算 一条 rank IC 时间序列,得到 5 个 IC 数字。 把 它们 画 出来,IC(h) 随 h 的 单调 变化 形状 就是 衰减 曲线。 半衰期 h_{1/2} 是 IC 降到 峰值 一半 时 对应 的 视界。

按 衰减 速度 给 信号 分 三 类:fast(h_{1/2} < 10 日, 短 视界 信号,例如 5 日 反转、 流动性 偏离);medium(10-60 日, 中 视界 信号,例如 60 日 残差 动量);slow(> 60 日, 长 视界 信号,例如 价值、 质量、 12-1 动量)。 慢 衰减 信号 在 月度 调仓 上 换手率 低、 容量 高,适合 大 资金;快 衰减 信号 需 高频 调仓,适合 高 频 / 中 频 套利 而 不是 大 容量 组合。 12-1 动量 在 沪深300 上 通常 是 慢 衰减 信号,h_{1/2} > 60 日,IC 在 h = 1, 21, 63 上 大致 平 缓。

下面 是 衰减 曲线 的 计算 函数:

import pandas as pd
import numpy as np
from scipy.stats import spearmanr

def decay_curve(signal: pd.Series, prices: pd.DataFrame, horizons=(1, 5, 21, 63, 252)) -> pd.DataFrame:
    # 1. 对 每个 视界 h 计算 前瞻 收益
    rows = []
    for h in horizons:
        fwd = prices.pct_change(h).shift(-h)
        # 2. 在 每个 调仓日 按 横截面 用 spearmanr 算 rank IC
        df = pd.concat({'s': signal, 'r': fwd.stack()}, axis=1).dropna()
        ic_t = df.groupby(level='date').apply(
            lambda g: spearmanr(g['s'], g['r']).statistic)
        # 3. 汇总 mean / std / t_stat
        rows.append({'h': h, 'mean_ic': ic_t.mean(), 'std_ic': ic_t.std(),
                     't_stat': ic_t.mean() / (ic_t.std() / np.sqrt(len(ic_t)))})
    return pd.DataFrame(rows).set_index('h')

decay_curve 的 函数名、参数 signal / prices / horizons、默认 元组 (1, 5, 21, 63, 252),以及 返回 列 mean_ic / std_ic / t_stat,在 中英 两版 中 字节 一致;仅 注释 翻译。

信号 自相关 与 换手率

慢 衰减 信号 的 一个 必然 后果:corr(signal_t, signal_{t-1}) 高。 月度 调仓 的 公式驱动 信号 在 日度 上 的 自相关 在 沪深300 上 通常 是 0.85-0.95;日度 重新计算 的 量价 信号 略 低,在 0.3-0.5;只 在 季报 更新 的 基本面 信号 超过 0.98。 自相关 高 意味着 换手率 低——信号 本身 是 持续 的。

换手率 的 操作 定义:相邻 两 期 信号 向量 的 L1 距离 除以 信号 自身 的 L1 范数:

turnovert=stst11st1\text{turnover}_t = \frac{\|s_t - s_{t-1}\|_1}{\|s_t\|_1}

这是 单 边 每 期 换手率。 年化 单 边 换手率 是 per_period_turnover * rebalance_freq(月度 调仓 时 rebalance_freq = 12); 双 边 / 往返 换手率 是 单 边 的 两 倍 (一买 一卖)。 一 个 0.1 的 单 边 每 期 换手率 意味着 每 期 组合 中 10% 的 资金 被 调仓 流动。

4.2.2 L1 的 清洗 流水 (winsorise -> rank -> z-score -> 行业 中性化 -> shift(1)) 会 平滑 信号 序列,降低 换手率;cross-sectional rank 把 噪声 信号 的 单 边 换手率 通常 从 0.3 降到 0.15-0.2。 涨跌停 板 在 沪深300 上 进一步 限制 换手——限制 板 当日 不可 成交 部分 折算 到 下 一 可交易日,这 反 而 让 实际 执行 的 换手率 略 低于 理论 计算。

Break-even IC

只 算 IC 不 看 换手率 等于 让 alpha 衰减 之前 的 显著性 数字 蒙蔽 你。 在 沪深300 上 一个 200% 年化 单 边 换手 的 信号,在 10 bp 往返 交易成本 下,光 摩擦 就 吃掉 2% 的 年化 收益。 break-even IC 是 这个 摩擦 反过来 折算 成 月度 IC 的 那个 数字:

ICbreak_evenTCannual_turnoverσrBR\text{IC}_{\text{break\_even}} \approx \frac{TC \cdot \text{annual\_turnover}}{\sigma_r \cdot \sqrt{BR}}

四 个 参数 在 公式 中 的 顺序 和 含义:(1) TC = 每 次 交易 往返 成本 (基点); (2) annual_turnover = 年化 单 边 换手率; (3) sigma_r = 横截面 收益 离散度; (4) BR = L1 的 广度。 规则 是 「实际 IC 低于 break-even IC 的 信号 无 量产 价值」——这是 一个 净 alpha 的 门槛,不是 IC 显著性 检验 的 门槛。 在 沪深300 上 (sigma_r ≈ 3% 月度, BR = 12, annual_turnover = 200%, TC = 10 bp 往返),break-even IC ≈ (10 * 2) / (300 * sqrt(12)) ≈ 0.019——所以 沪深300 上 的 公式驱动 信号 量产 门槛 大约 是 月度 IC ≈ 0.02。

下面 是 换手率 与 break-even IC 的 一体 计算:

import numpy as np

def turnover_and_break_even(signal: pd.DataFrame, tc_bps: float, sigma_r: float,
                            br: int, rebalance_freq: int = 12) -> dict:
    # 1. 单 边 每 期 换手率: L1 距离 除以 信号 L1 范数
    diff = signal.diff().abs().sum(axis=1)
    norm = signal.abs().sum(axis=1)
    per_period_turnover = (diff / norm).mean()
    # 2. 年化 单 边 换手率
    annual_turnover = per_period_turnover * rebalance_freq
    # 3. break-even IC: TC * annual_turnover / (sigma_r * sqrt(BR))
    break_even_ic = (tc_bps / 10000.0 * annual_turnover) / (sigma_r * np.sqrt(br))
    return {'per_period_turnover': per_period_turnover,
            'annual_turnover': annual_turnover, 'break_even_ic': break_even_ic}

turnover_and_break_even 的 函数名、 参数 signal / tc_bps / sigma_r / br / rebalance_freq、 以及 返回 字典 的 三 个 键,在 中英 两版 中 字节 一致;仅 注释 翻译。

平方根 冲击 模型 与 容量

容量 是 规模 维度: 在 多大 AUM 上,这条 信号 还 保持 它 在 纸面 IR 的 50%? 答案 来自 Almgren-Chriss 2000 的 平方根 市场冲击 模型:

impact(Q)kσrQ/ADV\text{impact}(Q) \approx k \cdot \sigma_r \cdot \sqrt{Q / ADV}

三 个 变量:(1) Q = 单 笔 交易 美元 / 元 规模;(2) ADV = 平均 日 美元 / 元 成交量;(3) k = 市场 特定 常数 (沪深300 在 ~0.3-0.6, 显著 高于 美股 大盘 的 0.1-0.3, 主因 是 散户 主导 与 机构 流动性 较低)。 由 此 反推 容量 公式:capacity ≈ ADV * (alpha_per_period / (k * sigma_r))^2——容量 与 universe ADV 成 线性 关系, 与 期望 仓位 大小 成 反 平方 关系。

Formula Explorer

impact(Q) = k * sigma_r * sqrt(Q / ADV)

沪深300 上 一个 月度 12-1 动量 信号, sigma_r ≈ 3%, alpha_per_period ≈ 0.03 * 3% = 0.09%(月度), ADV(沪深300 成员 加总)≈ 5000 亿 元 RMB / 日, k = 0.4——代入 得 capacity ≈ 5000亿 * (0.0009 / (0.4 * 0.03))^2 ≈ 5000亿 * 0.0056 ≈ 28 亿 元 RMB(月度 调仓 一次 性 持仓 上限)。 私募 业 (明汯、 幻方、 九坤、 灵均、 鸣 石) 单 信号 量产 容量 通常 在 2-20 亿 元 RMB; 多 信号 复合 容量 在 10-50 亿 元 RMB——明汯 公开 报告 总 AUM ~600 亿 元 RMB 拆 到 数 十 个 复合 与 策略 上。

涨跌停 板 在 容量 上 是 二阶 约束: 限制 板 日 的 可执行 流动性 为 零, T+1 结算 阻止 日内 平仓——两 者 在 容量 估算 时 拉低 ADV 的 有效 值。 stamp duty (印花税 0.05%) 单 向 收取(卖 出 端),换手率 高 的 信号 受 影响 更大;事件驱动 信号 (买入 后 等待 drift 完成 再 卖) 的 换手率 比 公式驱动 信号 (双向 频繁) 低,因此 TC 摩擦 也 更低。 量化 私募 业内 的 通行 计算 是 沪深300 上 大盘 单 信号 round-trip TC ~10-15 bp = (佣金 ~3 bp) + (半 价差 ~2-3 bp) + (印花税 ~5 bp,实际 round-trip ~5 bp) + (市场冲击 ~2-3 bp)。

L2 三 元 诊断 与 整合

把 三 个 数字 加 在 L1 IC 包 后面: 衰减 曲线 (附 半衰期)、 年化 单 边 换手率 (附 break-even IC)、 容量 (附 AUM-at-which-IR-drops-50% 基准)。 这 是 单 信号 完整 诊断 的 时间 与 规模 部分。 12-1 动量 在 沪深300 上 的 期望 数字: 衰减 曲线 在 h = 1, 21, 63 上 大致 平 (慢 衰减, h_{1/2} > 60 日); 月度 调仓 单 边 年化 换手率 ~180%; 在 10 bp 往返 TC 下 break-even IC ≈ 0.02; 容量 ~10-30 亿 元 RMB——所以 信号 是 量产 候选 且 还 没 用 到 容量 上限。

L1 + L2 一起 是 信号 评估 的 全 集; L3 进入 多 信号 卫生 步骤 正交化 (orthogonalisation), L4 是 复合 合成。 L2 名 「实际 backtest 的 IR 在 4.5.1 工程 化 backtest engine 之后 才 是 量产 真正 在 看 的 数字」 一次 并 转向 L3; 实际 backtest 与 撮 合 模型、 滑点 模拟 是 4.5 的 主题, transaction cost 全 套 框架 是 4.5.2 的 主题。 alpha 衰减 与 信号 漂移 在 L2 的 衰减 曲线 上 是 横截面 数字, 它 衍生 的 因子模型 暴露 调整 是 L3 的 因子 中性化 工序; 信号 的 因子载荷 与 风险 模型 的 全 套 framework 是 4.4.2 的 主题。

与 L3 的 衔接

L2 完成 后 你 有 一 条 完整 的 单 信号 评估: IC + IR + Grinold-Kahn (L1) + 衰减 + 换手 + 容量 (L2)。 但 在 现实 的 研究 流程 中,你 同时 拥 有 K 条 信号,且 它 们 的 IC 在 横截面 上 互相 相关; 一个 0.03 月度 IC 的 信号 加 上 另 一 个 0.03 月度 IC 的 信号 不 必然 给 你 0.04 的 复合 IC——通常 拿 到 0.032。 L3 引入 信号 卫生 步骤 正交化: 把 K 个 相关 信号 残差化 成 K 个 互相 正交 的 信号,只 用 它 们 的 边际 IC 作为 复合 输入。 这 是 多 信号 评估 的 第一 步,也 是 4.2.3 craft 从 单 信号 走向 复合 的 关键 跨度。

课程 组件 (Lesson components)

​Inline-code 列表 L2 的 三 个 诊断 维度​​:

  1. decay_curve IC(h) 在 h ∈ {1, 5, 21, 63, 252} 日 上, 附 half_life 作为 摘要;
  2. turnover (单 边 每 期、 年化、 附 现实 TC 下 的 break_even_ic);
  3. capacity (用 平方根 冲击 模型 计算, 附 AUM-at-which-IR-drops-50% 基准)。

每 个 信号 在 L1 IC 包 之外, 必 须 携带 时间 与 规模 三 元 诊断。

​Inline-code 列表 衰减 曲线 的 五 视界 集​​: h = 1, h = 5, h = 21, h = 63, h = 252 日。 衰减 分 类: fast (半衰期 < 10 日)、 medium (10-60 日)、 slow (> 60 日)。

​Inline-code 列表 break-even IC 公式 的 四 个 组件​​: IC_break_even ≈ TC * annual_turnover / (sigma_r * sqrt(BR)),其中 TC = 每 笔 往返 TC (bp), annual_turnover = 年化 单 边 换手率, sigma_r = 横截面 收益 离散度, BR = L1 广度。 实际 IC 低 于 break-even IC 的 信号 无 量产 价值。

​Inline-code 列表 平方根 冲击 模型 的 三 个 组件​​: impact(Q) ≈ k * sigma_r * sqrt(Q / ADV), Q 是 单 笔 美元 / 元 规模, ADV 是 平均 日 美元 / 元 成交量, k 是 市场 特 定 常数 (沪深300 在 ~0.3-0.6 区 间)。 容量 公式: capacity ≈ ADV * (alpha_per_period / (k * sigma_r))^2

两 个 fenced python 块: decay_curve 函数 (按 视界 算 rank IC, 返回 索引 为 h、 列 为 mean_ic / std_ic / t_stat 的 DataFrame) 和 turnover_and_break_even 函数 (单 边 每 期 + 年化 + break-even IC, 返回 per_period_turnover / annual_turnover / break_even_ic 字典)。

本 模块 用 到 的 词汇 还 有: 信息比率 (IR ——L1 引入, 在 break-even IC 框架 中 复用); Alpha 衰减 (本 课 中 心 主题); 涨停 (CN 大 盘 的 限制 板 影响 衰减 曲线 与 容量); T+1 结算 (CN A 股 与 美股 都 在 2024 年 5 月 28 日 后 T+1, 影响 日内 交易 但 不 影响 日 度 信号)。 滑点、 市场冲击、 交易成本 是 L2 的 三 个 核心 词汇, 与 break-even IC 框架 直接 挂钩。

练习

Exercise

给定 一个 signal_df (以 (date, symbol) 为 MultiIndex, 列 mom_12_1) 和 一个 prices_df (以 (date, symbol) 为 MultiIndex, 列 close),在 沪深300 universe 上、 2018-2023 范围 内 完成 五 项 任务。

(i) 在 h ∈ {1, 5, 21, 63, 252} 日 上 用 rank IC 计算 衰减 曲线; 把 IC 降到 峰值 一半 时 的 视界 报告 为 半衰期; 把 信号 分 类 为 fast / medium / slow 衰减 类型。

(ii) 在 月度 调仓 (一个 信号 观测 对应 21 个 交易日) 下 计算 年化 单 边 换手率。

(iii) 在 TC = 10 bps 往返、 sigma_r = 3% 月度、 BR = 12 下 计算 break-even IC。

(iv) 用 平方根 冲击 模型 (k = 0.4 沪深300 大盘 大致 数值) 与 universe 日 美元 / 元 成交量 计算 信号 容量; 把 IR 跌 到 纸面 IR 50% 时 的 AUM 报告 为 标准 容量 数字。

(v) 把 L1 的 实际 IC 与 break-even IC 对比; 判断 信号 是否 还 有 正 的 扣除 成本 后 IC, 并 推 出 扣除 成本 后 隐含 IR 的 大致 数字。

提示
衰减 曲线 在 每个 视界 上 重新 计算 corr(s_t, fwd_h_t); 用 pandas.pct_change(h).shift(-h) 拿 到 视界 h 的 前瞻 收益, 然后 在 (date, symbol) 上 与 信号 对齐。
提示
换手率 是 signal.diff().abs().sum(axis=1) / signal.abs().sum(axis=1) 的 时间 均值, 然后 年化 乘 12; 容量 公式 ADV * (alpha_per_period / (k * sigma_r))^2 给 AUM-at-50% 数字。