赛事前瞻有深度
AI 分析更客观

7.7 构造示例④:用赔率构造市场预期与离散度

构造示例
🕒 预计阅读:11 分钟 📅 更新时间:2026年09月14日 👁️ 0 次阅读 ✍️ 来源:球小策量化实验室
💡
提示:您当前为未登录状态,代码示例使用通用占位符展示。点击登录并免费领取 500 点体验金 后,所有代码将自动替换为您本人的专属 Key。

前面三个示例都在讲球队。这一篇讲市场——把数据数值变成可计算的量化指标。

一、第一步:数据数值转隐含概率

def implied_prob(odds):
    """数据数值转隐含概率(未去除服务成本)

    欧洲数据趋势:概率 = 1 / 数据数值
    """
    if not odds or odds <= 1.0:
        return None
    return 1.0 / odds

示例

数据数值 隐含概率
1.50 66.7%
2.00 50.0%
3.40 29.4%

二、第二步:去除服务成本(必须做)

三项数据数值的隐含概率之和会超过 100%,超出部分就是机构的服务成本。

def fair_probs(home_odds, draw_odds, away_odds):
    """去除服务成本,得到三项的「公平概率」

    思路:先算原始隐含概率,再按比例缩放,使总和等于 1
    """
    raw = [implied_prob(home_odds), implied_prob(draw_odds), implied_prob(away_odds)]
    if any(p is None for p in raw):
        return None

    s = sum(raw)
    if s <= 0:
        return None

    # 归一化
    fair = [p / s for p in raw]
    overround = s - 1.0    # 服务成本比例

    return {
        'home': round(fair[0], 4),
        'draw': round(fair, 4),
        'away': round(fair, 4),
        'overround': round(overround, 4),   # 服务成本率,通常 3%~8%
    }

# 示例
print(fair_probs(2.10, 3.40, 3.25))

为什么必须去服务成本?
不去服务成本,你的「模型概率」与「市场概率」比较时会有系统性偏差——你会系统性地认为市场高估了所有结果。
这是很多自建模型最常见的错误之一。

三、第三步:跨机构离散度

把多家机构的数据数值收齐,计算分布的离散程度。

import numpy as np

def market_spread(odds_list):
    """计算同一结果在不同机构间的离散度

    odds_list: 各机构对同一个结果的数据数值列表
    """
    if not odds_list or len(odds_list)  1.0])
    if len(arr) < 3:
        return None

    mean = arr.mean()
    std = arr.std()
    if mean <= 0:
        return None

    return {
        'mean': round(float(mean), 3),
        'std': round(float(std), 4),
        'cv': round(float(std / mean), 4),        # 变异系数:消除量纲,可跨场次比较
        'spread_pct': round(float((arr.max() - arr.min()) / mean), 4),
        'n_sources': len(arr),
    }

关键指标:变异系数(CV)

不要直接用标准差比较不同场次——数据数值量级不同(1.5 和 5.0 的标准差不可比)。

变异系数 = 标准差 / 均值,消除了量纲,可以跨场次比较。

CV 区间 解读
< 0.01 机构高度一致,市场定价充分
0.01 ~ 0.03 正常范围
0.03 ~ 0.06 存在分歧,值得关注
> 0.06 分歧显著,可能存在信息不对称或重大不确定性

四、第四步:数据数值随时间的变化

from datetime import datetime

def odds_drift(history):
    """计算数据数值的变动幅度

    history: 含 timestamp 与 odds 的记录列表(按时间正序)
    """
    if len(history) < 2:
        return None

    first = history[0]['odds']
    last = history[-1]['odds']
    if not first or first  0.01 else ('down' if change_pct < -0.01 else 'flat'),
    }

变动的解读

变动方向 含义
数据数值上升 该结果被认为更不可能发生(或市场流量趋势分布对手)
数据数值下降 该结果被认为更可能发生(或市场流量涌入)
平稳 市场共识稳定

五、第五步:预期差计算(最终目标)

