Last 5 matches (home venue for Home, away venue for Away), trimmed — goals for / against
1X2
Over / Under
Both Teams to Score
Top correct scores
Calculate probabilities on the Form tab to see your Match Verdict.
Match Verdict
Quick Stats
📋 Match Log
No matches logged yet. Calculate a fixture, then hit "Add to Match Log".
Calculate probabilities on the Inputs tab to use the EV Finder.
💰 EV Finder
Enter the decimal odds you're being offered for each market — PitchPulse compares them against its own fair probability and flags any positive-EV value. EV% = (fair probability × odds) − 1.
📋 EV Match Log
Saves whichever market above shows the highest positive EV right now. Track its hit rate here against the model's own Best Bet picks from the Verdict tab to see which approach is actually paying off.
No EV picks logged yet. Enter odds above, then hit "+ Log Best EV Pick".
💡 How To Use PitchPulse
Five recent matches per side, one league baseline, and PitchPulse turns it into a full set of match probabilities in one tap.
Step 1 — League Baseline: Pick a Country and League to auto-fill the average home/away goals for that competition, or type your own. Defaults are Home 1.50 / Away 1.20 — a generic mid-table read. Switching Advanced back off restores these defaults.
Step 2 — Team names: Name your Home and Away side.
Step 3 — Recent form: Read off each team's last 5 matches (home matches only for the Home side, away matches only for the Away side). Drop the single highest and single lowest goals-for, add up the remaining 3, and enter that as GF Σ — then do the same for goals-against as GA Σ.
Step 4 — Motivation Nudge (optional): Enable it and slide toward whichever side has more riding on this specific match — a relegation six-pointer, a cup final, a dead rubber. Leave it off for a normal fixture; it has no effect at the centre position.
Step 5 — Calculate: Hit "⚡ Calculate Probabilities". The Markets tab fills in with 1X2, Over/Under, BTTS, and the top correct scores; the stats strip up top shows λ Home, λ Away, the adaptive Dixon-Coles ρ, and the model's Best Bet — which shimmers gold whenever the pick hits a top-5 supermajority, the top Consensus tier in its score.
Step 6 — Track it: On the Verdict tab, hit "+ Add to Match Log" to save the pick, then fill in the real final score once the match is played. Signal Check and Calibration build up as your log grows. The log archives automatically each day — use 🗄 Archive or the ⬇ CSV/JSON buttons to export for analysis.
📊 Where To Get Your Team Stats
PitchPulse doesn't pull live data — you feed it the numbers, which keeps it fast, offline-friendly, and usable for any league on earth.
FlashScore.com & WhoScored.com — filter a team's results by venue (home or away), then read off the score of each of the last 5. Drop the best and worst goals-for, sum the remaining 3 for GF Σ; do the same for goals-against to get GA Σ.
Official league sites — most top-flight league sites (e.g. premierleague.com, laliga.com) list a filterable fixture history per club.
FBref.com — free match logs for almost every senior league worldwide, filterable by venue.
Use the Country/League selector on the Form tab first — it auto-fills from a built-in database. If your league isn't listed, search "[league name] goals per game average" for the current season, or just leave the defaults (1.50 home / 1.20 away) as a generic baseline.
⚙️ Good To Know
Inputs, theme, and the Match Log are saved in your browser's local storage only. There's no backend and nothing is ever sent anywhere.
Served over HTTPS, PitchPulse installs as a standalone app via the "Install App" button (or your browser's install prompt) and keeps working offline once installed.
Toggle the sun/moon icon in the header any time — your choice is remembered on next visit.
❓ Methodology & FAQ
A trimmed-mean Poisson model. Each team's last 5 matches (home-only for the Home side, away-only for the Away side) are averaged with the single best and single worst result dropped, so one outlier scoreline can't dominate the read on current form. Those trimmed averages become attack/defence strength relative to the league baseline, which convert into expected goals (λ) for each side — from there, independent Poisson distributions build the score matrix, with an adaptive Dixon-Coles correction applied to the low-scoring cells before it's renormalized. Every market on the Markets tab is derived from that final matrix.
Independent Poisson treats home and away goals as statistically unrelated, but real match goals are mildly coupled by things like game state and tactics — and that shows up specifically in the low-scoring cells. The Dixon & Coles (1997) tau correction adjusts exactly those four cells (0–0, 1–0, 0–1, 1–1) before the matrix is renormalized. Rather than a single fixed literature constant, ρ here is adaptive: it scales with the league's own average goals, growing more negative for defensive/low-scoring leagues and lighter for high-scoring ones — anchored so a league at the app's default baselines (1.50/1.20) reproduces the original literature-standard ρ = -0.13 exactly. It's derived purely from the League Baseline inputs above (never from either team's own GF/GA form) and runs automatically in the background — there's nothing to configure.
A single 6–0 or 0–5 in the last 5 can swing a raw average far more than it should. Trimming the high and low outcome keeps the read closer to a team's typical performance rather than its most extreme one.
HomeAttack = Home team's trimmed home goals-for ÷ league average home goals. HomeDefence = trimmed home goals-against ÷ league average away goals. Away strengths mirror this using the team's away form. Before that division, each trimmed sum is blended with a few "average" matches worth of the league baseline — so a genuine 0 across your 3 trimmed matches doesn't collapse to a guaranteed clean sheet, while a sum already near the league average is barely affected. That blend strength is adaptive: goals follow a Poisson distribution, so a 3-match sample is proportionally noisier in a low-scoring context than a high-scoring one — a defensive league (say 0.8 goals/game) gets pulled toward the baseline more firmly (around 46% weight) than a high-scoring one (say 2.5 goals/game, around 33%). At the app's own default baselines (1.50 / 1.20) it lands close to the original ~40% weight. λHome = HomeAttack × AwayDefence × league average home goals, and λAway = AwayAttack × HomeDefence × league average away goals. A strength of 1.00× means exactly league average; 1.25× means 25% above it.
1.50 home goals, 1.20 away goals per match — a generic mid-table baseline. Raw goal counts only mean something relative to context: 1.8 goals a game is modest in a high-scoring league and strong in a defensive one. Pick your league from the Country/League selector to auto-fill the real numbers, or enter them yourself for the sharpest read.
Best Bet ranks all seven direct markets (Home/Draw/Away, Over/Under 2.5, BTTS Yes/No) on one composite score: Excess × √(Consensus × Stability × Separation). Excess is probability minus that market's own league-baseline probability (computed from the raw league averages, before either team's form is applied) rather than raw probability — so a 55% Over 2.5 in a league that averages ~50% doesn't beat a 55% Home Win in a league where home sides only win ~35% of the time. Consensus checks whether the model's top 5 most likely scorelines back this market (3-of-5 majority / 4-5-of-5 supermajority for the 3-way 1X2 result, a stricter 4-of-5 / 5-of-5 for the 2-way BTTS and O/U markets). Stability re-runs the model with the last-5 GF/GA sums nudged ±1 goal and measures how much this market's probability swings — a fragile pick scores lower. Separation rewards a genuinely clear 1X2 leader over its runner-up, and stays neutral for BTTS/O-U since their runner-up is mathematically forced to be 1-probability. The three multipliers are combined under a square root before applying them to Excess, since taken raw they can swing wider (~0.25x–1.56x) than Excess itself typically does (~0.05–0.25) — the sqrt keeps them nudging the ranking rather than overriding a genuinely bigger edge. There's no fallback — Best Bet always lands on one of the seven real markets.
A bare majority (3-of-5 for 1X2, 4-of-5 for BTTS/O-U) is enough to earn the 1.15× Consensus boost, but the shimmer needs the top tier: a supermajority — 4-5 of 5 for the 1X2 market, a full 5-of-5 for the 2-way BTTS/O-U markets — worth the full 1.25× multiplier, is what lights up the gold highlight in the header stats strip.
When a Best Bet is confirmed this way and you log it, the Match Log entry itself is marked with a gold "✨ CONFIRMED" badge and the same shimmer, so it stands out from the rest of your log.
Best Bet answers "which market does the model trust most" — it never looks at odds. The EV Finder answers a completely different question: "given the odds I'm actually being offered, is this a good bet?" You type in the decimal odds for each of the same seven markets, and it compares them against the model's own fair probability: EV% = (fair probability × odds) − 1. Positive EV means the price is better than the model's fair value; negative means it isn't — regardless of whether that market happens to be the current Best Bet. A market can be the model's top confidence pick and still be poor value if the odds are short, and a market the model rates lower can still be +EV if the price is generous. Odds you type in persist while you keep recalculating the same fixture, but aren't saved to local storage — a fresh page load starts blank.
The EV Finder also has its own EV Match Log, separate from the main Match Log on the Verdict tab: hitting "+ Log Best EV Pick" saves whichever market currently shows the highest positive EV, and you can mark it HIT/MISS once the match is played, same as the main log. A comparison bar shows the resolved hit rate of your EV picks side by side with your Best Bet picks, so over time you can see which approach — chasing value or trusting the model's top confidence pick — is actually paying off for you. It's expected to log far less often than the main Match Log, since you'd only add to it when odds worth taking actually turn up.
A 🟢/🟡/🔴/⚪ tier for the specific bet category behind your current Best Bet (e.g. "Home Win"), computed from your own logged history using a Wilson score interval lower bound rather than a raw hit rate — so a 2-for-2 record doesn't get overrated. It needs 5+ resolved picks in that category before it rates anything; below that it shows ⚪ UNPROVEN.
The 📊 Calibration button opens a running Brier score (0–1 scale, lower is better) per market — 1X2, Over/Under 2.5, BTTS — comparing your all-time average against your last 10 resolved matches. This is independent of Signal Check: it grades the model's raw probabilities directly, rather than just whether the top pick won.
Hit "+ Add to Match Log" on the Verdict tab after calculating to save a prediction. Once the match is played, enter the real final score — it's marked ✅ HIT or ❌ MISS against the Best Bet pick, and rolls into the Hit Rate shown in the stats bar. Best Bet, the Match Log, and the Markets tab all grade against the same fixed Over/Under 2.5 line, so a logged "Over 2.5" always stays comparable.
It archives automatically. The first time the app checks after the calendar date changes — on load, or when you come back to an open tab — everything logged "today" moves into a dated archive bucket, and the Match Log starts fresh for the new day's fixtures. Nothing is deleted: open 🗄 Archive to browse every past day (with its HIT/MISS split) and export it as CSV or JSON. The ⬇ CSV / ⬇ JSON buttons next to "Clear all" export everything at once — today's log plus the full archive — as one file for spreadsheet or offline analysis.
No. Everything — inputs, theme, your Match Log, and its archive — lives in your browser's local storage. There's no backend and no data ever leaves your device unless you tap an export button yourself.
Yes — served over HTTPS, PitchPulse is an installable PWA. Use the "Install App" button in the header, or your browser's own install prompt, and it'll keep working offline afterward.
PitchPulse produces a probability estimate from recent form — not a guarantee. It doesn't account for injuries or opponent quality beyond the last-5-match window (the Motivation Nudge covers motivation, but it's a manual, subjective input — only as good as your own read on the match), and Signal Check / Calibration are only as meaningful as how many matches you've logged and resolved. Please gamble responsibly. — by Victor Korir
Questions about the model, licensing, or custom builds? Reach out directly: