Metadata-Version: 2.4
Name: simple-backtest-kankane
Version: 0.3.2
Summary: Simple backtesting framework for trading strategies
Author-email: Raghav Kankane <raghavkankane07@gmail.com>
License: MIT
Keywords: backtesting,trading,finance,algorithmic-trading
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=2.0.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: plotly>=5.14.0
Requires-Dist: joblib>=1.3.0
Requires-Dist: tqdm>=4.65.0
Requires-Dist: scipy>=1.11.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: jupyter>=1.0.0; extra == "dev"
Requires-Dist: matplotlib>=3.7.0; extra == "dev"
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
Provides-Extra: data
Requires-Dist: yfinance>=0.2.0; extra == "data"
Requires-Dist: ccxt>=4.0.0; extra == "data"
Requires-Dist: requests>=2.28.0; extra == "data"
Dynamic: license-file

<div align="center">

# Simple Backtest

**A high-performance, asset-agnostic backtesting framework for Python**

[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
[![Tests](https://img.shields.io/badge/tests-268%20passed-success.svg)](#)

[Features](#-features) • [Installation](#-installation) • [Quick Start](#-quick-start) • [Data Loaders](#-data-loaders) • [Documentation](#-documentation)

</div>

---

## 📖 About

Simple Backtest provides a clean framework for running strategy backtests with strong validation, robust metrics, and extensible architecture.

You can still bring your own pandas DataFrame, but the project now also includes **optional data source integrations** so users can load and normalize OHLCV data faster.

## ✨ Features

- **Backtesting Engine**: Fast, deterministic strategy execution
- **Validation First**: Actionable errors for data, config, and strategy inputs
- **Asset-Agnostic Design**: Works with stocks, forex, crypto, ETFs, and more
- **20+ Metrics**: Return, drawdown, Sharpe, Sortino, Calmar, alpha/beta, etc.
- **Optimization**: Grid search, random search, walk-forward
- **Optional Data Integrations**:
  - `CSVLoader`
  - `YFinanceLoader`
  - `CCXTLoader`
  - `AlphaVantageLoader`
  - `PolygonLoader`

## 📦 Installation

### Core package

```bash
pip install simple-backtest
```

### Optional loader dependencies

Install only what you use:

```bash
# Yahoo Finance
pip install yfinance

# Crypto exchange data
pip install ccxt

# REST API loaders (Alpha Vantage, Polygon)
pip install requests
```

### Development setup

```bash
git clone <your-repository-url>
cd simple-backtest
pip install -e ".[dev]"
```

**Requirements**: Python 3.10+

## 🚀 Quick Start

### Backtest from any OHLCV DataFrame

```python
from simple_backtest import Backtest, BacktestConfig, MovingAverageStrategy

# data must contain: Open, High, Low, Close (Volume optional unless configured)
strategy = MovingAverageStrategy(short_window=10, long_window=30, shares=10)
config = BacktestConfig.default(initial_capital=10000)

backtest = Backtest(data, config)
results = backtest.run([strategy])

print(results.get_strategy(strategy.get_name()).summary())
```

### Backtest using built-in CSV loader

```python
from simple_backtest import Backtest, BacktestConfig, CSVLoader, MovingAverageStrategy

loader = CSVLoader()
data = loader.load("data/aapl.csv", start="2020-01-01", end="2023-12-31")

backtest = Backtest(data, BacktestConfig.default(initial_capital=10000))
results = backtest.run([MovingAverageStrategy(short_window=10, long_window=30, shares=10)])
```

## 🔌 Data Loaders

All loaders inherit from `DataLoader` and return a validated DataFrame with standardized columns:

`Open`, `High`, `Low`, `Close`, `Volume`

Validation is always run internally before the DataFrame is returned.

### `CSVLoader`

- Reads local CSV files
- Auto-detects date column (`Date`, `date`, `Datetime`, `datetime`, or datetime index)
- Normalizes common column variants (`open` → `Open`, etc.)
- Supports optional date filtering via `start` and `end`

```python
from simple_backtest import CSVLoader

data = CSVLoader().load("prices.csv", start="2021-01-01", end="2021-12-31")
```

### `YFinanceLoader`

- Uses `yfinance.download(...)`
- Handles yfinance MultiIndex column outputs
- Raises clear import/data errors

```python
from simple_backtest import YFinanceLoader

data = YFinanceLoader().load("AAPL", "2020-01-01", "2023-12-31")
```

### `CCXTLoader`

- Uses `ccxt` exchange clients
- Supports constructor args: `exchange_name`, optional `api_key`, `api_secret`
- Converts millisecond timestamps to `DatetimeIndex`
- Auto-paginates OHLCV fetches for larger ranges

```python
from simple_backtest import CCXTLoader

loader = CCXTLoader(exchange_name="binance")
data = loader.load("BTC/USDT", "2021-01-01", "2021-12-31", timeframe="1d")
```

### `AlphaVantageLoader`

- Uses Alpha Vantage daily REST endpoint
- Constructor requires `api_key`
- Parses API JSON into standardized OHLCV DataFrame
- Applies `start` / `end` filtering post-load

```python
from simple_backtest import AlphaVantageLoader

loader = AlphaVantageLoader(api_key="YOUR_KEY")
data = loader.load("AAPL", "2020-01-01", "2023-12-31")
```

### `PolygonLoader`

- Uses Polygon aggregates REST endpoint
- Constructor requires `api_key`
- Handles `next_url` pagination
- Parses `o/h/l/c/v/t` fields into standardized OHLCV DataFrame

```python
from simple_backtest import PolygonLoader

loader = PolygonLoader(api_key="YOUR_KEY")
data = loader.load("AAPL", "2020-01-01", "2023-12-31", timespan="day", multiplier=1)
```

### Create your own loader

```python
import pandas as pd
from simple_backtest import DataLoader


class MyCustomLoader(DataLoader):
    def load(self, symbol, start, end) -> pd.DataFrame:
        # fetch/construct your data
        data = pd.DataFrame(...)
        return self._finalize_dataframe(data)
```

## 📚 Documentation

### Built-in strategy helpers

When writing a custom strategy (subclass of `Strategy`), you can use:

- `self.has_position()`
- `self.get_position()`
- `self.get_cash()`
- `self.get_portfolio_value()`
- `self.buy(shares)`
- `self.sell(shares)`
- `self.sell_all()`
- `self.hold()`
- `self.buy_percent(percent)`
- `self.buy_cash(amount)`

### Config presets

```python
from simple_backtest import BacktestConfig

config = BacktestConfig.default(initial_capital=10000)
config_zero_fees = BacktestConfig.zero_commission(initial_capital=10000)
config_hft = BacktestConfig.high_frequency(initial_capital=100000)
config_swing = BacktestConfig.swing_trading(initial_capital=10000)
```

### Optimizers

- `GridSearchOptimizer`
- `RandomSearchOptimizer`
- `WalkForwardOptimizer`

## 📓 Notebooks

Jupyter examples are available in the [notebooks](notebooks) folder:

- `01_basic_usage.ipynb`
- `02_candle_strategies.ipynb`
- `03_ta_strategies.ipynb`
- `04_ml_strategies.ipynb`
- `05_commission_usage.ipynb`
- `06_advanced_optimization.ipynb`

## 🛠️ Development

### Run tests

```bash
pytest
```

### Run linting

```bash
ruff check simple_backtest tests
```

### Format

```bash
ruff format simple_backtest tests
```

## 🤝 Contributing

Contributions are welcome.

1. Fork repository
2. Create branch
3. Add tests for changes
4. Run `pytest` and `ruff check`
5. Open pull request

## 📄 License

MIT. See [LICENSE](LICENSE).

## 📬 Support

- Issues: Use your repository issue tracker
- Discussions: Use your repository discussions page
