VectorBT – An Introductory Guide

5 min read

Get 10-day Free Algo Trading Course

Loading

Last Updated on May 10, 2023

Table of contents:

  1. What is VectorBT?
  2. What is VectorBT used for?
  3. Why should I use VectorBT?
  4. Why shouldn’t I use VectorBT?
  5. Is VectorBT free?
  6. What are some VectorBT alternatives?
  7. How to get started with VectorBT?
  8. How to get data with VectorBT?
  9. How to use technical indicators with VectorBT?
  10. How to define entries and exits with VectorBT?
  11. How to perform backtesting with VectorBT?
  12. How to plot backtesting results with VectorBT?
  13. How to perform analysis with VectorBT?
  14. How to use Telegram with VectorBT?
  15. How to schedule commands with VectorBT?
  16. Full code

What is VectorBT?

VectorBT is an open-source Python library for quantitative analysis and backtesting.

Link: https://vectorbt.dev/

What is VectorBT used for?

VectorBT is used by algorithmic traders and investors to perform quantitative analysis, strategy testing, and research. It is built and optimized for performance and uses NumPy and Numba under the hood.

Why should I use VectorBT?

  • VectorBT is open-source
  • VectorBT is easy to use
  • Is fast
  • Integrates with Telegram
  • Offers interactive charting via Jupyter notebooks

Why shouldn’t I use VectorBT?

  • VectorBT could use more features
  • It doesn’t have the best documentation
  • If you want to get serious with VectorBT, you will need to acquire a proprietary VectorBT Pro membership that gives you access to the upgraded library

Is VectorBT free?

VectorBT is an open-source library and it is free to use. Do keep in mind that there is VectorBT Pro which is a successor of VectorBT and comes with advanced features and performance which is a premium product on an invite-only GitHub basis.

What are some VectorBT alternatives?

VectorBT can be replaced with other software that can be more suitable for your needs. Here are some of them:

How to get started with VectorBT?

To get started with VectorBT, you will need to download the Python library via pip with the following command (you might want to have a new environment):

pip install -U vectorbt

If you want all the dependencies and features that VectorBT has, you will want to run this command:

pip install -U "vectorbt[full]"

If you are a fan of using Docker for your development, you have the option of spinning up a docker container that hosts a Jupyter Lab with VectorBT inside of it:

docker run --rm -p 8888:8888 -v "$PWD":/home/jovyan/work polakowo/vectorbt

The code block above 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 the token is the secret token printed in the console.

When you’re done with using the Docker container, Docker destroys the container after the notebook server exit, but any files written to the working directory in the container remain intact in the working directory of the host.

I’ll personally use it inside of a Google Colab notebook and install it via pip.

Now that we have VectorBT ready, let us explore in the following headers what it has to offer in terms of features and performance.

How to get data with VectorBT?

To get data with VectorBT, you will need to utilize the function that connects to Yahoo Finance to download the data and provide it with the asset you wish to obtain the data. For example, let’s obtain the ETH-USD ticker closing price data:

eth_price = vbt.YFData.download('ETH-USD').get('Close')
eth_price[:5]
Date
2017-11-09 00:00:00+00:00    320.884003
2017-11-10 00:00:00+00:00    299.252991
2017-11-11 00:00:00+00:00    314.681000
2017-11-12 00:00:00+00:00    307.907990
2017-11-13 00:00:00+00:00    316.716003
Freq: D, Name: Close, dtype: float64

How to use technical indicators with VectorBT?

To use technical indicators with VectorBT, you will need to use in-built functions that host indicators such as the MA, MSTD, BBANDS, RSI, and more. For example, let’s calculate a fast and slow MA for ETH and the RSI.

fast_ma = vbt.MA.run(eth_price, 10)
slow_ma = vbt.MA.run(eth_price, 50)
rsi = vbt.RSI.run(eth_price)

How to define entries and exists with VectorBT?

To define entries and exists with VectorBT, all you need to do is to define the logic of those conditions that need to be satisfied in order to be marked as an entry or exit.

For example, let’s define the entry to be when the fast MA crosses the slow MA while the RSI is over 50 and the exit when the slow MA crosses above the fast MA and the RSI is under 50:

entries = fast_ma.ma_crossed_above(slow_ma) & rsi.rsi_above(50)
exits = slow_ma.ma_crossed_above(fast_ma) & rsi.rsi_below(50)

Note that this strategy is just an example and strategies like this almost never work in real-life.

How to perform backtesting with VectorBT?

To perform backtesting with VectorBT, you can use the Portfolio function and its modules to define the trading requirements such as the entry and exit conditions, initial cash, and more. For example, let’s implement our exits and entries from the header above and backtest them:

pf = vbt.Portfolio.from_signals(eth_price, entries, exits, init_cash=10000)
pf.total_profit()
55760.53

Let us observe the overall statistics of our simple trading strategy that is only for showcase purposes by running the pf.stats() command:

Start                          2017-11-09 00:00:00+00:00
End                            2022-11-07 00:00:00+00:00
Period                                1825 days 00:00:00
Start Value                                      10000.0
End Value                                   65760.531431
Total Return [%]                              557.605314
Benchmark Return [%]                           393.42466
Max Gross Exposure [%]                             100.0
Total Fees Paid                                      0.0
Max Drawdown [%]                               61.262033
Max Drawdown Duration                  513 days 00:00:00
Total Trades                                          18
Total Closed Trades                                   17
Total Open Trades                                      1
Open Trade PnL                                1156.40722
Win Rate [%]                                   41.176471
Best Trade [%]                                318.026171
Worst Trade [%]                               -21.805347
Avg Winning Trade [%]                          71.673003
Avg Losing Trade [%]                            -10.7351
Avg Winning Trade Duration    83 days 06:51:25.714285715
Avg Losing Trade Duration               18 days 14:24:00
Profit Factor                                   3.388864
Expectancy                                   3212.007307
Sharpe Ratio                                    0.919382
Calmar Ratio                                    0.746707
Omega Ratio                                      1.23331
Sortino Ratio                                   1.378526

How to plot backtesting results with VectorBT?

To plot backtesting results with VectorBT, all you need to do is to utilize the plot function on your Portfolio module which will show the full backtest range with orders, trade returns, benchmarks, and more.

pf.plot().show()

As you can see from the interactive Plotly graph above, it takes one good trade to trump the others and keep us in a profitable state. The visualization is also nicely done. We can also plot other features of our portfolio:

pf.plot(subplots=['cash', 'assets', 'value']).show()

How to perform analysis with VectorBT?

To perform analysis with VectorBT, you can easily analyze different strategies across different assets and hyperparameters. For example, we can test 10000 windows combinations of a dual SMA crossover strategy on MSFT, AMZN, and AAPL stocks.

Again, this is just to demonstrate a simple example. Strategies like this almost never work in real-life.

import numpy as np

symbols = ["MSFT", "AMZN", "AAPL"]
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()

The example above is from the VectorBT documentation and has been slightly adapted.

In the graph above you can switch between the three stocks and observe which combination of the moving averages had the best performance. Beware of committing interpretation mistakes and falling to lookahead bias, overfitting and similar when doing things like these.

Moreover, is it just me or is there a shape of a rocket in the AMZN chart?

How to use Telegram with VectorBT?

To use Telegram with VectorBT, you can utilize the Telegram library command handler and ccxt. Below is an example from the VectorBT documentation that uses Binance to send ticker updates to your Telegram account:

from telegram.ext import CommandHandler
import ccxt

class BinanceTickerBot(vbt.TelegramBot):
    @property
    def custom_handlers(self):
        return CommandHandler('get', self.get),

    @property
    def help_message(self):
        return "Type /get [symbol] to get the latest ticker on Binance."

    def get(self, update, context):
        chat_id = update.effective_chat.id
        try:
            ticker = ccxt.binance().fetchTicker(context.args[0])
        except Exception as e:
            self.send_message(chat_id, str(e))
            return
        self.send_message(chat_id, str(ticker['last']))

bot = BinanceTickerBot(token='YOUR_TOKEN')
bot.start()

How to schedule commands with VectorBT?

To schedule commands with VectorBT, you can use the ScheduleManager module to run commands at specified time intervals. For example, we can obtain the latest BTC trades from Binance every 20 seconds with the following block of code:

from vectorbt.utils.datetime_ import datetime_to_ms, to_tzaware_datetime, get_utc_tz
from IPython.display import SVG, display, clear_output
import pandas as pd

exchange = ccxt.binance()

def job_func():
   since = datetime_to_ms(to_tzaware_datetime('10 seconds ago UTC', tz=get_utc_tz()))
   trades = exchange.fetch_trades('BTC/USDT', since)
   price = pd.Series({t['datetime']: t['price'] for t in trades})
   svg = price.vbt.plot().to_image(format="svg")
   clear_output()
   display(SVG(svg))

scheduler = vbt.ScheduleManager()
scheduler.every(20, 'seconds').do(job_func)
scheduler.start()

Full code

GitHub link

Igor Radovanovic