Como descobri que meu modelo de IA estava com métricas infladas - e o que fiz para corrigir
Eu estava feliz. Meu modelo de previsão de criptomoedas mostrava 87% de acurácia em alguns horizontes. Passei dias otimista, já pensando em como escalar o sistema.
Era mentira.
Não havia nenhum edge real naqueles números. O que eu tinha era um bug silencioso de overlap temporal que inflava artificialmente cada métrica. E o pior: quanto mais eu treinava, mais confiante o modelo ficava — no erro.
Este artigo é sobre como descobri o problema, as técnicas que usei para corrigi-lo, e por que a validação honesta é a única régua que importa em machine learning para mercados financeiros.
O sintoma: blocos de acertos e erros consecutivos
Meu sistema registrava um "trade" a cada 2 segundos. Quando o horizonte alvo fechava, eu comparava a previsão com o preço real da Binance e contabilizava acerto ou erro.
Olhando o histórico, vi algo estranho:
[0, 0, 0, 0, 0, 0, 0, 0, ... 300 zeros seguidos ...]
[1, 1, 1, 1, 1, 1, 1, 1, ... 200 uns seguidos ...]
[0, 0, 0, 0, 0, 0, 0, 0, ... 400 zeros seguidos ...]
Nenhum modelo real acerta 200 vezes seguidas e depois erra 400 vezes seguidas. Isso não é aprendizado — é artefato.
A causa: eu estava registrando um "trade" a cada 2 segundos, mas para o horizonte de 30 minutos isso significava ~900 snapshots. Só que não eram 900 trades independentes — era o mesmo evento de mercado registrado 900 vezes. Se o mercado subiu por 30 minutos, todos os 900 snapshots eram contados como "acertos". A acurácia não media a habilidade do modelo — media se o mercado tinha subido ou descido naquele período.
Isso se chama autocorrelação temporal nas amostras de validação, e é um dos erros mais comuns — e mais devastadores — em projetos de machine learning para séries temporais financeiras.
A solução: três técnicas emprestadas das finanças quantitativas
Para corrigir isso, implementei três técnicas inspiradas no trabalho de Marcos López de Prado e na literatura de finanças quantitativas:
- Amostragem espaçada
Em vez de avaliar o modelo em todas as linhas da validação, passei a avaliar apenas em pontos espaçados pelo tamanho do horizonte. Para o horizonte de 5 segundos, por exemplo, pego 1 amostra a cada 5 linhas. Para 1 minuto, 1 amostra a cada 60 linhas.
Isso elimina o overlap artificial: cada ponto de validação agora representa uma decisão independente do modelo.
- Embargo temporal
Adicionei uma faixa de segurança entre os dados de treino e validação — do tamanho do maior horizonte (1 dia, no meu caso). Isso garante que nenhum alvo do treino "vaze" informação para o período de validação. É uma prática padrão em finanças quantitativas, mas raramente aplicada em projetos independentes.
- Múltiplos blocos de tempo
Em vez de um único corte cronológico 80/20 (que pode pegar um regime de mercado específico), passei a validar o modelo em 3-4 blocos independentes de 30 dias, espalhados por todo o histórico de 1 ano. Se a acurácia for consistente em todos os blocos, é sinal de edge real. Se variar de 60% para 40% dependendo do mês, era sorte de regime.
O teste definitivo: baseline naive e simulação de PnL
Para confirmar que o modelo não estava apenas surfando microestrutura de mercado, comparei suas previsões contra um baseline ingênuo — simplesmente "o próximo movimento repete o sinal do último retorno". Meu modelo performou bem acima do baseline, indicando que havia aprendido padrões além do óbvio.
Depois fui além: simulei o PnL líquido com custos reais de execução (taxa taker, spread e slippage). O resultado foi doloroso, mas esclarecedor:
· Edge de 56% em 5 segundos, confirmado em 3 blocos independentes.
· PnL líquido negativo em todos os blocos — as taxas consumiam qualquer vantagem.
Ou seja: o edge era real, mas economicamente inviável naquele horizonte com execução a mercado.
Outro achado: conflito de gradiente entre horizontes
Durante os testes, notei que os horizontes de 30s e 1min estavam consistentemente abaixo de 50% — pior que o aleatório. Investiguei e descobri a provável causa: negative transfer (conflito de gradiente) entre as cabeças de previsão.
Minha arquitetura tem 10 cabeças especializadas (uma por horizonte) compartilhando o mesmo backbone (Transformer + BiLSTM). Os horizontes curtos (5s-15s), que têm muito mais amostras e sinal mais forte, estavam dominando o gradiente e puxando as cabeças de horizontes médios na direção errada.
Testei inverter o sinal das previsões desses horizontes em múltiplos blocos e a acurácia saltou de ~43% para ~56% — confirmando que o sinal existia, mas estava sendo aprendido ao contrário. A correção para isso (loss balanceada por horizonte) já está em implementação.
O que aprendi (e por que isso importa)
- Métrica inflada é pior que métrica ruim. Prefiro 52% honestos do que 87% que desaparecem quando você testa direito. A validação honesta dói, mas é o único caminho para construir algo que funcione de verdade.
- Edge estatístico ≠ edge lucrativo. Acertar 56% das direções em 5s é impressionante, mas se as taxas consomem toda a vantagem, o sistema não é viável. É preciso simular custos reais antes de comemorar.
- Validação multi-bloco é indispensável. Um único corte cronológico pode pegar um regime de mercado favorável e dar uma falsa sensação de edge. Testar em múltiplos períodos é a única forma de saber se o padrão é consistente.
- Baseline naive é o primeiro filtro. Se um modelo não consegue bater um baseline simples, ele não está aprendendo nada — está apenas surfando ruído.
Próximos passos
O backbone (Transformer + BiLSTM) funciona — isso está provado. O limite agora está nas features: indicadores puramente de preço (EMA, RSI, MACD) não carregam sinal suficiente para horizontes mais longos (15min, 1h). Estou testando features de volume e fluxo de ordens (taker buy/sell ratio, volume z-score) para ver se consigo extrair vantagem nesses timeframes.
Se funcionar, terei um edge real em horizontes lucrativos. Se não funcionar, terei uma conclusão sólida: o limite está nos dados públicos disponíveis, não no modelo ou na metodologia.
Ambos os resultados são válidos. É assim que se faz engenharia de verdade.
Referências:
· GitHub do projeto: https://github.com/eventhorizon-ia/EventHorizon