Un bug silencieux traîne dans beaucoup de systèmes de détection de value : l'EV affichée dépend d'un choix que personne n'a documenté. Ce choix, c'est le modèle utilisé pour retirer la marge du bookmaker. Changez-le, et le même pari passe de +1,2 % à +2,6 % d'EV — sans qu'une seule cote ait bougé.
Ce n'est pas un détail d'implémentation. C'est l'hypothèse centrale de toute votre valorisation : comment le book répartit-il sa commission entre les issues ?
Le point de départ : la somme dépasse 100 %
Sur un moneyline à 1,55 / 2,55, l'inverse de chaque cote donne 64,5 % et 39,2 %. Total : 103,7 %. Ces 3,7 points sont la marge. Tous les modèles cherchent à revenir à 100 % ; ils ne diffèrent que sur la façon de retirer le surplus.
odds = [1.55, 2.55]
raw = [1 / o for o in odds]
print(f"overround : {sum(raw) - 1:.2%}") # 3.70 %Additive : retirer la même chose à tout le monde
Le modèle le plus naïf : on soustrait à chaque probabilité une part égale du surplus. Facile à expliquer, mais il traite un favori à 90 % et un outsider à 5 % comme s'ils portaient la même charge de marge — ce qui n'est vrai chez aucun bookmaker.
def additive(odds):
raw = [1 / o for o in odds]
excess = (sum(raw) - 1) / len(raw)
return [p - excess for p in raw]Sur un marché très déséquilibré, l'additive peut produire une probabilité négative pour l'outsider le plus long. Si votre code n'a pas de garde-fou là-dessus, il sortira des cotes équitables absurdes plutôt qu'une erreur visible.
Multiplicative : la proportionnelle
On divise chaque probabilité par la somme. Rapide, sans paramètre, c'est le défaut de la plupart des outils. Sur un deux-issues serré, elle est difficile à battre. Son hypothèse — une marge répartie en pourcentage égal — reste cependant fausse dès que le marché est asymétrique.
def multiplicative(odds):
raw = [1 / o for o in odds]
total = sum(raw)
return [p / total for p in raw]
# 1.55 / 2.55 → probabilités 62.22 % / 37.78 %Power : courber la relation
On cherche un exposant k tel que la somme des probabilités élevées à la puissance k fasse exactement 1. Au lieu de décaler les probabilités, on déforme la courbe : effet faible sur les favoris, fort sur la queue de distribution. C'est ce comportement qui colle le mieux aux marchés à nombreuses issues.
from scipy.optimize import brentq
def power(odds):
raw = [1 / o for o in odds]
k = brentq(lambda k: sum(p ** k for p in raw) - 1, 0.5, 1.5)
return [p ** k for p in raw]Shin : la marge comme prime d'assurance
Shin ajoute une hypothèse économique : le book fixe sa marge pour se couvrir contre une proportion z de parieurs mieux informés que lui. Cette proportion est déduite des cotes, puis retirée — ce qui charge davantage les outsiders, exactement comme le font les books en pratique.
def shin(odds, iterations=100):
raw = [1 / o for o in odds]
total = sum(raw)
z = 0.0
for _ in range(iterations):
probs = [
(((z ** 2 + 4 * (1 - z) * p ** 2 / total) ** 0.5) - z) / (2 * (1 - z))
for p in raw
]
s = sum(probs)
z += (s - 1) / 2
return [p / s for p in probs]Odds ratio : un paramètre de distorsion
Le modèle odds ratio cherche un facteur unique appliqué au rapport de cotes (la « chance » plutôt que la probabilité) de chaque issue. Il donne souvent des résultats proches de Shin, avec une intuition plus simple : le book ne déforme pas les probabilités, il déforme les rapports.
Où les modèles divergent vraiment
Sur un deux-issues équilibré, tout le monde se tient dans un mouchoir : l'écart entre les cinq modèles reste sous 0,3 point de probabilité, c'est-à-dire dans le bruit de votre propre estimation. C'est en s'éloignant de la parité que les décisions changent :
- Favori marqué (1,10 contre 9,00) : la multiplicative sous-estime le favori et surestime l'outsider ; l'écart avec Shin dépasse un point sur l'outsider.
- 1X2 avec un nul mal prisé : power et Shin s'accordent, la multiplicative fabrique de la fausse value sur le nul.
- Marchés à nombreuses issues (outrights, correct score, buteurs) : la multiplicative devient franchement mauvaise sur les longues cotes. Power ou Shin, jamais elle seule.
- Handicaps asiatiques et totals : deux-issues très liquide, marge faible — le choix du modèle pèse peu, prenez le plus rapide.
Le modèle de devig n'est pas un réglage cosmétique : c'est votre hypothèse sur le comportement du bookmaker. Autant la choisir consciemment.
La règle qui compte plus que le modèle
Quel que soit votre choix, tenez-le. Le piège le plus coûteux n'est pas de prendre le « mauvais » modèle, c'est d'en changer entre le backtest et la production : vos EV historiques deviennent incomparables à vos EV live, et vous conclurez que votre edge s'est effondré alors que seule la règle de mesure a bougé.
- Figez un modèle par famille de marchés, et écrivez-le quelque part.
- Stockez le modèle utilisé à côté de chaque EV enregistrée — sinon vos données historiques ne sont plus interprétables.
- Avant d'ajuster votre seuil d'EV, vérifiez que ce n'est pas votre devig qui a changé.
Le faire côté serveur
Sur apinn, les cinq modèles sont implémentés côté serveur et appliqués au moment du tick : chaque ligne arrive avec sa cote de marché et sa cote équitable, dans le modèle que vous demandez. Vous choisissez votre hypothèse par requête — ou une fois pour toutes dans les préférences du compte — et vos backtests utilisent exactement le même calcul que votre bot.
curl -H "X-API-Key: $APINN_KEY" \
"https://api.apinn.io/api/odds?event_id=1610000123&model=shin"
# odds1/odds2 = cotes de marché
# todds1/todds2 = cotes équitables
# model = power (défaut) | multiplicative | additive | shin | odds_ratioVotre EV se réduit alors à une division — et le débat sur le devig se règle une fois, à froid, plutôt qu'à chaque tick.
Ces calculs, sur des données réelles
Cotes Pinnacle en temps réel, cotes équitables incluses, historique d'ouverture et de clôture — accès self-serve, clé API en quelques minutes.