def expected_value_gap(model_prob, market_fair_prob):
    """计算模型概率与市场公平概率的差值

    正值 = 模型认为市场低估了这个结果
    """
    if model_prob is None or market_fair_prob is None:
        return None

    gap = model_prob - market_fair_prob
    return {
        'gap': round(float(gap), 4),
        'model_prob': round(float(model_prob), 4),
        'market_prob': round(float(market_fair_prob), 4),
        # 相对偏离:便于跨场次比较
        'relative_gap': round(float(gap / market_fair_prob), 4) if market_fair_prob > 0 else None,
    }

判断门槛

差值 参考判断
< 2% 无实质优势,不构成信号
2% ~ 5% 微弱,需要更多验证
> 5% 值得深入检查是否存在信息遗漏

六、一个重要的合规与技术双重要求

不要把数据数值变动解释为「市场流量流」。
公开数据通常不含成交量。看到数据数值变动就说「大量市场流量涌入」,属于无依据推断。
正确的技术表述是「数据数值出现调整,可能反映市场对某类信息的反应」。
这既是技术严谨性要求,也是合规要求(见 6.6)。

七、完整的市场分析流水线

步骤 产出
① 收集多机构数据数值 原始数据数值列表
② 去服务成本 公平概率
③ 计算离散度(CV) 机构分歧程度
④ 计算数据数值变化 市场信息反应
⑤ 与模型概率对比 预期差

下一步该看什么

  • 权重怎么定(本篇最关键的方法论)→ 7.8
  • 如何验证指标有效 → 7.9

常见问题

第一步?数据数值转隐含概率
def implied_prob(odds): """数据数值转隐含概率(未去除服务成本) 欧洲数据趋势:概率 = 1 / 数据数值 """ if not odds or odds <= 1.0: return None return 1.0 / odds
关于「示例」,应该怎么理解?
数据数值 隐含概率 1.50 66.7% 2.00 50.0% 3.40 29.4%
第二步?去除服务成本(必须做)
三项数据数值的隐含概率之和会超过 100%,超出部分就是机构的服务成本。 def fair_probs(home_odds, draw_odds, away_odds): """去除服务成本,得到三项的「公平概率」 思路:先算原始隐含概率,再按比例缩放,使总和等于 1 """ raw = [implied_prob(home_odds), implied_prob(draw_o…
第三步?跨机构离散度
把多家机构的数据数值收齐,计算分布的离散程度。 import numpy as np def market_spread(odds_list): """计算同一结果在不同机构间的离散度 odds_list: 各机构对同一个结果的数据数值列表 """ if not odds_list or len(odds_list) 1.0]) if len(arr) < 3: retu…
关键指标?变异系数(CV)
不要直接用标准差比较不同场次——数据数值量级不同(1.5 和 5.0 的标准差不可比)。 用变异系数 = 标准差 / 均值,消除了量纲,可以跨场次比较。 CV 区间 解读 < 0.01 机构高度一致,市场定价充分 0.01 ~ 0.03 正常范围 0.03 ~ 0.06 存在分歧,值得关注 > 0.06 分歧显著,可能存在信息不对称或重大不确定性
第四步?数据数值随时间的变化
from datetime import datetime def odds_drift(history): """计算数据数值的变动幅度 history: 含 timestamp 与 odds 的记录列表(按时间正序) """ if len(history) < 2: return None first = history[0]['odds'] la…
免责声明

本栏目内容为足球数据分析方法的教学与科普,全部指标、模型与推演过程仅用于体育数据科学研究与信息展示,不构成任何形式的预测承诺,亦不涉及任何交易行为。文中「市场参考值」「参考值」等表述,均指公开可得的市场公开信息,仅用于说明数据比对方法。请读者遵守所在地区法律法规,理性认识竞技体育的偶然性。

🏠
赛事
📊
数据
🧩
功能
👤
我的

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫打赏

微信打赏二维码

登录

打开微信扫一扫,确认后自动完成登录