PitchPulsePro

Trimmed Mean * Dixon Coles
λ Home
λ Away
Adaptive ρ
🔥 Best Bet
λ Home
λ Away
Adaptive ρ
🔥 Best Bet

League Baseline

The league's average goals per match — converts raw form into attack and defence strength. Pick a league to auto-fill, or set the numbers yourself.

Advanced — pick a league or override
Using defaults: Home 1.50  |  Away 1.20 (toggle Advanced to change)

Team Form

Enter each side's name, then their last 5 matches — home venue only for Home, away venue only for Away.

Last 5 matches (home venue for Home, away venue for Away), trimmed — goals for / against

GF Σ
GA Σ
Enable Elo adjustment

Motivation Nudge

Enable motivation nudge
⚽ Most Likely Score
Home
– – –
Away
Top correct score probability
Expected Goals
Over 2.5
BTTS Yes
HT Score (Est)

1X2

Home
Draw
Away
Most likely score
Vs league baseline

Over / Under

Over
Under
Most likely Over score
Vs league baseline

Both Teams to Score

Yes
No
Most likely BTTS score
Vs league baseline

Top correct scores

    Calculate probabilities on the Form tab to see your Match Verdict.

    📋 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.

    💡 How To Use PitchPulse Pro

    Five recent matches per side, one league baseline, and PitchPulse Pro 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 — the market with the biggest edge over the league baseline — and it shimmers gold whenever all 3 of the top 3 most probable correct scores agree with it.

    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 Pro doesn't pull live data — you feed it the numbers, which keeps it fast, offline-friendly, and usable for any league on earth.

    Last 5 matches — goals for / against

    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.

    League averages

    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

    Everything stays on your device

    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.

    Installing PitchPulse Pro

    Served over HTTPS, PitchPulse Pro installs as a standalone app via the "Install App" button (or your browser's install prompt) and keeps working offline once installed.

    Light / dark mode

    Toggle the sun/moon icon in the header any time — your choice is remembered on next visit.

    ❓ Methodology & FAQ

    What model does PitchPulse Pro use?

    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.

    What is the Dixon-Coles correction, and why is it adaptive?

    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.

    Why drop the best and worst match?

    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.

    How are λ (expected goals) calculated?

    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.

    What are the default league averages, and why do they matter?

    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.

    What is Best Bet, and how is it different from "highest probability"?

    Best Bet ranks all seven direct markets (Home/Draw/Away, Over/Under 2.5, BTTS Yes/No) by each market's edge over its league baseline — what a coin-flip fixture in this league (using only the league's home/away goal averages, no team form) would show for that same market. Edge (excess) is that market's probability in this fixture minus its baseline probability, so it's a full-matrix number grounded in the actual league context, not just a raw percentage. A market has to clear that baseline by more than a small dead zone to be eligible to win — so the pick can't go to a market just because it's the "obvious" one in a low-variance league — and among the eligible markets, whichever has the biggest excess is the Best Bet pick, with ties falling back to raw probability. If nothing clears the baseline (a genuine coin-flip fixture), every market stays eligible so there's still a pick. That's the "different from highest probability" part — the pick can go to a market that isn't the single highest-probability one on its own, if it has the bigger edge over what's normal for this league. Separately, the top 3 most probable correct scores from the match's score matrix each imply a result, an Over/Under 2.5 read, and a BTTS read at once — e.g. a 2–1 implies Home Win + Over 2.5 + BTTS Yes — and cast a probability-weighted vote on those three axes. That vote never decides the winner; it's a corroborating signal only, feeding the "X/3 scorelines agree" note in the reason text and the gold shimmer when all 3 agree. If another market is backed by meaningfully more vote-weight than the winner, or is the single most probable market overall by a meaningful margin, the reason text flags that explicitly rather than staying silent. The "Why this pick?" breakdown under the Verdict card lists all seven markets with their probability, excess over baseline, and vote weight — markets excluded by the baseline gate are dimmed and marked with a ↓ rather than hidden, so the gate itself is checkable too.

    What does the 🧪 "Thin data" note mean?

    It's a caution flag, separate from the divergence warning above. Best Bet's excess figure comes from a trimmed 3-match sample blended with the league-average baseline (see "How are λ calculated?" below) — a small excess built mostly on that baseline prior, rather than the form you actually entered, is weaker evidence than the same-sized excess would be with a less-shrunk sample. It only appears when both are true: the winning market's edge over baseline is small, and this league's shrink blend leans mostly on the prior rather than the entered matches (a defensive/low-scoring league shrinks harder than an attacking one — see the adaptive shrinkage note above). A large excess is trusted regardless of shrinkage, since it had to survive the pull toward baseline to still be large. This flag doesn't change the pick itself — it's purely informational, telling you the confidence behind this particular edge is thinner than usual.

    Why does Best Bet sometimes shimmer gold?

    It shimmers when the pick is unanimous — all 3 of the top 3 correct scores agree on it. The Verdict tab always shows an "X/3 AGREE" badge next to the pick, so you can see at a glance whether it's 3/3 (shimmer, Strong Consensus), 2/3, or 1/3 (Cautious Lean) — picks that win Best Bet on vote weight without full 3/3 agreement don't shimmer, they're still the pick, just not the unanimous version of it.

    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.

    What is the EV Finder, and how is it different from Best Bet?

    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.

    What is Signal Check?

    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.

    What is Calibration (the Brier score)?

    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.

    How does the Match Log work?

    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.

    What happens to the Match Log after 24 hours?

    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.

    Does PitchPulse Pro store or send my data anywhere?

    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.

    Can I install PitchPulse Pro as an app?

    Yes — served over HTTPS, PitchPulse Pro 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.

    Disclaimer

    PitchPulse Pro 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

    📬 Contact the Developer

    Questions about the model, licensing, or custom builds? Reach out directly: