AI选股Agent全军覆没?LLM交易数据泄露检验:7个SOTA模型仅2个正收益的真相
爆火的多Agent交易框架,收益真的来自AI选股吗?
2026年,AI Agent做量化交易已经从”概念演示”进入了”实盘部署”阶段。TradingAgents、AlphaCrafter等开源框架在GitHub上疯狂刷星,知乎”AI交易Agent”话题阅读量破千万。看起来,让大模型读财报、分析新闻、生成交易信号,已经是触手可及的未来。
但一个问题始终悬在空中:那些漂亮的回测曲线,真的来自AI的”选股能力”吗?
还是因为模型在训练时已经”见过”了未来的数据,所谓alpha不过是数据泄露的幻觉?
这不是杞人忧天。2026年两篇重要论文给出了令人不安的答案:
- PolyBench(arXiv:2604.14199):让7个顶级大模型预测Polymarket事件,仅2个获得正收益,其余5个全部亏损——尽管它们的”陈述置信度”都很高。
- CSI300记忆基准(arXiv:2605.28359):在A股沪深300上测试10个LLM Agent,一旦控制数据泄露,alpha就消失了。
更扎心的是,我自己运行的中证800信号追踪系统,2861条实盘信号的整体胜率只有37.9%。
这篇文章就来做一次彻底的”拷问”:AI选股到底行不行?如果不行,问题出在哪里?
PolyBench实证:7个SOTA大模型,仅2个正收益
PolyBench是第一个基于Polymarket实时数据的多模态LLM预测基准。它的设计相当精巧:
| 维度 | 数据规模 |
|---|---|
| 二元预测市场 | 38,666个 |
| 事件总数 | 4,997个 |
| 评估时间窗口 | 2026-02-06 ~ 02-12 |
| 参评SOTA模型 | 7个 |
| 生成预测总数 | 36,165条 |
测试方式很直接:把Polymarket的订单簿状态和实时新闻流喂给大模型,让它判断事件结局(Yes/No),然后与市场结算结果对比。
结果令人震惊:
模型 CWR(正确率加权收益)
───────────────────────────────────────
MiMo-V2-Flash +17.6% ✅
Gemini-3-Flash +6.2% ✅
Model-C -2.1% ❌
Model-D -8.3% ❌
Model-E -11.7% ❌
Model-F -14.2% ❌
Model-G -19.5% ❌
7个模型中只有2个赚到了钱,5个模型在预测市场上稳定亏钱。更关键的是:所有模型在给出预测时,置信度表述都差不多——它们并不知道自己不知道。
核心发现:语言流畅度 ≠ 真实的概率推理能力。 模型可以说出非常”合理”的分析,但这不代表它真正理解了概率。
这跟投资圈的直觉完全吻合——那些侃侃而谈的分析师,未必比沉默寡言的量化模型赚得多。
CSI300记忆基准:防数据泄露后,alpha消失了
如果说PolyBench测的是LLM的”预测能力”,那么CSI300记忆基准测的是更致命的问题——数据泄露。
这篇论文(arXiv:2605.28359)在A股沪深300上对10个前沿LLM Agent做了2024-2026年的交易回测。设计上的核心创新是四级数据泄露控制协议:
| 级别 | 名称 | 泄露程度 | 说明 |
|---|---|---|---|
| L1 | bright | 严重泄露 | Agent可访问完整历史,含测试期数据 |
| L2 | stock-blind | 中度泄露 | 隐藏股票名称,但保留行业/特征 |
| L3 | date-blind | 轻度泄露 | 隐藏具体日期,但保留时序模式 |
| L4 | blinded | 严格隔离 | 时间、名称均脱敏,仅有裸特征 |
还设计了10个攻击者探针来验证防泄露效果——如果攻击者能从输入中恢复出股票代码(ticker恢复率),就说明泄露没防住。严格的基准要求top-1 ticker恢复率≤3%。
实验结果:
泄露级别 Agent累计收益 选股alpha
──────────────────────────────────────────────
L1 (bright) +15.2% (看起来不错) 似乎有 ✅
L2 (stock-blind) +8.7% 开始衰减 ⚠️
L3 (date-blind) +3.1% 接近消失 ⚠️
L4 (blinded) +1.2% 彻底消失 ❌
结论非常直接:当数据泄露被严格控制在L4级别时,LLM Agent的累计收益几乎完全由被动市场暴露(beta)解释,缺乏持续的选股alpha。
换句话说,L1级别下那15%的”超额收益”,很大程度是因为模型在预训练中已经”见过”了2024-2025年的行情走势。它不是在预测未来,而是在回忆过去。
数据泄露的四种形态:你中招了几种?
数据泄露不是只有”拿测试集训练”这一种。在实际的量化研究中,泄露形态远比想象中隐蔽:
形态1:时间泄露(最常见)
❌ 错误做法:用2015-2025年的全部数据训练因子权重,
然后在2018-2025年回测。
→ 模型"知道"了2018-2025年发生了什么。
✅ 正确做法:Walk-forward滚动验证。
2015-2017训练 → 预测2018;
2015-2018训练 → 预测2019;
...逐步推进。
形态2:特征泄露
用未来的信息计算今天的特征。典型例子:
# ❌ 致命错误:用了未来数据
df['future_return'] = df['close'].pct_change(5).shift(-5) # 往未来看5天
df['ma_cross_signal'] = (df['ma5'] > df['ma20']).astype(int)
# 如果ma_cross_signal的计算间接包含了future_return的信息...
形态3:标签泄露
标签里”藏”了答案。比如预测”明天是否涨停”,但输入特征里包含了涨停板信息。
形态4:LLM预训练泄露(最新且最难防范)
大语言模型在预训练时读过了互联网上所有的财报、新闻、股价讨论。当你让它分析”贵州茅台2024年走势”时,它可能直接调用了训练数据中的记忆,而不是在”推理”。
这就是CSI300记忆基准揭露的核心问题:对LLM Agent来说,数据泄露不只是你输入了什么,还包括它训练时见过什么。
自有数据印证:CSI800信号追踪2861条,均值回归型胜率仅33%
论文数据离我们太远?来看看我自己系统的实盘追踪。
我的量化系统每天对中证800成分股生成交易信号(基于RSI、均线、布林带等指标),然后自动追踪每条信号的次日表现。截至2026-06-17,已积累2861条已验证信号。
整体表现
| 指标 | 数值 |
|---|---|
| 总信号数 | 2,861条 |
| 开盘买入胜率 | 37.9% |
| 平均次日涨幅 | -0.36% |
| 开盘买入均收 | -0.22% |
| 最佳/最差 | +12.49% / -9.54% |
37.9%的胜率意味着:盲跟信号买入,10次里亏6次。
按信号类型拆解
这是最关键的发现:
| 类型 | 信号数 | 胜率 | 均收 |
|---|---|---|---|
| 动量型 | 382 | 53% | +0.58% |
| 均值回归型 | 650 | 33% | -0.29% |
| 混合型 | 1,829 | 36% | -0.36% |
动量型胜率53%、均值回归型仅33%——差距悬殊。
均值回归策略(“跌多了就买”)在A股震荡市中表现极差。RSI超卖不意味着反弹,可能只是持续下行的开始。这跟我之前写的布林带均值回归策略形成了残酷的对照:回测中好看的策略,实盘信号追踪下惨不忍睹。
按市场环境拆解
更反直觉的数据:
| 市场环境 | 信号数 | 胜率 | 均收 |
|---|---|---|---|
| 多头(>1) | 251 | 18% | -0.95% |
| 中性(-1~1) | 892 | 30% | -0.51% |
| 空头(<-1) | 1,718 | 45% | +0.04% |
空头市场买入胜率反而最高(45%),多头市场最差(18%)。 这完全违背了”顺势而为”的直觉。
合理的解释是:多头市场信号扎堆,大量投资者同时涌入推高了买入成本;空头市场反而是”恐慌性出清”后的反弹机会。这跟PolyBench的发现异曲同工——直觉和”合理分析”在市场中往往不靠谱。
爆发日 vs 衰退日
2026-06-10: 90只信号 | 胜率33% | 均收-0.31%
2026-06-11: 102只信号 | 胜率84% | 均收+1.68% ← 爆发日
2026-06-12: 54只信号 | 胜率80% | 均收+1.65% ← 爆发日
2026-06-15: 45只信号 | 胜率49% | 均收+0.62%
2026-06-16: 58只信号 | 胜率47% | 均收+0.50%
6/11-6/12的爆发日,胜率从33%跳升到84%。这两天发生了什么?市场从震荡转多的转折点,动量型信号集体发力。6/16的昊华科技信号分+3,次日涨+11.93%。
教训:策略收益的80%来自20%的爆发日,大部分时间信号是亏钱的。 如果你的回测把爆发日的收益”平滑”了,实盘体感会完全不同。
实操:用Python构建数据泄露检测探针
了解了泄露的危害,怎么在实际项目中检测和防范?以下是一个简化的数据泄露检测框架,灵感来自CSI300记忆基准的攻击者探针设计。
Step 1: 时间泄露检测器
import pandas as pd
import numpy as np
def check_time_leakage(features_df, label_series, max_lag=5):
"""
检测特征中是否包含未来信息。
核心思路:如果用今天的特征能"预测"明天的标签,
但用明天的特征预测今天的标签也work,说明有泄露。
"""
results = []
for col in features_df.columns:
# 正向:今天特征 → 明天标签
fwd_corr = features_df[col].corr(label_series.shift(-1))
# 反向:明天特征 → 今天标签(不应有相关性)
bwd_corr = features_df[col].shift(-1).corr(label_series)
if abs(bwd_corr) > 0.1 and abs(bwd_corr) > abs(fwd_corr) * 0.5:
results.append({
'feature': col,
'forward_corr': round(fwd_corr, 3),
'backward_corr': round(bwd_corr, 3),
'status': '⚠️ 疑似泄露'
})
return pd.DataFrame(results)
# 使用示例
leakage_report = check_time_leakage(X_train, y_train)
print(leakage_report)
Step 2: Walk-Forward回测框架
from sklearn.model_selection import TimeSeriesSplit
def walk_forward_backtest(model, X, y, n_splits=5):
"""
严格的时间序列前向验证。
每次只用过去数据训练,预测未来。
"""
tscv = TimeSeriesSplit(n_splits=n_splits)
results = []
for i, (train_idx, test_idx) in enumerate(tscv.split(X)):
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
model.fit(X_train, y_train)
pred = model.predict(X_test)
win_rate = (np.sign(pred) == np.sign(y_test)).mean()
results.append({
'fold': i + 1,
'train_period': f"{X_train.index[0].date()} ~ {X_train.index[-1].date()}",
'test_period': f"{X_test.index[0].date()} ~ {X_test.index[-1].date()}",
'win_rate': f"{win_rate:.1%}",
'avg_return': f"{(pred * y_test).mean():.2%}"
})
return pd.DataFrame(results)
Step 3: LLM预训练泄露探针
如果你在用LLM生成交易信号,最关键的检测是:模型是否在”回忆”而非”推理”?
import json
def probe_llm_memorization(llm_client, stock_data, test_dates):
"""
用三种方式提问同一只股票,检测LLM是否在用记忆。
如果脱敏后的预测能力大幅下降,说明存在预训练泄露。
"""
results = {'bright': [], 'stock_blind': [], 'date_blind': []}
for date in test_dates:
row = stock_data.loc[date]
# L1 bright: 完整信息(可能泄露)
prompt_bright = f"股票{row['name']}({row['code']})在{date}的RSI={row['rsi']:.1f},请预测明日涨跌。"
# L2 stock-blind: 隐藏名称
prompt_blind = f"某A股股票,行业={row['industry']},RSI={row['rsi']:.1f},MA20偏离={row['ma20_dev']:.1%},请预测明日涨跌。"
# L3 date-blind: 隐藏日期
prompt_date = f"股票{row['name']}({row['code']})某日的RSI={row['rsi']:.1f},请预测次日涨跌。"
results['bright'].append(llm_client.predict(prompt_bright))
results['stock_blind'].append(llm_client.predict(prompt_blind))
results['date_blind'].append(llm_client.predict(prompt_date))
# 如果bright准确率远高于stock_blind,说明模型在用名称"回忆"历史走势
return results
判断标准:如果bright模式准确率 > stock-blind + 10个百分点,高度怀疑预训练泄露。模型是通过”知道这是茅台”来回忆茅台的历史走势,而不是在分析RSI。
结论与避坑:AI选股要先过数据泄露这道坎
汇总三组数据的结论:
| 数据来源 | 核心发现 | 启示 |
|---|---|---|
| PolyBench (7个SOTA) | 仅2/7正收益 | 语言流畅度 ≠ 概率推理能力 |
| CSI300记忆基准 | L4防泄露后alpha消失 | LLM的”alpha”很大程度是预训练记忆 |
| 自有CSI800追踪 (2861条) | 整体胜率37.9%,均值回归33% | 实盘信号追踪是检验策略的唯一标准 |
五条避坑建议
- 永远用Walk-Forward回测。不要用固定分割,时间序列必须滚动验证。
- 检测LLM预训练泄露。用bright/stock-blind/date-blind分级测试,如果脱敏后预测能力断崖下降,那不是alpha是记忆。
- 运行实盘信号追踪。回测说得再好听,不如跑3个月信号追踪看真实胜率。我的系统从2861条追踪中学到的东西,比任何回测都多。
- 区分动量和均值回归。在A股震荡市中,动量型信号(53%胜率)远优于均值回归型(33%)。不要盲目套用”超卖买入”逻辑。
- 警惕爆发日依赖。如果策略80%的收益来自20%的日子,那它在”普通日子”里可能是亏钱的。实盘体感会远差于回测曲线。
AI Agent在量化交易中的价值,不在于”选股能力”(至少目前不是),而在于自动化数据管线、信号监控、风险预警这些”工程层面”。 关于这一点,我在AI Agent量化交易自动化实战中做过详细讨论。
AI选股的路还很长。但在谈论alpha之前,请先确认你的收益不是泄露的幻觉。
本文数据来源:PolyBench (arXiv:2604.14199)、CSI300记忆基准 (arXiv:2605.28359)、AlphaCrafter (arXiv:2605.05580)、自有CSI800信号追踪系统(cron 21ca2f58b097,2861条已验证信号)。