元标注 Meta-Labeling:把方向和仓位拆成两个模型
让一个 ML 模型直接预测涨跌,是金融机器学习最拥挤也最失败的路线。López de Prado 的元标注换了问法:先让一级模型(哪怕是最朴素的 MA 金叉)定方向,再训练一个二级模型只回答『这次信号该不该信、信多少』——标签是一级信号经三重障碍结算的对错(1/0),特征是信号发出时的市场状态。合成双状态市场(趋势市动量延续、震荡市均值回归)实测:胜率 59% 的金叉策略,经元模型过滤后精确率从 63% 提到 74%,代价是放掉 29% 的赚钱机会——用召回率换精确率正是交易想要的不对称;样本外净值三连跳:全执行 Sharpe 0.56 / 回撤 23%,过滤后 1.37 / 16%,概率仓位(size ∝ 2P−1)1.86 / 4.9%。打开黑箱看元模型学到了什么:趋势市金叉胜率 69% vs 震荡市 57%——它学会的是『什么时候该信趋势策略』这个 regime 判断,而这正是人类交易员最难量化坚持的纪律。三个诚实警告:元模型天花板受一级信号质量约束(垃圾进垃圾出)、双层结构过拟合风险翻倍(元特征应克制在个位数)、概率校准是仓位函数的前提(先看校准图再谈 Kelly)(中高阶)。
一句话版本#
元标注不让机器学习预测涨跌,只让它预测「我的策略这次信号会不会赚钱」——方向交给一级模型(规则、基本面、任何东西),二级模型专职决定做不做、做多大。方向与仓位解耦后,各自的问题都变简单了。
一、问题:让 ML 直接预测方向,为什么总是失败#
金融机器学习最直觉的用法是端到端:特征进、涨跌概率出。这条路线拥挤且失败率极高,原因可以压缩成一句话:方向预测是金融里信噪比最低的问题,而 ML 最擅长的恰恰不是这个。
日频价格方向的可预测成分通常只有百分之几,剩下全是噪声。让一个高容量模型在这种信噪比下学习,它大概率学到的是噪声的形状。更糟的是端到端模型输出的概率没有操作语义——0.53 的「上涨概率」该满仓还是空仓?没人知道,因为这个概率既混合了方向判断又混合了幅度预期,还没校准。
López de Prado 在 AFML 里提出的元标注(meta-labeling)把问题拆开:
- 一级模型管方向:可以是 MA 金叉、基本面打分、甚至人的判断。它不需要多准,只需要提供一个有微弱正期望的方向;
- 二级模型(元模型)管确信度:输入一级信号发出时的市场状态,输出「这次信号会赚钱的概率」。它是一个纯粹的二分类问题——标签就是一级信号经三重障碍结算后的对错。

这个拆分的妙处在于两个子问题都比原问题好解。方向问题交给了有经济学直觉支撑的规则(趋势、价值、套利逻辑),不需要 ML 在噪声里硬找;元模型面对的则是一个平衡得多的二分类——一级策略的胜率通常在 40%–60% 之间,正负样本天然接近均衡,且「策略何时失效」往往真的有可学的结构(波动状态、趋势强度、流动性环境)。
二、构造:标签来自三重障碍,特征来自信号时刻#
实验用合成的双状态市场:趋势市里动量延续(金叉后倾向继续涨),震荡市里均值回归(金叉往往是局部顶)。一级模型是最朴素的 MA(10)/MA(40) 交叉——金叉做多、死叉做空。全样本 176 次信号,整体胜率 59.1%:有正期望,但平庸。
元标签的构造只有两步:
import numpy as np
import pandas as pd
def make_meta_labels(price, signals, sigma, mult=2.0, max_hold=15):
"""
signals: [(t0, side)] 一级模型的信号时刻与方向 (+1/-1)
返回每个信号的元标签:1 = 一级信号做对了(触及盈利侧障碍)
"""
rows = []
for t0, side in signals:
w = mult * sigma[t0] * np.sqrt(max_hold / 2)
p0 = price[t0]
up, dn = p0 * (1 + w), p0 * (1 - w)
end = min(t0 + max_hold, len(price) - 1)
label = None
for t in range(t0 + 1, end + 1):
if price[t] >= up:
label = 1 if side == 1 else 0 # 多头触上=对,空头触上=错
break
if price[t] <= dn:
label = 0 if side == 1 else 1
break
if label is None: # 垂直障碍:按方向调整后的收益符号
label = 1 if (price[end] / p0 - 1) * side > 0 else 0
rows.append({"t0": t0, "side": side, "meta_label": label})
return pd.DataFrame(rows)
def meta_features(price, ma_fast, ma_slow, sigma, t, side):
"""元特征:信号发出时刻的市场状态(全部只用 t 时刻及之前的数据)"""
trend = abs(ma_fast[t] / ma_slow[t] - 1) / (sigma[t] * np.sqrt(20))
mom20 = (price[t] / price[t - 20] - 1) / (sigma[t] * np.sqrt(20))
# 效率系数:净位移/总路程,趋势市高、震荡市低
path = np.abs(np.diff(price[t - 20:t + 1])).sum()
eff = abs(price[t] - price[t - 20]) / (path + 1e-9)
return [trend, sigma[t] * 100, mom20 * side, eff]python两个设计决策值得注意:
mom20 * side:动量与信号方向相乘,让特征表达「市场是否顺着信号方向走」,多空信号共享同一个模型;- 效率系数(efficiency ratio):20 日净位移除以总路程,是区分趋势市/震荡市最便宜的特征——趋势市接近 1,震荡市接近 0。元模型的核心任务就是 regime 识别,这个特征直接命中要害。
元模型本身用最简单的逻辑回归。这是刻意的:元模型的样本量等于一级信号数(这里训练集只有 105 个),上任何高容量模型都是过拟合请柬。
三、实测:召回率换精确率,净值三连跳#
按时间 60/40 切分,样本外 71 个信号。先看元模型过滤(只执行预测概率 > 0.5 的信号)做了什么交易:

