Closing line value (CLV) calculator
Closing line value (CLV) is how much better your price was than the market's last price before kick-off:
your decimal odds / closing decimal odds − 1. Measure it against Pinnacle's closing line with the
vig taken out, ideally by the power method. A bet at 1.55 on an outcome that closes at a fair 1.4678 has a CLV of
+5.6 %. Beating the close over hundreds of bets is the most reliable sign that your prices are good.
1. CLV calculator
Enter the odds you took, then Pinnacle's closing prices for every outcome of the same market, and pick the one
you bet. American (-238, +655) or decimal (1.55) both work. It runs in
your browser; nothing is sent anywhere.
The default prices are a real Premier League moneyline at the close, the one worked through below. The fair row is the one to keep: the next sections say why.
2. What closing line value is
A price changes from the moment it opens until the match starts, as money and information come in. The last price before kick-off, the closing line, has absorbed all of it, so it is the best public estimate of each outcome's chance. If you took a better price than the close, you bought the outcome cheaper than the market finally valued it. That difference is your CLV.
CLV = your decimal odds / closing decimal odds − 1
Measured against the fair closing price, CLV is also your expected return if the close is right:
1.55 / 1.4678 − 1 is the same as 1.55 × 68.13 % − 1, +5.6 % per unit staked.
Results take thousands of bets to separate skill from luck. CLV says something from the first hundred, because it does not depend on who won.
3. Why Pinnacle's closing line
- Low margins and high limits. Pinnacle takes large bets from sharp bettors instead of limiting them, so their money moves its prices to where they should be.
- The benchmark everyone uses. Betting models, syndicates and research on market efficiency measure against Pinnacle's close; a soft bookmaker's close mostly tells you about its own margin.
- Every market, not only the main line. Totals, spreads, team totals and periods each have a close, so you can measure a bet on any of them against its own market.
4. Take the vig out of the close first
The raw closing price includes Pinnacle's margin, so every bet looks better against it than it is. Take the margin out, and do it by the power method on lopsided and three-way markets. Three bets on Arsenal v Chelsea, against the same close (−238, +655, +318; the columns are raw, no-vig and fair):
| Bet | Close: raw · no-vig · fair | CLV raw | CLV no-vig | CLV fair |
|---|---|---|---|---|
| Arsenal at 1.55 | 1.4202 · 1.5279 · 1.4678 | +9.14 % | +1.45 % | +5.60 % |
| Chelsea at 8.50 | 7.5500 · 8.1225 · 9.1293 | +12.58 % | +4.65 % | −6.89 % |
| Draw at 4.60 | 4.1800 · 4.4970 · 4.7813 | +10.05 % | +2.29 % | −3.79 % |
Against the raw close all three look like winners. Against the fair close only the favourite is: Chelsea at 8.50 is a long shot, and long shots carry more of the margin than the multiplicative no-vig takes off them. How the two methods differ is in Pinnacle no-vig odds.
5. Reading your CLV
- Average it over many bets. One bet's CLV is noise; the mean over a few hundred, with its spread, is the signal. Weight it by stake if your stakes vary.
- Compare like with like. Same market and same line: a bet on over 2.5 is measured against the closing over 2.5, not against a main line that moved to 2.75.
- Live bets too. A bet in play can be compared with the pre-match close of the same market, but the match has changed since: read it as a guide, not as a proof.
- CLV is not profit. Fees, limits, the spread on an exchange and stakes you could not get all come out of it.
6. Measure CLV in Python
With an OddsPush key, fetch the closing line of each match you bet on and compare. The close already carries the fair price of every outcome:
import json
import os
import urllib.request
BASE = "https://feed.oddspush.com/v1"
KEY = os.environ["ODDSPUSH_KEY"]
def closing_line(event_id: int) -> dict:
"""The closing line of a match, by its pre-match or its live event id."""
req = urllib.request.Request(f"{BASE}/closing/{event_id}", headers={"x-token": KEY})
with urllib.request.urlopen(req, timeout=10) as r:
return json.loads(r.read())
def clv(my_decimal: float, close: dict, key: str, designation: str) -> float | None:
"""CLV of a bet against the fair closing price: +0.05 is 5 % better than the close."""
for m in close["markets"]:
if m["key"] == key:
for leg in m["prices"]:
if leg["designation"] == designation:
return my_decimal / leg["fair_decimal"] - 1
return None # that market or line was not open at the close
# My bets: (event id, market key, outcome, decimal odds I took)
bets = [(1638780974, "s;0;m", "home", 1.55)]
for event_id, key, outcome, odds in bets:
value = clv(odds, closing_line(event_id), key, outcome)
print(event_id, key, outcome, "n/a" if value is None else f"{value:+.2%}")
1638780974 s;0;m home +5.60%
Market keys are the same before and during the match (s;0;m is the full-time moneyline,
s;0;ou;2.5 the 2.5 total), and you can look a close up by the pre-match or the live event id.
7. Pinnacle closing lines by API
OddsPush keeps Pinnacle's closing line of every match with pre-match prices, taken when the match really starts, with the no-vig and fair price of every open market. On the stream, turn it on once and each close arrives as its match kicks off:
{"type": "subscribe", "closing": true}
{
"type": "closing",
"data": {
"event_id": 1638780901,
"sport_id": 1,
"league": "England - Premier League",
"home": "Arsenal",
"away": "Chelsea",
"start_time": "2026-10-31T15:00:00Z",
"closed_ts": 1793458723075,
"reason": "live",
"live_event_id": 1638780974,
"markets": [
{
"key": "s;0;m",
"type": "moneyline",
"period": 0,
"version": 3772905262,
"isAlternate": false,
"margin": 0.075827,
"prices": [
{
"designation": "home",
"price": -238,
"no_vig": 0.654512,
"fair": 0.681313,
"no_vig_decimal": 1.5279,
"fair_decimal": 1.4678
},
{
"designation": "away",
"price": 655,
"no_vig": 0.123115,
"fair": 0.109537,
"no_vig_decimal": 8.1225,
"fair_decimal": 9.1293
},
{
"designation": "draw",
"price": 318,
"no_vig": 0.222373,
"fair": 0.20915,
"no_vig_decimal": 4.497,
"fair_decimal": 4.7813
}
]
}
]
}
}
Over REST, by event id, for 7 days after the start:
curl -H "x-token: $ODDSPUSH_KEY" "https://feed.oddspush.com/v1/closing/1638780974"
Every field, and the list of matches with a close (/v1/closing?sport_id=1), is in
the closing reference.
Pinnacle's closing line for every match
The free trial gives you REST and the live stream, with closing lines and no-vig and fair odds, all 13 sports, for 7 days. No card.
OddsPush is not affiliated with, endorsed by or sponsored by Pinnacle. This page explains a calculation; it is not betting or investment advice.