1. Introducción: la Superficie de Probabilidad Fundamental del Fútbol
En el trading cuantitativo de fútbol, los principales mercados (1X2, Más/Menos de goles, Hándicap Asiático, Ambos Marcan y margen exacto de victoria) no son fenómenos estadísticos independientes. Son derivados de una única distribución estocástica: la superficie de probabilidad conjunta de los resultados exactos.
Los apostadores recreativos suelen tratar los mercados como sucesos desconectados: apuestan a "Más de 2,5 Goles" en una casa, a "Gana el Arsenal" en otra y a "Ambos Marcan" en una tercera. Así quedan expuestos a márgenes acumulados en varias líneas derivadas. Los analistas cuantitativos hacen lo contrario: construyen una única cuadrícula de probabilidad bivariada, la Matriz de Resultado Exacto, y obtienen las cuotas justas de todos los mercados relacionados sumando subconjuntos de celdas.
- Victoria Local (1):
- Empate (X):
- Victoria Visitante (2):
- Más de 2,5 Goles:
- Ambos Marcan (Sí):
Esta guía técnica explica cómo construir la Matriz de Resultado Exacto a partir de las expectativas de goles de Poisson ( y ). Analizamos los límites de truncamiento de la masa de probabilidad, detallamos las sumas de celdas para cada mercado derivado, incorporamos la corrección de Dixon-Coles para resultados bajos, recorremos un ejemplo de matriz y ofrecemos código en Python.
2. Construcción de la Cuadrícula Bivariada: la Matriz de Probabilidades
Supongamos que el modelo econométrico fija las intensidades de goles esperados para el Local () y el Visitante (). Bajo la hipótesis clásica de Poisson independiente, la probabilidad de que el local marque exactamente goles y el visitante exactamente goles es el producto de sus funciones de probabilidad marginales:
Dimensión de la Matriz y Límites de Truncamiento
La distribución de Poisson tiene soporte infinito (), pero en la práctica la cuadrícula se trunca en un límite superior . ¿Qué dimensión conviene usar?
Lo que recoge una cuadrícula (resultados de a , 49 celdas) depende de las expectativas: el 99,9% de la masa de probabilidad para , el 99,1% para , pero solo el 95,2% para . Elija la cuadrícula según tolerancia explícita de cola omitida y parámetros definidos. Normalizar la cuadrícula truncada condiciona a ella, no recupera marcadores omitidos. Amplíela e informe la cola restante.
3. Mercados Derivados como Particiones de la Matriz
La gran ventaja operativa de la Matriz de Resultado Exacto es que cualquier mercado corresponde a una partición geométrica de la cuadrícula:
1. El Mercado de Resultado 1X2
Las 49 celdas se dividen en tres regiones mutuamente excluyentes respecto a la diagonal principal:
2. Líneas de Más/Menos Goles
Los mercados de total de goles evalúan si el marcador agregado supera un umbral de medio gol . La probabilidad del Menos es la suma de las celdas de las antidiagonales en las que :
3. Ambos Marcan (BTTS)
El mercado "Ambos Marcan: No" representa el suceso en que al menos un equipo no marca ( o ). Corresponde a la unión de la primera fila y la primera columna de la matriz:
4. Hándicaps Asiáticos
Para cualquier línea de Hándicap Asiático , la probabilidad de que el local cubra el hándicap es la suma de las celdas que cumplen :
4. La Corrección de Dixon-Coles para Resultados Bajos
Dixon y Coles (1997) comprobaron que los modelos de Poisson independientes infravaloran los empates y y sobrevaloran los resultados y . Para corregir este sesgo, las cuatro celdas de resultado bajo se multiplican por el factor de ajuste de Dixon y Coles :
Donde se ajusta con partidos históricos y suele ser pequeño y negativo (el código de abajo usa como ejemplo). La corrección traslada masa de probabilidad de los resultados y a los empates y , lo que eleva ligeramente la probabilidad de empate.
5. Ejemplo Paso a Paso: Manchester City contra Newcastle
Considere un partido hipotético de la Premier League con intensidades de goles esperados de (Manchester City como local) y (Newcastle como visitante).
La Cuadrícula Central (Subconjunto)
| Man City \ Newcastle | 0 Goles () | 1 Gol () | 2 Goles () | 3 Goles () |
|---|---|---|---|---|
| 0 Goles () | 0-0: 4.98% | 0-1: 4.23% | 0-2: 1.80% | 0-3: 0.51% |
| 1 Gol () | 1-0: 10.70% | 1-1: 9.10% | 1-2: 3.87% | 1-3: 1.10% |
| 2 Goles () | 2-0: 11.51% | 2-1: 9.78% | 2-2: 4.16% | 2-3: 1.18% |
| 3 Goles () | 3-0: 8.25% | 3-1: 7.01% | 3-2: 2.98% | 3-3: 0.84% |
Probabilidades de los Mercados Derivados y Cuotas Justas
Las cifras del 1X2 suman todos los resultados; en este partido la cuadrícula contiene el 99,3% de la masa de probabilidad.
- Victoria Local ():
- Empate ():
- Victoria Visitante ():
- Más de 2,5 Goles:
- Ambos Marcan (Sí):
6. Implementación en Python: Generador de la Cuadrícula de Resultado Exacto
A continuación se muestra un script en Python que genera la cuadrícula completa, aplica el ajuste de Dixon-Coles y obtiene los precios justos de todos los mercados derivados.
# correct_score_matrix_engine.py
import numpy as np
from scipy.stats import poisson
def generate_correct_score_matrix(lambda_home, mu_away, rho=-0.11, max_goals=6):
# Generates a calibrated 7x7 correct score probability matrix.
grid_size = max_goals + 1
matrix = np.zeros((grid_size, grid_size), dtype=np.float64)
# Compute raw independent Poisson probabilities
for i in range(grid_size):
p_home = poisson.pmf(i, lambda_home)
for j in range(grid_size):
p_away = poisson.pmf(j, mu_away)
matrix[i, j] = p_home * p_away
# Apply Dixon-Coles low-score correction tau
tau_00 = 1.0 - lambda_home * mu_away * rho
tau_01 = 1.0 + lambda_home * rho
tau_10 = 1.0 + mu_away * rho
tau_11 = 1.0 - rho
matrix[0, 0] *= tau_00
matrix[0, 1] *= tau_01
matrix[1, 0] *= tau_10
matrix[1, 1] *= tau_11
# Normalize matrix to 1.0 to absorb truncation error
matrix /= np.sum(matrix)
# Derive Ancillary Markets
p_home_win = np.sum(np.tril(matrix, -1))
p_draw = np.sum(np.diag(matrix))
p_away_win = np.sum(np.triu(matrix, 1))
# Over / Under 2.5
under_25_mask = np.array([[i + j <= 2 for j in range(grid_size)] for i in range(grid_size)])
p_under_25 = np.sum(matrix[under_25_mask])
p_over_25 = 1.0 - p_under_25
# Both Teams To Score (BTTS)
p_btts_yes = np.sum(matrix[1:, 1:])
p_btts_no = 1.0 - p_btts_yes
return {
'matrix': matrix,
'home_win_prob': p_home_win,
'draw_prob': p_draw,
'away_win_prob': p_away_win,
'over_25_prob': p_over_25,
'under_25_prob': p_under_25,
'btts_yes_prob': p_btts_yes,
'fair_1x2_odds': (1.0 / p_home_win, 1.0 / p_draw, 1.0 / p_away_win),
'fair_ou25_odds': (1.0 / p_over_25, 1.0 / p_under_25),
'fair_btts_odds': (1.0 / p_btts_yes, 1.0 / p_btts_no)
}
if __name__ == '__main__':
res = generate_correct_score_matrix(2.15, 0.85)
print("Fair 1X2 Odds:", np.round(res['fair_1x2_odds'], 2))
print("Fair Over/Under 2.5:", np.round(res['fair_ou25_odds'], 2))
print("Fair BTTS Odds:", np.round(res['fair_btts_odds'], 2))
7. Estabilidad Numérica y Normalización
Al calcular matrices de Poisson conjuntas, la precisión de coma flotante importa en resultados extremos como 6-5 o 5-4. El código de producción acumula los logaritmos de las funciones de probabilidad, , y vuelve al espacio de probabilidades con la exponencial para evitar el underflow. Dividir toda la cuadrícula por su suma acumulada hace que la probabilidad total sea exactamente 1, de modo que los precios de 1X2, totales, Ambos Marcan y hándicaps que se derivan de ella son coherentes entre sí.
