Meu Modelo Estava Lendo o Jornal de Amanhã
Por um tempo, um dos meus modelos parecia um gênio. Seu backtest era limpo, confiante, quase suave demais. Eu queria acreditar que finalmente tinha construído algo que funcionava.
Ele não havia aprendido nada que valesse a pena guardar. Tinha aprendido a trapacear — silenciosamente, através de um vazamento que eu mesmo havia construído, que o deixava ler informação do futuro antes de decidir o que fazer no passado.
O aluno suspeitosamente bom
Um modelo que tem um desempenho um pouco melhor do que você esperava é empolgante. Um modelo que tem um desempenho muito melhor do que teria qualquer direito de ter deveria te assustar. O meu era do segundo tipo: suave onde mercados reais são irregulares, confiante onde deveria estar incerto.
Em um post anterior, escrevi que o resultado mais perigoso é aquele que te lisonjeia. Era essa lição de novo, em uma fantasia mais sutil. Os números não eram absurdos desta vez — eram apenas bons demais, e “bom demais” é seu próprio tipo de bandeira vermelha, porque um edge genuíno em mercados é pequeno, ruidoso e difícil de conquistar. Um modelo que parece ter resolvido o mercado quase sempre encontrou, em vez disso, uma rachadura na sua simulação.
Por onde o futuro entrou
A rachadura estava na normalização — o passo nada glamouroso em que você reescala as entradas brutas para que um modelo possa aprender com elas. Para normalizar, você precisa de estatísticas: um centro, uma dispersão. E eu calculei essas estatísticas sobre o conjunto de dados inteiro de uma só vez.
Essa única escolha é onde o futuro vazou para dentro. Quando você calcula estatísticas sobre toda a história e depois as aplica a um ponto no passado, cada valor “normalizado” naquele momento passado codifica silenciosamente informação sobre dados que ainda não haviam acontecido. O modelo, olhando para qualquer instante dado, estava implicitamente sendo informado de algo sobre o formato de toda a linha do tempo — incluindo seu futuro. Ele nunca viu diretamente os preços de amanhã. Não precisava. Estava respirando um ar que tinha o amanhã misturado nele.
Por que o look-ahead é tão fácil de construir
O que torna o viés de look-ahead perigoso não é que seja difícil de criar. É que ele se infiltra através de um pré-processamento que, de resto, é totalmente comum. A maneira mais natural e legível de escrever o código — ajustar seu scaler nos dados, depois transformar os dados — já está errada para séries temporais, e nada reclama. Nenhuma exceção é lançada. Nenhum teste fica vermelho. Os números parecem completamente razoáveis. O único sintoma é que seu modelo é melhor do que deveria ser, que é o único sintoma que você tem menos motivação para investigar.
Essa é a armadilha do vazamento: ele não parece um bug. Parece sucesso.
O sinal revelador: brilhante aqui dentro, morto lá fora
Há uma assinatura reveladora, embora ela não seja prova por si só. Um modelo corrompido pelo look-ahead tende a ser brilhante nos dados contra os quais foi ajustado e a desmoronar no instante em que encontra dados nos quais não pode espiar. Uma grande lacuna entre a glória dentro da amostra e o colapso fora da amostra é um sinal de alerta de vazamento — embora também possa vir de overfitting, de uma mudança de regime, ou de custos que você subestimou. No meu caso, o vazamento era o culpado.
Então o teste que importava nunca foi “quão bom é o backtest?” Era “quanto pior ele fica quando eu torno a simulação honesta?” Quando fechei o vazamento, o desempenho caiu — e essa queda, por mais dolorosa que fosse, foi o primeiro número confiável que o sistema já havia me mostrado.
A correção: nunca use nada que você ainda não poderia saber
O reparo é um princípio, não uma linha de código: em qualquer momento da simulação, o modelo só pode usar informação que existia naquele momento ou antes dele. Para a normalização, isso significa derivar estatísticas de uma janela passada deslizante — ajustando sobre o que estava disponível até um dado instante, nunca sobre toda a linha do tempo, e nunca sobre um único ponto do futuro.
É mais lento. É mais trabalhoso. Produz backtests com aparência pior. Todos esses três são features, não custos, porque cada um deles é a simulação se recusando a deixar o modelo viajar no tempo. Um pipeline honesto paga um imposto em desempenho aparente, e esse imposto é o preço de números nos quais você pode realmente confiar.
Vazamento é uma família, não um único bug
A parte mais difícil de consertar isso não foi o normalizador. Foi perceber que o normalizador era apenas uma porta, e que o futuro podia entrar por muitas. O mesmo erro se esconde em como os rótulos são construídos, em features que secretamente resumem uma série inteira, em qualquer passo de pré-processamento que toque o passado e o futuro juntos. Feche um vazamento e você não fechou o vazamento; você apenas aprendeu como ele se parece, para poder ir procurar os outros.
Parei de pensar no look-ahead como um bug a ser consertado e comecei a tratá-lo como uma propriedade a ser auditada — algo que agora caço deliberadamente, partindo do pressuposto de que, se um resultado parece limpo demais, o futuro está entrando em algum lugar que eu ainda não verifiquei.
Por que backtests recompensam a trapaça
Por baixo de tudo isso há uma verdade desconfortável sobre backtests: eles não conseguem distinguir habilidade de retrospectiva. Um backtest paga exatamente o mesmo para um modelo que genuinamente antecipa o mercado e para um modelo que está silenciosamente lendo o gabarito. Ambos produzem uma curva linda. Dados estritamente à frente e nunca vistos são o teste mais forte que começa a separá-los — embora nem mesmo isso possa, por si só, provar que um pipeline está livre de vazamento.
É por isso que “ele foi bem no backtest” é o início de uma investigação, não o fim dela. Uma equity curve de boa aparência é uma pergunta: o modelo ganhou isso, ou eu acidentalmente o deixei trapacear? Toda a disciplina da pesquisa honesta é apenas aprender a fazer essa pergunta antes que o mercado a faça por você.
Um modelo lendo o jornal de amanhã sempre vai parecer um gênio. O gênio é seu, não dele — e ele vive inteiramente no vazamento que você esqueceu de fechar.
— Sem sinais, sem retornos, não é conselho de investimento.