Simple backtesting framework for trading strategies
Project description
Simple Backtest
A high-performance, asset-agnostic backtesting framework for Python
Features • Installation • Quick Start • Data Loaders • Documentation
📖 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:
CSVLoaderYFinanceLoaderCCXTLoaderAlphaVantageLoaderPolygonLoader
📦 Installation
Core package
pip install simple-backtest
Optional loader dependencies
Install only what you use:
# Yahoo Finance
pip install yfinance
# Crypto exchange data
pip install ccxt
# REST API loaders (Alpha Vantage, Polygon)
pip install requests
Development setup
git clone <your-repository-url>
cd simple-backtest
pip install -e ".[dev]"
Requirements: Python 3.10+
🚀 Quick Start
Backtest from any OHLCV DataFrame
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
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
startandend
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
from simple_backtest import YFinanceLoader
data = YFinanceLoader().load("AAPL", "2020-01-01", "2023-12-31")
CCXTLoader
- Uses
ccxtexchange clients - Supports constructor args:
exchange_name, optionalapi_key,api_secret - Converts millisecond timestamps to
DatetimeIndex - Auto-paginates OHLCV fetches for larger ranges
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/endfiltering post-load
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_urlpagination - Parses
o/h/l/c/v/tfields into standardized OHLCV DataFrame
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
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
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
GridSearchOptimizerRandomSearchOptimizerWalkForwardOptimizer
📓 Notebooks
Jupyter examples are available in the notebooks folder:
01_basic_usage.ipynb02_candle_strategies.ipynb03_ta_strategies.ipynb04_ml_strategies.ipynb05_commission_usage.ipynb06_advanced_optimization.ipynb
🛠️ Development
Run tests
pytest
Run linting
ruff check simple_backtest tests
Format
ruff format simple_backtest tests
🤝 Contributing
Contributions are welcome.
- Fork repository
- Create branch
- Add tests for changes
- Run
pytestandruff check - Open pull request
📄 License
MIT. See LICENSE.
📬 Support
- Issues: Use your repository issue tracker
- Discussions: Use your repository discussions page
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simple_backtest_kankane-0.3.2.tar.gz.
File metadata
- Download URL: simple_backtest_kankane-0.3.2.tar.gz
- Upload date:
- Size: 49.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8995e65b7603804da37022394b3e74f15880aeedf14ffea790c0bc1526cbb32
|
|
| MD5 |
9496cfe21883a4b4669388810b46dcd0
|
|
| BLAKE2b-256 |
c62c3aa4ef856b415ea0d697dec022b9f0ae728e32392a888aee4594b4bb19c1
|
File details
Details for the file simple_backtest_kankane-0.3.2-py3-none-any.whl.
File metadata
- Download URL: simple_backtest_kankane-0.3.2-py3-none-any.whl
- Upload date:
- Size: 62.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b142f8feac15d57b7c6a9b77d66415a773fb53caeb40f4e5152e5e63ee8d0ca3
|
|
| MD5 |
9d0d96a622f60943221c63435919f905
|
|
| BLAKE2b-256 |
fe5403a61b904c8a4523b8ed8bb707fdaa0147a35636004effcdeecef21bc79a
|