methodology

How our odds & data are made

Full transparency on sourcing, normalization, and modeling — so you can trust the numbers and cite them.

10 sections

EsportsOdds publishes two derived odds lines, CS2 statistics, and our own team & player rankings as a data product: a market line we compute by combining prices from multiple bookmakers and exchanges, and (once validated) our own model’s line. We never republish any individual bookmaker’s or exchange’s price, and we never name the books that feed the aggregate. This page documents exactly how every number is derived. It is informational — nothing here is betting advice or an inducement to bet.

1.

Data sources & provenance

Match, team, player and tournament data — results, maps, rosters and stats — is compiled from multiple independent public sources, cross-checked against each other, plus our own statistics parsed from public match data. We deliberately don’t rely on any single upstream source: facts are corroborated across sources, conflicts are resolved by recency and agreement, and every record carries internal provenance so a correction upstream can be traced and applied here. Player ratings are our own computation from raw performance data — never a third party’s rating republished. All of it is served through our CS2 data API.

2.

The market line (live)

Our published market line (eo_market) is a de-vigged aggregate: we monitor real prices across multiple bookmakers and exchanges, remove each book’s margin to recover fair probabilities, take the median across books, and re-normalize. A market line is only published when at least two independent books contribute, and every line carries a book_count so you can see how deep the consensus is. What we never do: republish a single book’s price, name a contributing book, or frame any price as “best” — the aggregate is a reference line, not a shopping comparison.

3.

Normalizing odds

We work in decimal odds throughout. Every published line is captured as a timestamped, append-only time series — one row per outcome, per update — and we never overwrite a value, so movement over time is preserved and auditable.

4.

Implied probability

The implied probability of any decimal price is 1 ÷ decimal odds. Raw bookmaker prices bake in a margin (the “vig” / overround), so implied probabilities across a market’s outcomes sum to more than 100%. Removing that margin — de-vigging — is the first step in both our market line and our model.

The same arithmetic is available as free tools, if you want to run it on your own numbers: the no-vig calculator (which compares the multiplicative, additive, power and Shin methods side by side), the vig calculator, and the implied probability calculator.

5.

Our modeled line — coming soon

We are building a proprietary model that estimates a fair probability and price for each outcome from match and player statistics. This model is not yet live. We will not present modeled lines as production data until they clear an accuracy-validation gate — measured against real outcomes — because a model people rely on must be shown to work before it ships.

When it goes live, we will publish its track record, not just its predictions: calibration (how closely predicted probabilities match real outcomes) and a Brier score against a stated no-skill baseline, so you can audit the model’s accuracy rather than take it on trust. Modeled lines are always rendered in our distinct model accent colour and clearly labelled as our estimate, so a modeled number can never be mistaken for the market line.

6.

Team & player rankings

Our CS2 team rankings are our own rating, computed from match results — not a copy of any other ranking. The team rating uses Glicko-2, a rating system (the successor to Elo) that tracks both a team’s strength and how certain we are of it. We replay every completed CS2 match in our data in date order; each map is one rated game against the opponent’s strength at that moment, so beating a strong team moves a rating more than beating a weak one.

Two deliberate choices keep the board honest. First, teams are ordered by a conservative estimate — the rating minus twice its uncertainty — so a team can’t top the table on a short hot streak we aren’t yet sure about; a proven record has to outweigh the doubt. Second, that uncertainty grows while a team is idle: a side that hasn’t played in weeks is rated less confidently than its last result alone would suggest, which is what makes “recent form” actually mean recent. A team needs a minimum of five rated matches in the recent window to appear at all, so no one ranks off two or three games.

Player ratings in our API and dashboard follow the same principle — our own per-map performance rating, averaged over a window, with a minimum-maps floor so a big game or two can’t vault someone over a season’s body of work. Everything is recomputed daily. Our public player pages show no rating (see the next section). Where we also show a third-party world ranking alongside ours, it is labelled as theirs and shown for comparison — never merged into, or presented as, our own number.

7.

Player pages: how percentiles and bands are worked out

