Skip to content

Calibration

Calibration fits a Dixon-Coles model to live market quotes, recovering the underlying \(\lambda_{\text{home}}\) and \(\lambda_{\text{away}}\) parameters.

How It Works

Given a Total Goals quote and an Asian Handicap quote, DixonColes.calibrate() uses two-step root-finding (scipy root_scalar) to find the \(\lambda\) values that reproduce the market-implied probabilities.

Example

from pyrf.market import Quote, Market
from pyrf.models import DixonColes

# Market quotes
tg_quote = Quote.build(
    market=Market.TOTAL_GOAL,
    line=2.5,
    over_odds=1.90,
    under_odds=2.00,
)

ah_quote = Quote.build(
    market=Market.ASIAN_HCAP,
    line=-0.5,
    over_odds=1.85,
    under_odds=2.05,
)

# Calibrate
model = DixonColes.calibrate(
    tg_quote=tg_quote,
    ah_quote=ah_quote,
    rho=-0.10,
)

print(f"Home λ: {model.lambda_home:.3f}")
print(f"Away λ: {model.lambda_away:.3f}")

The Calibration Pipeline

Market Quotes → margin_strip() → implied_prob() → root_scalar() → DixonColes(λ_home, λ_away, ρ)
  1. Strip bookmaker margins from both quotes
  2. Extract fair implied probabilities
  3. Solve for \(\lambda\) values that match those probabilities under the Dixon-Coles model

Choosing \(\rho\)

The dependence parameter \(\rho\) is typically fixed rather than calibrated from two quotes (there aren't enough degrees of freedom). Common choices:

  • \(\rho = -0.10\) — the RingfinityModelZero default
  • Estimate from historical data using maximum likelihood