因为我个人喜欢看足球,就一直以娱乐心态在小额投资。直到前年AI Coding工具越来越成熟,某一日突发念头想记录下自己的投资记录,用来沉淀数据和分析洞察。当开始着手做出第一版后,功能就从纯为记录慢慢演化为大小球分析。截止今日,已演进了三个阶段:从人工判断到AI辅助,再到回测量化。收益情况也能整体上有所盈利,但胜率还是未能保持长期稳定,某一个策略可以连续5、6轮均盈利,但在某轮开始失效出现亏损。
上周欧洲五大联赛均已收官,那就趁有空了,记录下演进迭代过程,也算是一个阶段性总结。

同时,接下来我将在赛前发布量化分析框架对中超赛事大小球分析结果,也欢迎有兴趣的朋友一起讨论、优化量化框架。


第一阶段:纯记录和人工分析

项目刚开始那会儿,大小球怎么判断?全靠人肉看。每场比赛前打开几个网页,扫一遍:

  • 基本面:两队最近踢得怎么样、历史交锋谁占优、排名大概在哪个位置
  • 盘口与指数:主流公司的大小球盘口线开到多少,指数在往哪个方向走
  • 情报信息:谁伤了谁停赛、球队战意如何、赛程紧不紧、天气怎样

然后就拍脑袋和凭直觉决定了。在系统上记录比赛信息、盘口和指数、去水后的隐含概率、我的信心概率、理由依据等,用于后续统计自己判断的胜率和ROI等。

这一阶段的问题不是准确率高低的问题——是根本没法全面复盘。赢了不知道是真看准了还是蒙的,输了也说不清是哪个环节判断错了。更麻烦的是,分析能力完全绑定在个人状态上,今天心情好和心情差,看同一场比赛可能得出完全不同的结论。


第二阶段:AI辅助分析

大模型能力上来之后,我开始试着把AI塞进分析流程里。这个阶段前后改了五次。

2.1 初探:比赛信息 + 盘口指数(XL策略)

最简单粗暴的做法:把比赛基本信息(谁打谁、什么联赛、第几轮)和盘口指数扔给大模型,让它自己联网搜情报,然后给结论。

输入数据

  • 比赛基本信息(主队、客队、联赛、时间)
  • 大小球盘口和指数
  • 模型联网搜索能力(伤病、天气、战术信息)

方法特点

  • 完全依赖大模型的推理和搜索能力
  • 没有任何结构化历史数据支撑
  • 提示词就一句话的事:"预测下列比赛的大小球"

效果

  • 好处:模型能快速整合多源信息,输出看着像模像样的分析报告
  • 坏处:模型会编数据,分析缺乏量化依据,结论可信度没法验证

这一轮至少验证了一件事:大模型确实能理解足球分析需要的那套推理逻辑。但"裸调"的方式太糙了,分析质量和抛硬币的区别没那么大。


2.2 引入统计数据(ML策略)

把数据采集从模型的"黑盒"里拿出来。系统先爬好结构化数据,模型只负责分析,不负责找数据。

新增输入

  • 主客队近期比赛的数据(交锋记录、近期战绩、积分榜排名)
  • 球队技术统计(射门、射正、控球率、危险进攻等指标)

方法演进

  • 从"让模型自己搜索一切"变成"系统预采集 + 模型分析"
  • 提示词拆成三块:比赛信息 → 联网搜索指令 → 结构化统计数据
  • 大模型强制开联网搜索,确保情报是最新的

关键进步

数据采集不再交给模型"黑盒"处理了。系统预先爬好结构化数据再喂给模型,幻觉空间小了很多。模型的分析好歹建立在真实数据上,不至于凭空编造。

还是没解决的问题

  • 所有分析还是靠一次模型调用,分析准确性没法验证。而且,同样的输入,大模型多次分析的结果可能是不一样的。
  • 没有历史投资数据做反馈,同样的坑可能反复踩

2.3 联赛数据洞察与历史投资数据(SL策略)

这次把视野从"单场比赛"拉到了"整个联赛",并且开始用历史投资数据说话了。

新增能力

  1. 联赛级别的大小球洞察

    • 统计同联赛所有赛事在不同盘口区间的大小球分布
    • 计算各盘口档位的大球率、小球率
    • 给出联赛倾向性(比如"中超本赛季大球倾向55%")
  2. 历史投资数据反馈

    • 读取历史投资记录,按主客队筛选
    • 生成CSV格式的历史投资明细让模型参考
    • 分析相同盘口区间的历史命中率
  3. 盘口变动分析(市场微观结构)

    • 对比初盘与即时盘口的变化方向(升盘/降盘)
    • 对比初盘指数与即时指数的变化(升水/降水)
    • 解读市场资金流向——所谓"聪明钱"在往哪边走
  4. 进阶价值模型

    • 从抓取到的联赛的历史记录计算ROI、期望值(EV)
    • 用Z-Score评估统计显著性
    • 凯利公式(Kelly Criterion)算最优投资比例
    • 威尔逊下界(Wilson Lower Bound)给保守胜率估计

方法架构

                    ┌─────────────────────┐
                    │   大模型(LLM)       │
                    │  enable_thinking=True │
                    │  enable_search=True   │
                    └──────────┬──────────┘
                               │
               ┌───────────────┼───────────────┐
               │               │               │
        ┌──────▼──────┐ ┌─────▼─────┐ ┌──────▼──────┐
        │ 爬取的比赛   │ │ 联赛洞察   │ │ 历史投资     │
        │ 统计数据     │ │ 分析报告   │ │ CSV数据      │
        │ (crawl)     │ │ (analysis │ │ (bet_csv)   │
        │             │ │  _md)     │ │             │
        └─────────────┘ └───────────┘ └─────────────┘

关键进步

这是第一次把分析从"单场视角"升级为"系统视角"。模型不再孤立地看一场比赛,能看到这场比赛在联赛中的位置、类似盘口的历史分布、以及之前投资的成败记录。

还是没解决的问题

  • 所有数据最终汇入单一模型调用,信息量太大模型容易顾此失彼
  • 不同分析维度的权重全由模型自己掂量,没有标准
  • 联网搜索结果质量不稳定,如伤停情报、士气、天气等数据时好时坏
  • 同一数据输入,多次分析的结果存在差异

2.4 多Agent协作模式(MAG策略)

一个模型处理所有信息不行,那就拆成多个专业Agent各管一摊。

Agent架构

Agent 模型 职责 配置
情报总监 (Chief Intelligence Officer) qwen3.5-plus 联网搜索实时情报(伤病、天气、战术) search=enabled, temperature=0.3
高级数据分析师 (Senior Data Analyst) qwen3.5-plus 分析统计数据、联赛洞察、历史投资 search=disabled, temperature=0.1
首席投资策略师 (Lead Betting Strategist) qwen3-max 综合前两个Agent输出做最终决策 thinking=enabled, temperature=0.3

执行流程

情报总监(联网搜索)  ────┐
                          ├─── 并行执行 ───┐
数据分析师(数据处理)  ────┘              │
                                           ▼
                                 首席投资策略师(综合决策)
                                           │
                                           ▼
                                     最终预测输出

编码到提示词中的决策原则

  1. 每个结论必须标注数据来源,没来源的别说
  2. 冲突处理规则:实时情报与历史数据矛盾时——伤病/战术因素优先采信实时情报,统计规律优先采信历史数据
  3. 盘口阈值规则:盘口≥3球且有防守信号 → 倾向小球;盘口≤2.25且战意低 → 倾向小球

关键进步

  • Agent各司其职:搜信息的、做数据的、拍板的,不同模型实例干不同事,各自用最适合的配置
  • 情报搜集和数据分析并行跑,省时间
  • 明确的决策规则减少了模型瞎发挥的空间,分析一致性提高不少
  • 用CrewAI框架编排,分析过程完整记录到AnalysisLog表,后面复盘方便

