SlickBet ⚽: Soccer Betting Screener by SlickML🧞
🧠 Philosophy
SlickBet ⚽ screens soccer matches via the Livescore API, scores each fixture with a 12-factor statistical model (form, venue, xG, odds, and more), and ranks betting opportunities — including safer double-chance picks.
Same SlickML spirit: prototype fast 🏎, keep axes clear, and measure with backtests 🔎.
fixtures × model × filters × backtest × export
✨ Features
- 📅 Multi-day screening — next N days of fixtures
- 📊 12-factor model — form, position, home, H2H, odds, goals, venue form, defense, momentum, match stats, xG, reliability
- 🎲 Double chance — 1X / X2 / 12 with confidence grades
- 🌍 League coverage — major & minor Europe, Asia, Americas
- 📈 Backtesting — historical accuracy + API response cache
- 🔧 Hyperparameter tuning — search weights on cached data
- 📄 PDF / JSON export — shareable reports and CLI scripting
🛠 Installation
Install Python >=3.10,<3.14 and uv, then:
git clone https://github.com/slickml/slick-bet.git
cd slick-bet
uv sync --locked --all-extras --all-groups
Task runner is Poe the Poet (same idea as slick-tune). Install once:
uv tool install poethepoet
poe greet
⚙️ Configuration
Set Livescore API credentials:
export LIVESCORE_API_KEY="your_api_key"
export LIVESCORE_API_SECRET="your_api_secret"
📌 Quick Start
# Screen all leagues for tomorrow (top 20)
poe run-all --days=1 --top=20
# Major European leagues only
poe run-major
# Backtest all leagues for 1 week
poe backtest-all-global --weeks=1
from slickbet import BettingScreener, ScreenerConfig
config = ScreenerConfig(min_probability=0.60, all_leagues=True)
screener = BettingScreener(config=config)
result = screener.screen_days(3)
for bet in result.get_top_k(10):
best_dc, prob = bet.double_chance.best_double_chance
print(f"{bet.match.home_team.name} vs {bet.match.away_team.name}: {best_dc} @ {prob:.1%}")
📋 Commands
Screener
| Command | Description |
|---|---|
poe run-all --days N |
Screen ALL leagues for next N days |
poe run-all-week |
Screen ALL leagues for next 7 days |
poe run-major |
Major European leagues (tomorrow) |
poe run-major-week |
Major European leagues for 7 days |
poe run-pl --days N |
Premier League only |
poe run-bundesliga --days N |
Bundesliga only |
poe run-laliga --days N |
La Liga only |
poe run-seriea --days N |
Serie A only |
poe run-ligue1 --days N |
Ligue 1 only |
poe run |
Screen tomorrow's games |
poe run-top --top K |
Show top K opportunities |
poe run-days --days N |
Screen next N days |
Backtest & tune
| Command | Description |
|---|---|
poe backtest-all --weeks N |
Major + minor European leagues |
poe backtest-all-global --weeks N |
All leagues (EU + Asia + Americas) |
poe backtest-pl --weeks N |
Premier League backtest |
poe tune --cache-dir DIR |
Tune weights on cached API data |
API cache (fast reruns / offline tune):
# Populate cache
slickbet backtest-all --weeks 12 --cache-dir data/api_cache
# Offline rerun
slickbet backtest-all --weeks 12 --cache-dir data/api_cache --cache-only
# Tune weights
slickbet tune --cache-dir data/api_cache --trials 20
Development
| Command | Description |
|---|---|
poe check |
Format check + ruff + mypy |
poe test |
Pytest with 100% coverage gate |
poe build |
Build sdist + wheel |
poe fix |
Auto-fix lint + format |
poe clean |
Remove caches and build artifacts |
💻 CLI
slickbet # tomorrow
slickbet --days 5 --top 10
slickbet --major-only
slickbet --asia-only
slickbet --americas-only
slickbet --all-leagues
slickbet --league 2 # competition ID
slickbet --min-prob 0.60
slickbet --json
slickbet --pdf my_report.pdf
slickbet backtest --competition 2 --weeks 4
slickbet backtest-all --include-asia --include-americas --weeks 4
slickbet competitions --country England
slickbet tune --cache-dir data/api_cache
🏆 League IDs
Major Europe
| ID | League | Country |
|---|---|---|
| 1 | Bundesliga | Germany |
| 2 | Premier League | England |
| 3 | La Liga | Spain |
| 4 | Serie A | Italy |
| 5 | Ligue 1 | France |
Minor Europe
| ID | League | Country |
|---|---|---|
| 68 | Belgian Pro League | Belgium |
| 8 | Primeira Liga | Portugal |
| 6 | Super Lig | Turkey |
| 196 | Eredivisie | Netherlands |
| 17 | 1. HNL | Croatia |
| 60 | Ekstraklasa | Poland |
| 75 | Premiership | Scotland |
| 9 | Super League | Greece |
Asia
| ID | League | Country |
|---|---|---|
| 313 | Saudi Pro League | Saudi Arabia |
| 67 | Hyundai A-League | Australia |
| 28 | J. League | Japan |
Americas
| ID | League | Country |
|---|---|---|
| 23 | Liga Professional | Argentina |
| 24 | Serie A | Brazil |
| 45 | Liga MX | Mexico |
Use slickbet competitions --country <name> to discover more IDs.
🧠 Model
flowchart TB
match[Match + stats / odds / form]
subgraph factors [12 weighted factors]
direction LR
venue["venue_form 20.6%"]
momentum["momentum 12.0%"]
defense["defense 10.4%"]
home["home 9.5%"]
reliability["reliability 8.7%"]
goals["goals 8.6%"]
matchStats["match_stats 7.1%"]
h2h["h2h 6.1%"]
odds["odds 5.5%"]
position["position 4.7%"]
xg["xg 3.7%"]
form["form 3.3%"]
end
composite[Weighted composite score]
probs[Home / away win probabilities]
drawRisk[Draw risk]
pred[BetPrediction]
dc["Double chance: 1X · X2 · 12"]
grade[Confidence grade]
match --> factors
factors --> composite
composite --> probs
composite --> drawRisk
probs --> pred
drawRisk --> pred
pred --> dc
pred --> grade
Tuned 12-factor weights (BettingModel.WEIGHTS in src/slickbet/model.py):
| Factor | Weight | Description |
|---|---|---|
| Venue form | 20.6% | Home/away specific win rates |
| Momentum | 12.0% | First-half lead + win rate + comebacks |
| Defense | 10.4% | Clean sheet rate |
| Home advantage | 9.5% | Historical home edge |
| Reliability | 8.7% | Discipline / cards |
| Goals | 8.6% | Attack/defense strength |
| Match stats | 7.1% | Possession, shots, conversion |
| H2H | 6.1% | Head-to-head |
| Odds | 5.5% | Bookmaker implied probability |
| Position | 4.7% | Table differential |
| xG | 3.7% | Expected goals differential |
| Form | 3.3% | Last 5 results |
Double chance & grades
- 1X — home or draw · X2 — away or draw · 12 — no draw
- 🔥 HIGH VALUE · ✅ GOOD BET · 👍 DECENT · ⚠️ RISKY
Backtest snippet (Python)
from slickbet import Backtester, format_backtest_report
results = Backtester().run(competition_id="313", weeks=4)
print(format_backtest_report(results))
print(f"Excl. draws: {results.accuracy_excluding_draws:.1%}")
print(f"Best DC: {results.best_double_chance_accuracy:.1%}")
📁 Project structure
slick-bet/
├── assets/
│ └── logo.png
├── src/slickbet/
│ ├── __init__.py
│ ├── api.py # Livescore client + domain models
│ ├── model.py # 12-factor betting model
│ ├── screener.py # Screening + formatting
│ ├── backtest.py # Historical evaluation
│ ├── cache.py # File-based API cache
│ ├── tune.py # Weight search
│ ├── cli.py # `slickbet` entrypoint
│ └── pdf_export.py # ReportLab PDFs
├── tests/
├── .github/workflows/ # ci.yml + cd.yml only
├── .coveragerc
├── ruff.toml
├── mypy.ini
├── pytest.ini
├── pyproject.toml
└── README.md
⚠️ Disclaimer
For educational and entertainment purposes only.
- Past performance does not guarantee future results
- Sports betting involves risk of financial loss
- Predict responsibly and within your means
- Check local laws in your jurisdiction
❓ Need help?
Join our Slack to talk with the SlickML team.
License
MIT — see LICENSE.
Metadata
Release files for slickbet 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| slickbet-0.3.0.tar.gz | 178.6 kB | Without provenance | Details for slickbet-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| slickbet-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for slickbet-0.3.0-py3-none-any.whl |
Total release size: 246.7 kB
Release files / slickbet-0.3.0.tar.gz
| Download URL | slickbet-0.3.0.tar.gz |
|---|---|
| Size | 178.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1c99b433699d075e8833af3c03ae84052e025d07663e0f106ab05d9208e69225
|
|
BLAKE2b-256 checksum How to use checksums |
7c551aa0e70f721a4ff4a6a4b9b88b6e7fb0648a46e964e8eefcbe6d7d2f6f2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / slickbet-0.3.0-py3-none-any.whl
| Download URL | slickbet-0.3.0-py3-none-any.whl |
|---|---|
| Size | 68.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3dbd1354f02ddde4d3a4fb81356c4fecd08674954ac4db99767ace4ccecb2076
|
|
BLAKE2b-256 checksum How to use checksums |
23c6b750ea2be171096aea54001e660e54e2e0ccbe17f075962611c18a56a754
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for slickbet 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.