Closing Line Value (CLV)¶
Summary¶
Closing line value (CLV) is the difference between the odds a bettor locked in when placing a bet and the final odds the sportsbook offered right before the game started. It is one of the most important validation metrics for sports betting models because the closing line is widely considered the most efficient market price — it incorporates all available information up to game time.
If a bettor consistently gets better odds than the closing line (positive CLV), it indicates their pre-game predictions are better than the market consensus. This is a stronger signal of genuine predictive ability than just checking win rates, because even a random bettor can get lucky over a small sample, but consistently beating the closing line requires real information advantage.
CLV is expressed as a percentage or in the same units as the odds (e.g., a bet at 2.10 that closes at 2.00 has positive CLV).
Key Concepts¶
- Closing line: The final odds offered by a sportsbook before an event starts. Considered the "true" market price.
- Pre-game line: The odds when the bet was placed (often hours or days before game time).
- Positive CLV: Betting at better odds than the closing line — indicates the bettor had information or predictive edge the market didn't have at the time of the bet.
- Negative CLV: Betting at worse odds than the closing line — indicates the bettor is typically getting poor timing or the market is more accurate.
- CLV vs. market efficiency: The closing line is not perfect — sharp bookmakers like Pinnacle come closest, but even closing lines reflect public bias (favorite-longshot bias, hometown bias).
- CLV validation in backtesting: Rather than just checking ROI, the client's spec requires checking whether the model consistently beats the closing line. This is a higher standard than just finding +EV bets.
Formulas¶
CLV as percentage:
$$CLV = \frac{odds_{bet} - odds_{close}}{odds_{close}} \times 100\%$$
For decimal odds: a bet at 2.10 closing at 2.00 → CLV = (2.10-2.00)/2.00 = +5%
For American odds:
$$CLV = \frac{american_{bet} - american_{close}}{american_{close}} \times 100\%$$
(Convert American to decimal first: +150 → 2.50, -150 → 1.667)
CLV from implied probabilities:
$$CLV = prob_{model} - prob_{close}$$
Where prob_close = 1/closing_decimal_odds.
Example:
- Model predicts 60% win probability → fair odds = 1/0.60 = 1.667
- Bet placed at 1.75 (57% implied)
- Closing odds = 1.65 (60.6% implied)
- CLV = (1/0.60 - 1/closing_odds) × 100% = (1.667 - 1.538) / 1.538 = +8.4%
Python Implementation¶
def closing_line_value(bet_odds, close_odds):
"""
Calculate CLV from decimal odds.
Args:
bet_odds: Decimal odds when bet was placed
close_odds: Decimal odds at market close
Returns:
CLV as decimal (e.g., 0.05 = 5% better than close)
"""
return (bet_odds - close_odds) / close_odds
def clv_from_probabilities(model_prob, bet_odds, close_odds):
"""
CLV calculation using probabilities.
prob_close = 1/close_odds (implied probability of closing line)
"""
prob_close = 1 / close_odds
return model_prob - prob_close
def evaluate_model_clv(bets_df):
"""
Evaluate model CLV across a set of bets.
bets_df needs: model_prob, bet_odds, close_odds, result
"""
bets_df['clv'] = (bets_df['bet_odds'] - bets_df['close_odds']) / bets_df['close_odds']
bets_df['clv_prob'] = bets_df['model_prob'] - (1 / bets_df['close_odds'])
# Summary stats
mean_clv = bets_df['clv'].mean()
clv_at_winning_bets = bets_df.loc[bets_df['result'] == 1, 'clv'].mean()
clv_at_losing_bets = bets_df.loc[bets_df['result'] == 0, 'clv'].mean()
return {
'mean_clv': mean_clv,
'clv_winners': clv_at_winning_bets,
'clv_losers': clv_at_losing_bets,
'pct_positive_clv': (bets_df['clv'] > 0).mean()
}
# Example
bets = [
{'model_prob': 0.60, 'bet_odds': 1.80, 'close_odds': 1.75, 'result': 1},
{'model_prob': 0.55, 'bet_odds': 2.00, 'close_odds': 2.10, 'result': 0},
{'model_prob': 0.70, 'bet_odds': 1.50, 'close_odds': 1.48, 'result': 1},
]
import pandas as pd
df = pd.DataFrame(bets)
print(evaluate_model_clv(df))
Notes¶
- CLV is a validation tool, not a betting decision tool — you can't know the closing line when placing the bet
- Pinnacle closing lines are considered the gold standard for market efficiency; using their closing lines as the benchmark gives the most reliable CLV estimates
- Favorite-longshot bias: CLV tends to be more reliable for favorites than underdogs; the market is less efficient for longshots but also more volatile
- For World Cup modeling: only 64 matches per tournament, so CLV metrics are noisy. Need multiple tournaments for reliable CLV validation.
- The client explicitly tests for CLV in model validation — this should be a core metric in the backtesting framework