还是没解决的问题

  • 多Agent协调带来了新的不确定性——Agent之间传话可能漏掉关键细节
  • 定量计算(期望值、概率估计)还是模型在做,精确度没保证
  • 各维度权重仍然由模型隐式决定,没法验证和优化

2.5 权重量化分析框架(KL策略)

这一版思路彻底变了。之前是"把数据给模型,让它自己判断",现在是"系统能算的全部算好,模型只填系统算不了的空白"。

A-F模块框架

模块 权重 内容 计算方式
A 攻防能力 35% 进攻质量、防守开放性、过程-结果修正 技术统计与联赛均值对比,加权指数化
B 节奏机会 20% 比赛节奏、有效终结、转换威胁、定位球 射门/射正/快攻/角球等指标加权评分
C 伤停战术 15% 伤病、停赛、战术阵型、球队新闻 只有这个模块由模型联网搜索评分
D 赛程战意 10% 赛程负荷、积分榜紧迫度 7天/10天窗口赛程密度 + 排名位置打分
E 指数定价 15% 同盘口历史分布、初盘EV分析、盘路变化 MatchOddsData历史回测 + 分层衰减模型
F 外部因素 5% 天气影响、外部稳定性 模型联网搜索评估

评分机制(以Module A为例)

每项技术统计与联赛均值比较,计算偏离百分比,映射到五档标准分:

偏离幅度 得分
≥ +15% 100
+5% ~ +15% 75
-5% ~ +5% 50
-15% ~ -5% 25
≤ -15% 0

子指标计算举例(按权重加权求和):

  • A模块中的 A1(进攻质量)= 0.40×射正指数 + 0.30×关键传球指数 + 0.20×危险进攻指数 + 0.10×进球指数

提示词结构

┌──────────────────────────────────────┐
│ 1. 比赛基本信息(含时区转换)         │
├──────────────────────────────────────┤
│ 2. A-F框架说明(~60行评分规则和公式) │
├──────────────────────────────────────┤
│ 3. 综合技术统计(match_team_technical │
│    _stats表)                         │
├──────────────────────────────────────┤
│ 4. 预计算的A/B/D/E/F模块得分表        │
├──────────────────────────────────────┤
│ 5. 过滤后的市场分析(MatchOddsData)   │
├──────────────────────────────────────┤
│ 6. 赛程密度(从爬取数据解析)          │
├──────────────────────────────────────┤
│ 7. 积分榜和近期战绩(爬取数据)         │
├──────────────────────────────────────┤
│ 8. 模型联网搜索(填充Module C + F)    │
└──────────────────────────────────────┘

这一版的意义

模型的角色从"全权分析师"缩小为"情报研究员 + 综合研判者"。量化评分有了明确公式和权重,每一项都可以独立验证和调优。模型的幻觉被关进了Module C(伤停情报)的笼子里,不再污染其他模块。这套框架后来成了第三阶段的底座。


第三阶段:回测量化分析(QX策略)

设计动机

KL策略有个别扭的地方:系统明明已经算出了所有模块的量化得分,但最后还是模型说了算。模型可能完全忽略量化信号,或者对得分的理解跑偏。这就让人想一个问题:

如果我们已经用精确公式算出了A/B/D/E/F模块得分,为什么还需要模型来做最终判断?

答案是可以不需要。用历史数据训练一个校准层,直接把模块得分映射为概率预测就行了。

方法架构

