Roman Prigodskii

Work

Vertex MMA

Live product UFC analytics and forecasting, in English and Russian, with virtual currency only.

A nine-model UFC forecasting stack, graded against the bookmaker’s closing line.

AUC on 664 bouts held out from January 2025
0.7244
fighters
4,581
bouts
8,906
events
795
simulations of every bout
10,000
vertexmma.com
A fighter profile: the Vertex Score, every UFC bout on a timeline with its stats on hover, and six attributes on a radar chart. Beside it, the same profile at phone width. Recorded from the live site on 27 September 2026.

The system

The main model picks the winner from 118 features, blending LightGBM, CatBoost and logistic regression, averaged over both orderings of the two fighters. Others handle debuts, how a fight ends and when, and a simulator plays each bout out ten thousand times.

Underneath sit 243,000 score-history rows, 49,000 official ranking snapshots, 86,000 career bouts, 41,000 round-stat rows and 31,000 judge scorecards. The site runs on Next.js and Postgres, with the models in Python.

UFC 332, Natalia Silva against Wang Cong

  1. The probabilitySilva at 62%, 2.7 points below the market’s 64.7%, and the four features behind the call.
  2. 10,000 simulationsHow it ends: a decision 60%, KO or TKO 25%, submission 16%, and the chance of a finish in each round.
  3. The oddsThe model’s prices, 1.55 and 2.53, beside the market’s, 1.49 and 2.75, and a price for each method.

The page for one scheduled bout: the model’s probability beside the market’s, the features behind it, and 10,000 simulated fights. Recorded before UFC 332.

vertexmma.com

Measured against the market

Held out from January 2025. On the 582 bouts with a price, the closing line is ahead on all three scores. The model is better calibrated than the line and less sharp; the rest of the gap is resolution, which needs information the public record does not contain.

The model against the closing line, on the 582 held-out bouts that carry one
MeasureModelClosing line
Accuracy higher is better0.67530.6838
Log-loss lower is better0.61710.5922
Brier lower is better0.21400.2035

On all 664 held-out bouts the model scores 0.6747 accuracy, 0.6137 log-loss, 0.2124 Brier and 0.7244 AUC.

AUC on 664 bouts held out from January 2025

0.7244

What never enters the model

Five separate mechanisms keep future information out of the features: history is snapshotted before it is applied, rating lookups stop strictly before the fight, ratings are replayed in date order on their own, a fighter’s career before the UFC is walked only up to the fight date, and the percentile-clipping anchor is frozen.

vertexmma.com
  1. 53after Thiago Moises17 July 2021
  2. 92after Charles Oliveira22 October 2022
  3. 99after Alexander Volkanovski21 October 2023
  4. 95after Ian Machado Garry15 August 2026
Islam Makhachev’s current Vertex Score, September 2016 to September 2026. Where a bout set the value, the tooltip names it; between bouts the score drifts from month to month.

Bookmaker odds are stored, shown and used to grade the model, but they never enter it: a closing line would be a near-leak in a backtest. Taking them out cost 1.5 points of test accuracy, and they stayed out.

What did not ship

Roughly two dozen ideas were built, tested and rejected, and each is written up in the repository next to the ones that shipped, with the reason. Among them:

  • Official UFC rankings, tried twice
  • Recency weighting
  • Seed bagging
  • Symmetry augmentation
  • A graded outcome label
  • Regional fights as training rows
  • Post-hoc calibration
  • A submission-specific axis

One feature that had shipped was later found to be a leak, and was removed.

The detection floor

Five seeds on a 3,087-bout walk-forward pool put the smallest improvement this pipeline can detect, with 80% power, at 0.00362 nats. The only change ever shipped to the winner model is worth 0.0026, inside that floor. Retraining the same recipe under another random seed produces 0.00207, 80% of it, and the pipeline had 56% power against its own shipped result.

Everything measured on the main pool, against the detection floorChange in out-of-fold log-loss in nats, negative is better, from minus 0.006 to 0.006. The detection floor is plus or minus 0.00362. Ten re-seeds of an unchanged recipe produce effects up to 0.00207. The only change the winner model shipped is worth 0.0026, and the largest re-seed is 80% of it. Every mark lies inside the floor. The arrow keys step through the marks.detection floor, −0.00362+0.00362−0.006−0.004−0.00200.0020.0040.006Ten re-seeds of the same recipe, which change nothingEleven candidate levers from one studyOne lever, read three waysThe only change the winner model shippedlargest, 0.00207a re-seed, 80% of it−0.0026← betterworse →
Everything measured on the main pool, against the detection floorChange in out-of-fold log-loss in nats, negative is better, from minus 0.006 to 0.006. The detection floor is plus or minus 0.00362. Ten re-seeds of an unchanged recipe produce effects up to 0.00207. The only change the winner model shipped is worth 0.0026, and the largest re-seed is 80% of it. Every mark lies inside the floor. The arrow keys step through the marks.detection floor, ±0.00362−0.00400.004Ten re-seeds, which change nothingEleven candidate leversOne lever, read three waysThe only change ever shipped: −0.00260.00207a re-seed: 80% of it← betterworse →
Change in out-of-fold log-loss, in nats, negative is better. The hatched band is what this instrument cannot resolve with 80% power.

The papers it led to

Both of my papers grew out of evaluating this model. The first re-tests 84 hypotheses about where it might beat the market, written down before any of them was scored, as bets at the bookmaker’s own prices. It is under review at a NeurIPS 2026 workshop. The second measures the smallest improvement the model-selection pipeline can detect, and finds that retraining under another random seed reproduces 80% of the only improvement the winner model ever shipped. It is a working paper.

Next.js 16, React 19, TypeScript 5.9 in strict mode, Tailwind 4, Postgres, Python 3.12, LightGBM and CatBoost. 35 routes in two languages, 1,533 translation keys each.