Metadata-Version: 2.5
Name: backtestbuddy
Version: 0.2.0
Summary: Sports-betting backtesting with bankroll simulation and risk metrics
Project-URL: Homepage, https://github.com/Pacman1984/backtestbuddy
Project-URL: Documentation, https://github.com/Pacman1984/backtestbuddy
Project-URL: Repository, https://github.com/Pacman1984/backtestbuddy
Project-URL: Issues, https://github.com/Pacman1984/backtestbuddy/issues
Author: Sebastian Pachl
License-Expression: MIT
License-File: LICENSE
Keywords: backtesting,betting,finance,quantitative-finance,sports-betting,trading
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: nbformat>=5.0.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: pandas>=1.3.0
Requires-Dist: plotly>=5.0.0
Requires-Dist: scikit-learn>=1.0.0
Provides-Extra: all
Requires-Dist: black>=23.0; extra == 'all'
Requires-Dist: flake8>=6.0; extra == 'all'
Requires-Dist: ipykernel>=6.0.0; extra == 'all'
Requires-Dist: isort>=5.12; extra == 'all'
Requires-Dist: jupyter>=1.0.0; extra == 'all'
Requires-Dist: mkdocs-awesome-pages-plugin>=2.9.0; extra == 'all'
Requires-Dist: mkdocs-material>=9.0; extra == 'all'
Requires-Dist: mkdocs>=1.5.0; extra == 'all'
Requires-Dist: mypy>=1.0; extra == 'all'
Requires-Dist: pytest-cov>=4.0; extra == 'all'
Requires-Dist: pytest>=7.0; extra == 'all'
Requires-Dist: ruff>=0.1.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: flake8>=6.0; extra == 'dev'
Requires-Dist: ipykernel>=6.0.0; extra == 'dev'
Requires-Dist: isort>=5.12; extra == 'dev'
Requires-Dist: jupyter>=1.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-awesome-pages-plugin>=2.9.0; extra == 'docs'
Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
Provides-Extra: test
Requires-Dist: pytest-cov>=4.0; extra == 'test'
Requires-Dist: pytest>=7.0; extra == 'test'
Description-Content-Type: text/markdown

# BacktestBuddy

[![Tests](https://github.com/Pacman1984/backtestbuddy/actions/workflows/tests.yml/badge.svg)](https://github.com/Pacman1984/backtestbuddy/actions/workflows/tests.yml)

Backtest sports-betting strategies in Python: a sequential bankroll simulation over your historical odds, with staking strategies, risk metrics, closing line value, and interactive Plotly charts.

Works with any data source: you pass a pandas DataFrame and tell BacktestBuddy which columns hold the odds, the outcome, the date, and your model output.

**Python >= 3.9 · MIT license**

## Features

- **Two ways to backtest**: `PredictionBacktest` for predictions you already have, `ModelBacktest` to train an sklearn-style model walk-forward.
- **Strategies**: fixed stake, Kelly criterion, value betting, unit staking, odds-band filter.
- **Metrics**: ROI, Yield, CAGR, Sharpe, Sortino, Calmar, drawdown, calibration (Brier, log loss, ECE), and a market baseline.
- **Closing line value**: compare the odds you took with any later or sharper line.
- **Margin removal**: multiplicative, additive, power, and Shin methods.
- **Odds stress test**: re-run with 1%, 2%, 3% worse odds to see how robust the edge is.
- **Charts**: bankroll and drawdown, reliability diagram, odds distribution.

## Installation

```bash
pip install backtestbuddy
```

## Quick example

```python
import numpy as np
import pandas as pd
import backtestbuddy as btb

# One row per match: date, decimal odds per outcome, actual outcome (0-based), model output
rng = np.random.default_rng(0)
n = 500
p_home = rng.uniform(0.3, 0.7, n)
data = pd.DataFrame({
    "date": pd.date_range("2023-01-01", periods=n, freq="D"),
    "odds_home": np.round(0.95 / p_home, 2),
    "odds_away": np.round(0.95 / (1 - p_home), 2),
    "winner": (rng.uniform(size=n) > p_home).astype(int),  # 0 = home, 1 = away
})
model_p = np.clip(p_home + rng.normal(0, 0.05, n), 0.01, 0.99)
data["prob_home"] = model_p
data["prob_away"] = 1 - model_p
data["prediction"] = (model_p < 0.5).astype(int)

backtest = btb.PredictionBacktest(
    data=data,
    odds_columns=["odds_home", "odds_away"],
    outcome_column="winner",
    date_column="date",
    prediction_column="prediction",
    model_prob_columns=["prob_home", "prob_away"],
    strategy=btb.KellyCriterion(downscaling=0.5),
    initial_bankroll=1000,
)
backtest.run()

metrics = backtest.calculate_metrics()
print(metrics["ROI [%]"], metrics["Yield [%]"], metrics["Max Drawdown [%]"])
# This toy model is only noise around the true odds, so the 5% margin wins: expect a loss.
backtest.plot()  # interactive Plotly chart
```

## Documentation

- [Getting Started](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/getting-started.md): data format and a first backtest, step by step
- [Core Concepts](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/core-concepts.md): how the simulation works
- [Backtest Module](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/backtest-module.md): classes, parameters, results columns, stress test
- [Strategies Module](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/strategies-module.md)
- [Metrics Module](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/metrics-module.md): every metric with its formula
- [Odds Module](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/odds-module.md): margin removal
- [Plots Module](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/plots-module.md)
- [Examples](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/examples.md)
- [Changelog](https://github.com/Pacman1984/backtestbuddy/blob/master/docs/changelog.md)

Browse the docs locally with `pip install backtestbuddy[docs]` and `mkdocs serve`.

## Development

The project uses [uv](https://docs.astral.sh/uv/). From a clone of the repository:

```bash
uv run --extra test pytest          # full test suite, including every docs example
uv run --extra docs mkdocs serve    # docs at http://127.0.0.1:8000
```

GitHub Actions runs the tests on Python 3.9 to 3.13 and builds the docs for every pull request.
