top of page

HKJC 賠率的內在一致性

8月20日
讀畢需時 19 分鐘

同一場波, 馬會同時開出主客和、讓球、入球大細、入球單雙、總入球、波膽等七類盤口。每一類都在講同一件事: 這場波會入多少球、哪一隊入得多。

問題是, 這七套報價背後, 是否真的存在同一個入球分布? 抑或每個盤口各自定價, 合併起來其實互相矛盾?

這個問題可以完全用數據回答, 不需要任何預測模型, 亦不需要知道賽果。本文用 56 場賽事、509 條盤口線、3,248 個獨立選項的即時報價, 加上 90,514 場有賽

果的歷史賠率, 把整個反解過程做一次, 並公開全部方法與程式碼。

本文屬量化研究與教學用途, 所有計算針對公開賠率數據的數學結構, 不構成任何投注建議。文中出現的「有效抽水」「最平路線」等概念, 描述的是成本高低, 不代表任何一種下注方式有正期望值。

本文重點

一句話總結: 可以還原, 而且一致程度遠超預期。逐場用該場全部盤口的報價反解一個 13×13 的比數聯合分布, 56 場合共 3,248 個選項的平均絕對殘差只有 0.20 個百分點

但這個結論有三個前提, 每一個都值得獨立討論:

去水方法不能隨便選。 五種常見的 de-vig 方法, 在 6% 抽水的讓球盤幾乎沒有分別, 在 50% 抽水的波膽盤可以相差幾倍。

市場心目中的分布不是 Poisson。 三參數的 Dixon–Coles 模型無論如何都對不上, 殘差是非參數解的 1.5 至 6 倍。

盤口之間有大量冗餘, 但不是完全冗餘。 任何一個「勝負類 + 入球類」的兩盤口組合, 已經足以推出其餘盤口到 0.5pp 以內; 但單靠總入球盤, 對主客和的預測誤差高達 32pp。

一、把七個盤口翻譯成同一種語言

要比較不同盤口, 首先要有共同的坐標系。足球賽果的最小完整描述就是最終比數 (i, j), 即主隊入 i 球、客隊入 j 球。取 K = 13 (0 至 12 球), 就有一個 13×13 = 169 格的機率表 p[i][j], 加起來等於 1。

有了這個格, 每一個投注選項都可以寫成格上的一個 0/1 遮罩。「大 2.5」就是所有 i + j ≥ 3 的格; 「主隊 −1」就是所有 i − j ≥ 2 的格; 「2:1」就是單一格。於是任何一個選項的公平機率, 都是遮罩與 p 的內積:

q  =  Σ over all (i,j)  of   W[i][j] · p[i][j]

所有盤口就此變成同一個線性方程組, 未知數是同一個 p

K = 13
I_IDX, J_IDX = np.meshgrid(np.arange(K), np.arange(K), indexing="ij")
TOTAL = I_IDX + J_IDX          # 總入球
DIFF  = I_IDX - J_IDX          # 主隊淨勝球

def weight_matrix(odds_type, cond, comb):
    if odds_type == "HAD":                      # 主客和
        return {"H": DIFF > 0, "D": DIFF == 0, "A": DIFF < 0}[comb].astype(float)

    if odds_type == "HIL":                      # 入球大細
        lines = parse_condition(cond)           # "2.5" → [2.5]; "2.5/3.0" → [2.5, 3.0]
        w = np.zeros((K, K))
        for L in lines:                         # 半球盤: 一半注碼落一條線
            hit = TOTAL > L if comb == "H" else TOTAL < L
            w += hit.astype(float) / len(lines)
        return w

    if odds_type == "HHA":                      # 讓球主客和
        h = float(cond)                         # 主隊讓球數, 可為負
        d = DIFF + h
        return {"H": d > 0, "D": d == 0, "A": d < 0}[comb].astype(float)
    ...

這段程式碼裡面最容易出錯、亦最關鍵的一點, 是走盤 (push)

讓球 0 球或整數球的盤, 打和會退還本金; 大細線是整數時, 總入球剛好等於該線亦會退還。走盤的正確處理方式不是當它輸, 而是把它排除在機率質量之外。換句話說, 一條有走盤可能的盤口線, 它所有選項的遮罩加起來不等於 1, 而是等於 1 − P(走盤)

寫成檢查式就是:

def sanity_check(book):
    """純分割盤: 各選項遮罩相加必須逐格等於 1; 有走盤的盤: 差額即走盤機率。"""
    s = book.weights.sum(axis=0)
    push = 1.0 - s
    assert (push >= -1e-9).all() and (push <= 1.0 + 1e-9).all()
    return push

這個檢查在後面的「等效賠率」計算裡救了一次命: 若把走盤當成輸, 讓球盤的成本會被系統性高估。

七類盤口的翻譯結果如下:

盤口

代號

選項數

對應格上條件

有走盤

讓球

HDC

2

DIFF + h > 0 / < 0

整數讓球會

入球單雙

OOE

2

TOTAL 單 / 雙

入球大細

HIL

2

TOTAL > L / < L

整數線會

主客和

HAD

3

DIFF 正 / 零 / 負

讓球主客和

HHA

3

DIFF + h 正 / 零 / 負

總入球

TTG

8

TOTAL = 0…6, ≥ 7

波膽

CRS

33

28 個明確比數 + 5 個「其他」桶

波膽盤要特別小心。馬會列出 28 個明確比數, 其餘全部歸入「其他主勝」「其他和局」「其他客勝」等桶。這些桶的遮罩是「符合該結果, 但不屬於任何一個已列比數」的補集, 不能簡單當成剩餘機率。


二、資料: 七個 snapshot, 56 場, 3,248 個選項

HKJC 的即時賠率經 GraphQL 端點提供。要注意兩點: 端點只接受白名單內的查詢字串, 而且所有變數必須齊備, 缺一個 optional 參數都會回 Invalid queration arguments

ENDPOINT = "https://info.cld.hkjc.com/graphql/base/"

FULL_VARS = {                      # 缺任何一個 key 都會被拒
    "date": None, "startDate": None, "endDate": None,
    "matchId": None, "tournId": None, "teamId": None,
    "pmPoolId": None, "featuredPoolsOnly": None, "fbOddsTypes": [],
}

def fetch_odds_batch(odds_types, date):
    body = {"query": QUERY_MATCH_LIST,          # 逐字抄自官方前端
            "variables": {**FULL_VARS, "date": date, "fbOddsTypes": odds_types}}
    r = requests.post(ENDPOINT, json=body, headers=BROWSER_HEADERS, timeout=30)
    return r.json()["data"]["matches"]

單次請求拉不齊七類盤口, 要分批再按 match_id 合併。收集器每五分鐘存一個完整 snapshot, 檔案帶時間戳, 之後統一整理成一張 tidy table。

七個 snapshot 合共記錄 3,758 條盤口線、23,531 個報價點。剔除已開賽的賽事, 每條盤口線只保留最新一次報價, 得出分析樣本:

  • 56 場賽事, 開賽時間橫跨 2026-08-17 至 2026-08-25, 距離開賽 0.7 小時至 8 日 (中位 20.7 小時)

  • 涵蓋英超 (10 場)、阿甲 (7)、墨超 (5)、巴甲 (4)、美職 (4) 等 20 項賽事

  • 509 條盤口線, 展開後 3,248 個獨立選項

其中 30 場七類盤口齊全, 另外 26 場欠讓球盤 (馬會只對部分賽事開讓球)。


三、抽水階梯: 同一場波, 成本相差八倍

去水之前先看抽水。抽水 (overround) 的定義是所有選項隱含機率之和減一:

overround  =  Σ (1 / o_i)  −  1        o_i = 第 i 個選項的賠率
圖 1:同一場波, 七個盤口的內建成本相差八倍

七個盤口排成一條非常整齊的階梯:

盤口

選項數

抽水中位

P10–P90

價值保留率

讓球

2

6.29%

5.36–6.65%

0.941

入球單雙

2

8.12%

8.11–8.22%

0.925

入球大細

2

8.28%

8.14–8.96%

0.924

主客和

3

13.26%

12.78–13.76%

0.883

讓球主客和

3

14.21%

14.10–14.47%

0.876

總入球

8

29.67%

29.53–29.98%

0.771

波膽

33

49.96%

49.90–50.50%

0.667

抽水與選項數的關係緊到近乎機械: 對數選項數解釋了 99.7% 的抽水中位變異 (斜率 0.152, 即選項數每翻一倍, 抽水加 10.6 個百分點, p = 1.1e-07)。

