高 IC + 低换手
排序信息稳定且不常变动,是最省成本的形态。此时要重点核对样本期是否足够长,避免把短期规律当成长期属性。
Alphalens · 换手率与因子 rank 自相关
两个名字里都带「换手」意味的指标经常被当成同一个东西,实际一个算「分位内成分换了多少」,另一个算「因子排名本身有多稳定」。前者直接对应调仓成本,后者描述因子排序的时间连续性——读错一个,成本估算就会差一个量级。
performance.py 中两个函数的 docstring 整理(非官方图);计算方法以源码为准。下表左三列来自源码 docstring,右两列是实际使用时的经验口径(不含任何收益承诺)。
| 对比项 | quantile_turnover(成分换手) | factor_rank_autocorrelation(排序自相关) |
|---|---|---|
| 官方定义 | 某一分位内的标的,在一段时间后被换掉的比例 | 因子平均排名在相邻观测之间的自相关 |
| 输入 | 分位标签(quantile factor)、要看的 quantile 编号、period | factor_data 与 period |
| 取值区间 | 0 到 1,越大表示换得越频繁 | 常见为 0 到 1,越接近 1 表示排名越稳定 |
| 回答的问题 | 如果按这个因子调仓,每次要动多少持仓 | 因子的排序信息会不会很快失效 |
| 典型用法 | 估算调仓成本量级、决定调仓频率 | 判断因子是否适合较低频的调仓 |
| 适用场景 | 有明确持仓周期假设时 | 比较同频因子之间的稳定性时 |
| 注意点 | period 参数直接改变结果:period 越长,换手自然越低 | 只反映排名,不反映因子值差距的实际大小 |
| 报告里怎么写 | 写明「根据 X 日换手率,每次调仓约替换 Y% 的成分」 | 写明「X 日排名自相关为 Y,排序在中期内保持稳定」 |
Alphalens 不会替你算成本,它只给成分替换比例。下面是一个纯量级换算的思考框架,不构成任何收益预测。
| 环节 | 你需要什么输入 | 库给出什么 | 换算思路 | 注意点 |
|---|---|---|---|---|
| 持仓替换比例 | 分位定义与调仓周期 | quantile_turnover 的均值/时序 | 乘以单边交易成本,得到每期成本的粗略量级 | 成本参数必须来自你自己的交易假设,库不给默认值 |
| 排序稳定性 | 因子值与观察窗口 | factor_rank_autocorrelation | 自相关低说明排名频繁变动,隐含换手偏高 | 它不直接给出换手比例,别拿它当换手率用 |
| 持有期选择 | 多个 period 的对照 | 各期换手曲线 | 把 period 与计划调仓周期对齐后再比 | 用短周期换手去论证长周期策略会严重高估成本 |
| 极端分位成本 | 最高/最低分位的换手 | plot_top_bottom_quantile_turnover | 多空两端换手通常高于中间分位 | 多空策略的成本要按两端分别估算 |
代码以源码签名为准;预期输出描述的是形状而非数值,因为数值取决于你的数据。
用 utils.quantize_factor 或直接取清洗后的 factor_data["factor_quantile"]。预期:得到一个名字为 quantile 的 Series,每期每个标的对应一个分位编号。
turnover = alphalens.performance.quantile_turnover(quantile_factor, quantile=5, period=5)。预期:返回时序,数值 0–1;turnover.mean() 给出该周期下的平均替换比例。
autocorr = alphalens.performance.factor_rank_autocorrelation(factor_data, period=1)。预期:返回时序,越接近 1 表示排名越连续;与上一步的换手指标方向相反。
用 plot_top_bottom_quantile_turnover 与 plot_factor_rank_auto_correlation,或直接 create_turnover_tear_sheet。预期:两条曲线同页对照;报告里写明所用的 period 与分位数。
换手率这条路径的使用者比收益与 IC 少,公开 issue 里的问题也更零散。下表按现象归类,每条都能在仓库里找到对应编号。
| 现象 | 可能原因 | 证据 | 处理方式 | 验证方法 |
|---|---|---|---|---|
create_turnover_tear_sheet 直接报错 | 触发了该函数的已知缺陷(公开 issue 有对应报告) | issue #341(2019-06-27)、#377(2020-05-07) | 改用 quantile_turnover + plotting 单独出图 | 同样数据下两条路径结果应一致 |
| 换手率数值异常高 | 统计口径混淆:把逐日换手当成周期换手 | 源码 period 参数语义 | 把 period 与计划调仓周期对齐 | period 越大,turnover 均值应单调下降 |
| 自相关接近 0 | 因子值本身噪声大,或频率与因子属性不匹配 | 源码 docstring | 换更长的 period 观察,或改因子定义 | 与 IC 的期数敏感度结论互相印证 |
| 换手图不显示 | 与 tear sheet 出图类问题同源(渲染/后端) | issue #369 / #370(图不可读、偶发空白图) | 显式指定 Agg 后端后保存,别依赖交互式显示 | 保存出的文件能打开且内容完整 |
| 分位编号与预期不符 | quantize_factor 的编号方向与你的假设相反 | issue #336 / #281(分位/分箱编号与零值处理) | 先打印一组样本核对编号与因子值的大小关系 | 编号越大对应因子值越大或越小,必须明确写进记录 |
| 换手率与自相关结论矛盾 | 两者描述的不是同一件事 | 两个函数 docstring | 不要强行统一:一个看成分,一个看排序 | 在报告中分别陈述,不合并成一个「稳定性」结论 |
单看任一指标都会误导。Alphalens 的三个指标要放在下面四种组合里读,才看得出问题在哪。
排序信息稳定且不常变动,是最省成本的形态。此时要重点核对样本期是否足够长,避免把短期规律当成长期属性。
信号有效但衰减很快,成本会吃掉大部分价差。处理方式通常是把持有期拉长看 IC 还剩多少,而不是直接上日频调仓。
排名几乎不变,但不变的方向没有预测力。这类因子可能只是某种静态暴露(如行业、风格),需要做中性化后重看。
既是噪声又频繁变动,通常意味着因子定义或频率不匹配。先修因子定义,不要靠调参数硬凑。
库只给成分替换比例,成本要自己建模。下面这张图用示例假设演示成本如何吃掉价差,图中的费率不是建议值,必须换成你自己的。
0.7976 与 0.7941,单次调仓成本约 23.88bp,单期价差由 196.10bp(毛)降到 172.22bp(净,示例口径)。仅演示机制,不构成任何收益预期。| 成本项 | 示例假设 | 怎么换成你自己的 | 为什么重要 | 注意点 |
|---|---|---|---|---|
| 佣金 | 单边 5bp(示例) | 用你的券商费率(含最低收费) | 双边都收 | 小额资金时最低收费会显著抬高实际费率 |
| 印花税 | 单边 5bp(示例,按卖出计) | 按当期税率与征收方向 | 只在卖出侧发生 | 税率会调整,需按历史时段分别取 |
| 滑点 | 单边 5bp(示例) | 用你自己的成交回测估计 | 对高频调仓影响最大 | 与大额委托、低流动性标的强相关 |
| 冲击成本 | 未单列(并入滑点示例) | 与成交额占比挂钩建模 | 容量约束的实际来源 | 需按标的成交额设单只上限 |
| 换手口径 | 用 quantile_turnover 的均值 | 逐期换手 × 当期费率,而不是用均值硬乘 | 换手随时间波动,均值会低估高峰期的成本 | 报告里要写明 period |
| 空头可行性 | 示例假设可做空 | 按你的实际约束(是否可融券、成本) | A 股做空约束与美股不同 | 不可做空时,只能用多头相对基准的价差 |
换手率很少单独决定策略是否可行,它总是与持有周期和资金容量绑在一起看。
quantile_turnover(qf, quantile=5, period=P),其中 P 与你计划的调仓周期一致。预期:P 越大,换手均值单调越低;用 1 日换手去论证周频策略会严重高估成本。
把同一 P 的 IC 与换手并列(见「IC 分析」页的衰减曲线)。预期:能找到一段「IC 仍明显为正、换手已明显下降」的区间,这通常就是候选调仓周期。
用标的日均成交额设单只持仓上限(例如不超过日成交额的某个比例,取值自定并写明)。预期:得到该因子在给定资金规模下需要多少个标的才能分散,以及是否需要剔除低流动性标的。
把「费率 × 持有期」做成矩阵,看净价差在哪些格子里仍为正。预期:一张能直接阅读的敏感性表,比一个最优点更有用。
| 权衡维度 | 调短持有期 | 调长持有期 | 判据 | 注意点 |
|---|---|---|---|---|
| IC 水平 | 通常更高(信号未被稀释) | 通常更低 | 看衰减曲线 | 不能只看点数最高的那一期 |
| 换手率 | 更高 | 更低 | 看该周期的换手均值 | period 必须与调仓周期一致 |
| 成本占比 | 更高(可能超过价差) | 更低 | 成本 / 毛价差 | 费率越高,最优周期越靠后 |
| 容量 | 要求更高流动性 | 相对宽松 | 按成交额设上限 | 低流动性标的会先被剔除 |
| 样本量 | 期数多,统计更稳 | 期数少,波动更大 | 非重叠窗口的期数 | 重叠窗口会虚高显著性 |
两个指标的计算口径以 performance.py 的 docstring 与实现为准;报错记录均给出公开 issue 编号。
不是。换手率描述「分位成分被替换了多少」,自相关描述「因子排名在时间上是否连续」。两者通常同向(排名越不稳定、换手越高),但数值不能互相换算,报告里也不该合并成一个结论。
没有通用标准,它完全取决于分位数量、period 与数据频率。可操作的做法是横向比较:同一份数据下,比较不同因子的换手率;或者比较同一个因子在不同 period 下的换手变化趋势。
与你的调仓计划一致。如果你的策略计划每周调仓,就用 5 个交易日作为 period,而不是用 1 天——用 1 天算出的换手率会严重高估实际成本。
只能得到量级估算。真实成本还包含冲击成本、容量限制、以及不同标的流动性差异,这些库都不提供。任何成本估算都应以你自己的交易假设为准,本站不做任何成本或收益承诺。
公开 issue #341 与 #377 记录了该函数的报错。它把多个绘图步骤串在一起,任何一步的参数或版本不兼容都会让整块报告失败。稳妥做法是先用 quantile_turnover 把数算出来,再用 plotting 单独画图。
它们只是研究阶段的描述性统计,不含任何交易建议。是否能用于实际投资,取决于你完整的风控、合规与成本框架;本页所有内容仅供研究参考,不构成投资建议。
在换手类报告与全量 tear sheet 的换手段里,包含分位换手表与自相关曲线。若报告渲染失败,就按上面第 4 步自己画。具体输出结构以你所跑版本的实现为准。
没有已证实集成。换手与自相关必须在装了 Alphalens 的环境里计算;客户端侧的 chart-image 技能只能承担「把已算好的数据画成图」这一步,不参与指标计算。