AI AgentLLM交易数据泄露回测陷阱多Agent量化

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年的交易回测。设计上的核心创新是四级数据泄露控制协议

级别名称泄露程度说明
L1bright严重泄露Agent可访问完整历史,含测试期数据
L2stock-blind中度泄露隐藏股票名称,但保留行业/特征
L3date-blind轻度泄露隐藏具体日期,但保留时序模式
L4blinded严格隔离时间、名称均脱敏,仅有裸特征

还设计了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次

按信号类型拆解

这是最关键的发现:

类型信号数胜率均收
动量型38253%+0.58%
均值回归型65033%-0.29%
混合型1,82936%-0.36%

动量型胜率53%、均值回归型仅33%——差距悬殊。

均值回归策略(“跌多了就买”)在A股震荡市中表现极差。RSI超卖不意味着反弹,可能只是持续下行的开始。这跟我之前写的布林带均值回归策略形成了残酷的对照:回测中好看的策略,实盘信号追踪下惨不忍睹。

按市场环境拆解

更反直觉的数据:

市场环境信号数胜率均收
多头(>1)25118%-0.95%
中性(-1~1)89230%-0.51%
空头(<-1)1,71845%+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%实盘信号追踪是检验策略的唯一标准

五条避坑建议

  1. 永远用Walk-Forward回测。不要用固定分割,时间序列必须滚动验证。
  2. 检测LLM预训练泄露。用bright/stock-blind/date-blind分级测试,如果脱敏后预测能力断崖下降,那不是alpha是记忆。
  3. 运行实盘信号追踪。回测说得再好听,不如跑3个月信号追踪看真实胜率。我的系统从2861条追踪中学到的东西,比任何回测都多。
  4. 区分动量和均值回归。在A股震荡市中,动量型信号(53%胜率)远优于均值回归型(33%)。不要盲目套用”超卖买入”逻辑。
  5. 警惕爆发日依赖。如果策略80%的收益来自20%的日子,那它在”普通日子”里可能是亏钱的。实盘体感会远差于回测曲线。

AI Agent在量化交易中的价值,不在于”选股能力”(至少目前不是),而在于自动化数据管线、信号监控、风险预警这些”工程层面”。 关于这一点,我在AI Agent量化交易自动化实战中做过详细讨论。

AI选股的路还很长。但在谈论alpha之前,请先确认你的收益不是泄露的幻觉。


本文数据来源:PolyBench (arXiv:2604.14199)、CSI300记忆基准 (arXiv:2605.28359)、AlphaCrafter (arXiv:2605.05580)、自有CSI800信号追踪系统(cron 21ca2f58b097,2861条已验证信号)。

💬 评论