Por que um ótimo backtest pode não significar nada — e como diferenciar uma vantagem real de uma ilusão de curve-fitting.
Você termina a varredura, escolhe o conjunto de parâmetros com o maior Sharpe, e a curva do backtest fica boa demais para ser verdade. Quando ela realmente roda, o desempenho não se distingue do aleatório. O que aconteceu no meio tem nome.
Uma estratégia está overfitted quando seus parâmetros foram ajustados tão precisamente aos dados históricos que a estratégia está essencialmente memorizando o passado em vez de aprender uma regra generalizável. Ela parece excepcional no backtest e tem desempenho ruim — ou aleatório — ao operar ao vivo.
O overfitting nem sempre é intencional. Ele acontece naturalmente sempre que você:
Suponha que você varra 100 combinações de parâmetros. Mesmo que sua estratégia não tenha nenhuma vantagem, algumas combinações vão produzir um Sharpe positivo só por acaso — cerca de 5 em 100 a um nível de significância de 5%. Se você escolher a melhor e reportar como o desempenho da sua estratégia, está reportando ruído como sinal.
Esse problema piora quanto mais parâmetros você varre. Uma estratégia com 2 parâmetros independentes em uma grade 20×20 tem 400 combinações. Uma estratégia com 4 parâmetros em uma grade 10×10×10×10 tem 10,000. Cada dimensão adicional multiplica a chance de esbarrar em um pico sortudo.
A técnica prática mais importante para evitar overfitting é não escolher o pico.
Observe um mapa de calor de Sharpe de uma varredura de parâmetros. A célula absolutamente melhor pode mostrar Sharpe 1.8. Um passo à esquerda: 0.4. Um passo acima: 0.3. Esse pico é frágil — ele existe porque a combinação exata de parâmetros acabou se ajustando a alguns eventos específicos de mercado nos seus dados de treino.
Em vez disso, encontre o platô: a região onde o Sharpe é consistentemente alto em muitas combinações de parâmetros vizinhas. Se o Sharpe é 1.2 em uma vizinhança 3×3 de valores de parâmetros, isso é um sinal robusto — a vantagem existe em uma faixa de parâmetros, não apenas em um ponto específico.
# O find_plateau do Blave Agent: escolhe a vizinhança com a # maior média de Sharpe em uma janela 3×3 ao redor de cada célula — # não a única célula com o valor máximo. best_idx = argmax(neighborhood_average_sharpe)
É por isso que o script de varredura de parâmetros — o scan.py que fica na pasta de cada estratégia — usa find_plateau em vez de simplesmente pegar o melhor Sharpe. Um conjunto de parâmetros situado no topo de um platô suave tem muito mais chance de generalizar do que um situado em um pico agudo cercado de baixo desempenho.
A única forma válida de medir o desempenho real de uma estratégia é testá-la em dados que ela nunca viu. Se você otimizar os parâmetros usando dados de 2020–2023 e depois avaliar em 2024, o desempenho de 2024 é uma estimativa genuinamente out-of-sample.
Se você otimizar em 2020–2024 e reportar o desempenho de 2020–2024: isso é in-sample. Mesmo que você não tivesse a intenção de fazer overfitting, o processo de otimização usou implicitamente os resultados de 2020–2024 para selecionar os parâmetros. O Sharpe reportado inclui o benefício da retrospectiva.
| Método | Válido? | Notas |
|---|---|---|
| Otimizar no histórico completo, reportar o desempenho do histórico completo | ✗ | In-sample — overfitting garantido |
| Otimizar nos primeiros 70%, reportar o desempenho dos últimos 30% | ✓ | Divisão simples treino/teste — válida, mas limitada |
| Walk-forward: otimizar em uma janela móvel, reportar o período seguinte | ✓✓ | Mais realista — mesmo método usado ao operar ao vivo |
Outra armadilha comum de overfitting é varrer toda a faixa de valores possíveis de parâmetros, incluindo valores extremos que acabam produzindo um Sharpe alto em um período histórico atípico.
O Blave Agent usa uma abordagem diferente para estratégias baseadas em limiares: derivar a faixa de varredura da própria distribuição do indicador. Ele toma o p5 e o p95 da distribuição histórica do indicador como as duas pontas, e o ponto médio aritmético dos dois — não a mediana — como divisor; os candidatos de entrada ficam na metade superior (do ponto médio até p95) e os de saída na metade inferior (de p5 até o ponto médio). Isso mantém os dois limiares fundamentados em faixas de dados observadas, evitando extremos claramente irrealistas.
Pico agudo no mapa de calor de Sharpe. A melhor combinação de parâmetros está cercada por valores muito mais baixos. Um passo de parâmetro em qualquer direção derruba o Sharpe em 0.5+. A vantagem não é robusta — é local.
O Sharpe do backtest não sobrevive out-of-sample. A estratégia mostra Sharpe 2.0 no período de treino e 0.2 em um período de teste reservado. Quanto maior a diferença, mais overfitted é a estratégia.
Poucos trades. Uma estratégia com 12 trades em 3 anos de backtest tem quase nenhum poder estatístico. Alguns poucos trades sortudos podem produzir um Sharpe de 2.0+ puramente por acaso. Exija pelo menos 30–50 trades completos antes de tratar as métricas do backtest como significativas.
Parâmetros suspeitosamente redondos. Se seus melhores parâmetros são SMA(50) / SMA(200) ou RSI(14) ou exatamente 1.0 / −1.0, muitas vezes isso é resultado de varrer e ter sorte em um valor "padrão" bem conhecido. Eles podem funcionar pelos motivos errados.
A estratégia só funciona em um regime de mercado. Se o desempenho do backtest é inteiramente impulsionado por um único período de alta ou de baixa, e é estável ou negativo em todos os outros, a estratégia pode ter aprendido aquele regime específico em vez de uma regra geral.
Não existe um corte universal, mas um princípio útil: todo parâmetro livre adicional deveria ter uma razão prévia para existir na lógica da estratégia. Não adicione um parâmetro porque ele permite ajustar melhor os dados — adicione porque ele representa uma dimensão genuína do mecanismo de mercado que você está explorando.
Uma estratégia com dois parâmetros que representam conceitos significativos (uma janela de sinal rápida e uma janela de confirmação lenta, por exemplo) é mais defensável do que uma estratégia com seis parâmetros em que vários deles foram adicionados para "eliminar" períodos de perda específicos visíveis no gráfico.