Python library for backtesting and analyzing trading strategies at scale
Project description
vectorbt: Powerful toolkit for quants.
Installation · Features · Usage · Resources · License
vectorbt takes a novel approach to backtesting: it operates entirely on pandas and NumPy objects, and is accelerated by Numba to analyze any data at speed and scale. This allows for testing of many thousands of strategies in seconds.
In contrast to other backtesters, vectorbt represents complex data as (structured) NumPy arrays. This enables superfast computation using vectorized operations with NumPy and non-vectorized but dynamically compiled operations with Numba. It also integrates Plotly and Jupyter Widgets to display complex charts and dashboards akin to Tableau right in the Jupyter notebook. Due to high performance, vectorbt can process large amounts of data even without GPU and parallelization and enables the user to interact with data-hungry widgets without significant delays.
With vectorbt, you can
- Backtest strategies in a couple of lines of Python code
- Enjoy the best of both worlds: the ecosystem of Python and the speed of C
- Retain full control over execution (as opposed to web-based services such as TradingView)
- Optimize your trading strategy against many parameters, assets, and periods in one go
- Uncover hidden patterns in financial markets
- Analyze time series and engineer new features for ML models
- Supercharge pandas and your favorite tools to run much faster
- Visualize strategy performance using interactive charts and dashboards (both in Jupyter and browser)
- Fetch and process data periodically, send Telegram notifications, and more
Installation
pip install -U vectorbt
To also install optional dependencies:
pip install -U "vectorbt[full]"
See License notes on optional dependencies.
Troubleshooting:
Docker
You can pull the most recent Docker image if you have Docker installed.
docker run --rm -p 8888:8888 -v "$PWD":/home/jovyan/work polakowo/vectorbt
This command pulls the latest polakowo/vectorbt
image from Docker Hub. It then starts a container running
a Jupyter Notebook server and exposes the server on host port 8888. Visiting http://127.0.0.1:8888/?token=<token>
in a browser loads JupyterLab, where token is the secret token printed in the console. Docker destroys
the container after notebook server exit, but any files written to the working directory in the container
remain intact in the working directory on the host. See Jupyter Docker Stacks - Quick Start.
There are two types of images:
- polakowo/vectorbt: vanilla version (default)
- polakowo/vectorbt-full: full version (with optional dependencies)
Each Docker image is based on jupyter/scipy-notebook and comes with Jupyter environment, vectorbt, and other scientific packages installed.
:zap: Features
Pandas
- Pandas acceleration: Compiled versions of most popular pandas functions, such as mapping, reducing, rolling, grouping, and resamping. For best performance, most operations are done strictly using NumPy and Numba. Attaches a custom accessor on top of pandas to easily switch between pandas and vectorbt functionality. >>
- Flexible broadcasting: Mechanism for broadcasting array-like objects of arbitrary shapes, including pandas objects with MultiIndex.
- Pandas utilities: Grouping columns, wrapping NumPy arrays, transforming pandas objects and their indexes, and more. >>
Data
- Data acquisition: Supports various data providers, such as Yahoo Finance, Binance, and CCXT. Can merge multiple symbols with different index, as well as update them. >>
- Data generation: Supports various (random) data generators, such as GBM. >>
- Scheduled data updates: Can periodically update any previously downloaded data. >>
- Data preparation: Transformation, rescaling, and normalization of data. Custom splitters for cross-validation. Supports Scikit-Learn splitters, such as for K-Folds cross-validation. >>
- Labeling for ML: Discrete and continuous label generation for effective training of ML models. >>
Indicators
- Technical indicators: Most popular technical indicators with full Numba support, including Moving Average, Bollinger Bands, RSI, Stochastic, MACD, and more. Out-of-the-box support for 99% indicators in Technical Analysis Library, Pandas TA, and TA-Lib thanks to built-in parsers. Each indicator is wrapped with the vectorbt's indicator engine and thus accepts arbitrary hyperparameter combinations - from arrays to Cartesian products. >>
- Indicator factory: Sophisticated factory for building custom technical indicators of any complexity. Takes a function and does all the magic for you: generates an indicator skeleton that takes inputs and parameters of any shape and type, and runs the vectorbt's indicator engine. The easiest and most flexible way to create indicators you will find in open source. >>
Signals
- Signal analysis: Generation, mapping and reducing, ranking, and distribution analysis of entry and exit signals. >>
- Signal generators: Random and stop loss (SL, TSL, TP, etc.) signal generators with full Numba support. >>
- Signal factory: Signal factory based on indicator factory specialized for iterative signal generation. >>
Modeling
- Portfolio modeling: The fastest backtesting engine in open source: fills 1,000,000 orders in 70-100ms on Apple M1. Flexible and powerful simulation functions for portfolio modeling, highly optimized for best performance and memory consumption. Supports two major simulation modes: 1) vectorized backtesting using user-provided arrays, such as orders, signals, and records, and 2) event-driven backtesting using user-defined callbacks. Supports shorting and individual as well as multi-asset mixed portfolios. Combines many features across vectorbt into a single behemoth class. >>
Performance
- Performance metrics: Numba-compiled versions of metrics from empyrical and their highly-optimized rolling versions. Adapter for QuantStats. >>
- Stats builder: Class for building statistics out of custom metrics. Implements a preset of tailored statistics for many backtesting components, such as signals, returns, and portfolio. >>
- Records and mapped arrays: In-house data structures for analyzing complex data, such as simulation logs. Fully compiled with Numba. >>
- Trade analysis: Retrospective analysis of trades from various view points. Supports entry trades, exit trades, and positions. >>
- Drawdown analysis: Drawdown statistics of any numeric time series. >>
Plotting
- Data visualization: Numerous flexible data plotting functions distributed across vectorbt.
- Figures and widgets: Custom interactive figures and widgets using Plotly, such as Heatmap and Volume. All custom widgets have dedicated methods for efficiently updating their state. >>
- Plots builder: Class for building plots out of custom subplots. Implements a preset of tailored subplots for many backtesting components, such as signals, returns, and portfolio. >>
Extra
- Notifications: Telegram bot based on Python Telegram Bot. >>
- General utilities: Scheduling using schedule, templates, decorators, configs, and more. >>
- Caching: Property and method decorators for caching most frequently used objects.
- Persistance: Most Python objects including data and portfolio can be saved to a file and retrieved back using Dill.
:sparkles: Usage
vectorbt allows you to easily backtest strategies with a couple of lines of Python code.
- Here is how much profit we would have made if we invested $100 into Bitcoin in 2014:
import vectorbt as vbt
price = vbt.YFData.download('BTC-USD').get('Close')
pf = vbt.Portfolio.from_holding(price, init_cash=100)
pf.total_profit()
8961.008555963961
- Buy whenever 10-day SMA crosses above 50-day SMA and sell when opposite:
fast_ma = vbt.MA.run(price, 10)
slow_ma = vbt.MA.run(price, 50)
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)
pf.total_profit()
16423.251963801864
- Generate 1,000 strategies with random signals and test them on BTC and ETH:
import numpy as np
symbols = ["BTC-USD", "ETH-USD"]
price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
n = np.random.randint(10, 101, size=1000).tolist()
pf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)
mean_expectancy = pf.trades.expectancy().groupby(['randnx_n', 'symbol']).mean()
fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title='randnx_n', yaxis_title='mean_expectancy')
fig.show()
- For fans of hyperparameter optimization: here is a snippet for testing 10,000 window combinations of a dual SMA crossover strategy on BTC, USD, and LTC:
symbols = ["BTC-USD", "ETH-USD", "LTC-USD"]
price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
windows = np.arange(2, 101)
fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=['fast', 'slow'])
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf_kwargs = dict(size=np.inf, fees=0.001, freq='1D')
pf = vbt.Portfolio.from_signals(price, entries, exits, **pf_kwargs)
fig = pf.total_return().vbt.heatmap(
x_level='fast_window', y_level='slow_window', slider_level='symbol', symmetric=True,
trace_kwargs=dict(colorbar=dict(title='Total return', tickformat='%')))
fig.show()
Digging into each strategy configuration is as simple as indexing with pandas:
pf[(10, 20, 'ETH-USD')].stats()
Start 2015-08-07 00:00:00+00:00
End 2021-08-01 00:00:00+00:00
Period 2183 days 00:00:00
Start Value 100.0
End Value 620402.791485
Total Return [%] 620302.791485
Benchmark Return [%] 92987.961948
Max Gross Exposure [%] 100.0
Total Fees Paid 10991.676981
Max Drawdown [%] 70.734951
Max Drawdown Duration 760 days 00:00:00
Total Trades 54
Total Closed Trades 53
Total Open Trades 1
Open Trade PnL 67287.940601
Win Rate [%] 52.830189
Best Trade [%] 1075.803607
Worst Trade [%] -29.593414
Avg Winning Trade [%] 95.695343
Avg Losing Trade [%] -11.890246
Avg Winning Trade Duration 35 days 23:08:34.285714286
Avg Losing Trade Duration 8 days 00:00:00
Profit Factor 2.651143
Expectancy 10434.24247
Sharpe Ratio 2.041211
Calmar Ratio 4.6747
Omega Ratio 1.547013
Sortino Ratio 3.519894
Name: (10, 20, ETH-USD), dtype: object
The same for plotting:
pf[(10, 20, 'ETH-USD')].plot().show()
It's not all about backtesting - vectorbt can be used to facilitate financial data analysis and visualization.
- Let's generate a GIF that animates the %B and bandwidth of Bollinger Bands for different symbols:
symbols = ["BTC-USD", "ETH-USD", "ADA-USD"]
price = vbt.YFData.download(symbols, period='6mo', missing_index='drop').get('Close')
bbands = vbt.BBANDS.run(price)
def plot(index, bbands):
bbands = bbands.loc[index]
fig = vbt.make_subplots(
rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,
subplot_titles=('%B', 'Bandwidth'))
fig.update_layout(template='vbt_dark', showlegend=False, width=750, height=400)
bbands.percent_b.vbt.ts_heatmap(
trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale='Spectral', colorbar=dict(
y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5
)), add_trace_kwargs=dict(row=1, col=1), fig=fig)
bbands.bandwidth.vbt.ts_heatmap(
trace_kwargs=dict(colorbar=dict(
y=(fig.layout.yaxis2.domain[0] + fig.layout.yaxis2.domain[1]) / 2, len=0.5
)), add_trace_kwargs=dict(row=2, col=1), fig=fig)
return fig
vbt.save_animation('bbands.gif', bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)
100%|██████████| 31/31 [00:21<00:00, 1.21it/s]
And this is just the tip of the iceberg of what's possible. Check out Resources to learn more.
Resources
Documentation
Head over to the documentation to get started.
Notebooks
- Performance analysis of Moving Average Crossover
- Performance analysis of stop signals
- Backtesting per trading session
- Portfolio optimization
- Plotting MACD parameters as 3D volume
- Walk-forward optimization
- Running Telegram signal bot
- Porting RSI strategy from backtrader
- Pairs trading (vs backtrader)
Note: you must run the notebook to play with the widgets.
Dashboards
Articles
Getting Help
- If you need supervision or any help with your implementation, join a private chat
- For questions on Numba and other parts, the best place to go to is StackOverflow
- If you have general questions, start a new GitHub Discussion
- Alternatively, you can ask on Gitter
- If you found what appears to be a bug, please create a new issue
- For other inquiries, please contact the author
License
This work is fair-code distributed under Apache 2.0 with Commons Clause license. The source code is open and everyone (individuals and organizations) can use it for free. However, it is not allowed to sell products and services that are mostly just this software.
If you have any questions about this or want to apply for a license exception, please contact the author.
Installing optional dependencies may be subject to a more restrictive license.
Disclaimer
This software is for educational purposes only. Do not risk money which you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file vectorbt-0.22.0.tar.gz
.
File metadata
- Download URL: vectorbt-0.22.0.tar.gz
- Upload date:
- Size: 494.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.6.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9f05259e2c0b916c0550e2558aa393c75ae86a5420b5fcda7e2ddebb27582f53 |
|
MD5 | 02eedd91d8862f65026a8189ef8fd70a |
|
BLAKE2b-256 | ea0f78bcaec356202cc87eff7a68a65830834ed345fd7776205227da167071c0 |