用同場配對比較更清楚。以同一場的讓球盤為基準, 波膽盤的抽水多 44.0 個百分點, 即 8.15 倍 (t = 407); 總入球盤多 23.7pp, 即 4.85 倍。這不是抽樣噪音, 是定價政策。

P10–P90 那一欄同樣值得看。波膽盤的抽水區間只有 49.90–50.50%, 幾乎沒有變化 — 這是一條硬性設定的 50% 線, 而非按賽事風險調整的結果。

還有一個較細緻的觀察。入球大細盤的抽水會隨盤口線偏離主線而上升:

偏離主線

條數

抽水中位

最長賠率中位

0.00

56

8.19%

2.00

0.25

39

8.26%

2.05

0.75

17

8.66%

2.70

1.00

31

8.67%

2.75

1.25

10

8.96%

3.70

同一場波、同一類盤口, 走遠一條線就貴多 0.8pp。這與後面「冷門被抽得更狠」的發現是同一個現象的兩面。


四、去水: 五種方法, 抽水愈厚分歧愈大

抽水要移除才能得到公平機率。這一步沒有唯一答案, 常見有五種做法, 每種對「抽水如何分攤在各選項之間」有不同假設。

以下用 r_i = 1/o_i 表示原始隱含機率, B = Σ r_i 表示 booksum:

Proportional (按比例): q_i = r_i / B。假設抽水按機率大小等比例攤分。最簡單, 亦最常見。

Additive (等額扣減): q_i = r_i − (B − 1)/n。假設每個選項扣同樣多的絕對機率。

Power (冪律):k 使 Σ r_i^k = 1。抽水對長賠率的相對影響較大。

Odds-ratio:c 使 Σ r_i / (c + r_i − c·r_i) = 1

Shin: 假設市場中有比例 z 的知情資金, 莊家為此加價。求解

         sqrt( z² + 4(1−z)·r_i²/B )  −  z
q_i  =  ───────────────────────────────────      並要求  Σ q_i = 1
                    2(1−z)
def shin(odds):
    r = 1.0 / np.asarray(odds, dtype=float)
    B = r.sum()

    def total(z):
        return (np.sqrt(z * z + 4 * (1 - z) * r * r / B) - z).sum() / (2 * (1 - z))

    lo, hi = 0.0, 0.9                      # 二分法求 z 使機率和為 1
    for _ in range(80):
        mid = (lo + hi) / 2
        if total(mid) > 1.0:
            lo = mid
        else:
            hi = mid
    z = (lo + hi) / 2
    q = (np.sqrt(z * z + 4 * (1 - z) * r * r / B) - z) / (2 * (1 - z))
    return q / q.sum()

在薄抽水的盤口, 五種方法給出的答案幾乎相同, 選哪一種都無所謂。在厚抽水的盤口, 情況完全不同。

圖 2:抽水愈厚, 「怎樣去水」愈影響結論

左圖是同一條總入球盤 (抽水 29.7%) 的五種去水結果。頭三格差別有限, 但看右圖便清楚: 分歧全部集中在長尾。到「6 球」和「7 球以上」, additive 直接把機率壓到 0, shin 給出的機率只有 proportional 的 0.38 倍, power 是 0.67 倍。

這不是一條盤口的個別現象。把 HKJC 全部盤口線, 加上 4,000 場 Pinnacle 收市 1X2 作參照畫在一起:

圖 9:市場一致, 但成本沒有消失

左圖橫軸是該盤口的抽水, 縱軸是五種方法對「最冷一項」給出的機率分歧幅度 (最高減最低, 除以平均)。這條關係跨越四個數量級: Pinnacle 收市盤 2.8% 抽水時, 分歧不足 1%; 馬會讓球盤 6% 抽水時約 0.5%; 到總入球和波膽盤, 分歧超過 100%, 即最高與最低的估計相差超過一倍。

結論很直接: 分析薄抽水市場時, 去水方法幾乎不影響結論; 分析厚抽水市場時, 去水方法本身就是結論的一部分。


五、免模型一致性檢查: 不用任何模型, 直接對數

有了去水後的機率, 就可以做第一個真正的檢驗, 而且完全不需要任何預測模型。

原理是: 某些事件可以由多於一個盤口精確計算。例如 P(總入球 ≥ 3), 波膽盤可以加總、總入球盤可以加總、大細 2.5 盤直接就是。如果三個盤口背後真的是同一個分布, 三個數字應該一致。

TARGETS = {
    "P(主勝)":      DIFF > 0,
    "P(和局)":      DIFF == 0,
    "P(總入球≥3)":  TOTAL >= 3,
    "P(總入球單數)": TOTAL % 2 == 1,
    ...
}

def exact_value(book, mask, devig):
    """只有當 mask 可由該盤口的選項精確拼砌時才回傳數值, 否則回 None。"""
    w = book.weights                      # (n_outcome, K, K)
    inside  = (w * mask).sum(axis=(1, 2))
    outside = (w * ~mask).sum(axis=(1, 2))
    if not (np.isclose(inside, 0) | np.isclose(outside, 0)).all():
        return None                        # 有選項橫跨目標邊界, 無法精確計算
    q = devig(book.raw)
    return q[inside > outside].sum()

這個檢查的好處是沒有任何自由度: 兩個盤口對同一件事的講法, 要麼一致, 要麼不一致。

先看單一目標。以波膽盤為基準 (它包含最完整的資訊), 其他盤口的偏差 (百分點, 正數代表該盤口報得較高):

目標

盤口

additive

odds_ratio

power

proportional

shin

P(主勝)

HAD

+0.94

+0.52

+1.10

−0.50

+0.53

P(主勝)

HHA

−1.25

+0.09

−1.15

+1.80

−0.38

P(總入球≥3)

HIL

+4.35

−3.40

−0.50

−3.88

+1.07

P(總入球≥3)

TTG

+2.97

−1.90

−0.02

−2.13

+1.09

看第三、四行。同一件事 P(總入球 ≥ 3), 用 additive 去水會得出大細盤比波膽盤高 4.35pp, 用 proportional 去水則得出低 3.88pp。方向都相反

把全部目標 × 全部盤口對加起來:

去水方法

盤口對數

平均絕對偏差

最大盤口對偏差

不含波膽

shin

12

0.927pp

1.987pp

0.863pp

power

12

1.176pp

2.815pp

1.864pp

odds_ratio

12

1.859pp

3.817pp

1.635pp

proportional

12

1.911pp

3.880pp

1.758pp

additive

12

2.431pp

5.010pp

1.667pp

圖 3:去水方法決定了盤口之間對不對得上

Shin 令各盤口最接近同一個分布, 平均絕對偏差 0.93pp, 是 additive 的三分之一。右圖把「大細盤 vs 總入球盤對 P(總入球 ≥ 3) 的講法」逐場畫出來: proportional 的點系統性地偏在對角線一邊 (平均絕對偏差約 1.7pp), shin 的點則貼住對角線 (約 0.5pp)。

只看抽水相近的二元盤 (排除長尾定價的干擾), 結論略有分歧: P(總入球≥3) 上 shin 最好 (0.49pp), P(主勝) 上則是 odds_ratio 最好 (1.01pp), shin 緊隨 (1.11pp)。沒有一種方法在所有測試上通殺, 但 shin 是唯一在兩項測試都排前二的方法。


六、正式反解: 一個 13×13 分布, 對到七個盤口

免模型檢查只用到少數幾個「剛好可以互相對照」的事件。真正的問題是: 能不能為每一場波找到一個 169 格的分布 p, 同時解釋該場所有盤口的每一個報價?

把每個選項寫成一條方程: w · p = q。全部堆起來變成矩陣方程 A p ≈ b, 再加上 p ≥ 0Σp = 1

def build_system(books, q_all):
    """每個選項一行: A[k] · vec(p) = 該選項的去水後機率。"""
    rows, rhs = [], []
    for b in books:
        q = q_all[id(b)]
        push = 1.0 - b.weights.sum(axis=0)       # 走盤機率, 逐格
        for k in range(b.n):
            rows.append(b.weights[k].ravel())
            rhs.append(q[k] * (1.0 - float((push * p_hint).sum())))
    return np.asarray(rows), np.asarray(rhs)

單靠最小平方會有問題: 169 個未知數、幾十條有效方程, 解不唯一, 而且會把質量推到極端比數上。所以用最大熵原則: 在所有滿足約束的分布之中, 取離參照分布最近 (KL 散度最小) 的那個, 即除盤口本身的資訊外不額外假設任何結構:

min over p :   Σ p_ij · log( p_ij / p_ref_ij )   +   λ · ‖A·p − b‖²
subject to :   p ≥ 0 ,  Σ p = 1

參照分布 p_ref 用同一場的 Dixon–Coles 擬合結果, 目的只是給極端比數一個合理的尾部形狀, 對主要格點的影響可以忽略。

def solve_maxent(A, b, p_ref=None, lam=1e4):
    ref = np.full(A.shape[1], 1.0 / A.shape[1]) if p_ref is None else p_ref
    log_ref = np.log(np.clip(ref, 1e-12, None))

    def obj(theta):                       # softmax 參數化, 自動滿足 p≥0, Σp=1
        p = np.exp(theta - theta.max()); p /= p.sum()
        kl = float(p @ (np.log(np.clip(p, 1e-300, None)) - log_ref))
        r = A @ p - b
        return kl + lam * float(r @ r)

    res = minimize(obj, log_ref.copy(), method="L-BFGS-B",
                   options={"maxiter": 4000})
    p = np.exp(res.x - res.x.max())
    return p / p.sum()

結果如下。逐場反解 56 場, 用 shin 去水:

盤口

power

proportional

shin

入球單雙

0.101

0.044

0.038

波膽

0.167

0.231

0.123

總入球

0.376

0.365

0.236

入球大細

0.515

0.354

0.270

讓球主客和

1.152

1.013

0.402

讓球

0.543

0.398

0.433

主客和

1.166

0.742

0.475

全盤口合計

0.378

0.358

0.200

(單位: 百分點)

平均絕對殘差 0.20 個百分點。 換個講法: 每場用一個 169 格的分布去解釋該場所有盤口的報價, 56 場合計 3,248 個報價, 平均每個報價的機率誤差是萬分之二十。

用 shin 去水的殘差, 比 proportional 或 power 細接近一半。這與第五節的免模型檢查獨立地指向同一個結論。

單場的樣子:

圖 4:河床 對 小阿根廷人, 由七個盤口反解出一個分布

左邊是還原出來的比數聯合分布, 中間是它推算的總入球邊際分布與總入球盤報價的對照。右邊最能說明問題: 這場波七個盤口共 60 個選項, 全部落在對角線上, 最大偏離只有 0.78pp。由 60% 級數的主勝機率, 一路到 0.2% 級數的冷門比數, 跨越三個數量級都對得上。

答案是肯定的: 七個盤口確實共用同一個入球分布。


七、市場心目中的分布, 不是 Poisson

反解出來的 p 有 169 個自由度。一個自然的追問是: 需要這麼多嗎? 足球比分的標準模型 Dixon–Coles 只用三個參數 (λ主、λ客、低比數修正 ρ), 會不會已經足夠?

把同一組約束改為擬合 Dixon–Coles 的三個參數, 再比較殘差:

圖 5:市場心目中的入球分布, 不是一個 Poisson 模型

盤口

Dixon–Coles (3 參數)

非參數 (169 格)

倍數

主客和

0.815

0.475

1.7×

讓球

0.548

0.433

1.3×

讓球主客和

0.658

0.402

1.6×

入球大細

0.413

0.270

1.5×

總入球

0.427

0.236

1.8×

波膽

0.220

0.123

1.8×

入球單雙

0.222

0.038

5.8×

跨場的參數中位是 λ主 = 1.463、λ客 = 1.125、ρ = −0.021, 數值本身很合理。但殘差全面較高, 而且差距最大的是入球單雙, 這正是 Poisson 結構最緊的地方。獨立 Poisson 的總入球單雙機率由 λ 完全決定, 沒有任何自由度; 市場的報價明顯不受這個約束。

需要強調的是, 0.22pp 的殘差以絕對水平計依然很細, Dixon–Coles 作為近似仍然實用。但市場的定價確實帶有三參數模型容納不了的結構, 這個結構是系統性的, 不是噪音。


八、資訊冗餘: 用哪幾個盤口就足夠?

既然七個盤口共用一個分布, 那它們之間必然有大量重複資訊。哪些是冗餘, 哪些是獨有?

做法是留一驗證: 只用部分盤口反解 p, 再看它對沒有參與擬合的盤口報價預測得幾準。