┌─────────────────────────────────────────────────────┐
│                   QX策略架构                        │
├─────────────────────────────────────────────────────┤
│  输入:联赛、赛季、轮次、主客队、盘口、大小球指数    │
├─────────────────────────────────────────────────────┤
│                                                      │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
│  │ Module A │ │ Module B │ │ Module D │ │Module E ││
│  │ 攻防能力  │ │ 节奏机会  │ │ 赛程战意  │ │指数定价  ││
│  │  (同KL)  │ │  (同KL)  │ │  (同KL)  │ │ (同KL)  ││
│  └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘│
│       │            │            │            │      │
│       └────────────┴────────────┴────────────┘      │
│                          │                           │
│                    Optuna优化权重                     │
│                 (每联赛独立配置)                     │
│                          │                           │
│                          ▼                           │
│                   加权综合得分                         │
│                          │                           │
│                          ▼                           │
│              Walk-forward Platt校准                  │
│           (将原始得分映射为校准概率)                  │
│                          │                           │
│                          ▼                           │
│                    决策引擎                           │
│         over_edge > margin → 大球                     │
│        under_edge > margin → 小球                     │
│              否则 → 不投                              │
└─────────────────────────────────────────────────────┘

核心组件

1. Optuna超参优化

每个联赛独立训练一套最优权重配置。Optuna在历史数据上搜索最佳超参数组合,包括各模块权重、子模块内部权重(比如A模块里射正/关键传球/危险进攻/进球的比例)、采样窗口大小、决策阈值(value_margin)。

目前已覆盖的联赛:中超、韩K联、英超、西甲、德甲、法甲、意甲、巴甲、挪超、瑞典超。

2. Walk-forward Platt校准

用sigmoid函数把模块综合得分校准为概率估计:

$$P(over) = \frac{1}{1 + e^{-(\alpha \cdot score + \beta)}}$$

其中 α(斜率)和 β(截距)通过同联赛同赛季历史赛事的模块得分与实际大小球结果拟合得出。采用Walk-forward方式——只用当前轮次之前的数据拟合参数,防止未来信息泄露。

3. 决策引擎

over_edge = predicted_prob - implied_prob
if over_edge > value_margin:
    推荐大球
elif under_edge > value_margin:
    推荐小球
else:
    不投资

置信度分级:

  • edge ≥ 0.10 → 高置信度
  • edge ≥ 0.05 → 中高置信度
  • edge ≥ 0.02 → 中低置信度
  • edge < 0.02 → 低置信度

与第二阶段的关键差异

维度 第二阶段(KL策略) 第三阶段(QX策略)
决策主体 大模型 确定性算法
Module C(伤停情报) 模型联网搜索评分 不使用(无模型)
权重来源 人工设定 Optuna历史数据优化
概率估计 模型主观判断 Platt统计校准
可回测性 有限(依赖模型输出) 完全可回测
稳定性 受模型版本影响 完全确定
运行成本 API调用费用 几乎为零

关于第三阶段的实话

第三阶段不是否定第二阶段。说实话,没有第二阶段那些折腾,根本到不了这里。正是通过KL/AL框架的实践,我们发现了三件事:

  1. A-F模块的量化得分其实已经包含了大小球预测所需的大部分信息
  2. 大模型在量化得分基础上做的"综合判断",并没有比统计校准强多少
  3. 模型的不确定性(温度、版本更新、提示词敏感性)反而在往里加噪声

所以第三阶段做的事情本质上就是:把第二阶段真正有效的部分(A-F量化框架)留下来,把引入噪声的部分(大模型主观判断)扔掉,然后用历史回测系统性地把权重调对。


总结

三个阶段走下来,简单来说是:

阶段 核心方法 关键突破
纯人工分析 建立了分析的基本维度认知
AI辅助分析(5次迭代) 从裸调模型 → 结构化数据 → 联赛级洞察 → 多Agent协作 → 量化框架约束模型
回测量化分析 移除模型,Optuna优化 + Platt校准,全自动可回测决策

每一次改动都不是为了追求技术上的花哨,说到底就是在反复回答一个问题:什么信息真正有预测价值?什么信息采取怎样的方法组合在一起能确保单轮胜率>亏损点?
第三阶段并不是终点,我准备使用中超继续跑一段时间,来验证下当前回测量化框架的准确率是否能一直保持?若当失效了,要怎样进行回测调整?