Skip to main content

nba-edge

Repo: nba-ratings · Package: nba-edge

CI License: MIT

Reusable Elo, win-probability, and Kelly-sizing primitives for NBA-style models.

Why This Repo Matters

This is the library layer of the sports ML stack:

  • reusable rating logic instead of notebook snippets
  • portable win-probability helpers for downstream services
  • Kelly and implied-probability helpers for decision support
  • small, dependency-light package design

Pairs well with nba-clv-dashboard for evaluation UI. Employer one-pager: case study.

What It Includes

  • Elo updates, including a margin-of-victory-weighted variant
  • Logistic win probability
  • Kelly fraction sizing & multi-leg parlay sizing
  • Bidirectional odds format conversions (American, Decimal, Implied Probability)
  • Bookmaker vig-removal tools (Proportional and Equal Margin methods)
  • Model evaluation metrics (Brier Score, Log Loss)

Install

pip install -e .  # local; not yet on PyPI

The library has zero runtime dependencies (see pyproject.toml). The root-level requirements.txt is unrelated to the library — it only exists so Streamlit Community Cloud can find the demo app's dependencies (demo/requirements.txt, i.e. streamlit + pandas).

Example

from nba_edge import (
    logistic_win_prob,
    update_elo,
    kelly_fraction,
    american_to_decimal,
    american_to_implied_prob,
    remove_vig,
    parlay_odds,
    kelly_parlay,
    brier_score,
    log_loss,
)

# 1. Ratings & win probability
p = logistic_win_prob(rating_diff=120)
new_h, new_a = update_elo(1600, 1580, 1.0)

# 2. Odds conversions & Vig Removal
dec = american_to_decimal(-110)      # Convert American to Decimal
p_implied = american_to_implied_prob(-110)  # Convert American to Implied Probability
p_fair_h, p_fair_a = remove_vig(-110, -110, method="proportional")  # Remove vig

# 3. Bet sizing & Parlays
stake = kelly_fraction(p, -110, fraction=0.25)
# Compute combined parlay odds/joint probability for independent legs
parlay = parlay_odds([-110, +130])
# Parlay Kelly sizing (fraction = 0.25 for quarter-Kelly)
parlay_stake = kelly_parlay([0.60, 0.55], [-110, +130], fraction=0.25)

# 4. Model evaluation
predictions = [0.75, 0.40, 0.65]
outcomes = [1.0, 0.0, 1.0]
bs = brier_score(predictions, outcomes)
ll = log_loss(predictions, outcomes)

Margin-of-victory Elo

Plain Elo treats every win the same, but a 30-point blowout is a stronger signal than a 2-point nail-biter. update_elo_with_margin applies a FiveThirtyEight-style multiplier so ratings move further on lopsided games and less when a team that was already heavily favored piles on:

from nba_edge import update_elo_with_margin

new_h, new_a = update_elo_with_margin(1600, 1580, 1.0, margin=22)

Publish

pip install build twine
python -m build
twine upload dist/*

Non-goals

  • No bundled NBA database or scrapers
  • Not a tipster product
  • Not a full modeling workflow by itself

CI

pytest + ruff on Python 3.10-3.12.

License

MIT

Metadata

Release files for nba-edge 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nba-edge 0.1.0
File Size Uploaded Provenance
nba_edge-0.1.0.tar.gz 17.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nba-edge 0.1.0
File Interpreter ABI Platform
nba_edge-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 25.6 kB

Release files / nba_edge-0.1.0.tar.gz

Download URL nba_edge-0.1.0.tar.gz
Size 17.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b87ad4da0a3aa40eabcae7afef37c424a37ba94150c3631c74520010f31aa33a
BLAKE2b-256 checksum
How to use checksums
658296124cd1169ec6875f9990515f3dc3f0f9013678ade239b97dc9e0c85678
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / nba_edge-0.1.0-py3-none-any.whl

Download URL nba_edge-0.1.0-py3-none-any.whl
Size 8.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a560f640b7af263e44870b22211040aa1486b40a8835fa1d5df151345fc31810
BLAKE2b-256 checksum
How to use checksums
70f78b5fe78dee0bd2a0d5a879fab106a036de5f6ab8f82d738deeb1bc26072d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for nba-edge 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page