圖 6:只有總入球盤, 就完全推不出哪隊會贏

擬合用盤口

擬合外選項數

平均絕對殘差

RMSE

只用總入球

2,800

8.14pp

16.71

只用波膽

1,400

0.77pp

0.97

主客和 + 入球大細

2,774

0.49pp

0.85

讓球主客和 + 入球大細

2,636

0.47pp

0.79

主客和 + 總入球

2,632

0.46pp

0.80

任何一個「勝負類 + 入球類」的兩盤口組合, 已經足以推出其餘五個盤口到 0.5pp 以內。單靠波膽盤一個 (它有 33 個選項) 也做到 0.77pp。

反例極端: 只用總入球盤, 樣本外殘差是 8.14pp, 高出十幾倍。逐盤口拆開看就明白原因:

擬合外盤口

平均絕對殘差

讓球

38.04pp

主客和

32.19pp

讓球主客和

26.04pp

波膽

3.71pp

入球大細

0.73pp

入球單雙

0.47pp

總入球盤只約束 TOTAL 的邊際分布, 對 DIFF 一無所知。它可以完美推出大細和單雙 (兩者都只是 TOTAL 的函數), 但對「哪隊贏」的預測誤差高達 32 至 38 個百分點, 相當於完全沒有資訊。

圖 6 右邊補上另一個發現: 在各種兩盤口組合下, 樣本外殘差最集中的位置都是讓球盤。讓球盤的線由莊家選定, 而且經常是四分一球 (例如 −0.5/−1.0), 它帶著「市場認為差距落在哪個窄區間」的資訊, 是其他盤口的粗網格捕捉不到的。


九、歷史驗證: 90,514 場有賽果的樣本

以上全部分析都沒有用到賽果 — 這是刻意的, 因為一致性是賠率的內在性質。但要判斷「哪種去水最貼近真實機率」, 始終要有結果數據。

用 football-data.co.uk 的歐洲 13 個聯賽、21 個球季共 90,514 場, 其中 58,026 場有 Pinnacle 收市 1X2 賠率。

圖 8:在有賽果的歷史樣本上驗證同一套方法

第一項: 收市 1X2 的校準。 Pinnacle 收市盤平均抽水只有 2.77%:

方法

log loss

Brier

平均絕對分桶偏差

對 power 的 Δlog loss

p

power

0.97386

0.57982

0.427pp

additive

0.97387

0.57983

0.425pp

+0.11e-4

0.556

shin

0.97392

0.57985

0.526pp

+0.66e-4

0.015

odds_ratio

0.97395

0.57986

0.558pp

+0.92e-4

0.0018

proportional

0.97420

0.57998

0.913pp

+3.38e-4

7.1e-06

這裡出現一個表面矛盾: 在 HKJC 的跨盤口一致性測試裡 shin 最好, 在歷史校準測試裡卻是 power 最好, shin 排第三。

矛盾其實不存在。看清楚 log loss 的差距: 最好與最差之間只有 3.4e-4, 在 0.974 的水平上是萬分之三。抽水只有 2.8% 時, 五種方法本來就近乎等價, 排名的實際意義極低。

真正有用的是校準曲線的形狀。圖 8 左圖顯示, proportional 在熱門一端 (報價機率 65% 以上) 系統性高估 2.70pp, 在冷門一端 (5–10%) 系統性低估 1.72pp。這就是教科書上的 favourite–longshot bias。Shin 把這個偏差壓到 1.74pp 和 1.06pp, 減幅約三分之一, 但沒有完全消除。

換句話說: 熱門被低估、冷門被高估的現象, 有一部分來自去水方法的假設錯誤, 但另有一部分是市場的真實定價偏好, 任何去水方法都消不掉。

第二項: 歷史樣本的免模型一致性。 用 8,631 場同時有 1X2 與亞洲讓球收市盤的賽事, 檢查「讓球 −0.5 應該等於 P(主勝)」這類恆等式:

讓球線

proportional

additive

power

odds_ratio

shin

−0.5

0.258

0.259

0.267

0.102

0.147

0.0

0.086

0.085

0.103

0.102

0.093

+0.5

0.254

0.259

0.270

0.111

0.155

合計

0.187

0.188

0.200

0.104

0.127

(單位: 百分點)

