## Python

Running simple and fast backtests in Python with vectorbt

# Running simple and fast backtests in Python with vectorbt vectorbt is the new Python Backtesting framework I’m using these days. I really like it so I decided to share an example of the simplest strategy built in the vecotrbt from scratch, so you can understand why I like it. This library is developed mostly in Pandas and Numpy so it should be really fast as well.

Let’s create a simple long only MA strategy. We’ll enter long when fast moving average cross over slow moving average and will close our position on the opposite cross.

```import vectorbt as vbt
```

Next, I’ll download data from Yahoo Finance. There are many more other options, but for simplicity I’ll use build-in options for Yahoo finance:

```data = vbt.YFData.download(
'AAPL',
interval = '1d'
)
```

This code will download daily OHLC data Apple stock for the entire history. In this backtest I’ll use only close data so I’ll create another variable with only close:

```data_close = data.get('Close')
```

Next, let’s compute the moving averages we need for our signals. For that we can use build-in functions for moving average computations:

```ma_fast = vbt.MA.run(data_close, 10)
ma_slow = vbt.MA.run(data_close, 50)
```

After MAs are computed we can create calculate our signals. Again I’ll use build-in functions for MA crosses:

```entries = ma_fast.ma_crossed_above(ma_slow)
exits   = ma_fast.ma_crossed_below(ma_slow)
```

Now we have everything to run our backtest, in our case I’ll use “from_signal” function from vectorbt:

```res = vbt.Portfolio.from_signals(
data_close,
entries = entries,
exits = exits,
freq = 'd'
)
```

So now our backtest is computed, so let’s check performance and other metrics of our strategy. To get basic metrics you can use stats() method of your backtesting results object:

```res.stats()
```

This will output the following metrics:

```Start                          1980-12-12 00:00:00+00:00
End                            2022-08-05 00:00:00+00:00
Period                               10501 days 00:00:00
Start Value                                        100.0
End Value                                  210757.880978
Total Return [%]                           210657.880978
Benchmark Return [%]                       165184.748186
Max Gross Exposure [%]                             100.0
Total Fees Paid                                      0.0
Max Drawdown [%]                               72.076296
Max Drawdown Duration                 1512 days 00:00:00
Win Rate [%]                                   48.031496
Avg Winning Trade Duration    79 days 19:16:43.278688524
Avg Losing Trade Duration     21 days 09:05:27.272727272
Profit Factor                                   3.360768
Expectancy                                   1504.281019
Sharpe Ratio                                    0.883608
Calmar Ratio                                    0.422827
Omega Ratio                                     1.191955
Sortino Ratio                                   1.300257
dtype: object```

It’s quite easy to plot nice charts with metrics and signals. For that, you can use the plot() method specifying what plots you want to compute over the backtesting results.

```fig = res.plot(subplots = ['cum_returns', 'orders', 'trade_pnl'])
fig.show()
```

This will output you 3 plots. All these plots will be dynamic plots built with plotly, so you can zoom on it, explore details, etc.

```res.positions.records_readable
```

This code will output you a nice pandas data frame with some metrics for all your trades:

So that’s it, As you can see it’s a really nice library that will allow you to code backtests and explore your strategies just in a few lines of code. I think I’ll create more content about it, so let me know what you want to know about it.

```import vectorbt as vbt

'AAPL',
interval = '1d'
)

data_close = data.get('Close')

ma_fast = vbt.MA.run(data_close, 10)
ma_slow = vbt.MA.run(data_close, 50)

entries = ma_fast.ma_crossed_above(ma_slow)
exits   = ma_fast.ma_crossed_below(ma_slow)

res = vbt.Portfolio.from_signals(
data_close,
entries = entries,
exits = exits,
freq = 'd'
)

res.stats()

fig = res.plot(subplots = ['cum_returns', 'orders', 'trade_pnl'])
fig.show()  