LotteryCortex combine quatre techniques normalement réservées aux quantitative analysts et data scientists. Nous les rendons accessibles à quiconque achète un billet.
Cette page décrit chaque algorithme exécuté par LotteryCortex — de l'ingestion des données à la sélection des tickets. Tout est ouvertement documenté : pour chaque étape nous nommons le fichier source dans le code. Pas une solution miracle, mais la pile d'analyse de loterie la plus complètement documentée publiquement que nous ayons pu construire.
Algorithmes en détail
1. Shrinkage bayésien des fréquences
Combien de fois un numéro a été tiré, corrigé par la quantité de données disponibles.
- La fréquence brute surestime les numéros 'chauds' quand l'historique est court. Nous superposons un a priori de Dirichlet avec estimation automatique d'alpha (dirichletAlphaAuto, méthode des moments sur la variance empirique).
- Le résultat est une probabilité a posteriori par numéro qui se contracte vers 1/N (uniforme) tant que l'historique est petit, puis suit la vraie fréquence dès qu'il y a assez de tirages.
p̂(n) = (count(n) + α) / (totalDraws · k + α · N)
src/lib/engine-core.ts · src/lib/advanced-stats.ts
2-4. EMA pondéré en temps avec plusieurs demi-vies
Les tirages récents pèsent plus que les anciens — trois horizons en parallèle.
- Pour chaque tirage i depuis la fin nous attribuons le poids w_i = 0.5^(i / H). Nous exécutons trois EMA en parallèle avec H = 8, 26 et 78 tirages (court/moyen/long).
- Une demi-vie courte capture les 'hot streaks'. Une demi-vie longue évite de surréagir à un tirage isolé. Le blender d'ensemble choisit le poids de chaque horizon par loterie — réglé par grid-search.
EMA_H(n) = Σ_i 0.5^(i/H) · 1[n ∈ draw_i]
src/lib/engine-core.ts (HALF_LIVES = [8, 26, 78])
5. Boost de cooccurrence PMI
Quels numéros apparaissent ensemble plus souvent que le hasard ne le prédirait ?
- Nous calculons la Pointwise Mutual Information : PMI(a,b) = log [P(a,b) / (P(a)·P(b))]. PMI positif = la paire apparaît ensemble plus que sous indépendance.
- Par numéro candidat nous sommons le PMI avec tous les numéros du tirage le plus récent. Cela donne un signal 'suivre le motif' sans surajuster : PMI est borné et tronqué à ±3.
score_PMI(n) = Σ_{m ∈ lastDraw} clip(log[P(n,m) / (P(n)P(m))], ±3)
src/lib/engine-core.ts
6. Probabilités de transition de Markov
À partir du dernier tirage nous estimons la probabilité de transition vers le numéro suivant.
- Nous construisons une matrice de transition N×N T où T[a,b] = P(b dans draw_t+1 | a dans draw_t), estimée avec lissage de Laplace.
- Pour le score live nous prenons la moyenne de T[a, n] sur tous les a du dernier tirage. Les numéros froids ne le restent pas indéfiniment ; cette étape modélise une mémoire finie.
src/lib/engine-core.ts
7. Ensemble & poids réglés
Les six signaux sont fusionnés via une agrégation pondérée de rangs.
- Chaque signal est converti en percentiles de rang [0, 1]. Puis combiné linéairement avec les poids w = (w_bayes, w_ema1, w_ema2, w_ema3, w_pmi, w_markov). Uniforme par défaut ; réglé par loterie via grid-search + validation ROI.
- L'agrégation de rangs est robuste aux différences d'échelle entre signaux et empêche un score aberrant de dominer l'ensemble.
score(n) = Σ_s w_s · rank_s(n) / N
src/lib/engine-core.ts · src/lib/engine-tuning.functions.ts
8. Méta-apprenant (régression logistique, 12 features)
Une logreg par loterie apprend la combinaison non-linéaire optimale des signaux moteur.
- Vecteur de features (12 dim.) : les 6 rangs moteur + interactions (EMA1·PMI, Bayes·Markov, EMA3·Bayes) + récence + hot streak (apparitions dans les 10 derniers) + cold streak (absences consécutives).
- Entraînement : logreg régularisée L2 avec SGD sur tout l'historique. Perte = log-loss sur le label '1 si le numéro est apparu au tirage suivant'. Rétrocompatible : les anciens modèles 9-dim fonctionnent toujours.
P(n au prochain tirage) = σ(w · features(n) + b)
src/lib/meta-learner.ts
9. Gradient Boosted Decision Stumps
Second méta-apprenant qui capte les interactions non-linéaires sans réseau de neurones.
- Mini-clone de LightGBM : decision stumps itératifs sur les résidus. Chaque stump choisit 1 feature + seuil qui réduit maximalement la perte ; nous ajoutons lr · stump.output à la prédiction courante.
- La sortie est sérialisable en JSON et stockée à côté de la logreg dans engine_config.meta_weights.gbm. Le blender empilé combine les deux.
src/lib/gbm.ts
10. Blender stacking out-of-fold
Logreg + GBM sont combinés sans fuite de données.
- Nous découpons l'historique en 5 folds stratifiés. Par fold nous entraînons logreg + GBM sur 4 folds et prédisons sur le fold retenu. Ces prédictions OOF deviennent les entrées d'une deuxième couche méta-logreg qui apprend la pondération optimale.
- Résultat : probabilités calibrables sans que le méta-apprenant ne revoie ses propres données d'entraînement.
src/lib/advanced-stats-v3.ts · src/lib/nested-cv.ts
11. Calibration isotonique & Platt
Les probabilités brutes du modèle sont monotonisées pour être vraiment des probabilités.
- Platt scaling ajuste une sigmoïde à 1 paramètre sur les scores bruts en données de validation. La régression isotonique (Pool-Adjacent-Violators) est une version non-paramétrique imposant seulement la monotonie.
- Nous mesurons l'Expected Calibration Error (ECE) sur les prédictions out-of-fold ; le calibreur au plus faible ECE passe en production.
src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts
12. Générateur de tickets anti-clustering
Les tickets candidats sont échantillonnés, les mauvaises structures rejetées.
- Nous tirons les numéros proportionnellement au score d'ensemble (softmax avec température τ réglée par loterie). Chaque candidat est validé :
- • max 3 de la même décennie (anti-clustering),
- • somme dans l'IQR historique (pas de tickets uniquement bas ou hauts),
- • répartition de parité dans la distribution empirique,
- • pas de suite arithmétique de ≥4 nombres consécutifs.
- Les candidats rejetés sont rééchantillonnés jusqu'à avoir N tickets valides.
src/lib/engine-core.ts (generateAntiClusterTickets)
13. Sélection greedy submodulaire de portefeuille
Parmi des milliers de candidats nous choisissons K tickets qui couvrent ensemble le maximum.
- Problème : choisir K tickets maximisant la somme de P(numéro tiré) sur les tickets sélectionnés, avec rendements décroissants pour le chevauchement.
- Les fonctions submodulaires portent une garantie d'optimalité de 1 − 1/e ≈ 63 % pour la solution greedy. Par itération nous prenons le ticket au plus grand gain marginal et appliquons un facteur 0.4 aux numéros déjà couverts.
f(S ∪ {t}) − f(S) = Σ_{n ∈ t} remain[n] · (½ si bonus)
src/lib/portfolio-optimizer.ts
14. Portefeuille à variance minimale Markowitz
Au-delà de la couverture nous minimisons la corrélation mutuelle entre tickets.
- Corrélation entre tickets i et j ≈ |overlap| / √(|t_i|·|t_j|). Greedy : choisir à chaque étape le ticket avec le plus haut EV moins λ · Σ corr(courant, déjà choisis).
- L'aversion au risque λ est un paramètre réglable (défaut 1.2). Plus λ est élevé = plus de diversification, score attendu par ticket plus bas mais variance de paiement total du portefeuille plus basse.
util(t) = EV(t) − λ · Σ_{j ∈ picked} overlap(t, j)
src/lib/markowitz.ts
15. Correction de popularité jackpot partagé
Un gain sur une combinaison 'populaire' est partagé avec plus de gagnants.
- popularityScore() compte : % numéros ≤ 31 (anniversaires), % dans la moitié basse, suites consécutives ≥3, progressions arithmétiques, même chiffre final, croix/diagonales sur la grille.
- Sur cette base nous estimons le nombre de co-gagnants et appliquons adjustJackpotForSharing() : l'EV à l'étape gating utilise le paiement attendu après partage, pas le jackpot brut.
src/lib/popularity.ts
16. EV gating conscient du jackpot
Conseiller 'jouer' seulement si la valeur attendue est positive.
- EV = Σ_tier P(tier) · payout(tier) − ticketCost. P(tier) est exact à partir des cotes combinatoires (coefficients binomiaux selon la formule de la loterie). Payout(tier) vient de PRIZE_TIERS — pour la classe jackpot remplacée par le jackpot courant (après partage de popularité).
- Nous calculons aussi le break-even jackpot : le montant où EV = 0. En dessous, l'UI affiche '⏸ passer'.
- Le critère de Kelly détermine une mise optionnelle pour les abonnés planifiant plusieurs semaines.
EV = Σ_t P(t) · payout(t) − cost | break-even = (cost − Σ_{t≠jp} P(t)·payout(t)) / P(jp)
src/lib/ev-gating.ts
17. Détection de régime (CUSUM + HMM 2 états + filtre particulaire)
Détecter si le générateur de tirages lui-même a dérivé.
- CUSUM suit par numéro une déviation cumulée par rapport à la fréquence attendue et alerte au franchissement du seuil h.
- Un HMM 2 états (hot/cold) est entraîné par Baum-Welch sur la série temporelle de fréquence ; les transitions sont décodées par Viterbi.
- Un filtre particulaire Sequential Monte Carlo maintient 200 particules sur l'état de régime caché et donne une probabilité douce par tirage.
- Lors d'un changement de régime, l'EMA courte reçoit temporairement plus de poids (adaptation en ligne).
src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts
18. Extensions statistiques niveau 3
Conformal prediction, modèle de gap Binomial Négatif, copules, Shapley, et plus.
- • Split-conformal prediction → bande sur les méta-probs avec couverture garantie.
- • A posteriori Dirichlet-Multinomial sur le tirage complet (pas seulement par numéro).
- • Modèle de gap Binomial Négatif pour la surdispersion entre apparitions.
- • Copule gaussienne pour les dépendances de paires manquées par PMI.
- • Test de permutation par signal (label-shuffle) → p-valeur pour 'mieux que l'aléatoire'.
- • Attribution SHAP par ticket (approximation linéaire) → explique pourquoi ce ticket a été choisi.
- • CVaR / Expected Shortfall sur les paiements de portefeuille.
- • Goodness-of-fit Anderson-Darling sur l'uniformité.
src/lib/advanced-stats-v2.ts · src/lib/advanced-stats-v3.ts
19. Auto-tuner : nested CV + grid-search
Un pg_cron hebdomadaire révise les poids du moteur et les méta-modèles par loterie.
- CV stratifiée 5-fold externe → estimation de ROI hors échantillon. CV interne → sélection de preset.
- Grid-search sur simplex de poids 6-dim (pondéré BMA) + presets de demi-vies (HALF_LIFE_GRID). Pour chaque config : simuler K tickets par fold, scorer avec les paliers de gains, agréger le ROI avec IC bootstrap 95 %.
- Un nouveau preset n'est accepté que si CI-low > ROI baseline (pas un coup de chance).
- Les résultats vont dans engine_config (DB) et sont immédiatement actifs pour tous les abonnés.
src/lib/engine-tuning.functions.ts · src/routes/api/public/hooks/auto-tune.ts
20. Bandit Thompson-sampling (sélection de preset en ligne)
Entre les auto-tunes, un bandit bascule en direct entre presets selon le ROI courant.
- Par preset nous maintenons un a posteriori Beta(α, β) : α = gains (ROI > 0), β = pertes. À chaque pick de production nous échantillonnons depuis chaque Beta et choisissons le plus grand.
- Les mises à jour viennent du tracker : dès qu'un tirage est terminé, les presets choisis reçoivent +1 sur α ou β.
- Résultat : même sans re-tuning complet le système converge en ligne vers le meilleur preset.
pick = argmax_p Beta(α_p, β_p).sample()
src/lib/bandit.ts
21. Backtest walk-forward
Chaque stratégie est testée sans connaissance future (pas de fuite).
- À partir de MIN_HISTORY nous itérons tirage par tirage. Par tirage nous construisons le modèle UNIQUEMENT à partir des tirages antérieurs, générons N tickets et scorons contre le vrai tirage.
- Nous agrégeons les hits par palier, le ROI moyen, le P&L cumulé et une baseline aléatoire de contrôle. Une stratégie ne 'gagne' que si son IC est au-dessus de l'aléatoire.
src/lib/backtest.functions.ts
22. Systèmes de wheeling (covering designs)
Garantie mathématique : avec M numéros corrects dans le pool, toujours un gain Y-sur-X.
- Nous implémentons les full wheels, key wheels et covering designs abrégés. Pour chaque (taille de pool, taille de ticket, garantie) nous prenons l'ensemble combinatoirement optimal.
- Le générateur de wheels se combine avec l'optimiseur de portefeuille : les candidats sont d'abord wheelés, puis sélectionnés submodulairement.
src/lib/wheel.functions.ts
Honnêtement
Les loteries sont et restent des jeux de hasard. Aucune analyse ne peut prédire un tirage. Ce que LotteryCortex fait : vous aider à prendre de meilleures décisions sur les combinaisons à jouer, quand miser plus et quand sauter une semaine.
Les tirages de loterie sont conçus pour être aléatoires. Aucun algorithme — ici ou ailleurs — ne peut prédire le résultat. Ce que nous faisons de mesurable : choisir de meilleures répartitions de numéros, éviter les combinaisons populaires (pour partager moins en cas de gain) et conseiller honnêtement de passer quand la valeur attendue est négative. L'auto-tuner valide chaque semaine que notre courbe de ROI est significativement au-dessus de l'aléatoire — si ce n'était plus le cas, vous le lirez ici en premier.
Pourquoi LotteryCortex ?
La plupart des outils de loterie ont plus de 10 ans, sont uniquement en anglais et conçus pour desktop. LotteryCortex est moderne, mobile-first et axé sur l'UE — avec un moteur d'IA qui continue d'apprendre des nouveaux tirages.