在 2.4–3.0% 抽水的市場, 兩個獨立盤口對同一件事的講法相差只有 0.10 至 0.20 個百分點。市場的內在一致性極高, 這也印證了第六節在 HKJC 高抽水環境下得出的 0.20pp 殘差並非巧合。

第三項: 加一個盤口, 分布準多少。 用 6,000 場, 分別以不同盤口組合擬合 Dixon–Coles, 再看它對真實比數的預測:

擬合盤口

比數 log loss

1X2 log loss

大細 log loss

對讓球盤誤差

對大細盤誤差

只用 1X2

2.9373

0.9606

0.7128

1.39pp

10.32pp

1X2 + 大細 2.5

2.8651

0.9609

0.6741

0.65pp

0.01pp

1X2 + 大細 + 讓球

2.8646

0.9612

0.6741

0.29pp

0.07pp

基準線: 用整體實際入球率的固定模型 (λ主 = 1.519, λ客 = 1.175), 比數 log loss 是 3.0351。

從只用 1X2 到加入大細盤, 比數 log loss 由 2.9373 跌到 2.8651, 對大細盤的定價誤差由 10.32pp 跌到 0.01pp。再加讓球盤, 比數預測幾乎沒有進一步改善 (2.8651 → 2.8646), 但對讓球盤自身的定價誤差再減一半。

這一點與第八節完全吻合: 勝負類與入球類各取其一就足夠, 第三個盤口帶來的邊際資訊很有限。


十、實務含意: 抽水不是平均分佈的

既然可以還原一個公平分布, 就可以反過來量度每一個選項的實際成本。方法是留一法: 反解時剔除該盤口自身, 用其餘六個盤口還原的分布作為公平值, 再算

edge_i  =  q_fair_i × o_i  −  1        負值即每 1 元注碼的期望損失
圖 7:抽水不是平均分佈的

盤口

選項數

平均有效抽水

最好選項

最差選項

讓球

60

5.81%

−2.70%

−10.70%

入球單雙

112

7.54%

−4.39%

−10.61%

入球大細

306

8.29%

−2.30%

−24.70%

主客和

168

13.27%

−5.06%

−49.62%

讓球主客和

306

14.72%

+1.44%

−41.78%

總入球

448

28.71%

−10.04%

−77.17%

波膽

1,848

50.63%

−6.06%

−100.00%

平均值與第三節的名義抽水基本吻合, 這本身是一個一致性檢查。但「最好」與「最差」兩欄的距離說明, 名義抽水只是平均數。

按賠率分組看得更清楚:

賠率區間

波膽

主客和

讓球主客和

入球大細

總入球

1–1.5

−9.9%

−8.8%

−6.4%

2–3

−11.5%

−14.6%

−8.6%

−18.4%

5–10

−27.9%

−18.8%

−25.8%

−28.9%

10–25

−31.2%

−33.4%

−36.1%

−36.4%

60–150

−70.5%

−53.3%

150 以上

−80.0%

同一個主客和盤內, 熱門選項的有效抽水約 10%, 賠率 10 以上的冷門選項則接近 33%。波膽盤賠率 150 以上的選項, 有效抽水達 80%。第三節看到的「盤口線走遠一條就貴 0.8pp」, 在這裡放大成三倍以上的成本差距。

同一個觀點, 選錯路線貴三倍。 由於同一件事可以經多個盤口表達, 成本差別可以直接量度:

觀點

入球大細

總入球

波膽

主客和

大 2.5 (總入球 ≥ 3)

8.21%

25.41%

37.97%

細 2.5 (總入球 ≤ 2)

7.48%

21.22%

28.34%

主勝

36.18%

13.21%

和局

30.52%

14.47%

兩隊皆有入球

35.16%

「大 2.5」經大細盤表達成本 8.21%, 經總入球盤加總是 25.41%, 經波膽盤砌是 37.97%。同一個觀點、同一個結算條件, 成本差 4.6 倍。逐場統計, 大細盤在 75% 場次是最平路線, 總入球盤佔 25%。

最後: 有沒有套戥? 既然七個盤口共用一個分布但各有抽水, 一個自然問題是能否組合出無風險利潤。用線性規劃求「最少要多少本金, 才能保證任何比數下都收回 1 元」:

