VectorBT: Backtesting Ultrarrápido em Python
Como usar VectorBT para testar milhares de combinações de parâmetros em segundos, otimizar estratégias de trading em cripto e visualizar resultados com heatmaps e gráficos interativos.
VectorBT é a biblioteca Python mais rápida para backtesting de estratégias de trading. Enquanto frameworks tradicionais como Backtrader processam operações uma a uma (loop), VectorBT opera sobre arrays inteiros usando NumPy + Numba — alcançando velocidade próxima ao nível C.
- GitHub: polakowo/vectorbt
- Caso de uso ideal: otimização de parâmetros em larga escala (testar centenas ou milhares de combinações)
pip install vectorbtPor que VectorBT é Diferente
| Aspecto | Backtrader (loop) | VectorBT (vetorizado) |
|---|---|---|
| Velocidade | ~1 combinação/s | ~1.000+ combinações/s |
| Otimização | Manual (loops externos) | Nativa (broadcasting de arrays) |
| Visualização | Básica | Interativa (Plotly) |
| Curva de aprendizado | Fácil | Média |
| Casos de uso | Qualquer estratégia | Estratégias com parâmetros otimizáveis |
Conceito Fundamental: Broadcasting
VectorBT testa múltiplos parâmetros simultaneamente passando arrays em vez de valores únicos:
import vectorbt as vbt
import numpy as np
# Dados: BTC últimos 2 anos
btc = vbt.YFData.download("BTC-USD", period="2y").get("Close")
# RSI com UM período (tradicional)
rsi_14 = vbt.RSI.run(btc, window=14)
# RSI com MÚLTIPLOS períodos (broadcasting)
rsi_multi = vbt.RSI.run(btc, window=[10, 14, 20, 30])
# → gera 4 séries de RSI ao mesmo tempoBacktest Básico
import vectorbt as vbt
# Download de dados
btc = vbt.YFData.download("BTC-USD", period="2y").get("Close")
# Calcular RSI
rsi = vbt.RSI.run(btc, window=14)
# Definir sinais
entries = rsi.rsi_below(30) # Compra quando RSI < 30
exits = rsi.rsi_above(65) # Vende quando RSI > 65
# Criar portfolio
portfolio = vbt.Portfolio.from_signals(
btc,
entries,
exits,
init_cash=10_000,
fees=0.001, # 0,1% por operação (Binance spot)
slippage=0.0005, # 0,05% de slippage
freq='D' # Frequência dos dados
)
# Resultado
print(portfolio.stats())Saída de exemplo:
Start 2023-01-01
End 2024-12-31
Period 730 days
Start Value 10000.0
End Value 13420.5
Total Return [%] 34.20
Annualized Return [%] 16.31
Benchmark Return [%] 89.40 ← Buy-and-hold
Max Drawdown [%] -12.8
Win Rate [%] 52.3
Profit Factor 1.73
Sharpe Ratio 1.44Otimização de Parâmetros em Grade
O diferencial do VectorBT: testar todas as combinações de parâmetros com uma linha de código.
import vectorbt as vbt
import numpy as np
btc = vbt.YFData.download("BTC-USD", period="2y").get("Close")
# RSI com múltiplos períodos
rsi = vbt.RSI.run(btc, window=np.arange(10, 31, 2)) # 10, 12, 14...30 (11 valores)
# Múltiplos thresholds de entrada
entries = rsi.rsi_below(np.arange(25, 41, 5)) # 25, 30, 35, 40 (4 valores)
exits = rsi.rsi_above(np.arange(60, 76, 5)) # 60, 65, 70, 75 (4 valores)
# 11 × 4 × 4 = 176 combinações testadas simultaneamente
portfolio = vbt.Portfolio.from_signals(
btc, entries, exits,
init_cash=10_000,
fees=0.001,
slippage=0.0005
)
# Heatmap de Profit Factor para cada combinação
# Eixo X: threshold de entrada; Eixo Y: período do RSI
pf = portfolio.profit_factor
# Selecionar apenas entradas (rsi_below) × período (window)
# (média sobre os thresholds de saída)
heatmap = pf.vbt.heatmap(
x_level="rsi_below",
y_level="rsi_window",
)
heatmap.show()
# Encontrar o melhor parâmetro
melhor_idx = pf.idxmax()
print(f"Melhor combinação: {melhor_idx}")
print(f"Profit Factor: {pf.max():.2f}")Múltiplos Indicadores: MACD + RSI
import vectorbt as vbt
import pandas as pd
# Dados para 3 pares
pares = ["BTC-USD", "ETH-USD", "SOL-USD"]
dados = vbt.YFData.download(pares, period="2y").get("Close")
# MACD para todos os pares
macd = vbt.MACD.run(dados, fast_window=12, slow_window=26, signal_window=9)
# RSI para todos os pares
rsi = vbt.RSI.run(dados, window=14)
# Sinal combinado: MACD crossover + RSI saudável
entries = (
macd.macd_above(macd.signal) & # MACD acima da linha de sinal
rsi.rsi_below(60) # RSI não sobrecomprado
)
exits = (
macd.macd_below(macd.signal) | # MACD abaixo da linha de sinal
rsi.rsi_above(70) # RSI sobrecomprado
)
portfolio = vbt.Portfolio.from_signals(
dados, entries, exits,
init_cash=10_000,
fees=0.001
)
# Estatísticas por par
print(portfolio.stats(agg_func=None)) # Sem agregação → por parVisualização Interativa
# Plotar o portfolio com gráfico interativo (Plotly)
portfolio.plot().show()
# Gráfico de drawdown ao longo do tempo
portfolio.drawdown().plot().show()
# Retorno cumulativo
portfolio.cumulative_returns.plot().show()
# Ordens executadas no gráfico de preço
portfolio.orders.plot().show()
# Relatório completo em HTML (útil para documentar)
portfolio.plot().write_html("resultado_backtest.html")Walk-Forward Analysis com VectorBT
import vectorbt as vbt
import pandas as pd
import numpy as np
btc = vbt.YFData.download("BTC-USD", period="3y").get("Close")
# Dividir em janelas de 90 dias (treino) + 30 dias (validação)
n_janelas = 8
resultados = []
for i in range(n_janelas):
inicio_treino = i * 30
fim_treino = inicio_treino + 90
inicio_val = fim_treino
fim_val = inicio_val + 30
if fim_val > len(btc):
break
treino = btc.iloc[inicio_treino:fim_treino]
validacao = btc.iloc[inicio_val:fim_val]
# Otimizar no treino
rsi_treino = vbt.RSI.run(treino, window=np.arange(10, 25))
ent = rsi_treino.rsi_below(np.arange(25, 40, 5))
sai = rsi_treino.rsi_above(65)
pf_treino = vbt.Portfolio.from_signals(treino, ent, sai, fees=0.001)
melhor_window = int(pf_treino.profit_factor.idxmax()['rsi_window'])
melhor_below = int(pf_treino.profit_factor.idxmax()['rsi_below'])
# Validar com os melhores parâmetros
rsi_val = vbt.RSI.run(validacao, window=melhor_window)
ent_val = rsi_val.rsi_below(melhor_below)
sai_val = rsi_val.rsi_above(65)
pf_val = vbt.Portfolio.from_signals(validacao, ent_val, sai_val, fees=0.001)
resultados.append({
'janela': i + 1,
'window': melhor_window,
'below': melhor_below,
'retorno_validacao': float(pf_val.total_return)
})
df_wf = pd.DataFrame(resultados)
print(df_wf)
print(f"\nRetorno médio na validação: {df_wf['retorno_validacao'].mean():.2%}")VectorBT vs Freqtrade: Quando Usar Cada Um
| Critério | VectorBT | Freqtrade |
|---|---|---|
| Otimização em escala | Muito melhor (broadcasting) | OK (Hyperopt) |
| Deploy em produção | Não (só backtesting) | Sim (bot completo) |
| Machine Learning | Manual (sklearn externo) | Nativo (FreqAI) |
| Facilidade | Média (requer pandas/numpy) | Alta (framework pronto) |
| Velocidade de backtest | Excelente | Boa |
| Múltiplos pares | Sim (nativo) | Sim |
| Visualização | Interativa (Plotly) | Básica |
Workflow recomendado:
1. VectorBT → Encontrar os melhores parâmetros em grande escala
2. Freqtrade → Implementar a estratégia otimizada para produção
3. Paper trading → 30-90 dias
4. Produção → Capital real pequeno, escale gradualmentePróximos Passos
- Freqtrade: Bot Open-Source — do backtest ao bot em produção
- Hummingbot: Market Making — estratégias de market making
- Backtesting de Estratégias — metodologia completa
Aviso Legal: Conteúdo educativo. Resultados de backtesting não garantem performance futura. Não constitui recomendação de investimento.
Freqtrade: Bot Open-Source Completo para Cripto
Guia prático do Freqtrade: instalação, criação de estratégias em Python, backtesting, otimização com Hyperopt, FreqAI com machine learning, paper trading e deploy em produção.
Hummingbot: Market Making Automatizado em Cripto
Como usar o Hummingbot para market making e arbitragem em exchanges centralizadas e DEXes. Estratégias nativas, configuração, riscos de inventory e como gerar renda com spreads.