精确率从 63.4% 提升到 74.4%,代价是召回率降到 71.1%——放掉了约 29% 的赚钱机会。这个交换在分类学里是中性的,在交易里是净赚的:错过机会的成本是零(不亏钱),执行坏信号的成本是真金白银加回撤。交易天然偏好精确率,元标注就是把这个偏好显式写进系统的机制。
再看钱。三种执行方式,同一个一级策略:

| 执行方式 | Sharpe | 最大回撤 |
|---|---|---|
| 一级模型全执行 | 0.56 | 23.4% |
| 元模型过滤(P>0.5 等权) | 1.37 | 16.1% |
| 元模型概率仓位(size ∝ 2P−1) | 1.86 | 4.9% |
概率仓位是元标注的完全体:size = min(cap, k·max(0, 2P−1))——概率刚过 0.5 时仓位接近零,确信度高才上量。它比硬阈值过滤多赚的部分,恰恰来自「半信半疑的信号小仓试、高确信的信号重仓上」这个连续化决策。回撤从 23% 压到 5% 不是因为方向判断变准了(方向还是那个金叉),而是资金暴露的分配从均匀变成了按确信度加权。
四、打开黑箱:元模型学到了什么#
元模型不是玄学,它学到的东西可以直接检查。按效率系数中位数把样本外信号分成两组:

趋势市(高效率系数)里金叉胜率 69.4%,震荡市里只有 57.1%。 元模型学会的核心规律一句话可以说完:趋势策略只该在趋势市里被信任。 左图的概率分箱确认这个学习是可用的——预测概率高的分箱实际胜率也高,样本外校准基本贴对角线。
这个发现值得停一秒。「震荡市别用趋势策略」是每个交易员都会背的常识,但人类执行这条纪律的记录很差:连亏三次金叉后放弃策略,恰好错过趋势启动;趋势末端浮盈上头,重仓接了最后一棒。元模型做的事情就是把这条纪律变成一个每次信号都冷静执行的数字。元标注框架的深层价值不在预测,在纪律的机械化。
这也解释了元标注为什么对「人类策略」特别有用:基金经理的选股、宏观判断、甚至聊天群里的荐股,只要能整理出历史信号序列和结算结果,都可以套一个元模型来学习「这个信号源在什么条件下靠谱」。一级模型不必是代码。
五、三个诚实的警告#
警告一:元模型救不了没有期望的一级信号。 元标注的数学上限是一级信号里本来就存在的正期望子集。如果金叉在这个市场里彻底无效(胜率 50%、盈亏比 1),元模型最多学会「全都别做」——这其实也有价值(省了交易成本和时间),但别指望它点石成金。垃圾进,垃圾出,元标注只是把垃圾分类做得更好。
警告二:双层结构的过拟合风险是叠加的。 一级模型的参数(均线周期)+ 元模型的特征选择 + 概率阈值 + 仓位函数系数,自由度比单模型系统多一倍。防线有三条:元特征控制在个位数且每个都要有先验说得通的理由(本文只用 4 个);元模型用低容量模型(逻辑回归、浅树);训练测试严格按时间切分并对重叠事件做 purge。本文实验的 Sharpe 1.86 是合成数据上的演示值,真实市场里元标注的典型贡献是把 Sharpe 提升 20%–50%,不是翻三倍。
警告三:概率校准是仓位函数的前提。 size ∝ 2P−1 隐含假设 P 是真实频率意义上的概率。如果元模型输出的 0.7 实际只对应 55% 胜率(过度自信),仓位函数会系统性重仓在不该重仓的地方——比不用仓位函数更糟。上线前必须画校准图(预测概率分箱 vs 实际胜率),树模型和神经网络通常需要额外做 Platt scaling 或 isotonic 校准;逻辑回归天然校准较好,这是本文选它的另一个理由。
A 股落地的补充:T+1 意味着元模型过滤掉的信号省下的不只是亏损,还有一整天无法撤出的暴露;做空侧信号在个股层面不可执行,元标注框架下可以把死叉信号重新解读为「平多仓 + 空仓等待」,元模型此时预测的是「该不该清仓」——框架不变,语义换掉即可。
六、总结#
- 端到端预测方向是在金融最低信噪比的问题上硬碰硬;元标注把问题拆成方向(一级模型)× 确信度(元模型),两个子问题各自变简单;
- 元标签 = 一级信号经三重障碍结算的对错;元特征 = 信号时刻的市场状态(趋势强度、波动水平、效率系数),方向乘进动量特征让多空共享模型;
- 实测链条:精确率 63%→74%(放掉 29% 机会),净值 Sharpe 0.56→1.37(过滤)→1.86(概率仓位),回撤 23%→5%——提升主要来自资金暴露按确信度重分配;
- 元模型学到的本质是 regime 纪律(趋势市才信趋势策略),它的价值是把人类最难坚持的纪律机械化;
- 三条红线:一级信号必须自带正期望、元特征克制在个位数、仓位函数上线前先验证概率校准。
元标注是 AFML 三件套的第二块:三重障碍给标签,元标注给仓位,唯一性加权和 Purged CV 守住验证环节。缺一块,另外两块的可信度都要打折。
本文使用合成数据演示方法论,所有数值为受控模拟结果,不构成投资建议。