# 變數: 每個選項的注碼 x_i ≥ 0
# 約束: 對每個比數 (i,j), Σ_k x_k · payoff_k(i,j) ≥ 1
# 目標: min Σ x_i          → 最優值 < 1 即存在套戥
res = linprog(c=np.ones(n), A_ub=-payoff.T, b_ub=-np.ones(K * K), bounds=(0, None))

56 場全部檢查:

  • 七個盤口同時使用, 保證回本的最低本金中位為 1.0689

  • 最佳單一盤口需要 1.0778 元

  • 出現套戥 (低於 1.00) 的場數: 0 / 56

跨盤口組合相對最佳單一盤口的改善, 中位只有 0.73 個百分點, 最大 1.94 個百分點 (圖 9 右)。

這個結果與前面的分析吻合: 正因為七個盤口高度一致, 它們之間才沒有套戥空間。跨盤口組合唯一的作用, 是把保證回本的成本由 7.8% 壓到 6.9%, 距離收支平衡仍然很遠。


十一、方法的限制

樣本的時間跨度短。 七個 snapshot 集中在約 40 分鐘內, 距離開賽 0.7 小時至 8 日不等, 不足以分析賠率隨開賽時間的動態。「臨近開賽時一致性會否收窄」這個問題, 本文回答不到。

參照分布的選擇有影響。 最大熵解在約束稀疏的格點 (例如 8:3 這類比數) 主要由 p_ref 決定。本文用 Dixon–Coles 作參照, 換一個參照會改變極端尾部, 但對佔九成以上機率質量的主要格點影響很細。

走盤機率的處理是近似。 計算約束右邊時, 走盤機率用當前迭代的 p 估算, 存在輕微的循環依賴。實測收斂很快, 但這是一個近似。

波膽盤的「其他」桶。 五個 catch-all 桶佔的機率不多 (等比例隱含機率約 0.3–4%), 但它們的遮罩定義依賴「馬會明確列出了哪 28 個比數」, 若不同賽事列表不同, 需要逐場重建。


總結

七個盤口能否還原一個一致的市場預期入球分布? , 而且一致程度遠高於預期: 同一場波之內, 七類結算方式完全不同的盤口共用同一個 169 格分布時, 平均誤差只有 0.20 個百分點 (56 場、3,248 個選項)。

但這個「能」有條件。去水方法在厚抽水的盤口是決定性的; 市場的分布不服從三參數 Poisson 結構; 而勝負類與入球類盤口之間, 存在不能互相取代的資訊。

概念

實務作用

章節

比數格上的線性約束

把七類盤口翻譯成同一種語言

走盤的正確處理

避免系統性高估讓球盤成本

抽水 ∝ log(選項數)

一眼判斷某盤口的定價層級

去水方法的分歧隨抽水擴大

決定何時要認真挑方法

四、九

免模型一致性檢查

不用賽果就能評估去水方法

最大熵反解

由多個盤口合成一個分布

非參數 vs Dixon–Coles

判斷參數模型夠不夠用

留一樣本外測試

找出哪些盤口帶獨有資訊

逐選項有效抽水

量度真實成本而非名義抽水

線性規劃套戥檢查

驗證市場一致性的另一個角度

最後補充一點: 高度一致本身就是套戥空間不存在的原因。若七個盤口真的各自為政, 反而會出現無風險套利的縫隙; 實際觀察到的是 56 場全部沒有。對於想由賠率提取市場觀點的人, 這代表任何一個資訊量足夠的盤口已經包含大部分內容, 不必逐個盤口分開處理。


Reference

  1. Shin, H. S. (1993). Measuring the Incidence of Insider Trading in a Market for State-Contingent Claims. The Economic Journal, 103(420), 1141–1153.

  2. Dixon, M. J., & Coles, S. G. (1997). Modelling Association Football Scores and Inefficiencies in the Football Betting Market. Journal of the Royal Statistical Society: Series C, 46(2), 265–280.

  3. Štrumbelj, E. (2014). On Determining Probability Forecasts from Betting Odds. International Journal of Forecasting, 30(4), 934–943.

  4. Clarke, S., Kovalchik, S., & Ingram, M. (2017). Adjusting Bookmaker's Odds to Allow for Overround. American Journal of Sports Science, 5(6), 45–49.

  5. Jaynes, E. T. (1957). Information Theory and Statistical Mechanics. Physical Review, 106(4), 620–630.


資料來源



bottom of page