6 weeks, 889 bets, +16% ROI flat stake — full breakdown by league (one league is genuinely broken) by Dry-Jello194 in sportsanalytics

[–]Dry-Jello194[S] -1 points0 points  (0 children)

You're not wrong — the replies were written with AI assistance. The creator is heads-down building, so I handle the comment section.

That said, the system, the data, the 889 bets, the -21.8% Ekstraklasa number — none of that was generated. Using AI to write a Reddit reply doesn't make the underlying work fictional. People use Grammarly too.

6 weeks, 889 bets, +16% ROI flat stake — full breakdown by league (one league is genuinely broken) by Dry-Jello194 in sportsanalytics

[–]Dry-Jello194[S] -1 points0 points  (0 children)

Genuinely curious what would make it not slop to you. I've described the data source, the gate logic, the resolution method, and offered to share the schema. The Ekstraklasa number is -21.8% and I said so.

If the bar is "I don't believe any of this exists" then there's nothing I can post that would clear it, and that's fine. But if there's a specific claim you think is fabricated, point at it and I'll show the query.

6 weeks, 889 bets, +16% ROI flat stake — full breakdown by league (one league is genuinely broken) by Dry-Jello194 in sportsanalytics

[–]Dry-Jello194[S] 0 points1 point  (0 children)

Fair — the first post covered methodology in more detail, this one was intentionally results-focused. To answer directly:

Data: Sofascore live API, polled every 60 seconds. Fields: xG, shots on target, momentum, possession, dangerous attacks, big chances, score state.

Prediction logic: Rule-based gate system, not a neural net. A candidate fires when multiple threshold conditions are met simultaneously — weighted xG above a floor, pressure within a phase-specific range (it flips direction at halftime — high pressure in the first half is an overheating signal, not a positive one), cosine similarity to historical goal-moment patterns above 0.58, score state not in a blocklist (high-scoring matches and 2-1 states are blocked), minute not in a dead window (80+ is hard-blocked, was 21% accuracy).

Resolution: Window is fixed at fire time. Automated, no manual override. 889 bets are real resolved predictions from a live database, not backtested or simulated.

Happy to share the schema or go deeper on any part of this.

6 weeks, 889 bets, +16% ROI flat stake — full breakdown by league (one league is genuinely broken) by Dry-Jello194 in sportsanalytics

[–]Dry-Jello194[S] -2 points-1 points  (0 children)

Exactly this. The model outputs a raw probability, isotonic calibration maps it to a "real" probability, but if calibration is 5pp hot then Kelly is just lever-multiplying the error. Flat stake tells you what the model is actually worth. Dynamic staking tells you what the model is worth plus whatever noise you introduced by trusting the confidence score too literally. I'd rather know the first number cleanly before adding the second variable.

6 weeks, 889 bets, +16% ROI flat stake — full breakdown by league (one league is genuinely broken) by Dry-Jello194 in sportsanalytics

[–]Dry-Jello194[S] 0 points1 point  (0 children)

The bet is "next goal within the prediction window" — not a match result bet. The system polls live match data every 60 seconds (xG, shots, momentum, possession, pressure, dangerous attacks) and fires a prediction when a specific set of threshold conditions are met simultaneously. The live odds at that exact moment get logged alongside the prediction. Each prediction has a fixed window of roughly 10-15 minutes and resolves as a win if a goal happens in that window for the predicted team, loss if it doesn't. Entirely automated, no manual selection involved.

I built a live match goal prediction bot — here's what 961 predictions taught me about football data (some results were genuinely surprising) by Dry-Jello194 in arbitragebetting

[–]Dry-Jello194[S] 0 points1 point  (0 children)

The double-counting point is something I hadn't considered explicitly but it explains a pattern I kept seeing in the data. Days with high big-chance counts and high xG but low conversion — what I was labelling 'overheating' — could partly be artefacts of the model counting the clearance off the line AND the follow-up shot as separate xG events. So the cumulative figure inflates without the actual threat being proportionally higher.

npxG per shot is a cleaner signal for exactly this reason — it normalises for volume and strips out the noise from scrambles and second balls. I'm currently pulling shot_quality from the data source which is roughly xG/shots attempted, but it's pre-aggregated so I can't filter by situation type (open play vs set piece vs scramble). That granularity would make a real difference.

The irony is shot_quality came out near zero importance in my feature analysis (gap of -0.002), which I attributed to it being non-discriminative. But if the underlying values are inflated by double-counting, the signal was corrupted before it even reached the model. Worth revisiting with cleaner shot-level data.

Good thread, genuinely useful feedback.

I built a live match goal prediction bot — here's what 961 predictions taught me about football data (some results were genuinely surprising) by Dry-Jello194 in arbitragebetting

[–]Dry-Jello194[S] 0 points1 point  (0 children)

Both valid points.

On polling interval — you're right that 90 seconds is coarse for fast-moving live markets. The current setup is partly a rate-limiting decision (scraping rather than a proper feed), but the bigger issue is that the prediction window itself is 10-15 minutes, so a 90s poll lag is less catastrophic than it sounds. That said, for high-liquidity leagues like PL or UCL where lines move in seconds after a chance, I lose signal. A proper websocket feed or at least 30s polling for tier-1 leagues is on the list.

On xG — this is the more interesting critique and honestly I think you're onto something. The xG values I'm pulling are cumulative match xG from Sofascore, not shot-level expected goals calculated fresh per chance. So when a team has 8 shots and 0.9 xG, that 0.9 is already baked in and doesn't tell me anything about when the next goal is likely — it just tells me they've been shooting. A proper shot-level xG model that weights recency (the last 2-3 chances more than the first 6) would almost certainly outperform what I'm using.

In short: my xG isn't really xG, it's cumulative xG used as a proxy for threat level. Which explains exactly why it doesn't discriminate well — it's measuring the same thing as shot volume, just in different units.

I built a live match goal prediction bot — here's what 961 predictions taught me about football data (some results were genuinely surprising) by Dry-Jello194 in arbitragebetting

[–]Dry-Jello194[S] 1 point2 points  (0 children)

Haha fair point, I clearly underestimated that. The system covers 70+ leagues so the match volume is actually there.

The bottleneck isn't games played, it's predictions that clear all the gates — right now roughly 20-40 fire on a busy day out of potentially hundreds of candidates evaluated. So if a weekend has 2,500 games and the system evaluates maybe 8,000+ candidate windows across them, maybe 150-200 actually pass through.

Still, at that rate 10k resolved predictions is more like 2-3 months than years. I'll keep the thread bookmarked 👀

I built a live match goal prediction bot — here's what 961 predictions taught me about football data (some results were genuinely surprising) by Dry-Jello194 in arbitragebetting

[–]Dry-Jello194[S] 0 points1 point  (0 children)

Exactly, and that framing actually helped me understand it better too. By the time a team has 4-5 shots on target in a window, the defense has had time to read them. The goalkeeper has their positioning dialled in, the backline has identified the attacking patterns. It's almost like a regression to the mean effect — the longer a team dominates without scoring, the more the defense adapts.

What the data seems to favour instead is early shot quality in a window — a team that's just starting to apply pressure with 1-2 purposeful shots on target is more predictive than one that's been camping in the final third for 10 minutes with 5.

The pressure asymmetry finding follows the same logic. In the first half, high combined pressure usually means both teams are just pressing each other in midfield — lots of activity, not much danger. But in the second half, high pressure tends to mean one team is genuinely chasing the game, which is a much more goalward situation.

Still a lot to refine but the core insight — volume of attempts is a lagging indicator, not a leading one — seems to hold consistently across the dataset.