足球博彩中怎么进行套利交易(二)

在上一节中,我们对球队名称标准化的问题做了总结.我承认这不是一个完美的方法,因为足球数据里会不断出现新的联赛,新的球队,新的杯赛名称,以及不同网站对同一支球队的不同翻译.

所以在真实系统里,我不认为存在一个一劳永逸的球队名称归一化方案.更现实的答案是:先建立稳定的标准化规则,再持续运行归一化脚本,把新出现的特殊情况不断修订进去.足球数据的标准化不是一次性工程,而是一个需要长期维护的基础设施.

这篇文章的内容建立在球队名称已经统一以后.也就是说,我们已经可以确认不同数据源里的“阿根廷 VS 佛得角”指向同一场比赛.接下来要解决的问题是:同一场比赛下,不同玩法,不同盘口,不同博彩公司之间,怎样判断它们能不能组成套利结构.

标准化以后的数据大致会长成这样:

id,starttime,league,event,dealer,lay,bettype,handicap,odd_home,odd_draw,odd_away,currency,Max_amount,Min_amount,other,timeStamp
15889684,2023-09-28 08:30,自由杯,弗鲁米嫩 VS 巴西国际,no,360,over,2,1.8,0.0,0.0,cny,0,0,,2023-09-27 13:53
15889685,2023-09-28 08:30,自由杯,弗鲁米嫩 VS 巴西国际,no,360,under,2,0.0,0.0,2.05,cny,0,0,,2023-09-27 13:53

每一行都是同一场比赛下的一条盘口信息.它告诉我们:比赛是谁对谁,数据来自哪个 dealer,玩法是什么,盘口线是多少,主胜/平/客胜或者大小球方向的赔率是多少.

但是到这里还不能直接计算套利.因为一条数据只是一个报价,它本身并不知道自己和另外一条数据在规则上是什么关系.我们还需要先建立博彩规则映射.

问:为什么要先建立足球博彩规则映射?

套利交易的核心不是“看起来赔率很高”,而是“无论比赛结果是什么,都有一部分下注能够覆盖这个结果”.

例如 moneyline 有主胜,平局,客胜三种结果.如果我能在不同公司分别拿到足够高的主胜,平局,客胜赔率,那么这三条下注腿可以覆盖 90 分钟内的所有胜平负结果.

但是足球博彩不只有 moneyline.常见玩法包括:

玩法 常见含义
moneyline 胜平负
moneyline2in1 二选一胜平负变体
asiahandicap 亚洲让球
over / under 大小球
total 总进球数类玩法
correct score 精确比分
BTTS 双方是否进球

这些玩法并不总是在同一个维度里.例如全场 moneyline 不能和半场大小球混在一起计算,因为它们结算的比赛范围不同.全场 90 分钟规则下的结果,半场 45 分钟规则下的结果,加时赛规则下的结果,都应该被视为不同维度.

所以第一条原则是:只有同一个比赛维度下的玩法,才可以放进同一个套利模型中.

足球常规盘口通常按 90 分钟结算,包括伤停补时,不包括加时赛和点球大战.举一个规则例子:假设某场比赛 90 分钟比分是 1:1,加时赛以后变成 3:2.对于本文讨论的全场 moneyline,asiahandicap,over/under 等常规盘口,结算依据仍然是 90 分钟的 1:1,不是加时赛后的 3:2.

这件事看似简单,但非常重要.如果不同数据源或不同盘口的结算范围不一致,就算公式上看起来存在套利,真实执行时也可能不是同一个风险空间.

问:moneyline 套利为什么最容易理解?

moneyline 是最直观的例子.它把一场足球比赛的 90 分钟结果分成三类:

  1. 主队胜.
  2. 平局.
  3. 客队胜.

如果我们分别下注这三类结果,并且下注金额按赔率比例调整,就有可能做到三种结果下返还金额都大于总投入.

假设某场比赛不同博彩公司提供了如下赔率:

投注项 博彩公司 十进制赔率
Moneyline Home 主胜 Bookmaker A 2.30
Moneyline Draw 平局 Bookmaker B 3.70
Moneyline Away 客胜 Bookmaker C 4.20

先做最基础的倒数和判断:

\[ \frac{1}{2.30}+\frac{1}{3.70}+\frac{1}{4.20}=0.9428<1 \]

由于三项赔率倒数之和小于 1,说明存在理论套利空间.

如果计划投入总资金 1000 元,下注金额不是三项平均分配,而是按赔率倒数比例分配:

投注项 赔率 投注金额
Moneyline Home 主胜 2.30 460.63 元
Moneyline Draw 平局 3.70 286.36 元
Moneyline Away 客胜 4.20 253.01 元
合计 1000.00 元

最终返还如下:

90 分钟赛果 返还金额 净利润
主胜 460.63 × 2.30 = 1059.45 元 59.45 元
平局 286.36 × 3.70 = 1059.53 元 59.53 元
客胜 253.01 × 4.20 = 1062.64 元 62.64 元

这就是最基础的三项盘套利.核心原则是:套利不是让每一项下注金额相等,而是根据赔率调整资金比例,让不同赛果下的返还金额尽可能接近.

moneyline 之所以容易理解,是因为它只有三种互斥结果,并且每一条下注腿只有全赢或全输.但是足球博彩真正复杂的地方在于,很多盘口不是简单的赢和输.

问:为什么不能只用赔率倒数判断所有套利?

因为 asiahandicap 和 over/under 里存在走水,半赢,半输.

例如大小球 2.0:

总进球数 Over 2.0 Under 2.0
大于 2 球 全赢 全输
正好 2 球 走水 走水
小于 2 球 全输 全赢

再例如亚洲让球 -0.25:

赛果 下注主队 -0.25
主队赢球 全赢
平局 半输
主队输球 全输

这些盘口不能简单地套用 moneyline 的倒数和公式.因为某些比分状态下,一条下注腿可能不是全赢,也不是全输,而是半赢,半输或退回本金.

所以我们需要把每一种玩法都转换成一个更通用的表达:它在每一个可能比分下的结算结果是什么.

问:怎么用脚本计算出能够全包的玩法组合?

我的方法是建立一套基于穷举比分的多维度模型.

为了便于说明,先把足球比赛的进球数限制在 0,1,2.那么可能比分一共有 9 种:

比分状态
0:0
0:1
0:2
1:0
1:1
1:2
2:0
2:1
2:2

在这 9 种比分里:

moneyline_home 中奖的比分是:

1:0, 2:0, 2:1

moneyline_draw 中奖的比分是:

0:0, 1:1, 2:2

moneyline_away 中奖的比分是:

0:1, 0:2, 1:2

为了把 moneyline,亚盘,大小球放进同一个模型里,我把结算结果统一成五种代码:

代码 含义
0 全输
50 半输
100 走水
150 半赢
200 全赢

moneyline 只有全赢和全输,所以它的收益矩阵可以写成:

Bet Type 0:0 0:1 0:2 1:0 1:1 1:2 2:0 2:1 2:2
ML Home 0 0 0 200 0 0 200 200 0
ML Draw 200 0 0 0 200 0 0 0 200
ML Away 0 200 200 0 0 200 0 0 0

这个表格就是规则映射.它不是赔率表,而是玩法在每一种比分下的结算表.

如果某个比分状态下,ML Home 的代码是 200,意思是主胜下注全赢.如果代码是 0,意思是这条下注腿在这个比分下全输.

问:收益矩阵怎样扩展到更多玩法?

同样的方法可以扩展到亚洲让球,大小球,双方进球,精确比分等玩法.

例如在同样的 9 个比分状态下,加入一些常见玩法后,矩阵可以写成:

Bet Type 0:0 0:1 0:2 1:0 1:1 1:2 2:0 2:1 2:2
ML Home 0 0 0 200 0 0 200 200 0
ML Draw 200 0 0 0 200 0 0 0 200
ML Away 0 200 200 0 0 200 0 0 0
AH -1 0 0 0 100 0 0 200 200 100
AH -0.75 0 0 0 150 0 0 200 200 50
AH -0.5 0 0 0 200 0 0 200 200 0
AH -0.25 50 0 0 200 50 0 200 200 50
AH +0 100 0 0 200 100 0 200 200 100
AH +0.25 150 0 0 200 150 0 200 200 150
AH +0.5 200 0 0 200 200 0 200 200 200
O2.5 0 0 0 0 0 200 0 200 200
U2.5 200 200 200 200 200 0 200 0 0
BTTS Yes 0 0 0 0 200 200 0 200 200
BTTS No 200 200 200 200 0 0 200 0 0
Correct Score 0:0 200 0 0 0 0 0 0 0 0
Correct Score 0:1 0 200 0 0 0 0 0 0 0
Correct Score 0:2 0 0 200 0 0 0 0 0 0
Correct Score 1:0 0 0 0 200 0 0 0 0 0
Correct Score 1:1 0 0 0 0 200 0 0 0 0
Correct Score 1:2 0 0 0 0 0 200 0 0 0
Correct Score 2:0 0 0 0 0 0 0 200 0 0
Correct Score 2:1 0 0 0 0 0 0 0 200 0
Correct Score 2:2 0 0 0 0 0 0 0 0 200

这张表的意义是:每一种玩法都被转换成了一个收益向量.

例如:

\[ MLHome=(0,0,0,200,0,0,200,200,0) \]

\[ U2.5=(200,200,200,200,200,0,200,0,0) \]

如果几条下注腿的收益向量加起来,能在每一个比分状态下都形成覆盖,那么它们才有可能组成套利组合.

问:这张矩阵解决了什么问题?

它解决了三个问题.

第一,它把不同玩法放进了同一个坐标系.不管是 moneyline,asiahandicap,over/under,还是 correct score,最后都变成“在每个比分下返回什么代码”.

第二,它让脚本可以自动判断覆盖关系.如果一组下注腿在某些比分下全部为 0,说明这组下注腿没有覆盖全结果,不可能是安全套利.

第三,它为下一步计算下注比例打好了基础.矩阵里的 200,150,100,50,0 还不是最终金额,但它们可以根据真实赔率转换成返还倍数.比如全赢代码 200 会转换成赔率 \(O\),半赢代码 150 会转换成 \((O+1)/2\),走水代码 100 会转换成 1.

所以从这一刻开始,套利就不再只是一个赔率倒数问题,而是一个收益向量的线性组合问题.

下一篇继续写:当我们已经有了收益矩阵以后,怎样把真实赔率代入进去,解出每一条下注腿应该投入多少比例,并判断最差比分下是否仍然盈利.