Atualizado em 07/08/2026
Todo mundo que otimiza estratégia já viveu a mesma cena: a curva de capital do backtest sobe, o Sharpe passa de 4, e no mercado real aquilo derrete. O motivo é aritmético. Quando você guarda o melhor entre muitos candidatos, o número que sobrou carrega a sorte de amostra de todos os outros. Já escrevi aqui sobre o Sharpe deflacionado como forma de descontar quantos testes você fez, e sobre os limites da otimização de Markowitz quando a matriz de covariância é estimada em cima do passado. Este texto é sobre o passo anterior: medir a probabilidade de que a estratégia campeã do seu backtest seja pura sorte de amostra. E vou contar com número próprio, porque a minha carteira foi reprovada nesse teste.
O que a pesquisa mostra: Bailey, Borwein, López de Prado e Zhu formalizaram a Probabilidade de Overfitting do Backtest (PBO) via validação cruzada combinatoriamente simétrica: um PBO acima de ~50% condena o processo de seleção, porque a estratégia campeã do in-sample tem mais de metade de chance de ficar abaixo da mediana fora da amostra (Bailey, Borwein, López de Prado e Zhu, 2017).
A matemática de por que testar muito fabrica lucro no papel
Um único backtest te dá um número, não uma probabilidade. O problema começa quando você roda o segundo, o décimo, o milésimo. O melhor Sharpe entre N configurações cresce com o número de tentativas mesmo quando nenhuma delas tem vantagem real. A aproximação que uso é a do False Strategy Theorem de Bailey e López de Prado: o máximo Sharpe esperado só por acaso cresce com a raiz de 2 · ln(N) dividida pela raiz do horizonte de teste. Em texto: quanto mais coisas você testa, mais alto fica o teto do que o ruído sozinho consegue produzir, e esse teto sobe rápido no começo (por causa do logaritmo) e depois desacelera.
Botei número no meu próprio caso porque o StrategyQuant X me ilude exatamente por aqui. O loop multi-seed dele acha 600 estratégias, valida, gera mais 600 com sementes novas, repete. O número efetivo de tentativas fica enorme. Com um build de ~3 anos, o melhor Sharpe in-sample só de sorte (zero vantagem) é ~1,8 com 600 tentativas e ~2,5 com 60.000. Ou seja: “o SQX achou 600 estratégias lucrativas” não é evidência de nada. Ruído puro também produz centenas de sobreviventes. Foi a primeira coisa que precisei aceitar antes de confiar em qualquer carteira minha.
PBO: a probabilidade de a campeã ser sorte
Bailey, Borwein, López de Prado e Zhu (2017) formalizaram isso no PBO via CSCV (Combinatorially Symmetric Cross-Validation). A conta é simples. Você pega a matriz de resultados de todas as N configurações que testou, corta o período em S pedaços, e em todas as combinações possíveis de “metade treino / metade teste” você pergunta: a configuração que foi a melhor no treino, em que posição do ranking ela caiu no teste? Se a campeã do in-sample vira medíocre no out-of-sample com frequência, o seu processo de seleção está pescando ruído. O PBO é a fração dessas combinações em que a melhor do treino ficou abaixo da mediana no teste.
O valor de corte que uso é o dos próprios autores: PBO acima de ~50% condena o processo, porque quer dizer que a sua “melhor estratégia” tem mais de metade de chance de ficar na metade de baixo fora da amostra. A vantagem do CSCV sobre um walk-forward simples é que ele é livre de modelo e usa ranking, não retorno absoluto, então não depende de a era de teste ter sido boa ou ruim. Ele mede o vício do seu funil de seleção. É ali que o estrago acontece.
A minha carteira de 42 robôs, reprovada pela auditoria adversarial
Peguei um pool de 139 robôs e montei um construtor com seis regras de bom senso (risco por covariância, teto por fator, corte de clones por célula, lote igual). A saída foram 42 robôs, e todo número que eu media melhorou: Sharpe de 3,76 para 5,24, concentração em iene de 71% para 34%. Eu queria acreditar.
Antes de ligar qualquer coisa, pedi uma auditoria adversarial: quatro agentes re-derivando as contas de forma independente, com a tarefa explícita de derrubar a carteira. Eles derrubaram. Três achados.
O Sharpe 5,24 era ilusão de seleção. Decompondo o ganho, ele veio de média ×1,33 e volatilidade ×0,95. Quase tudo saiu da média, e a volatilidade caiu 5%, ou seja o trabalho foi feito por manter os vencedores do período. Sortear 10 robôs por célula ao acaso dava Sharpe ~4,7, praticamente igual. E o meu Sharpe selecionado estava no percentil 100 de 2.000 sorteios. Fit-ao-alvo é isso: a carteira foi escolhida pelo Sharpe de 2024-2026 e depois avaliada pelo Sharpe do mesmo 2024-2026. Pra fechar, em dólar somado o resultado caiu (de $23,8 mil para $9,6 mil); só a média 1/N subia, porque eu tinha selecionado a média.
O “balanceado” era cosmético. Trocar iene por EUR/GBP/CAD não diversifica: todos são o mesmo fator dólar. Colapsando no fator real, a carteira tinha ~1,8 fatores de risco independentes, idêntico ao pool solto de 139. O rebalanceamento mexeu no nome do par e deixou o fator dólar intacto.
O resultado era memória da janela. A frase do red-team que eu guardei: “o exercício responde qual pedaço de 2024-2026 teria sido melhor em 2024-2026.” Uma janela de três anos responde sobre ela mesma e cala sobre a era seguinte. Veredito: não usar a carteira. Na hora eu registrei que o método refinava com precisão um pool contaminado, e essa parte do registro estava errada, como conto abaixo.
Tem um segundo capítulo, e ele é um erro meu de leitura. Eu tinha acusado o pool inteiro de ser 100% in-sample. Quando revisei o arquivo de configuração do SQX ponta a ponta, vi que estava errado: o pipeline tinha, sim, um out-of-sample de verdade entre 2021 e 2023 antes de qualquer coisa; o rótulo “IST” nos CSVs era só o nome do reteste final, não ausência de OOS. Corrigi o registro. O que sobreviveu à correção é o diagnóstico principal: o pool de robôs estava limpo, e o overfitting morava na minha camada de seleção, que escolheu o maior lucro dentro de 2024-2026 e mediu o resultado em 2024-2026. Circular. A lição transferível é dupla: o rótulo de um export não conta a história do processo, e a camada que otimiza merece a mesma desconfiança que os dados.
CPCV, purga e embargo: quando o PBO não basta
O PBO diz se o seu processo de seleção é vicioso. Ele não te dá a vantagem forward. Pra isso você precisa medir fora da janela de seleção de verdade, e é aí que entra o CPCV de López de Prado (2018): Combinatorial Purged Cross-Validation. Duas peças importam. A purga remove do treino as amostras cujo horizonte se sobrepõe ao teste, senão informação do futuro vaza pra trás (trades que ainda estavam abertos na fronteira). O embargo é uma janela de segurança depois do teste, pra matar a autocorrelação residual de séries financeiras. Sem essas duas, o seu cross-validation vaza e te devolve um número otimista demais.
No meu projeto isso virou um walk-forward honesto: seleciona os robôs numa era, mede na era seguinte, cinco dobras expandindo de 2019 a 2026, 300 sorteios por dobra como benchmark aleatório. O resultado mais importante que o projeto já produziu é que o controle de risco da esteira generaliza forward (bate 75-100% dos sorteios aleatórios do mesmo tamanho em 4 das 5 dobras, percentil mediano 90), ao contrário do min-var e do teto de cauda, que desabaram pra percentil ~50 = fitting puro. Mas o mesmo walk-forward me deu o número que uso pra dimensionar risco: a inflação do drawdown da seleção pro forward é 1,75×, só pelo viés de escolher. O drawdown real fora da amostra é quase o dobro do que o backtest mostra, antes mesmo de contar mudança de regime.
Como uso PBO/CSCV/DSR na prática, com os furos que encontrei
Na minha esteira, a validação estatística é um módulo de verdade (numpy puro): PSR, DSR, PBO-CSCV, block bootstrap estacionário, dominância estocástica, Memmel. Rodo três camadas. A primeira é o portão de overfitting: PSR acima de 0,95, DSR com o N do funil real (nunca N=5 de mentirinha), PBO-CSCV nos robôs individuais, checagem de plateau e concentração. Só quem passa nesse portão avança pro ranking robusto e pro desempate.
Nos cinco portfólios finais que testei, a camada de overfitting passou: não há overfit (PSR=1, DSR~1 até N=500, PBO baixo, ~0,075). O desconforto honesto veio depois: eles ficaram estatisticamente empatados. O que eu tinha eleito como campeão pelo Calmar (chamo de P3) não lidera o ranking médio; quem lidera por parcimônia é o P2, com 14 robôs. Ninguém tem probabilidade de vitória acima de 50% no bootstrap, ninguém domina no SSD, os testes de Memmel dão todos não-significantes. Passar no PBO te diz que você não está overfitado. Não te diz que você achou o melhor. São perguntas diferentes.
E um furo meu, que vale mais contado do que escondido: a minha própria função de PBO estava com o ranking invertido numa versão, reportando o complemento (1 − PBO). Cheguei a anotar “PBO dos robôs = 0,91” achando que estava ótimo, quando na verdade 0,91 seria péssimo; o valor certo, depois do conserto, era ~0,09. Quem calcula PBO com código próprio: teste o sinal com um caso degenerado conhecido antes de confiar. A ferramenta que mede overfitting também pode estar overfitada ao seu bug.
Não foi o único erro de código que peguei no caminho. Uma regra morta na entrada do robô de grid inflou o resultado de 23 robôs em cerca de 36%, e o ranking dos vencedores se inverteu depois do conserto.
A regra de bolso com que fico: estabeleça o mecanismo econômico antes de otimizar; registre N (o número real de tentativas, incluindo os multi-seed); estime PBO por CSCV; desconte o Sharpe pelo N efetivo (no meu caso o N efetivo era ~2-3 fatores, não 42); e confirme fora da janela de seleção com purga e embargo. Nenhuma métrica isolada decide. PBO baixo é condição necessária, não suficiente.
Os números deste artigo
| Métrica | Valor | Contexto |
|---|---|---|
| Sharpe da carteira de 42 robôs | 5,24 | no percentil 100 de 2.000 sorteios |
| Decomposição do ganho de Sharpe | média ×1,33 / vol ×0,95 | ganho veio de manter vencedores |
| Resultado em dólar somado | $23,8 mil → $9,6 mil | a seleção derrubou o líquido |
| Fatores de risco independentes reais da carteira | ~1,8 | colapsando no fator dólar |
| Inflação do drawdown seleção → forward | 1,75× | só por viés de seleção |
| PBO dos portfólios finais | ~0,075 | bem abaixo do corte de 50% |
PBO substitui o walk-forward?
Não. O PBO mede se o seu processo de seleção premia ruído, usando ranking dentro do próprio conjunto de testes. O walk-forward mede se a vantagem sobrevive numa era que não existia quando você selecionou. São complementares: um PBO baixo com walk-forward ruim significa que você selecionou de forma disciplinada uma estratégia que mesmo assim não generaliza. Foi mais ou menos o meu caso.
Qual PBO é aceitável?
Os autores usam 50% como divisor: acima disso, a campeã do in-sample tem mais chance de ficar abaixo da mediana no out-of-sample do que acima, o que condena o processo. Na prática eu trabalho bem abaixo disso (os meus portfólios deram ~0,075). Mas cuidado: PBO baixo com N mal contado é falsa segurança. O N tem que incluir toda a busca, inclusive as sementes que você descartou.
Quantos testes “contam” para o overfitting?
Todos, inclusive os que você jogou fora. É o erro mais comum. Se o seu otimizador rodou 600 combinações e você guardou 3, o N para deflação é 600 (ou mais, se houve multi-seed), não 3. Foi por ignorar isso que “600 sobreviventes” me pareceram vantagem, quando o teto do puro acaso já era Sharpe ~1,8.
PBO é o mesmo que Sharpe deflacionado?
Não, são parentes. O Sharpe deflacionado (DSR) ajusta o valor do Sharpe pra baixo dado o número de testes e a não-normalidade dos retornos, devolvendo uma probabilidade de o Sharpe verdadeiro ser positivo. O PBO devolve a probabilidade de a sua seleção ser overfitada. Uso os dois juntos na mesma camada.
De onde vem o conceito de PBO?
Do grupo de David Bailey, Jonathan Borwein, Marcos López de Prado e Qiji Jim Zhu, no artigo de 2017 no Journal of Computational Finance. O CPCV com purga e embargo está no livro de López de Prado de 2018. A motivação empírica maior vem de Harvey, Liu e Zhu (2016), que catalogaram mais de 300 fatores “descobertos” na literatura e argumentaram que o corte tradicional de t > 2,0 é frouxo demais; o honesto fica perto de t > 3,0.
Referências
- Bailey, D. H.; Borwein, J. M.; López de Prado, M.; Zhu, Q. J. (2017). The Probability of Backtest Overfitting. Journal of Computational Finance, 20(4). link.
- Bailey, D. H.; López de Prado, M. (2014). The Deflated Sharpe Ratio: Correcting for Selection Bias, Backtest Overfitting, and Non-Normality. Journal of Portfolio Management, 40(5). link.
- López de Prado, M. (2018). Advances in Financial Machine Learning. Wiley. (CPCV, purged cross-validation, embargo). link.
- Harvey, C. R.; Liu, Y.; Zhu, H. (2016). … and the Cross-Section of Expected Returns. Review of Financial Studies, 29(1). link.
- CPCV: a validação cruzada que não vaza, e o bug que inverteu o meu resultado
- Anatomia de uma Estratégia Real: Keltner e Estocástico no EUR/USD, e a Degradação de Só 1%
- Anatomia de uma Estratégia Real: Bollinger e WaveTrend no EUR/USD, 7 Anos Abertos Sem Esconder Nada
- Diário de um Portfólio de Robôs (7): A Esteira, a Máquina que Monta o Portfólio em Seis Estações
Presente para Leitores: Robô de Gradiente Linear Gratuito
Estou liberando o acesso ao meu setup pessoal de Gradiente Linear sem custo nenhum. É só clicar e me pedir o arquivo.
Quem escreve: Flávio Araújo
Trader algorítmico há mais de 13 anos, MBA em Mercado de Capitais e Derivativos. Mantém um laboratório próprio que já rodou mais de 20 milhões de backtests e analisou mais de 20 mil estratégias, e opera um portfólio de robôs acompanhado publicamente no blog. LinkedIn · Instagram · YouTube
