been using both for 2+ years.
here’s when to use each.
quick verdict #
vectorbt: fast parameter sweeps, simple strategies
backtrader: complex strategies, event-driven logic
my usage: 70% vectorbt, 30% backtrader
speed comparison #
test: 5 years of daily data, moving average crossover
import vectorbt as vbt
import pandas as pd
import time
# vectorbt approach
start = time.time()
price = vbt.YFData.download("SPY", start="2020-01-01", end="2025-01-01").get("Close")
fast_ma = vbt.MA.run(price, [10, 20, 30, 40, 50])
slow_ma = vbt.MA.run(price, [50, 100, 150, 200])
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(price, entries, exits)
print(f"VectorBT: {time.time() - start:.2f}s")
# VectorBT: 0.42s for 20 parameter combinations
import backtrader as bt
import time
class MACrossover(bt.Strategy):
params = (('fast', 10), ('slow', 50))
def __init__(self):
self.fast_ma = bt.ind.SMA(period=self.p.fast)
self.slow_ma = bt.ind.SMA(period=self.p.slow)
self.crossover = bt.ind.CrossOver(self.fast_ma, self.slow_ma)
def next(self):
if self.crossover > 0:
self.buy()
elif self.crossover < 0:
self.sell()
start = time.time()
for fast in [10, 20, 30, 40, 50]:
for slow in [50, 100, 150, 200]:
cerebro = bt.Cerebro()
cerebro.addstrategy(MACrossover, fast=fast, slow=slow)
# ... data feeding, run
print(f"Backtrader: {time.time() - start:.2f}s")
# Backtrader: 8.7s for 20 parameter combinations
winner: vectorbt (20x faster for parameter sweeps)
feature comparison #
| feature | vectorbt | backtrader |
|---|---|---|
| speed | very fast | slow |
| parameter optimization | excellent | manual loops |
| complex order logic | limited | excellent |
| multi-timeframe | awkward | native |
| portfolio simulation | basic | advanced |
| indicators library | 50+ | 100+ |
| broker integration | no | yes |
| live trading | no | yes |
| learning curve | moderate | steep |
when to use vectorbt #
parameter optimization:
# test 1000 parameter combinations in seconds
import vectorbt as vbt
import numpy as np
price = vbt.YFData.download("SPY").get("Close")
# create parameter grid
fast_windows = np.arange(5, 50, 5)
slow_windows = np.arange(50, 200, 10)
fast_ma, slow_ma = vbt.MA.run_combs(
price,
window=fast_windows,
r=2, # combinations of 2
short_names=['fast', 'slow']
)
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(price, entries, exits)
# get best parameters instantly
print(pf.sharpe_ratio().idxmax())
quick strategy validation:
# validate idea in 5 lines
rsi = vbt.RSI.run(price, window=14)
entries = rsi.rsi_crossed_below(30)
exits = rsi.rsi_crossed_above(70)
pf = vbt.Portfolio.from_signals(price, entries, exits)
print(f"Sharpe: {pf.sharpe_ratio():.2f}")
when to use backtrader #
complex order logic:
class ComplexStrategy(bt.Strategy):
def __init__(self):
self.order = None
self.stop_order = None
def next(self):
if not self.position:
if self.signal():
# bracket order with stop loss and take profit
main = self.buy(size=100, transmit=False)
self.sell(
size=100,
exectype=bt.Order.Stop,
price=self.data.close[0] * 0.98,
parent=main,
transmit=False
)
self.sell(
size=100,
exectype=bt.Order.Limit,
price=self.data.close[0] * 1.05,
parent=main,
transmit=True
)
multi-timeframe analysis:
class MultiTimeframe(bt.Strategy):
def __init__(self):
# daily timeframe
self.sma_daily = bt.ind.SMA(self.data0, period=20)
# weekly timeframe (resample)
self.sma_weekly = bt.ind.SMA(self.data1, period=10)
def next(self):
# only trade when daily and weekly aligned
if self.sma_daily[0] > self.sma_daily[-1]:
if self.sma_weekly[0] > self.sma_weekly[-1]:
self.buy()
my workflow #
step 1: idea validation (vectorbt)
# quick test: does this idea have any merit?
# 10 minutes max
step 2: parameter optimization (vectorbt)
# find optimal parameters
# test 1000+ combinations
# 30 minutes
step 3: complex logic (backtrader)
# implement full strategy with:
# - proper position sizing
# - stop losses
# - take profits
# - scaling in/out
# 2-4 hours
step 4: walk-forward validation (custom)
# out-of-sample testing
# 1-2 hours
real example: my vol selling strategy #
vectorbt phase (2 hours):
found optimal IV rank threshold: 45-60%
found optimal DTE range: 21-35 days
found optimal delta: 0.15-0.25
backtrader phase (8 hours):
implemented full premium collection logic.
added early exit rules (50% profit).
added adjustment triggers (100% loss).
tested bracket orders.
validated against 3 years data.
performance comparison #
my backtests (same strategy, same data):
| metric | vectorbt | backtrader |
|---|---|---|
| setup time | 10 min | 45 min |
| run time (1000 params) | 45 sec | 12 min |
| sharpe reported | 1.82 | 1.79 |
| max drawdown | -12.4% | -12.8% |
| total return | 34.2% | 33.8% |
slight differences due to:
execution assumptions.
slippage modeling.
fee calculations.
both valid, vectorbt faster.
recommendation #
use vectorbt when:
-
testing new ideas quickly
-
optimizing parameters
-
simple entry/exit logic
-
need speed over complexity
use backtrader when:
-
complex order types
-
multi-timeframe strategies
-
broker integration needed
-
production-ready backtests
the NexusFi Battle of the Bots thread has 2,300+ replies discussing algorithmic strategy development approaches. good resource for seeing how other algo traders structure their backtesting workflows.
my final setup #
vectorbt: quick validation, parameter sweeps
backtrader: complex strategies, final validation
custom numpy: walk-forward analysis, production
70/30 split works for me.
tonight (may 28, 2:22am) #
vectorbt vs backtrader comparison. vectorbt: 20x faster for parameter sweeps, excellent for quick validation. backtrader: better for complex orders, multi-timeframe, broker integration. my workflow: vectorbt for ideas and optimization (70%), backtrader for complex logic (30%). same strategy backtests: vectorbt 45sec vs backtrader 12min, results within 1% difference. use both for different purposes.
2:22am wednesday. backtesting framework comparison. vectorbt: fast parameter optimization (1000 combos in 45sec), simple API, no live trading. backtrader: complex order logic, multi-timeframe, broker integration, steep learning curve. my workflow: vectorbt for idea validation and parameter sweeps (70%), backtrader for complex strategies and final validation (30%). both valid, vectorbt faster for iteration.
-AK