Skip to main content

Simple backtesting framework for trading strategies

Project description

Simple Backtest

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

Python Version License: MIT Code style: ruff Tests

FeaturesInstallationQuick StartData LoadersDocumentation


📖 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

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 (openOpen, etc.)
  • Supports optional date filtering via start and end
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 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
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
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
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

  • GridSearchOptimizer
  • RandomSearchOptimizer
  • WalkForwardOptimizer

📓 Notebooks

Jupyter examples are available in the 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

pytest

Run linting

ruff check simple_backtest tests

Format

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.

📬 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

simple_backtest_kankane-0.3.1.tar.gz (49.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simple_backtest_kankane-0.3.1-py3-none-any.whl (62.1 kB view details)

Uploaded Python 3

File details

Details for the file simple_backtest_kankane-0.3.1.tar.gz.

File metadata

  • Download URL: simple_backtest_kankane-0.3.1.tar.gz
  • Upload date:
  • Size: 49.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for simple_backtest_kankane-0.3.1.tar.gz
Algorithm Hash digest
SHA256 c2bb524c076173895c7d3bc82e701891029e763695b7125f2b70054ba90d30f8
MD5 2a4e649f5788a91a1720a33581ad6075
BLAKE2b-256 1d025b87f27a0dd3edb1ba04dc60f0194ef8d5b4b5a12bd8d944b88b77b52320

See more details on using hashes here.

File details

Details for the file simple_backtest_kankane-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for simple_backtest_kankane-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 940e1a23572bdb695958d6e54c88327cd7c2be8baf1062f00be5b0c8a36669fa
MD5 7e989cc333175a57f801792f2813b6e1
BLAKE2b-256 ae46cdefd2922a377991be40bb93514c74721d11f15078f466855e2d38d2f728

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page