Introduction to Backtesting with VectorBT
Vectorbt is a backtesting library for Python. It allows you to quickly and easily backtest strategies in only a few lines of code. Vectorbt was developed to address some of the performance shortcomings of other backtesting libraries. It excels at processing large amounts of data. By representing strategy data as numpy arrays, it takes advantage of the fast computation speeds numpy offers for vectorized operations. This allows for testing hundreds of variations of strategies relatively quickly.
Alpaca's Market Data can be accessed through Vectorbt. Alpaca's Market Data along with Vectorbt allows you to backtest over 5+ years of historical data across thousands of US stocks and cryptocurrencies.
Accessing Historical Data
Before we get started, you’ll need to install vectorbt. This can be done using pip.
pip install vectorbt
Vectorbt provides equity and crypto data through various data providers.
Alpaca is one of the data providers integrated with vectorbt. To access Alpaca data, you’ll need to first set your API keys within the vectorbt settings.
import vectorbt as vbt vbt.settings.data['alpaca']['key_id'] = 'Your API Key' vbt.settings.data['alpaca']['secret_key'] = 'Your Secret Key'
Now we can start accessing data through Alpaca. We can access both equity and crypto data through vectorbt. Data is retrieved using the
Download method. One of vectorbt’s unique features is the ability to define times in a variety of ways. In addition to defining absolute dates such as
2021-03-11 UTC, we can define relative dates such as a start time of
4 days ago UTC and end time of
1 day ago UTC. We can also provide a timeframe we’d like our data to be resolved at like
15m, which tells vectorbt that we want 15 minute bars.
alpacadata = vbt.AlpacaData.Download(symbol='AAPL', start='4 days ago UTC`, end=`1 day ago UTC`, timeframe='1h') alpaca.get_data() # Open High Low Close Volume # timestamp # 2021-12-23 14:00:00+00:00 177.0500 177.0500 177.0500 177.0500 1967 # 2021-12-23 15:00:00+00:00 177.0500 177.0500 177.0300 177.0500 3218 # ... ... ... ... ... ... # 2021-12-27 15:00:00+00:00 178.0000 178.0079 177.9311 177.9710 106395 # 2021-12-27 16:00:00+00:00 177.9700 178.0564 177.9430 177.9600 153325 # [105 rows x 5 columns]
The free market data plan limits the historical data you can request. With the free plan you aren't able to query data from within the past 15 minutes and the data is limited to only IEX. On the other hand, with a premium market data subscription, you can access data from all US exchanges and there are no limits on the historical data you can query. If your API keys are associated with an account with a premium market data subscription, you will automatically be able to access unlimited data in your historical data calls.
alpacadata = vbt.AlpacaData.Download(symbol='GME', start='4 hours ago UTC`, end=`now UTC`, timeframe='1h') alpaca.get_data()
Simple Moving Average Crossover
Let’s backtest a simple moving average crossover strategy; buy when the 10-day moving average crosses above the 20-day moving average, and sell when opposite. For this, we are going to use MA class for calculating moving averages and generating signals.
fast_ma = vbt.MA.run(alpacadata, 10, short_name='fast') slow_ma = vbt.MA.run(alpacadata, 20, short_name='slow') entries = fast_ma.ma_crossed_above(slow_ma) entries # Date # 2019-01-01 00:00:00+00:00 False # 2019-01-02 00:00:00+00:00 False # 2019-01-03 00:00:00+00:00 False # ... ... # 2019-12-30 00:00:00+00:00 False # Freq: D, Length: 366, dtype: bool
We can calculate when our strategy exits using the
exits = fast_ma.ma_crossed_below(slow_ma) exits # Date # 2019-01-01 00:00:00+00:00 False # 2019-01-02 00:00:00+00:00 False # 2019-01-03 00:00:00+00:00 False # . .. ... # 2019-12-30 00:00:00+00:00 False # 2019-12-31 00:00:00+00:00 False # 2020-01-01 00:00:00+00:00 False # Freq: D, Length: 366, dtype: bool
Finally our portfolio return is calculated by passing in the signals we computed earlier and the price of
pf = vbt.Portfolio.from_signals(alpacadata, entries, exits) pf.total_return() # 0.636680693047752
The real power of vectorbt arises when looking at variations of a strategy. Vectorbt makes it fast and easy to test how changes in parameters affect performance. For example, let’s say we wanted to test how performance of our strategy compares when trading
BTCUSD, and when changing our moving average slow and fast periods.
alpacadata = vbt.AlpacaData.Download(symbol=['AAPL', “BTCUSD”], start='4 days ago UTC`, end=`1 day ago UTC`, timeframe='1h') fast_ma = vbt.MA.run(alpacadata, [10, 20], short_name='fast') slow_ma = vbt.MA.run(alpacadata, [30, 30], short_name='slow')
We can calculate the entries and exits as we did before and then calculate the difference in portfolio performance.
entries = fast_ma.ma_crossed_above(slow_ma) exits = fast_ma.ma_crossed_below(slow_ma) pf = vbt.Portfolio.from_signals(alpacadata, entries, exits) pf.total_return() # fast_window slow_window symbol # 10 30 AAPL 0.848840 # BTCUSD 0.244204 # 20 30 AAPL 0.543411 # BTCUSD -0.319102
Vectorbt is a blazingly fast backtrading library. It allows you to not only backtest your strategy, but also optimize its parameters quickly. Check out the vectorbt documentation for more information.
All investments involve risk and the past performance of a security, or financial product does not guarantee future results or returns. Keep in mind that while diversification may help spread risk it does not assure a profit, or protect against loss, in a down market. There is always the potential of losing money when you invest in securities, or other financial products. Investors should consider their investment objectives and risks carefully before investing.
Cryptocurrency is highly speculative in nature, involves a high degree of risks, such as volatile market price swings, market manipulation, flash crashes, and cybersecurity risks. Cryptocurrency is not regulated or is lightly regulated in most countries. Cryptocurrency trading can lead to large, immediate and permanent loss of financial value. You should have appropriate knowledge and experience before engaging in cryptocurrency trading. For additional information please click here.
Alpaca does not prepare, edit, or endorse Third Party Content. Alpaca does not guarantee the accuracy, timeliness, completeness or usefulness of Third Party Content, and is not responsible or liable for any content, advertising, products, or other materials on or available from third party sites.
Securities brokerage services are provided by Alpaca Securities LLC ("Alpaca Securities"), member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc. Technology and services are offered by AlpacaDB, Inc.
Cryptocurrency services are provided by Alpaca Crypto LLC ("Alpaca Crypto"), a wholly-owned subsidiary of AlpacaDB, Inc. Alpaca Crypto is not a member of SIPC or FINRA. Cryptocurrencies are not stocks and your cryptocurrency investments are not protected by either FDIC or SIPC.
This is not an offer, solicitation of an offer, or advice to buy or sell securities or cryptocurrencies, or open a brokerage account or cryptocurrency account in any jurisdiction where Alpaca Securities or Alpaca Crypto respectively, are not registered.