Methodology

Published,
so you can
argue with it

Every number Latent puts on a screen (this site, a post, a paid report) is derived by us from match-level data we hold, by the rules on this page. Nothing is licensed and rebadged. Where the data cannot support a claim, the claim is not made, and the gap is listed in section 08 rather than smoothed over.

201,463 Player-match stat rows
6,665 Finished matches
12,574 Player-seasons
4,694 Rankable players 270+ minutes in a season

Figures on this page are read from the database each time it is built. Last finished match in the data: 2026-08-24. Page built 2026-08-25.

01 · Sources

What the numbers are built from

Five layers, all held locally, all queried read-only by the scripts that generate this site.

  • Per-match player statistics 201,463 player-match rows across 6,665 finished matches in 7 competitions and 28 seasons: minutes, goals, shots, passes, duels, touches and more, per player per match. Every metric we publish is our own derivation from this layer. We never republish a third party's player rating.
  • Transfer records 66,860 completed moves in and out of our markets, 21,480 of them across a border, 4,150 with a disclosed fee. This is what grounds destination analysis, fee comparables and the ledger in transfers that actually happened.
  • Post-move outcomes 4,887 destination season rows: how much a player who left actually played afterwards. Minutes earned at the destination are the closest thing a transfer has to a verdict, and they calibrate the Latent Level.
  • Continental competition 5,741 player-match rows from 272 European matches played by 127 of our clubs across 5 competitions: real evidence of how these squads perform against stronger opposition, rather than a projection of it.
  • Second-tier and destination squads 13,449 stat rows from a second-tier feeder competition, and a squad snapshot of 6,207 players at 212 clubs in 12 destination markets, taken 2026-08-14.
02 · Coverage

Stated exactly, per competition

Coverage is uneven, because the underlying collection is. The honest response is to print the table, not to imply a depth that only exists in two of these competitions.

Player-statistic coverage by competition Data labels, not a ranking. Rankable = players with at least 270 minutes in a season.
CompetitionStats fromSeasons MatchesRankableStat rows
USL ChampionshipUnited States · USLC202072,7501,72582,943
EkstraklasaPoland · EKS21/2261,5681,10948,263
VirslīgaLatvia · LAT2023467749520,155
A LygaLithuania · LIT2023467050720,150
MeistriliigaEstonia · EST2023466241319,587
Ukrainian Premier LeagueUkraine · UPL25/2622663848,114
Canadian Premier LeagueCanada · CPL20261721512,251
The consequence, said plainly

The deepest histories we hold are not the markets the brand started in. There is no player-statistic history before the first season listed for each competition (not thin history, none), so multi-year trend work and "we would have seen him coming" evidence is only possible where the seasons column is large. Any page or report implying otherwise would be wrong.

Ball-carry data

Carry collection began part-way through our history and, in one competition, part-way through a season. Where it covers only part of a league-season, the carry percentile is suppressed for that whole season rather than ranking players measured on different match sets against each other. The rate survives, the ranking does not.

Where carry data exists at all Competitions and seasons not listed have no carry data whatsoever.
Competition / seasonPlayers with a rate Percentile published
CPL 2026151 of 151● ranked
EKS 25/26321 of 420◐ rate only
EKS 26/27128 of 128● ranked
USLC 202511 of 529◐ rate only
USLC 2026474 of 474● ranked
A rate that exists for a handful of players in a season is not a basis for a claim about that season. Where the count is small the percentile is deliberately absent, and no carry comparison should be drawn from the rate alone.
03 · Rates

How a per-90 is computed

  • Honest denominators A statistic is divided only by the minutes in which that statistic was actually collected, never a partial numerator over full-season minutes. Getting this wrong is how a player with eleven recorded carries in one match ends up at the 97th percentile for a season, which is exactly the defect this rule was written to kill.
  • 270 collected minutes, per statistic Each rate has its own gate. Below it the rate is reported unavailable, not estimated. A player used in short substitute cameos may clear the gate for one statistic and not another; his rolling form line is then drawn with gaps rather than filled with zeros.
  • Missing is never zero A statistic a competition did not record renders as "not recorded" on the site, in graphics and in reports. Gaps are never filled with zeros, league averages or model output.
  • Goals and assists are the one exception, deliberately Some feeds omit the goals field entirely for a player who did not score, rather than writing zero. Treated naively that removes every goalless player from the goals ranking, so they are never penalised for not scoring. We treat an absent goal field as a genuine zero, so a goalless player ranks last instead of vanishing.
