Behavioral Model Interactive
Anchoring Effects
People rely too heavily on the first piece of information they see. Opening lines, season averages, and round numbers all create anchoring biases.
โ The Anchoring Bias
How It Works
- 1. Person sees initial value (anchor)
- 2. They adjust from the anchor toward their estimate
- 3. Adjustment is typically insufficient
- 4. Final estimate is biased toward anchor
Famous Study
Tversky & Kahneman (1974): Spun a wheel showing 10 or 65, then asked "What % of African countries are in the UN?"
- โข Anchor of 10 โ average guess: 25%
- โข Anchor of 65 โ average guess: 45%
- โข Random anchor still affected judgment!
Player Props Example
15 35
15 35
0.1 0.8
Lower adjustment = stronger anchoring bias
๐ Bias Analysis
True Value 25
Anchor 30
Public Estimate 28.0
Mispricing +3.0 pts
Anchoring Visualization
True: 25
Anchor: 30
Public: 28.0
15
35
Public estimate is pulled toward the anchor, creating exploitable bias.
Opening Line Anchoring
18 28
18 28
Opening
23.5
Public Expects
23.1
True Value
22
Line opened too high. Public still anchors high โ take UNDER.
๐ฏ Common Anchoring Points
Opening Line
Public doesn't adjust enough from opener
Edge: Fade line movement in wrong direction
Season Average
Ignores recent context/matchup
Edge: Value in contextual adjustments
Last Game
Overweight recent performance
Edge: Fade outliers (regression)
Round Numbers
Cluster bets at 25, 30, etc.
Edge: Value at 24.5, 30.5
๐ฐ Pricing Implications
For Line Setting
- โ Opening line sets the public's anchor
- โ Even if you move the line, public adjusts slowly
- โ Strategic opener can capture value
For Finding Edge
- โ Look for lines that opened wrong
- โ Fade insufficient adjustments
- โ Value often at non-round numbers
R Code Equivalent
# Anchoring model
estimate_with_anchor <- function(anchor, true_value, adjustment = 0.4) {
# People start at anchor and adjust toward true value
# But adjustment is typically insufficient
public_estimate <- anchor - (anchor - true_value) * adjustment
mispricing <- public_estimate - true_value
list(
anchor = anchor,
true_value = true_value,
public_estimate = public_estimate,
mispricing = mispricing
)
}
# Example
result <- estimate_with_anchor(30, 25, 0.4)
cat(sprintf("Anchor: %.1f, True: %.1f\n", result$anchor, result$true_value))
cat(sprintf("Public estimate: %.1f\n", result$public_estimate))
cat(sprintf("Mispricing: %+.1f pts\n", result$mispricing))โ Key Takeaways
- โข People anchor on first information seen
- โข Adjustment from anchor is insufficient
- โข Opening lines, season averages are common anchors
- โข Creates exploitable mispricing
- โข Fade lines that opened wrong
- โข Value at non-round numbers (24.5 vs 25)