Como Fazer Backtesting Rigoroso em Cripto
Guia completo de backtesting para estratégias de trading em cripto: metodologia, métricas essenciais, armadilhas de overfitting, walk-forward analysis e ferramentas (TradingView, VectorBT, Freqtrade, Backtrader).
Backtesting é simular sua estratégia em dados históricos para entender como ela teria se saído no passado. É o passo mais crítico antes de colocar capital real em qualquer bot — e o mais frequentemente feito de forma errada.
Regra de ouro: uma estratégia que não passou no backtesting nunca deve operar com capital real. Uma estratégia que passou no backtesting ainda precisa de paper trading antes do capital real.
Por que Backtesting Mal Feito é Perigoso
Os erros mais comuns que fazem um backtest parecer lucrativo quando não é:
| Erro | Impacto | Solução |
|---|---|---|
| Sem taxas | Superestima lucro em 10-40% | Inclua maker/taker/slippage |
| Look-ahead bias | Usa dados do futuro para decidir | Verifique que indicadores usam apenas close passado |
| Overfitting | Otimizado para o passado, falha no futuro | Valide em dados out-of-sample |
| Período único | Funciona só em bull market | Teste em múltiplos ciclos (bull + bear + lateral) |
| Execução perfeita | Assume que ordens são sempre preenchidas | Adicione slippage e simule rejeições |
| Dados ruins | Gaps, dados incorretos, survivorship bias | Use feeds de dados verificados |
Metodologia de Backtesting em 5 Etapas
Etapa 1: Hipótese Clara
Antes de codificar, defina:
- O que a estratégia faz? (ex: "compra quando RSI < 30 e fecha quando RSI > 60")
- Por que deveria funcionar? (lógica de mercado, não apenas fit histórico)
- Em que condições de mercado? (lateral, tendência, alta volatilidade)
Etapa 2: Separar Dados de Treinamento e Validação
Dados totais disponíveis: 4 anos de dados (2021-2024)
├── Treinamento (70%): 2021-2023
│ └── Aqui você otimiza os parâmetros
│
└── Validação / Out-of-Sample (30%): 2024
└── Aqui você testa sem tocar nos parâmetrosSe a estratégia funciona bem no treinamento mas mal na validação → está overfitted.
Etapa 3: Incluir Custos Reais
| Exchange | Par | Maker | Taker | Slippage típico |
|---|---|---|---|---|
| Binance | BTC/USDT Spot | 0,10% | 0,10% | 0,05% |
| Binance | BTCUSDT Perp | 0,02% | 0,05% | 0,03% |
| Bybit | BTC/USDT Spot | 0,10% | 0,10% | 0,05% |
| Bybit | BTCUSDT Perp (maker) | 0,02% | 0,05% | 0,03% |
| OKX | BTCUSDT Perp | 0,02% | 0,05% | 0,03% |
Etapa 4: Walk-Forward Analysis
Em vez de otimizar em todo o histórico de uma vez, otimize em janelas deslizantes:
Janela 1: Treina em Jan-Jun 2022 → Valida em Jul-Sep 2022
Janela 2: Treina em Apr-Sep 2022 → Valida em Out-Dez 2022
Janela 3: Treina em Jul-Dez 2022 → Valida em Jan-Mar 2023
...Se os parâmetros ótimos variam muito entre janelas → estratégia é instável.
Etapa 5: Paper Trading (Simulação ao Vivo)
Antes do capital real, rode a estratégia em tempo real mas com capital fictício:
- Duração mínima: 30-90 dias
- Volume: pelo menos 50 operações para ter significância estatística
- Se o performance ao vivo divergir muito do backtest → revise o modelo
Ferramentas de Backtesting
1. TradingView Strategy Tester (Pine Script)
Prós: mais fácil, visual, sem instalação, dados históricos de alta qualidade Contras: limitado a estratégias simples, sem flexibilidade para lógica complexa
//@version=5
strategy("Backtest Simples", initial_capital=10000,
commission_type=strategy.commission.percent, commission_value=0.1,
slippage=2)
rsi = ta.rsi(close, 14)
ema200 = ta.ema(close, 200)
if rsi < 30 and close > ema200
strategy.entry("Long", strategy.long)
if rsi > 65
strategy.close("Long")Veja os resultados em Strategy Tester > Performance Summary.
Métricas mais importantes no TradingView:
- Net Profit
- Profit Factor
- Max Drawdown
- Total Closed Trades (mínimo: 30-50 trades)
- Percent Profitable
2. VectorBT (Python) — O Mais Rápido
Por que usar: testa milhares de combinações de parâmetros em segundos, usando NumPy + Numba para performance de nível C.
pip install vectorbtimport vectorbt as vbt
import pandas as pd
# Download de dados históricos
btc = vbt.YFData.download("BTC-USD", period="2y").get("Close")
# RSI com vectorbt
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 e calcular resultado
portfolio = vbt.Portfolio.from_signals(
btc,
entries,
exits,
init_cash=10_000,
fees=0.001, # 0,1% por operação
slippage=0.0005 # 0,05% de slippage
)
# Métricas
print(portfolio.stats())
portfolio.plot().show()Otimização de parâmetros em grade:
# Testar todas as combinações de RSI (10 a 20) e threshold (25 a 35)
rsi = vbt.RSI.run(btc, window=vbt.Default(range(10, 21)))
entries = rsi.rsi_below(vbt.Default(range(25, 36)))
exits = rsi.rsi_above(65)
portfolio = vbt.Portfolio.from_signals(btc, entries, exits,
init_cash=10_000, fees=0.001)
# Heatmap de profit factor por combinação
portfolio.profit_factor.vbt.heatmap(
x_level="rsi_above", y_level="rsi_below"
).show()3. Freqtrade — Bot + Backtesting Completo
O Freqtrade é um framework open-source que inclui bot, backtesting, otimização e paper trading — tudo integrado.
pip install freqtrade
freqtrade create-userdir --userdir user_dataCriar estratégia:
# user_data/strategies/RSIStrategy.py
from freqtrade.strategy import IStrategy
import talib.abstract as ta
import pandas as pd
class RSIStrategy(IStrategy):
timeframe = '1h'
stoploss = -0.05 # Stop de 5%
roi = {"0": 0.10} # Take profit de 10%
def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict):
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
dataframe['ema200'] = ta.EMA(dataframe, timeperiod=200)
return dataframe
def populate_entry_trend(self, dataframe, metadata):
dataframe.loc[
(dataframe['rsi'] < 30) &
(dataframe['close'] > dataframe['ema200']),
'enter_long'
] = 1
return dataframe
def populate_exit_trend(self, dataframe, metadata):
dataframe.loc[
dataframe['rsi'] > 65,
'exit_long'
] = 1
return dataframeRodar backtesting:
freqtrade backtesting \
--strategy RSIStrategy \
--timeframe 1h \
--timerange 20220101-20231231 \
--fee 0.001Resultado gerado automaticamente:
BACKTESTING REPORT
------------------
Pair | Trades | Win% | Profit | Drawdown
BTCUSDT | 87 | 54% | 23.4% | -8.2%
ETHUSDT | 92 | 51% | 18.7% | -9.1%
Total | 179 | 52% | 21.1% | -9.8%Otimização com Hyperopt:
freqtrade hyperopt \
--strategy RSIStrategy \
--hyperopt-loss SharpeHyperOptLoss \
--epochs 200 \
--timeframe 1h4. Backtrader — Clássico e Flexível
pip install backtraderimport backtrader as bt
class RSIStrategy(bt.Strategy):
params = dict(rsi_period=14, rsi_oversold=30, rsi_overbought=65)
def __init__(self):
self.rsi = bt.indicators.RSI(period=self.p.rsi_period)
def next(self):
if self.rsi < self.p.rsi_oversold and not self.position:
self.buy()
elif self.rsi > self.p.rsi_overbought and self.position:
self.sell()
cerebro = bt.Cerebro()
cerebro.addstrategy(RSIStrategy)
cerebro.broker.setcash(10000)
cerebro.broker.setcommission(commission=0.001)
# Adicionar dados (ex: CSV da Binance)
data = bt.feeds.GenericCSVData(dataname='btcusdt_1h.csv',
dtformat='%Y-%m-%d %H:%M:%S',
datetime=0, open=1, high=2, low=3, close=4, volume=5)
cerebro.adddata(data)
cerebro.run()
cerebro.plot()Métricas Essenciais para Avaliar uma Estratégia
| Métrica | Fórmula / Definição | Referência Mínima |
|---|---|---|
| Net Profit | Lucro total no período | Positivo |
| Win Rate | Trades vencedores / total | > 40% (depende do payoff) |
| Profit Factor | Ganhos brutos / Perdas brutas | > 1,5 |
| Max Drawdown | Maior queda de pico a vale | < 20% |
| Sharpe Ratio | (Retorno - RF) / Volatilidade | > 1,0 |
| Sortino Ratio | Similar ao Sharpe, só downside risk | > 1,5 |
| Avg Trade Duration | Tempo médio por operação | Depende da estratégia |
| Recovery Factor | Net Profit / Max Drawdown | > 3 |
O payoff importa tanto quanto o win rate:
Estratégia A: 60% win rate, lucro médio = US$50, perda média = US$150
Expectativa = (0,60 × 50) - (0,40 × 150) = 30 - 60 = -US$30 por trade ✗
Estratégia B: 40% win rate, lucro médio = US$200, perda média = US$80
Expectativa = (0,40 × 200) - (0,60 × 80) = 80 - 48 = +US$32 por trade ✓Próximos Passos
- Freqtrade: Bot Open-Source Completo — backtesting + produção integrados
- VectorBT: Backtesting Ultrarrápido — otimização de parâmetros em larga escala
- API Trading com Python — do backtest ao bot em produção
Aviso Legal: Conteúdo educativo. Performance passada não é garantia de resultado futuro. Não constitui recomendação de investimento.
Introdução ao API Trading com Python
Como começar a operar cripto via API com Python: autenticação, dados de mercado em tempo real (REST e WebSocket), colocação de ordens, monitoramento de posições e gestão de risco no código.
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.