Our public player pages show what a player did in recorded matches, and where each of their figures sits among other players’. These are records of what happened. They are not a judgement of anyone’s ability, and not a prediction. Player pages show no rating — no single number sums a player up — and we do not publish rankings of players against each other on our public pages.

The period. Percentiles and bands always cover the player’s last 12 months of CS2 matches, up to the newest match we have recorded. Where a page shows a longer record, it is labelled “CS2 era”: every CS2 match we hold, and nothing from the game that came before it.

What a recorded map is. A map the player actually played, on one of the ten competitive maps, in a completed match that was not a walkover, with a statistics line recorded for the player. A figure also needs its own inputs, so a recorded map can be missing from some figures.

Who is compared. Events are graded by tier, S being the highest, then A, then B. Every figure is compared against the players who have a page: everyone with at least 30 recorded maps at S, A or B-tier events, or at least 20 at S or A-tier events, in the last 12 months. A player who falls a little below that line keeps their page, and their place in the group, for up to 14 days. Anyone whose page has been taken down at their request is left out. Each player page prints one group size, the number of players who have a page. A player with no figure for something is left out of that figure’s comparison, so the group behind a single figure can be a little smaller than the number printed.

Percentile. A player’s percentile for a figure is the share of the group whose figure is lower than theirs. A percentile of 80 means 80% of the group have a lower figure; the group includes the player. A higher figure always means more of the thing measured — more damage, more kills for each death, and so on.

Exact percentile or band. Players with at least 20 recorded maps at top-tier events (S or A) in the last 12 months are our “established” players, and their pages show the exact percentile. A player stays established for up to 14 days after falling a little below that line. Every other player’s page shows one of these five bands instead, and no other label:

  • top 10%: a percentile of 90 or more
  • top 25%: 75 or more, but under 90
  • above the middle: 55 or more, but under 75
  • around the middle: 45 or more, but under 55
  • below the middle: under 45

No label singles out the bottom of the group.

Too few maps, no figure. A figure is not shown when fewer than 10 of the player’s recorded maps have the statistics it needs.

The figures. Percentiles and bands are given for these eight figures only. Each is worked out from totals across the player’s recorded maps, not as an average of each map’s figure:

  • ADR (average damage per round): the damage the player dealt to opponents, divided by the rounds they played.
  • KAST: the share of rounds in which the player got a kill or an assist, survived, or was traded (the opponent who killed them was killed soon after).
  • K/D: total kills divided by total deaths.
  • Headshot share: the share of the player’s kills that were headshots.
  • Opening-duel success: of the rounds where the player was part of the round’s first kill, as the killer or the one killed, the share where they got the kill.
  • Multi-kill round share: the share of rounds in which the player got two or more kills.
  • Clutches per map: rounds the player won as their team’s last player alive, per map.
  • Trade-kill share: the share of the player’s kills that were trades — killing an opponent soon after that opponent killed a teammate.

The number of maps a player has played is shown as a count only, with no percentile or band.

We work these figures out when a page is prepared; they are not stored as records in our database. A player can ask us to take their page down at any time, without giving a reason — see our Player Data Notice.

8.

Update cadence

Pre-match lines are refreshed on a regular polling cadence, typically within tens of seconds of an upstream change. Rankings are recomputed daily. Any freshness indicator on our pages reflects how recently a number was updated, bounded by our ingest cadence — it is not a countdown and not a signal to act quickly.

9.

Limitations

  • Coverage depth varies by tournament tier and by what upstream sources publish.
  • The market line requires at least two contributing books — thinner matches may have stats but no published line.
  • Our model, once released, is an estimate derived from public statistics — it is not a guarantee, and it does not represent any bookmaker’s price.
  • Historical and current data can contain gaps or corrections; we version and revise.
10.

Corrections

Found something that looks wrong? Tell us at data@esportsodds.gg and we’ll investigate and correct the record.

Make your first call today

Start free with a sandbox key: a fixed sample of past matches, no card. Then one plan, $49/mo for 50,000 requests.