Table des matières
Sport-Arbitrage
Sport-Arbitrage est une petite calculatrice web pour l’arbitrage en paris sportifs : on saisit les cotes que deux sites offrent pour un même match, et elle indique si parier sur des issues opposées aux deux endroits assure un gain, puis comment répartir la mise. C’est un dépôt AlgoÉTS qui contient une page web et un carnet Python reposant sur les mêmes formules.
1. Aperçu
index.html est un formulaire unique mis en forme avec Tailwind CSS 2.2.19 chargé depuis un CDN. Toute la logique se trouve dans script.js :
hasArbitrageOpportunity(odds)additionne les inverses des cotes et signale une occasion quand la somme est inférieure à 1.calculateArbitragePercentagerenvoie(1 − Σ 1/cote) × 100.calculateOptimalStakesrépartit la mise totale proportionnellement à l’inverse de chaque cote, pour que chaque issue rapporte le même montant.calculateTotalReturnetcalculateGuaranteedProfitdonnent le gain par issue, puis le plus petit gain moins la mise.calculateArbitrage()lit le formulaire, teste deux paires entre les sites (victoire au site 1 avec défaite au site 2, et défaite au site 1 avec victoire au site 2), ajoute un match nul à chaque paire en mode trois issues, puis affiche une carte par occasion.
arbitrage.ipynb reprend les mêmes fonctions en Python, avec des cotes d’exemple codées en dur dans la première cellule.
2. Cas d’utilisation
Calculatrice web qui vérifie les cotes de deux sites de paris pour repérer un arbitrage et répartir la mise.
- Choisir 2 ou 3 issues
- Parieur
Le sélecteur Number of Odds d’index.html appelle toggleOddsFields() dans script.js, qui n’affiche les deux champs Draw que pour trois issues.
- Saisir les cotes de deux sites
- Parieur
Le formulaire reçoit les cotes Win et Lost des sites 1 et 2, les cotes Draw facultatives et la mise totale.
- Repérer un arbitrage
- Parieur
calculateArbitrage() teste des paires fixes entre les deux sites ; hasArbitrageOpportunity() signale un arbitrage quand la somme des inverses des cotes est inférieure à 1.
- Répartir la mise
- Parieur
Pour chaque occasion, script.js affiche le pourcentage d’arbitrage, les mises optimales, le gain par issue et le profit garanti.
- Vérifier le calcul en Python
- Parieur
arbitrage.ipynb reprend les mêmes fonctions en Python avec des cotes d’exemple codées en dur pour le cas à deux issues.
2.1. Scénario : Tester les cotes d’exemple du carnet
- Ouvrir index.html dans un navigateur et laisser Number of Odds à 2.
- Saisir Win Site 1 = 1.3, Lost Site 1 = 3.93, Win Site 2 = 1.42 et Lost Site 2 = 2.9.
- Entrer une mise totale (Total Investment) de 100 et cliquer sur Calculate.
- Lire le résultat : seule la paire lost-site1 et win-site2 se qualifie, avec des mises d’environ 26,54 et 73,46.
- Comparer avec la ligne de profit garanti (environ 4,31) et relancer arbitrage.ipynb pour vérifier les mêmes chiffres.
Fichiers consultésREADME.mdindex.htmlscript.jsstyle.cssarbitrage.ipynb
3. Fonctionnement de l’algorithme
Probabilité implicite. Une cote décimale o rapporte o fois la mise quand le pari gagne, mise comprise. La probabilité à laquelle ce pari est à l’équilibre vaut 1/o : c’est la probabilité implicite. Chez un même bookmaker, les probabilités implicites de toutes les issues dépassent 1 au total ; l’excédent est sa marge. Deux sites aux avis un peu différents peuvent pourtant diverger assez pour qu’en prenant la meilleure cote de chaque issue d’un site à l’autre, la somme passe sous 1.
Condition d’arbitrage. Pour des issues qui couvrent tous les résultats possibles, avec des cotes o₁ … oₙ prises sur n’importe quels sites :
S = 1/o₁ + 1/o₂ + … + 1/oₙ
il y a arbitrage quand S < 1
Répartition des mises. Pour obtenir le même gain quelle que soit l’issue, chaque mise doit être proportionnelle à sa probabilité implicite : miseᵢ = investissement × (1/oᵢ) / S. Chaque issue rapporte alors miseᵢ × oᵢ = investissement / S, et le profit garanti vaut investissement × (1/S − 1). C’est exactement ce que calculent calculateOptimalStakes, calculateTotalReturn et calculateGuaranteedProfit.
Exemple détaillé, deux issues. Le site 1 propose 2,10 sur une victoire et 1,80 sur une défaite ; le site 2, 1,75 sur une victoire et 2,05 sur une défaite.
| Étape | Valeur |
|---|---|
| Site 1 seul : 1/2,10 + 1/1,80 | 1,0317, une marge de 3,2 %, pas d’arbitrage |
| Site 2 seul : 1/1,75 + 1/2,05 | 1,0592 |
| Victoire au site 1 + défaite au site 2 : 1/2,10 + 1/2,05 = 0,4762 + 0,4878 | 0,9640 < 1, arbitrage |
| Défaite au site 1 + victoire au site 2 : 1/1,80 + 1/1,75 | 1,1270, aucun |
| Mises pour 1 000 $ : 1000 × 0,4762 / 0,9640 et 1000 × 0,4878 / 0,9640 | 493,98 $ sur la victoire, 506,02 $ sur la défaite |
| Gain dans les deux cas : 493,98 × 2,10 = 506,02 × 2,05 | 1 037,35 $ |
| Profit garanti | 37,35 $, soit 3,73 % de l’investissement |
La page affiche un « pourcentage d’arbitrage » de 3,60 %, qui vaut (1 − S) × 100. C’est l’écart sous 1, pas le rendement : le rendement sur la somme misée est 1/S − 1, ici 3,73 %.
Trois issues. Avec un match nul, les mêmes formules prennent trois cotes. Une victoire à 2,60 au site 1, une défaite à 3,40 au site 2 et un nul à 3,50 au site 1 donnent S = 0,3846 + 0,2941 + 0,2857 = 0,9644. Pour 1 000 $, les mises valent 398,79 $, 304,96 $ et 296,25 $, chaque issue rapporte 1 036,86 $ et le profit est de 36,86 $.
flowchart TD
A["Lire les cotes : victoire et défaite aux sites 1 et 2, nuls si 3 issues, investissement"] --> B{"Deux ou trois issues ?"}
B -->|deux| P1["Paire A : victoire site 1 + défaite site 2"]
B -->|deux| P2["Paire B : défaite site 1 + victoire site 2"]
B -->|trois| P3["Ensemble A : victoire site 1 + défaite site 2 + nul site 1"]
B -->|trois| P4["Ensemble B : défaite site 1 + victoire site 2 + nul site 2"]
P1 & P2 & P3 & P4 --> S["S = somme des 1/cote"]
S --> C{"S < 1 ?"}
C -->|non| N["Combinaison ignorée"]
C -->|oui| K["miseᵢ = investissement × (1/oᵢ) / S"]
K --> R["gainᵢ = miseᵢ × oᵢ = investissement / S"]
R --> G["profit = min(gain) − investissement"]
G --> O["Une carte de résultat par combinaison"]
N --> E{"Au moins une carte ?"}
O --> E
E -->|non| X["No Arbitrage Opportunities Found"]
4. Démarrage
Rien à compiler. Clonez le dépôt et ouvrez la page dans un navigateur (la feuille Tailwind vient de jsDelivr : sans réseau, la mise en forme manque) :
git clone https://github.com/AlgoETS/Sport-Arbitrage.git
cd Sport-Arbitrage
Ouvrez ensuite index.html, choisissez 2 ou 3 cotes, remplissez les cotes et la mise totale, puis cliquez sur Calculate. Pour la version Python :
jupyter notebook arbitrage.ipynb
5. Guide du dépôt
index.html: formulaire de la calculatrice, consignes et zone de résultats.script.js: affichage des champs, test d’arbitrage, répartition de la mise, gains et profit.arbitrage.ipynb: version Python des formules pour le cas à deux issues.style.css: styles de mise en page de base (non référencés parindex.html).
6. Fonctionnalités
- passer d’un marché à deux issues (victoire/défaite) à un marché à trois issues (victoire/défaite/nul) ;
- tester des paires entre les deux sites avec la somme des inverses des cotes ;
- afficher le pourcentage d’arbitrage, les mises optimales, le gain par issue et le profit garanti ;
- tout calculer dans le navigateur, sans serveur ni compte ;
- vérifier les mêmes calculs dans un carnet Jupyter.
7. Limites
- Seules deux paires fixes sont testées. En mode trois issues, le nul du site 1 accompagne toujours la victoire au site 1 et la défaite au site 2, et le nul du site 2 la défaite au site 1 et la victoire au site 2 ; les autres combinaisons ne sont jamais essayées.
- Le « pourcentage d’arbitrage » affiché vaut
(1 − S) × 100, un peu moins que le rendement réel1/S − 1. - Les formules supposent des cotes décimales, et le formulaire ne valide pas les saisies : un champ vide donne
NaN. - Les mises ne sont pas arrondies et ignorent frais, plafonds de mise et variations de cotes : le « profit garanti » ne tient que si chaque pari est accepté aux cotes saisies.
style.cssn’est pas relié à la page, et le carnet ne couvre que le cas à deux issues.- Il n’y a pas de tests.
8. Sources
9. Pipeline CI/CD
Aucun pipeline CI/CD dans le dépôt. Le code se construit et se lance à la main, comme décrit plus haut.
Généré à partir du code au commit dbee188.
10. Schéma de déploiement
Mermaid Schéma de déploiement
flowchart LR
repo[("Dépôt GitHub")]
local["Poste local"]
repo -->|"cloner et lancer"| local
Le dépôt ne contient ni Dockerfile, ni fichier Compose, ni configuration d’hébergement : le code s’exécute sur le poste qui le clone.
11. Dépendances externes
Le dépôt ne déclare aucun paquet externe : aucun manifeste (pyproject.toml, requirements.txt, package.json, pom.xml…) n’y figure.
12. Glossaire
Dépôt
Les fichiers source, la configuration et l’historique versionné d’un projet.
README
Le document d’entrée du dépôt, qui présente généralement son rôle et son installation.
Dépendance
Une bibliothèque, un outil ou un service nécessaire à la compilation ou à l’exécution d’un composant.
HTTP
Un protocole de requête et réponse utilisé par les navigateurs et services web. Une requête comprend une méthode, un chemin, des en-têtes et parfois un corps.
Port publié
Un port de l’hôte associé au port d’un service dans un conteneur. Sa publication peut rendre le service accessible hors du réseau des conteneurs.
Interface en ligne de commande
Une interface textuelle où les commandes et arguments choisissent les opérations. Les codes de retour permettent aux scripts de détecter un succès ou un échec.
Compilation
Les étapes qui transforment les sources et dépendances en programme exécutable ou en livrable distribuable.
Mermaid
Un langage de diagrammes textuel. Les nœuds et liens décrivent un modèle ; le diagramme n’exécute pas le projet.
13. Références
- AlgoÉTS. (2026, 5 novembre). [Web page] github.com.
- AlgoETS. (2026, 5 novembre). Sport-Arbitrage. [Software repository] github.com.
- AlgoETS. (2026, 5 novembre). README. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). index.html. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). script.js. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). arbitrage.ipynb. [Source file or documentation] github.com.
Les sources sans date de publication indiquent la date de leur dernière vérification, le 5 novembre 2026. Les liens des fichiers conservent la révision inspectée lorsqu’elle est disponible.