backtesting.py
:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
Top Related Projects
bt - flexible backtesting for Python
Python Backtesting library for trading strategies
Portfolio analytics for quants, written in Python
Python library for backtesting trading strategies & analyzing financial markets (formerly pythalesians)
Lean Algorithmic Trading Engine by QuantConnect (Python, C#)
An Algorithmic Trading Library for Crypto-Assets in Python
Quick Overview
Backtesting.py is a lightweight, fast, and extensible backtesting framework for Python. It allows users to test and optimize trading strategies using historical data, providing a simple yet powerful API for simulating trading scenarios and analyzing results.
Pros
- Fast and efficient, utilizing vectorized operations for improved performance
- Easy to use with a clean and intuitive API
- Highly customizable and extensible for advanced users
- Supports various data sources and formats
Cons
- Limited built-in indicators compared to some other backtesting libraries
- Lacks some advanced features found in more comprehensive frameworks
- Documentation could be more extensive for complex use cases
- May require additional libraries for certain functionalities (e.g., plotting)
Code Examples
- Basic strategy implementation:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA, GOOG
class SmaCross(Strategy):
def init(self):
price = self.data.Close
self.ma1 = self.I(SMA, price, 10)
self.ma2 = self.I(SMA, price, 20)
def next(self):
if crossover(self.ma1, self.ma2):
self.buy()
elif crossover(self.ma2, self.ma1):
self.sell()
bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002)
stats = bt.run()
bt.plot()
- Using custom indicators:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import GOOG
def RSI(array, n):
# Custom RSI implementation
pass
class RsiStrategy(Strategy):
def init(self):
self.rsi = self.I(RSI, self.data.Close, 14)
def next(self):
if self.rsi[-1] < 30:
self.buy()
elif self.rsi[-1] > 70:
self.sell()
bt = Backtest(GOOG, RsiStrategy, cash=10000)
stats = bt.run()
- Optimizing strategy parameters:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA, GOOG
class SmaCross(Strategy):
def init(self):
price = self.data.Close
self.ma1 = self.I(SMA, price, self.n1)
self.ma2 = self.I(SMA, price, self.n2)
def next(self):
if crossover(self.ma1, self.ma2):
self.buy()
elif crossover(self.ma2, self.ma1):
self.sell()
bt = Backtest(GOOG, SmaCross, cash=10000)
stats = bt.optimize(n1=range(5, 30, 5),
n2=range(10, 70, 5),
maximize='Sharpe Ratio',
constraint=lambda p: p.n1 < p.n2)
Getting Started
To get started with Backtesting.py, follow these steps:
-
Install the library:
pip install backtesting
-
Import required modules and create a strategy:
from backtesting import Backtest, Strategy from backtesting.lib import crossover from backtesting.test import SMA, GOOG class MyStrategy(Strategy): def init(self): # Initialize indicators pass def next(self): # Define trading logic pass bt = Backtest(GOOG, MyStrategy, cash=10000) stats = bt.run() bt.plot()
-
Customize the strategy, run backtests, and analyze results using the provided API and documentation.
Competitor Comparisons
bt - flexible backtesting for Python
Pros of bt
- More flexible and customizable, allowing for complex trading strategies
- Better suited for professional-grade backtesting and portfolio analysis
- Supports multiple assets and portfolio rebalancing
Cons of bt
- Steeper learning curve and more complex API
- Less beginner-friendly documentation
- Slower performance for simple backtests
Code Comparison
bt:
strategy = bt.Strategy('s1', [bt.algos.RunMonthly(),
bt.algos.SelectAll(),
bt.algos.WeighEqually(),
bt.algos.Rebalance()])
backtest = bt.Backtest(strategy, data)
res = bt.run(backtest)
backtesting.py:
class Strategy(bt.Strategy):
def init(self):
self.sma = self.I(ta.SMA, self.data.Close, 20)
def next(self):
if self.data.Close[-1] > self.sma[-1]:
self.buy()
elif self.data.Close[-1] < self.sma[-1]:
self.sell()
bt = Backtest(data, Strategy, cash=10000, commission=.002)
stats = bt.run()
Both libraries offer powerful backtesting capabilities, but they cater to different user needs. bt is more suitable for advanced users and complex strategies, while backtesting.py provides a simpler, more intuitive interface for beginners and straightforward backtests.
Python Backtesting library for trading strategies
Pros of Backtrader
- More extensive documentation and community support
- Greater flexibility and customization options
- Supports a wider range of data feeds and brokers
Cons of Backtrader
- Steeper learning curve due to its complexity
- Slower execution speed compared to Backtesting.py
Code Comparison
Backtrader:
class MyStrategy(bt.Strategy):
def __init__(self):
self.sma = bt.indicators.SimpleMovingAverage(self.data.close, period=20)
def next(self):
if self.data.close[0] > self.sma[0]:
self.buy()
elif self.data.close[0] < self.sma[0]:
self.sell()
Backtesting.py:
class MyStrategy(Strategy):
def init(self):
self.sma = self.I(SMA, self.data.Close, 20)
def next(self):
if self.data.Close > self.sma:
self.buy()
elif self.data.Close < self.sma:
self.sell()
Both examples implement a simple moving average crossover strategy. Backtrader uses a more object-oriented approach with separate methods for initialization and trading logic, while Backtesting.py combines both in a single class. Backtrader's syntax is more verbose, but it offers greater flexibility for complex strategies.
Portfolio analytics for quants, written in Python
Pros of QuantStats
- Comprehensive performance analytics and risk metrics
- Extensive visualization capabilities for portfolio analysis
- Integration with popular data sources like Yahoo Finance
Cons of QuantStats
- Primarily focused on analysis rather than strategy implementation
- May require additional tools for actual trading execution
- Less suitable for high-frequency trading scenarios
Code Comparison
QuantStats example:
import quantstats as qs
# Fetch data and calculate returns
stock = qs.utils.download_returns('AAPL')
# Generate tearsheet
qs.reports.html(stock, output='AAPL_tearsheet.html')
Backtesting.py example:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
class SmaCross(Strategy):
def init(self):
self.sma1 = self.I(SMA, self.data.Close, 10)
self.sma2 = self.I(SMA, self.data.Close, 20)
def next(self):
if crossover(self.sma1, self.sma2):
self.buy()
elif crossover(self.sma2, self.sma1):
self.sell()
bt = Backtest(GOOG, SmaCross, cash=10000, commission=.002)
bt.run()
bt.plot()
QuantStats focuses on performance analysis and reporting, while Backtesting.py provides a framework for implementing and testing trading strategies. QuantStats excels in generating comprehensive reports and visualizations, whereas Backtesting.py offers more flexibility in strategy development and execution simulation.
Python library for backtesting trading strategies & analyzing financial markets (formerly pythalesians)
Pros of finmarketpy
- More comprehensive financial market analysis tools
- Supports a wider range of asset classes and trading strategies
- Offers advanced risk management and portfolio optimization features
Cons of finmarketpy
- Steeper learning curve due to its broader scope
- Less focused on backtesting specifically
- May be overkill for simple trading strategy testing
Code Comparison
backtesting.py:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
class SmaCross(Strategy):
def init(self):
self.sma1 = self.I(SMA, self.data.Close, 10)
self.sma2 = self.I(SMA, self.data.Close, 20)
def next(self):
if crossover(self.sma1, self.sma2):
self.buy()
elif crossover(self.sma2, self.sma1):
self.sell()
finmarketpy:
from finmarketpy.backtest import Backtest
from finmarketpy.economics import Market
from finmarketpy.curve import IRCurve
market = Market(market_data=['libor'])
ir_curve = IRCurve()
backtest = Backtest()
backtest.calculate_trading_PnL(market, ir_curve)
This comparison highlights the different focus areas of the two libraries. backtesting.py is more streamlined for simple strategy backtesting, while finmarketpy offers a broader range of financial market analysis tools and supports more complex scenarios.
Lean Algorithmic Trading Engine by QuantConnect (Python, C#)
Pros of Lean
- More comprehensive and feature-rich platform for algorithmic trading
- Supports multiple asset classes and markets
- Offers live trading capabilities in addition to backtesting
Cons of Lean
- Steeper learning curve due to its complexity
- Requires more setup and configuration
- Less suitable for quick, simple backtests
Code Comparison
Lean (C#):
public class SimpleMovingAverageAlgorithm : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2012, 1, 1);
SetEndDate(2012, 12, 31);
SetCash(100000);
AddEquity("SPY", Resolution.Daily);
}
}
backtesting.py (Python):
class SmaCross(Strategy):
def init(self):
price = self.data.Close
self.ma1 = self.I(SMA, price, 10)
self.ma2 = self.I(SMA, price, 20)
def next(self):
if crossover(self.ma1, self.ma2):
self.buy()
elif crossover(self.ma2, self.ma1):
self.sell()
Lean offers a more structured approach with built-in methods for setting up the backtest environment, while backtesting.py provides a simpler, more concise syntax for defining trading strategies. Lean's code is more verbose but offers greater flexibility and control over the backtesting process.
An Algorithmic Trading Library for Crypto-Assets in Python
Pros of Catalyst
- More comprehensive ecosystem for crypto trading, including live trading capabilities
- Supports multiple exchanges and cryptocurrencies
- Offers advanced features like portfolio optimization and risk management
Cons of Catalyst
- Steeper learning curve due to its complexity
- Less active development and community support
- Requires more setup and configuration compared to Backtesting.py
Code Comparison
Catalyst example:
from catalyst import run_algorithm
def initialize(context):
context.asset = symbol('btc_usdt')
def handle_data(context, data):
order(context.asset, 1)
run_algorithm(capital_base=10000, data_frequency='daily', initialize=initialize, handle_data=handle_data)
Backtesting.py example:
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
class SmaCross(Strategy):
def init(self):
self.sma1 = self.I(SMA, self.data.Close, 10)
self.sma2 = self.I(SMA, self.data.Close, 20)
def next(self):
if crossover(self.sma1, self.sma2):
self.buy()
elif crossover(self.sma2, self.sma1):
self.sell()
bt = Backtest(data, SmaCross, cash=10000)
bt.run()
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Backtesting.py
Backtest trading strategies with Python.
Project website + Documentation
Installation
$ pip install backtesting
Usage
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA, GOOG
class SmaCross(Strategy):
def init(self):
price = self.data.Close
self.ma1 = self.I(SMA, price, 10)
self.ma2 = self.I(SMA, price, 20)
def next(self):
if crossover(self.ma1, self.ma2):
self.buy()
elif crossover(self.ma2, self.ma1):
self.sell()
bt = Backtest(GOOG, SmaCross, commission=.002,
exclusive_orders=True)
stats = bt.run()
bt.plot()
Results in:
Start 2004-08-19 00:00:00
End 2013-03-01 00:00:00
Duration 3116 days 00:00:00
Exposure Time [%] 94.27
Equity Final [$] 68935.12
Equity Peak [$] 68991.22
Return [%] 589.35
Buy & Hold Return [%] 703.46
Return (Ann.) [%] 25.42
Volatility (Ann.) [%] 38.43
Sharpe Ratio 0.66
Sortino Ratio 1.30
Calmar Ratio 0.77
Max. Drawdown [%] -33.08
Avg. Drawdown [%] -5.58
Max. Drawdown Duration 688 days 00:00:00
Avg. Drawdown Duration 41 days 00:00:00
# Trades 93
Win Rate [%] 53.76
Best Trade [%] 57.12
Worst Trade [%] -16.63
Avg. Trade [%] 1.96
Max. Trade Duration 121 days 00:00:00
Avg. Trade Duration 32 days 00:00:00
Profit Factor 2.13
Expectancy [%] 6.91
SQN 1.78
Kelly Criterion 0.6134
_strategy SmaCross(n1=10, n2=20)
_equity_curve Equ...
_trades Size EntryB...
dtype: object
Find more usage examples in the documentation.
Features
- Simple, well-documented API
- Blazing fast execution
- Built-in optimizer
- Library of composable base strategies and utilities
- Indicator-library-agnostic
- Supports any financial instrument with candlestick data
- Detailed results
- Interactive visualizations
Bugs
Before reporting bugs or posting to the
discussion board,
please read contributing guidelines, particularly the section
about crafting useful bug reports and ```
-fencing your code. We thank you!
Alternatives
See alternatives.md for a list of alternative Python backtesting frameworks and related packages.
Top Related Projects
bt - flexible backtesting for Python
Python Backtesting library for trading strategies
Portfolio analytics for quants, written in Python
Python library for backtesting trading strategies & analyzing financial markets (formerly pythalesians)
Lean Algorithmic Trading Engine by QuantConnect (Python, C#)
An Algorithmic Trading Library for Crypto-Assets in Python
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot