I’m building a small football betting research bot
Hey everyone,
I’ve been tinkering with a betting research bot recently. I’m not trying to sell picks or pretend I’ve cracked betting. It’s paper-only for now and the goal is to find out whether combining decent data, odds and news can produce anything useful.
At the moment it runs once a day early in the morning and looks only at games being played that day. It pulls fixtures and odds, builds a basic team-form/xG baseline, checks news and availability, and then asks an AI model to review the whole picture. It can return a pick, but it can also say pass, no value, market conflict or insufficient data. I don’t want it forcing a bet just because there are games on.
For now we are only working on football and I’m currently using API-Football for fixtures and stats, Football-Data for older results and odds, and OddsPapi to test current prices and bookmaker links. I also have an OpenRouter model extracting things like injuries, suspensions, lineup news and manager changes from public sources.
One thing I learned the hard way: the API-Football predictions endpoint can produce some pretty wild probabilities. I’m treating those as a rough reference, not as the model’s answer. The bot calculates its own baseline, checks it against the market, and has safety filters for bad data, conflicting signals and suspiciously huge EV numbers.
How the bot actually makes a decision
The bot is not supposed to bet just because a team is the favorite or because an AI says it likes a pick. The intended flow is:
Build the day’s slate. Once a day it fetches fixtures for enabled leagues, keeps only games scheduled for that day which have not started, and attaches the available odds.
Create a basic statistical baseline. For football, the current prototype uses recent goals-for/goals-against and team-form data to estimate expected home and away goals. A simple Poisson calculation turns those expected goals into rough probabilities for 1X2 and Over/Under 2.5. This is a first baseline, not a proven or well-calibrated model.
Add context. The system collects news and tries to identify relevant injuries, suspensions, managerial changes and lineup information. OpenRouter classifies the article and records the event, team, impact, confidence and evidence. Generic form articles are treated as context, not automatically as actionable news.
Compare the model with the market. It looks at the bookmaker odds, converts them into approximate implied probabilities after removing the margin, and compares those with the model estimate. It also tracks odds movement. If the news suggests a team is weakened but the market moves strongly in the opposite direction, the bot marks a conflict and avoids promoting the pick.
Apply hard safety filters. A recommendation can be rejected for missing data, questionable odds, conflicting information, unconfirmed lineups, a major-player rumour or an implausibly large estimated edge. An extreme calculated EV is treated as a possible model/data problem, not as “easy money.”
Return a verdict. The output can be `PASS`, `LEAN`, `NO_VALUE`, `WATCH`, `WATCH_MARKET_CONFLICT`, `INSUFFICIENT_DATA` or a provisional paper candidate. It should be allowed to return no picks.
Log and settle paper picks. Recommendations and odds are timestamped and stored. After the match, the result is fetched and the paper record is settled at one unit per recommendation. Duplicate recommendations for the same fixture, market and selection are excluded.
A key limitation is that the football probability estimates are not yet properly calibrated. The AI can help interpret the structured information, but its stated probability should not be treated as a reliable probability merely because it sounds confident. We’re tracking results, but we need a much larger out-of-sample sample and calibration checks before claiming an edge.
The external tipster-consensus layer is not yet part of the active decision process. I want to add public, timestamped tips as another signal, while distinguishing independent opinions from copied posts and tracking each source’s results. Odds sources and executable bookmaker prices are also still being checked separately; I don’t want the bot to present a price from one book as if it were available at another.
I’ve also started a separate EuroLeague experiment. I downloaded a full historical season with team and player stats and built an early baseline model. It looks promising on a couple of metrics, but I don’t have historical odds to test whether it would actually have found value. So, for now, that’s research only too. I will get into it after I have finalized with Football.
The results so far are mixed. The current paper sample is still small because of the Nations League, so I’m not claiming there’s an edge. I’m assuming there isn’t one until it survives a much bigger, properly logged sample.
I’m now trying to improve the data side. I’d like recommendations for:
- Affordable odds APIs with good coverage of bookmakers ideally with historical odds and timestamps.
- Reliable football data for xG, lineups and player availability.
- Public tipster or analyst sources that publish timestamped picks, so I can track them properly rather than cherry-pick winning posts.
- Ways to spot when several channels are independently backing the same pick versus just copying one source.
If you’ve built something similar, I’d especially appreciate feedback on the probability model and validation setup. What data sources have you found reliable for historical odds, xG, lineups and injuries? And what’s a sensible way to track public tipsters without counting copied posts as independent opinions?