Metadata-Version: 2.4
Name: elo-system
Version: 2.0.1
Summary: Elo rating system for fantasy sports leagues (Fantrax NBA and Sleeper NFL, with multi-season dynasty support).
Author-email: Rohan V <r.vahalia@gmail.com>
License-Expression: MIT
Project-URL: Repository, https://github.com/riders994/eloSystem
Keywords: elo,fantasy,sports,fantrax,sleeper,rating
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Games/Entertainment
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=2.2
Requires-Dist: numpy>=1.26
Requires-Dist: PyYAML>=6.0
Requires-Dist: psycopg2-binary>=2.9
Requires-Dist: rv_pytools>=1.2.1
Requires-Dist: requests>=2.31
Provides-Extra: sleeper
Requires-Dist: sleeper>=2.0; extra == "sleeper"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-mock>=3; extra == "dev"
Requires-Dist: pyflakes>=3; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Dynamic: license-file

# elo-system

An Elo rating system for fantasy sports leagues. It scrapes weekly scoreboards
from a fantasy platform, converts them into per-week Elo ratings, and supports
multi-season **dynasty** ratings with an offseason regression-to-mean
adjustment.

- **Platforms:** Fantrax (NBA, head-to-head categories) and Sleeper (NFL,
  head-to-head points). Sleeper needs its optional extra: `pip install -e
  .[sleeper]`.
- **Scoring:** football is rated against the league median by default
  (`scoring: median`), so a team's week stands or falls on its own score
  rather than on who it was scheduled against; `scoring: default` rates each
  matchup head to head on the two teams' share of the points instead.
- **Outputs:** per-season and combined-dynasty rating frames, written to CSV or
  published to a Postgres star schema. Either backend can serve as the reader
  or the writer, and the two round-trip to the same frames. The schema keeps a
  person (`dim_manager`) separate from the accounts they play under
  (`dim_manager_platform`), so one manager can be in several leagues, on
  several Discord servers, across more than one platform.

## Installation

The project depends on a fork of `fantraxapi` (the PyPI release is broken for
H2H-rotisserie leagues), so it installs from source rather than from PyPI:

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .            # add [dev] for the test/lint tooling
```

`requirements.frozen` holds the exact, reproducible dependency pins (including
the fantraxapi fork commit) used during development.

## Layout

```
elo_system/
  elo_system.py            EloSystem orchestrator (config + reader/writer wiring)
  tools/
    elo_league.py          EloLeague: season management + run/dynasty pipeline
    elo_data.py            EloCSV / EloSQL persistence backends
    basics/                LeagueBase/DataBase, Elo math, config IO, constants
    helpers/               scraper, league, formatter, calculator, frame_manager
```

## Configuration

`resources/configs/` holds one shared config for each backend and one *ratings*
config per league:

```
resources/configs/
  sys_config.yml           reader/writer, and the ratings config of each league
  csv_config.yml           shared: where CSV frames are written
  sql_config.yml           shared: the Postgres connection
  ratings_macho_mandarins.yml  one league
  ratings_die_nasty.yml      another
```

`sys_config.yml` names the leagues, and one `EloSystem` drives one of them:

```yaml
ratings_configs:
  macho_mandarins: ratings_macho_mandarins.yml
  die_nasty: ratings_die_nasty.yml
default_league: macho_mandarins
```

```python
EloSystem('resources/configs/sys_config.yml')                # default_league
EloSystem('resources/configs/sys_config.yml', 'die_nasty') # a named league
```

Each league's CSV frames go in their own subdirectory of the CSV config's
`write_loc`, named for the league key, since the frames are named by season
alone and would otherwise collide:

```
resources/ratings/
  macho_mandarins/2024_season_elo.csv  ...  dynasty_elo.csv
  die_nasty/2022_season_elo.csv  ...  dynasty_elo.csv
```

Override one league's subdirectory with `ratings_dir` in its ratings config.

## Tests

```bash
python -m pytest          # run from the repo root
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for development notes and conventions,
and [CHANGELOG.md](CHANGELOG.md) for release history.