04 · Percentiles

The peer group is exact, or there is no percentile

  • Scope Same competition, same season, same position group, minimum 270 minutes. Every percentile we print is printed with the size of the cohort it was computed against.
  • Never across competitions A 90th percentile in one league and a 90th in another are not the same claim, so they are never blended, averaged or compared. Cross-competition comparison is what the Latent Level exists for, and it is a separate number with its own published test.
  • Cohort floor of 10 If fewer than ten players survive the minutes gate in a peer group, no percentile is published at all. The smallest cohort currently behind any published percentile is 10 players. Early in a season this means a competition publishes few percentiles or none. That is the floor working, not missing data.
  • No mixed cohorts If a statistic covers only part of a league-season, its percentile is suppressed for the whole season. A percentile whose peer group is "whoever the provider happened to cover" is not the ranking the number claims to be.
05 · Export Index

The flagship number, defined

One score per player per season: the mean of five per-90 output percentiles (goals, assists, progressive carries, key passes and duel win rate) against the peer group above, then multiplied by an age factor that favours youth (×1.15 at 21 or under, ×1.05 from 22 to 24, ×1.00 after that), because the same output from a younger player is worth more to the buyer. 8,565 player-seasons currently carry one.

  • An index, not a percentile Like the Latent Level, the Export Index is a score on its own scale: whole numbers running about 69 to 1,127, averaging 510. It is deliberately not on a 0–100 scale, because a mean of percentiles carrying an age multiplier will exceed 100 and then invites the question "out of what?". It is never printed with a percent sign, never described as a percentile, and never drawn on a shared axis with the percentile bars it is built from. Nor is it clamped: clamping would destroy the ordering exactly at the top, where the ordering is the whole point.
  • Goalkeepers are not ranked by it The index contains no shot-stopping, so a goalkeeper's index would be a ranking of how well he does things he is not there to do. Goalkeepers carry no index at all: 0 of them appear in any index or leaderboard on this site. Their 816 ranked seasons are ranked keeper against keeper instead.
  • A season is scored only on components available to all of it Where a component covers part of a season, the whole season is scored on the remaining components, so every player in a league-season sits on the same scale. The cost is real and we took it anyway: one season lost its carry ranking entirely.
06 · Latent Level

Cross-league rating, with the backtest attached

Percentiles stop at the league border. The Latent Level is the cross-competition number: a player's within-league output, adjusted for the opposition he produced it against, then translated by an empirical league-strength graph fitted on 1,678 completed moves across 335 league nodes and 706 corridors, calibrated on what players who actually made those moves did next, measured in minutes earned. 8,565 player-seasons carry a Level.

  • It is an index, and never out of 100 The Level is a score on its own scale. Published values run about 64 to 1411; the average across every player-season that carries one is 559, and the average of a single competition-and-position cohort runs from about 319 to 756 depending on which cohort it is. That spread is the reason a Level is only readable next to the cohort average printed beside it, which is how every Latent report prints it. It is never a percentage and never out of 100. Method level-v1.1 rescaled the first version's numbers by ten to remove exactly that ambiguity; ordering, correlations and every backtest figure below are unchanged by it.
  • The validation rule No Level appears in any Latent report until its backtest against real post-move outcomes is published on this page, with the method version it applies to. Revise the method and the backtest re-runs and republishes here. A rating whose accuracy you cannot check is marketing.

The backtest, published in full

Run on 522 completed moves abroad where we hold both a pre-move Level and the player's post-move league minutes, plus 223 permanent moves with a disclosed fee. Reproduce it with pipeline/level.py backtest against the same database.

Method
level-v1.1, run 2026-08-25
Fee correlation
Spearman(pre-move Level, fee actually paid) = +0.281 on 223 permanent exports with a disclosed fee. This is the strongest receipt: the ordering the Level produces lines up with what buyers paid.
Retention correlation
Spearman(Level, share of a nominal season played at the destination) = +0.069 raw, and -0.014 once destination difficulty, loan status and age are accounted for. The within-league performance composite on its own scores -0.024.
Quartiles
Holding a place is defined as dest league minutes >= 1350 in best of first two seasons. Top Level quartile 36% (n = 131) versus bottom quartile 29% (n = 131).
Exactly what we claim, and what we do not

The Latent Level is a corridor-calibrated cross-league rating with a published backtest. What the receipts support is that its ordering is consistent with the fees the market paid, and that its cross-league component carries a real if small association with minutes retention. What they do not support, on our own published numbers, is predicting whether an individual player will hold a place after a transfer. Once destination difficulty, loan status and age are accounted for, the player-specific part of the Level adds essentially nothing to that. So no Latent report will tell you a player is going to stick, and any provider who tells you theirs does should be asked for this page.

Limits of the validation set

The join between transfer records and our match data is by name and birth year, because no shared identifier exists, so transliterated names silently fail to match and the tested set skews toward the competitions whose names survive the join. By origin: EKS 173, LIT 118, LAT 97, USLC 68, EST 56, UPL 10 ; the competition the brand is best known for contributes 10 of 522 tested moves, because our history there is two seasons deep. Retention also counts an injury as a failure, because we hold no injury data to separate it out.

The league coefficients, and why they are not a ranking

The translation factors below are fitted from how each league's exporters actually fared after moving. They are not an opinion of league quality, and we will not present them as one, because the fit has a bias we can name: exporters are not a random sample of their league. A competition that exports a few well-chosen players into a friendly corridor fits stronger than one that exports many squad players into hard ones.

Corridor translation factors Not a league ranking, and not usable as one. Read them as the exchange rate along observed transfer corridors.
NodeFactorMoves in fit
EKS1.51294
LAT1.22158
UPL1.05626
USLC0.99120
LIT0.91187
EST0.8993
UPL20.86168
CPL0.64188

The clearest evidence that this is not a quality table is in the table itself: it puts competitions in an order no scout would sign off. We publish it anyway, with the reason, because the alternative is a hidden coefficient doing the same work unexamined.

Mean published Level by competition Shown so a Level you see elsewhere on this site has somewhere to be read against. Cohort averages differ by position too.
CompetitionPlayer-seasons Mean Level
EKS2,027755
LAT858607
UPL364525
USLC3,570498
LIT818457
EST790446
CPL138319

See the flag ledger

07 · Audit gates

What runs before a number is allowed out

Every refresh passes automated integrity checks before anything reaches this site or a report. A competition that fails a blocking check does not publish until it is repaired. This has happened, and it held a publish.

  • Goal-attribution guard Goals credited to individual players are reconciled against match scorelines for every season of every competition. The expected band is roughly 0.95–0.98; the shortfall is own goals, which are correctly credited to nobody. Anything below it is investigated down to the individual match. This check caught a current season missing two entire matchdays of statistics, at 0.78.
  • Coverage detection Every statistic is checked, in every season, for partial coverage, so a statistic that phased in mid-season can never masquerade as a full-season rate.
  • Staleness recheck Recently played matches are re-queried against the source, because a match ingested within days of kickoff can be cached before its statistics exist and would otherwise stay empty forever.
Goal attribution, current state Player-credited goals over scoreline goals, all finished matches with a score. Not a league table and not derived from one.
CompetitionCreditedScoreline Ratio
CPL2082130.977
USLC7,4427,6910.968
LIT1,6101,6690.965
UPL6476710.964
EKS4,0424,1920.964
LAT1,9432,0220.961
EST1,8611,9410.959
08 · Stated limits

What we don't have, and won't fake

These are the limits of the data underneath every Latent product. Each is stated in any report it touches. None is ever papered over with an invented number, and this list is maintained as the working defect log, not as marketing.

  • No event locations, so no expected goals, heatmaps or pass maps We hold event counts, not pitch coordinates. Producing those charts would mean inventing the underlying geometry, so we don't produce them at all.
  • No physical or tracking data No distances, sprint counts or load. Where a question needs them, the report says the data does not exist rather than proxying it from something else.
  • No injury data: minutes gaps are an availability signal only We flag stretches where a player's club played at least three matches without him. The cause (injury, suspension, registration, selection) is not recorded anywhere in our sources and is never asserted. Calling these "injury history" would be a false claim.
  • No contract data in the match database Where contract status matters to a valuation, the report says it must be verified with the club or agent. In the destination-squad snapshot, contract end dates are published by the source for a large minority of players in two of the destination markets (58% and 64% coverage), so "contracts expiring" counts there are floors, never totals. Every other destination market: 82%+.
  • No league tables A table rebuilt from our match results can disagree with the official one, because awarded and technical results appear in a standings feed and not in match data. Rather than publish a table a visitor could check and find wrong, we publish none. The same figures are still safe as an opposition-strength weight, which is the only place they are used. Observed: 5 of 10 clubs off by 1–3 points in one in-progress season.
  • Ball-carry data exists only where it is collected See the table in section 02. Where it is absent or partial, carry metrics are suppressed rather than estimated, and no carry-based claim is made about a competition that has none.
  • Goalkeepers have no index, style, comparables or valuation Our metric set contains no shot-stopping, so a goalkeeper archetype or valuation would be fabricated. Goalkeepers get keeper-against-keeper percentiles on what we do measure, and nothing else, until a goalkeeping metric set exists.
  • Market value is matched by name, and the value model has no support at the top Our match database holds no market-value field, so values come from the transfer source, joined by name. The valuation residual model is fitted on a market whose mass sits well below €3m; above that it is out of support and we say so on the output. A large positive residual on an expensive player means the market is pricing something domestic percentiles do not measure; it does not mean "overpriced". Fit: R²(log) 0.41, median absolute log residual 0.17 (about ±50%), n = 2,864.
  • Corridor median fees are frequently zero On most corridors out of our markets the median fee is literally €0: free transfers dominate. A median like that describes the corridor's habit, not a player's worth, so fee ranges are built only from comparables that carried an actual fee, and a €0 median is never presented as a valuation.
  • Post-move minutes are a reference share, not an exact one We do not hold destination-league match counts, so post-move playing time is expressed against a 34-match reference season. The shares are comparable with each other and captioned as such, never as "share of his club's minutes".
  • Destination squads are a point-in-time snapshot Squad depth, ages and values behind any destination shortlist are current as of the snapshot date printed with them (2026-08-14). A snapshot older than 14 days re-scrapes automatically before a shortlist is computed, but a report read months later is reading that day's squads.
  • Identity between our data and the transfer records is a name match No shared identifier exists between the two, so players are joined by accent-stripped name plus birth year, and ambiguous names are dropped rather than guessed. Transliterated names fail silently. This limits the backtest, the ledger and every comparable-player outcome, in the same direction each time: it loses real matches, it does not invent them.
  • The opposition adjustment is coarse Opponent quality is points-per-match from our own results, bounded to ±5% of the composite. Squad-value data for our own clubs was never collected, so nothing finer is available, and early in a season the input is noisy.
  • A handful of matches carry no usable data, permanently Three matches across the database are recorded as finished with no scoreline and no statistics at source; two more carry a scoreline but no player statistics and cannot be repaired. Four goals are unattributable as a result. No player metric is affected (no statistics means nothing enters a season total), but a match count is off by those matches where they fall.
  • The statistics source is an unofficial public endpoint It is undocumented and could close. We mitigate by caching everything we read, requesting slowly, and publishing only our own derived metrics, never the source's own player rating. Licensed event data is the upgrade path once revenue justifies it, and it would remove several of the limits above.
09 · Reproducing it

Check us

The two pages that exist to be checked are this one and the ledger. Everything on both is generated from the databases at build time, so neither can drift from what the data says without the build changing.

Ledger
166 published flags, 43 of them gradeable, with the date each was first published and an explicit "too early to grade" state. Open the ledger · the raw flag record.
Level backtest
pipeline/level.py backtest: rebuilds the numbers in section 06 from the same tables, including the per-move rows behind them.
Percentiles
Every percentile on the site is printed with its cohort size. If a cohort looks too small to you, it is stated rather than hidden, and below ten it is not published at all.
Contradictions
If a number on this site disagrees with something you can verify, tell us and we will publish the correction here rather than quietly change it. info@latentscouting.com

Commission a report The flag ledger