An Augmented Rating System for Test cricket: adapting Glicko's model
Paper • 2603.02574 • Published
YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
A complete League of Legends esports match prediction system integrated with Polymarket for edge detection. Built on Oracle's Elixir match data (2014–2026) with a dual ELO rating system and XGBoost probability model.
┌────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ Oracle's Elixir CSV (165 columns, 1.1M+ rows) │
│ Google Drive auto-sync (daily updates) │
└──────────────┬─────────────────────────────────────────────┘
│
┌──────────────▼─────────────────────────────────────────────┐
│ FEATURE ENGINEERING │
│ • Rolling team stats (15-game window, exp. weighted) │
│ • Gold/XP/CS diffs at 10, 15, 20, 25 min │
│ • Objective control (dragons, barons, towers, heralds) │
│ • Vision metrics (wards, vision score) │
│ • Win/loss streaks │
│ Total: 115 pre-game features per matchup │
└──────────────┬─────────────────────────────────────────────┘
│
┌──────────────▼─────────────────────────────────────────────┐
│ DUAL ELO RATING SYSTEM │
│ Regional Rating: Updated from domestic league games │
│ Meta Rating: Updated from international events only │
│ μ_total = μ_regional + μ_meta │
│ → Solves cross-region comparison (LCK vs LPL vs LEC) │
│ • Margin of victory scaling (gold diff / game length) │
│ • Time-based σ inflation (off-season uncertainty) │
│ • Roster change detection → σ increase │
└──────────────┬─────────────────────────────────────────────┘
│
┌──────────────▼─────────────────────────────────────────────┐
│ PREDICTION MODEL │
│ XGBoost + Isotonic Regression Calibration │
│ • 63% accuracy, 0.67 AUC-ROC, 0.225 Brier Score │
│ • Time-series cross-validation (no data leakage) │
│ • Bo3/Bo5 series probability extension │
│ • Ensemble: 70% model + 30% ELO │
└──────────────┬─────────────────────────────────────────────┘
│
┌──────────────▼─────────────────────────────────────────────┐
│ POLYMARKET INTEGRATION │
│ Gamma API → Market discovery (tag_slug: esports) │
│ CLOB API → Live bid/ask/mid prices │
│ Edge = Model_prob - Market_mid │
│ Kelly criterion for position sizing │
│ 248+ active LoL markets detected │
└────────────────────────────────────────────────────────────┘
| Metric | Value |
|---|---|
| Accuracy | 63.0% |
| AUC-ROC | 0.672 |
| Brier Score | 0.224 (calibrated) |
| Log Loss | 0.639 (calibrated) |
| League | Accuracy | Brier Score | Games |
|---|---|---|---|
| LCK | 65.8% | 0.227 | 1,853 |
| LCP | 63.8% | 0.227 | 376 |
| LTA N | 67.6% | 0.225 | 213 |
| MSI | 62.4% | 0.234 | 234 |
| LEC | 61.8% | 0.257 | 1,077 |
| LPL | 59.9% | 0.250 | 2,796 |
| Worlds | 59.2% | 0.251 | 520 |
| Overall | 61.5% | 0.245 | 8,085 |
elo_diff — ELO rating difference (4.7%)diff_opp_towers_mean — Opponent tower diff (3.7%)diff_earned_gpm_mean — Gold per minute diff (2.2%)diff_towers_mean — Tower control diff (1.9%)diff_result_mean — Win rate diff (1.7%)| Rank | League | Strength | Method |
|---|---|---|---|
| 1 | LCK | 2.621 | MSI/Worlds results |
| 2 | LPL | 1.827 | MSI/Worlds results |
| 3 | LEC | 0.960 | MSI/Worlds results |
| 4 | LTA | 0.850 | Prior (limited intl) |
| 5 | CBLOL | 0.319 | MSI/Worlds results |
| 6 | LCP | 0.283 | MSI/Worlds results |
How it works: League strengths start from priors based on historical international performance. They are then updated via a Bayesian ELO-style system every time teams from different leagues meet at MSI, Worlds, FST, or EWC. The system uses K=0.02 for conservative updates.
| Rank | Team | League | μ | Games |
|---|---|---|---|---|
| 1 | Gen.G | LCK | 70.4 | 906 |
| 2 | T1 | LCK | 64.4 | 910 |
| 3 | Bilibili Gaming | LPL | 55.5 | 899 |
| 4 | Dplus Kia | LCK | 52.5 | 903 |
| 5 | Top Esports | LPL | 52.4 | 896 |
| 6 | JD Gaming | LPL | 50.8 | 845 |
| 7 | G2 Esports | LEC | 49.4 | 698 |
# Install dependencies
pip install -r requirements.txt
# Download data from Google Drive
python -c "
import gdown
gdown.download_folder('https://drive.google.com/drive/folders/1gLSw0RLjBbtaNy0dgnGQDAZOHIgCe-HH',
output='data/raw', quiet=False)
"
# Train the model (uses 2022-2026 data)
python -m lol_predictor.main train --backtest
# Predict a specific match
python -m lol_predictor.main predict --team-a "T1" --team-b "Gen.G" --league LCK --format bo5
# Compare against market odds
python -m lol_predictor.main edge --team-a "T1" --team-b "Gen.G" --market-odds 0.40 --format bo5
# Scan Polymarket for live LoL markets
python -m lol_predictor.main scan
# Show team ratings
python -m lol_predictor.main ratings --top 30
# Run full scheduler (daily retrain + 5-min scanning)
python -m lol_predictor.main run
The system uses a dual rating architecture (inspired by PandaSkill):
μ_total = μ_regional + μ_meta
σ_total = sqrt(σ_regional² + σ_meta²)
P(A wins) = Φ((μ_A - μ_B) / sqrt(σ_A² + σ_B²))
1. Download latest CSVs from Google Drive (updated daily)
2. Rebuild ELO ratings from scratch (warm-up: 2019-2021, train: 2022-2026)
3. Recompute all rolling features
4. Retrain XGBoost with early stopping
5. Calibrate with isotonic regression
6. Save model artifacts
1. Query Polymarket Gamma API for active LoL esports events
2. Parse market questions to extract team names + match format
3. Fetch live CLOB prices (mid, bid, ask, spread)
4. Generate model predictions for each detected matchup
5. Compute edges: model_prob - market_mid
6. Flag edges > 5% with Kelly criterion sizing
7. Log results to data/processed/scan_logs/
lol_predictor/
├── __init__.py
├── config.py # All configuration (leagues, params, API URLs)
├── main.py # CLI entry point
├── train.py # Training pipeline orchestrator
├── predict.py # Match prediction + market edge analysis
├── data/
│ └── loader.py # CSV loading, cleaning, game pairing
├── features/
│ ├── engineering.py # Rolling stats, H2H, league strength
│ └── elo_system.py # Dual ELO (regional + meta) rating system
├── model/
│ └── predictor.py # XGBoost model + calibration + backtesting
├── polymarket/
│ └── scanner.py # Gamma API + CLOB price fetcher + edge detection
└── scheduler/
└── runner.py # Cron-like scheduler for retrain + scan
MIT