slickbet¶
SlickBet - Soccer Betting Screener.
Public package API for screening upcoming soccer matches, ranking betting opportunities, and backtesting the prediction model against historical data.
Examples
>>> from slickbet import BettingScreener
>>> screener = BettingScreener()
>>> result = screener.screen_tomorrow()
>>> for bet in result.get_top_k(5):
... print(f"Bet on {bet.match.home_team.name}: {bet.probability:.1%}")
Submodules¶
Attributes¶
Exceptions¶
Custom exception for Livescore API errors. |
Classes¶
Aggregated results from a backtest run. |
|
Backtester for evaluating betting model against historical data. |
|
Possible betting outcomes. |
|
Represents a betting prediction for a match. |
|
Model for calculating betting probabilities based on match statistics. |
|
Main screener class for finding betting opportunities. |
|
A completed historical match with scores and outcomes. |
|
Client for interacting with the Livescore API. |
|
Represents a soccer match. |
|
Match outcomes (betting results) at different periods. |
|
Match scores at different periods. |
|
Match statistics from the API. |
|
Represents betting odds for a match. |
|
Result of a single prediction compared to actual outcome. |
|
Configuration for the betting screener. |
|
Result of running the betting screener. |
|
Represents a soccer team. |
|
Detailed team performance statistics from recent matches. |
Functions¶
|
Generate a formatted report of backtest results. |
|
Format a prediction for display. |
|
Format a summary of screener results. |
Package Contents¶
- class slickbet.BacktestResults[source]¶
Aggregated results from a backtest run.
- property away_predictions: list[PredictionResult]¶
Predictions where we bet on away team.
- property best_double_chance_accuracy: float¶
Accuracy when following the recommended double chance bet.
- by_probability_threshold(threshold: float) BacktestResults[source]¶
Filter results by minimum probability threshold.
- Parameters:
threshold (float) – Minimum prediction probability (inclusive).
- Returns:
BacktestResults – New results object with filtered predictions.
- from_date: datetime.datetime | None = None¶
- property high_confidence_accuracy_excl_draws: float¶
Accuracy for high confidence predictions, excluding draws.
- property high_confidence_results: list[PredictionResult]¶
Predictions with confidence > 0.3.
- property high_probability_accuracy_excl_draws: float¶
Accuracy for high probability predictions (>60%), excluding draws.
- property high_probability_results: list[PredictionResult]¶
Predictions with probability > 60%.
- property home_predictions: list[PredictionResult]¶
Predictions where we bet on home team.
- property low_draw_risk_results: list[PredictionResult]¶
Predictions where draw risk < 30%.
- results: list[PredictionResult] = []¶
- to_date: datetime.datetime | None = None¶
- class slickbet.Backtester(client: slickbet.api.LivescoreClient | None = None, model: slickbet.model.BettingModel | None = None, cache_dir: str | pathlib.Path | None = None, cache_only: bool = False)[source]¶
Backtester for evaluating betting model against historical data.
Examples
>>> backtester = Backtester() >>> results = backtester.run( ... competition_id="1", # Premier League ... weeks=4, ... ) >>> print(f"Accuracy: {results.accuracy:.1%}")
- BUNDESLIGA = '1'¶
- LA_LIGA = '3'¶
- LIGUE_1 = '5'¶
- PREMIER_LEAGUE = '2'¶
- SERIE_A = '4'¶
- model¶
- run(competition_id: str = '1', weeks: int = 4, from_date: datetime.datetime | None = None, to_date: datetime.datetime | None = None, min_probability: float = 0.0, verbose: bool = True, debug: bool = False) BacktestResults[source]¶
Run backtest on historical data.
- Parameters:
competition_id (str, optional) – Competition ID to backtest
weeks (int, optional) – Number of weeks of history (if from_date not specified)
from_date (datetime or None, optional) – Start date for historical data
to_date (datetime or None, optional) – End date for historical data (defaults to today)
min_probability (float, optional) – Minimum probability threshold for predictions
verbose (bool, optional) – Print progress information
debug (bool, optional) – Print detailed match-by-match predictions and results
- Returns:
BacktestResults – BacktestResults with all predictions and accuracy metrics
- class slickbet.BetOutcome[source]¶
Bases:
enum.EnumPossible betting outcomes.
- AWAY_OR_DRAW = 'away_or_draw'¶
- AWAY_WIN = 'away_win'¶
- DRAW = 'draw'¶
- HOME_OR_AWAY = 'home_or_away'¶
- HOME_OR_DRAW = 'home_or_draw'¶
- HOME_WIN = 'home_win'¶
- class slickbet.BetPrediction[source]¶
Represents a betting prediction for a match.
- double_chance: DoubleChancePrediction | None = None¶
- property expected_value: float¶
Calculate expected value assuming fair 2.0 odds.
EV = (probability * potential_win) - (1 - probability) * stake
- Returns:
float – Expected value per unit stake at even money.
- match: slickbet.api.Match¶
- property match_stats_used: bool¶
Check if match statistics were used in this prediction.
- Returns:
bool – True if match statistics contributed to the prediction
- recommended_outcome: BetOutcome¶
- class slickbet.BettingModel(form_weight: float | None = None, position_weight: float | None = None, home_weight: float | None = None, h2h_weight: float | None = None, odds_weight: float | None = None, goals_weight: float | None = None, venue_form_weight: float | None = None, defense_weight: float | None = None, momentum_weight: float | None = None, match_stats_weight: float | None = None, xg_weight: float | None = None, reliability_weight: float | None = None, min_confidence: float = 0.55)[source]¶
Model for calculating betting probabilities based on match statistics.
The model uses a weighted scoring system combining multiple factors.
ENHANCED VERSION with 12 factors: - Core: Form, Position, Home Advantage, H2H, Odds - Goals: Attack/defense strength, Venue Form, Defense (clean sheets) - Momentum: First-half performance and consistency - Match Stats: Historical averages (possession, attacks, shots on target) - xG: Expected Goals differential (quality of chances created) - Reliability: Team discipline based on card counts (fewer cards = more reliable)
Weights optimized based on 120-day backtest across 5 major leagues (704 matches): - Bundesliga: 81.3% accuracy (excl. draws) - Premier League: 78.2% accuracy (excl. draws) - Serie A: 74.8% accuracy (excl. draws) - Ligue 1: 70.9% accuracy (excl. draws) - La Liga: 68.9% accuracy (excl. draws)
- DRAW_RISK_THRESHOLD = 0.15¶
- HOME_ADVANTAGE = 0.12¶
- MIN_CONFIDENCE = 0.55¶
- WEIGHTS¶
- filter_confident_predictions(predictions: list[BetPrediction], min_confidence: float | None = None) list[BetPrediction][source]¶
Filter predictions by minimum confidence threshold.
- Parameters:
predictions (list[BetPrediction]) – List of predictions to filter
min_confidence (float or None, optional) – Minimum confidence (defaults to model’s threshold)
- Returns:
list[BetPrediction] – Filtered list of predictions
- min_confidence = 0.55¶
- predict(match: slickbet.api.Match) BetPrediction[source]¶
Generate a betting prediction for a match.
- Parameters:
match (Match) – Match object with statistics
- Returns:
BetPrediction – BetPrediction with probabilities and recommendation
- weights¶
- class slickbet.BettingScreener(config: ScreenerConfig | None = None, api_client: slickbet.api.LivescoreClient | None = None, model: slickbet.model.BettingModel | None = None)[source]¶
Main screener class for finding betting opportunities.
Examples
>>> screener = BettingScreener() >>> result = screener.screen_tomorrow() >>> for bet in result.get_top_k(10): ... print(bet)
- client¶
- config¶
- model¶
- screen_date(date: datetime.datetime) ScreenerResult[source]¶
Screen matches for a specific date.
- Parameters:
date (datetime) – The date to screen
- Returns:
ScreenerResult – ScreenerResult with ranked predictions
- screen_days(days: int = 7) ScreenerResult[source]¶
Screen matches for the next N calendar days (not 24-hour windows).
Uses calendar-day logic so results are invariant of run time; each day includes all games that kick off that day in Central time.
- Parameters:
days (int, optional) – Number of calendar days to screen (default: 7)
- Returns:
ScreenerResult – ScreenerResult with ranked predictions from all days
- screen_tomorrow() ScreenerResult[source]¶
Screen tomorrow’s matches (next calendar day, all fixtures that day).
Uses calendar-day logic so results are invariant of run time: e.g. running at 8am or 11pm both get the same “tomorrow” fixtures.
- Returns:
ScreenerResult – Ranked predictions for tomorrow’s fixtures.
- class slickbet.HistoricalMatch[source]¶
A completed historical match with scores and outcomes.
Per https://live-score-api.com/documentation/reference/15/football_data_history_matches
- date: datetime.datetime¶
- outcomes: MatchOutcome¶
- scores: MatchScores¶
- exception slickbet.LivescoreAPIError[source]¶
Bases:
ExceptionCustom exception for Livescore API errors.
- class slickbet.LivescoreClient(api_key: str | None = None, api_secret: str | None = None, cache_dir: str | pathlib.Path | None = None, cache_only: bool = False)[source]¶
Client for interacting with the Livescore API.
Uses LIVESCORE_API_KEY and LIVESCORE_API_SECRET environment variables.
- BASE_URL = 'https://livescore-api.com/api-client'¶
- CUP_TO_LEAGUE_MAPPING¶
- api_key¶
- api_secret¶
- cache: slickbet.cache.ApiCache | None¶
- cache_only¶
- enrich_match_with_stats(match: Match) Match[source]¶
Enrich a match object with additional statistics.
- Parameters:
match (Match) – The match to enrich
- Returns:
Match – Match with additional stats (form, standings, H2H, performance)
- get_competitions(country_id: str | None = None) list[dict[str, Any]][source]¶
Get list of available competitions.
- Parameters:
country_id (str or None, optional) – Optional country ID to filter competitions
- Returns:
list[dict[str, Any]] – List of competition dictionaries with id, name, country
- get_countries() list[dict[str, Any]][source]¶
Get list of available countries.
- Returns:
list[dict[str, Any]] – List of country dictionaries with id and name
- get_fixtures_by_date(date: datetime.datetime, competition_id: str | None = None, fetch_all_pages: bool = True) list[Match][source]¶
Get all fixtures for a specific date.
- Parameters:
date (datetime) – The date to fetch fixtures for
competition_id (str or None, optional) – Optional competition ID to filter by
fetch_all_pages (bool, optional) – Whether to fetch all pages (default: True)
- Returns:
list[Match] – List of Match objects
- get_fixtures_list(date: datetime.datetime | None = None, competition_ids: list[str] | None = None, country_id: str | None = None, fetch_all_pages: bool = True) list[Match][source]¶
Get fixtures using the list endpoint with competition_id and country_id filtering.
This endpoint is more efficient for filtering by competition/country as it provides these fields directly, avoiding the need for name-based heuristics.
- Parameters:
date (datetime or None, optional) – The date to fetch fixtures for (defaults to tomorrow)
competition_ids (list[str] or None, optional) – List of competition IDs to filter by
country_id (str or None, optional) – Country ID to filter by
fetch_all_pages (bool, optional) – Whether to fetch all pages (default: True)
- Returns:
list[Match] – List of Match objects
- get_head_to_head(home_team_id: str, away_team_id: str, limit: int = 5) dict[source]¶
Get head-to-head statistics between two teams.
- Parameters:
home_team_id (str) – Home team ID
away_team_id (str) – Away team ID
limit (int, optional) – Number of recent H2H matches to consider
- Returns:
dict – Dictionary with H2H statistics
- get_history(competition_id: str | None = None, team_id: str | None = None, from_date: datetime.datetime | None = None, to_date: datetime.datetime | None = None, page: int = 1) list[HistoricalMatch][source]¶
Get historical match data.
Per https://live-score-api.com/documentation/reference/15/football_data_history_matches
- Parameters:
competition_id (str or None, optional) – Filter by competition (comma-separated for multiple)
team_id (str or None, optional) – Filter by team (comma-separated for multiple)
from_date (datetime or None, optional) – Get matches from this date onwards
to_date (datetime or None, optional) – Get matches until this date
page (int, optional) – Page number for pagination
- Returns:
list[HistoricalMatch] – List of HistoricalMatch objects
- get_match_statistics(match_id: str) MatchStatistics[source]¶
Get statistics for a live or completed match.
Per https://live-score-api.com/documentation/reference/23/match-statistics Statistics are only available after the match has started.
- Parameters:
match_id (str) – The match ID
- Returns:
MatchStatistics – MatchStatistics object with available stats
- get_team_form(team_id: str, limit: int = 5) str[source]¶
Get recent form for a team (last N matches).
- Parameters:
team_id (str) – The team ID
limit (int, optional) – Number of recent matches to consider
- Returns:
str – Form string like “WWDLW” (W=win, D=draw, L=loss)
- get_team_history(team_id: str, limit: int = 10) list[HistoricalMatch][source]¶
Get recent match history for a specific team.
- Parameters:
team_id (str) – The team ID
limit (int, optional) – Maximum number of matches to return
- Returns:
list[HistoricalMatch] – List of HistoricalMatch objects (most recent first)
- get_team_performance_stats(team_id: str, num_matches: int = 10, verbose: bool = False) TeamPerformanceStats[source]¶
Calculate detailed performance statistics for a team from recent matches.
This provides goal-based metrics that improve prediction accuracy: - Goals scored/conceded per game (attack/defense strength) - Clean sheet rate (defensive solidity) - Home/Away specific win rates - Points per game - Match statistics averages (possession, corners, attacks, shots on target)
- Parameters:
team_id (str) – The team ID
num_matches (int, optional) – Number of recent matches to analyze
verbose (bool, optional) – Print debug info about match-statistics availability
- Returns:
TeamPerformanceStats – TeamPerformanceStats with calculated metrics
- get_team_standings(competition_id: str) dict[str, int][source]¶
Get team standings/positions for a competition.
- Parameters:
competition_id (str) – The competition/league ID
- Returns:
dict[str, int] – Dictionary mapping team ID to position
- get_tomorrow_fixtures() list[Match][source]¶
Get all fixtures scheduled for tomorrow.
- Returns:
list[Match] – List of Match objects for tomorrow’s games
- session¶
- class slickbet.Match[source]¶
Represents a soccer match.
- away_performance: TeamPerformanceStats | None = None¶
- home_performance: TeamPerformanceStats | None = None¶
- kickoff_time: datetime.datetime¶
- statistics: MatchStatistics | None = None¶
- class slickbet.MatchOutcome[source]¶
Match outcomes (betting results) at different periods.
Values are “1” (home win), “X” (draw), or “2” (away win).
- class slickbet.MatchScores[source]¶
Match scores at different periods.
- class slickbet.MatchStatistics[source]¶
Match statistics from the API.
Per https://live-score-api.com/documentation/reference/23/match-statistics Statistics are only available for live/completed matches, not fixtures. Values are “home:away” format (e.g., “48:52” for possession).
- static calculate_xg_estimate(shots_on_target: int, shots_off_target: int, dangerous_attacks: int, attacks: int, possession: float | None = None) float[source]¶
Calculate estimated xG (Expected Goals) using a model-based approach.
Based on Expected Goals principles from: https://en.wikipedia.org/wiki/Expected_goals
The model assigns probabilities to goal-scoring opportunities based on: 1. Shot quality (on target vs off target) 2. Chance quality (dangerous attacks indicate high-probability chances) 3. Contextual factors (possession, total attacks)
Model inputs (as per Wikipedia): - Shot location/quality: inferred from shots on target (higher xG) - Phase of play: inferred from dangerous attacks (high-quality chances) - Contextual factors: possession and attack volume
- Parameters:
shots_on_target (int) – Number of shots on target (higher probability of goal)
shots_off_target (int) – Number of shots off target (lower probability)
dangerous_attacks (int) – Number of dangerous attacks (high-quality chances)
attacks (int) – Total number of attacks (context factor)
possession (float or None, optional) – Possession percentage (0-100), used to adjust shot quality
- Returns:
float – Estimated xG value (sum of shot probabilities)
- has_data() bool[source]¶
Check if this MatchStatistics object has any meaningful data.
- Returns:
bool – True if at least one statistic field has data
- static parse_float_stat(value: str | None) tuple[float, float] | None[source]¶
Parse
home:awayformat to a float tuple (for xG).- Parameters:
value (str or None) – Stat string like
"1.2:0.8".- Returns:
tuple[float, float] or None –
(home, away)values, or None if unparseable.
- class slickbet.PredictionResult[source]¶
Result of a single prediction compared to actual outcome.
- property best_double_chance_correct: bool¶
Whether the recommended double chance bet would have won.
- prediction: slickbet.model.BetPrediction¶
- class slickbet.ScreenerResult[source]¶
Result of running the betting screener.
- get_away_wins() list[slickbet.model.BetPrediction][source]¶
Get all predictions recommending away win.
- get_home_wins() list[slickbet.model.BetPrediction][source]¶
Get all predictions recommending home win.
- get_top_k(k: int) list[slickbet.model.BetPrediction][source]¶
Get top K betting opportunities by double chance.
- Parameters:
k (int) – Number of predictions to return.
- Returns:
list[BetPrediction] – Top
kpredictions sorted by best double-chance probability.
- predictions: list[slickbet.model.BetPrediction]¶
- timestamp: datetime.datetime¶
- property top_bets: list[slickbet.model.BetPrediction]¶
Get predictions sorted by best double chance probability (highest first).
- property top_bets_by_win: list[slickbet.model.BetPrediction]¶
Get predictions sorted by win probability (highest first).
- class slickbet.TeamPerformanceStats[source]¶
Detailed team performance statistics from recent matches. Used to improve betting predictions with goal-based metrics.
Based on: https://live-score-api.com/documentation/reference/27/getting-teams-last-matches
- slickbet.__version__ = '0.1.0'¶
- slickbet.format_backtest_report(results: BacktestResults) str[source]¶
Generate a formatted report of backtest results.
- Parameters:
results (BacktestResults) – Aggregated backtest results.
- Returns:
str – Multi-line human-readable report.
- slickbet.format_prediction(prediction: slickbet.model.BetPrediction, rank: int = 0) str[source]¶
Format a prediction for display.
- Parameters:
prediction (BetPrediction) – The prediction to format
rank (int, optional) – Optional rank number to display
- Returns:
str – Formatted string representation
- slickbet.format_summary(result: ScreenerResult) str[source]¶
Format a summary of screener results.
- Parameters:
result (ScreenerResult) – The screener result to summarize
- Returns:
str – Formatted summary string