Method · what the code actually maximises
How a letter is chosen
Expected points from a match simulation, then a mixed-integer programme under FPL’s constraints. The same mathematics that writes the weekly email, in prose.
Contents: the loop · minutes · the match draw · markets · the MIP · transfers & hits · chips · worked example · limits · questions
01
The loop
Once, for the whole league: pull the public FPL player list and fixtures, estimate minutes and per-90 rates, simulate every player’s next five gameweeks, cache a table of means and variances.
Then, for you: read the public entry (current 15, bank, chips used, transfer history for sell prices). Solve the squad. Render the letter. Nothing is posted back to FPL.
The daily job only sends when a deadline is within 60 hours, or when you force a run.
02
Minutes
Appearance points sit on the 60-minute cliff, so minutes are modelled first. Last six matches are exponentially weighted with half-life 3. That produces P(start), P(cameo), and expected minutes in each bucket. Injured / suspended / unavailable goes to zero. “Doubtful” is scaled by FPL’s published chance of playing next round.
Summer signings keep last season’s minutes only as a weak prior. A 27-minute outing stays in the cameo bucket; eighty minutes is a start.
03
The match draw
Attacking rates (xG/90, xA/90) are shrunk toward a position prior:
Fixture strength uses FPL’s own attack/defence ratings, home/away, and FDR. Set-piece roles (penalties, corners, direct free kicks) are layered on and a typical penalty xG is stripped from stayers so pens are not counted twice. Missed penalties are −2 in the same draw. Bonus is crude: 0.3 × (goals + assists) inside the draw.
Every player in a fixture shares one scoreline. Home and away goals are Poisson with team λ. If your team’s goals come up 0, that player’s goals and assists in that world are zeroed. Clean sheet requires opponent 0 and ≥60 minutes. Goalkeepers and defenders lose a point per two conceded on that same draw.
Linearity of expectation still holds: three Arsenal defenders have three times the clean-sheet points in the mean. What the shared draw forbids is a world where Arsenal keep a clean sheet and Saka also scored.
04
Markets
For EPL fixtures with a liquid Polymarket regular-time team-total Over/Under 0.5, Under is P(that side scores 0). Opponent clean sheet is the other team’s blank. Prices that sum past 1.00 are de-vigged. First-half lines are ignored.
Over 1.5 / 2.5 is not read. A 4–0 is whatever this Poisson λ implies, plus FPL’s −1 per two conceded. Later gameweeks with no book stay on FPL xGC until the market lists them.
05
The fifteen and the eleven
PuLP + CBC. Binary own / start / captain variables. Constraints are the game: 2 GK, 5 DEF, 5 MID, 3 FWD; max three per club; exactly one starting keeper; at least three defenders, two midfielders, one forward; budget in tenths of a million.
XI and captain are re-picked each of the next five gameweeks inside the solver. The email’s (C) and (V) are then overwritten to this gameweek’s highest-μ starters. The MIP may have used mean-variance to decide who to own; the armband on the letter is who you should actually click.
Anyone with P(play) < 0.55 cannot start. A fifth starting defender costs 1.2 xP per week in the objective; a one-forward XI costs 0.8. Bench is worth 0.1 × their μ, which also gives Bench Boost something to look at.
The square-root mean-SD utility from textbooks is replaced by a linear penalty on variance so the programme stays a MIP. Captain variance is tripled (captain points are an extra copy of the player, so variance scales by 1+3=4 on that extra). The code uses 3 × σ² on the captain variable plus 1 × on the start variable.
06
Transfers, hits, unused frees
The solver is run at T = 0, 1, and 2 relative to your current fifteen. After that:
A hit is rejected unless the three-gameweek XI gain versus rolling beats 4 plus a 1.0 margin. Incoming outfielders must start this gameweek (backup keeper excepted). If the “best” T=2 is Wharton to the bench, that plan is delayed: next week’s free transfer can still fetch him after results.
Wildcard rebuilds the 15 at current sell-plus-bank. Free Hit rebuilds this week only, then reverts. Neither is played just because the MIP gap is pretty. See chips.
07
Chips as stopping problems
Triple Captain extra value this week is the captain’s μ. Bench Boost is the sum of bench μ. Play now if that beats the expected best remaining week, estimated by Monte Carlo with noise and a prior that a double gameweek is still coming (until fixtures confirm). Epsilon 0.5 points so the letter does not flip on a knife-edge.
Wildcard and Free Hit: the MIP gap is shrunk while this season is still a small sample (GW2 is one result). The first n/e usable weeks of each half are for looking, unless the trusted gap is an outlier. After that, play if the trusted gap beats the expected best remaining swing. Unused chips get cheaper to fire in the last three gameweeks of GW19 and GW38. One chip per week: if Wildcard or Free Hit is the move, Triple Captain and Bench Boost stay in the packet.
08
Worked example
Why Cherki → Ndiaye on one free transfer with £1.5m left in the bank.
| Fact | What the programme does with it |
|---|---|
| Cherki played 27 minutes | Cameo bucket. Five-week μ is minutes-starved. |
| Ndiaye modelled as a 90-minute mid | Appearance points plus a full rate × minutes. |
| T = 1, F = 1 | Hit 0. Unused FT bonus 0 because the free transfer is spent. |
| £1.5m left in the bank | Does not increase the objective. Spending it on a worse mid would lose. |
| Wharton would not start this GW | That incoming is illegal for this letter. Delayed. |
| Fernandes μ > Szoboszlai μ this GW | Armband on Fernandes even if Szoboszlai wins the five-week table. |
09
Limits
Variance in the MIP still adds player σ² as if they were independent. The shared scoreline is in each player’s own μ and σ². Clean-sheet points already sit in those means; the optimiser does not add a covariance bonus for stacking a back line.
Two midfielders can still both be credited with a goal when the team only scored one. Price changes are left to FPL. Mid-week unpublished squads are invisible until the next deadline publishes picks. Team strength uses FPL’s attack and defence ratings. Sell prices follow the public transfer history and the usual half-profit rule.
If Polymarket is down, FPL λ is used and the run continues. The letter will say when team totals were blended.
10
Questions
This page is the public write-up. If you want more detail, a walkthrough of a letter, or to argue with a call, write to support@fpl-manager.com.