Janela longa passa uma sensação de segurança que raramente se sustenta. Trinta dias de dados, milhares de registros, um número no fim — parece que o tamanho da amostra resolve a dúvida sozinho. Resolve, desde que o sistema medido seja o mesmo do primeiro ao último dia da janela. Quase nunca é.

Deploy, fix, cutover, troca de prompt. Qualquer um deles muda o comportamento medido no meio do período, e o agregado continua saindo com casas decimais e cara de verdade. A pergunta que passei a fazer antes de olhar qualquer número desses é sempre a mesma: isso descreve o sistema de hoje, ou uma mistura dele com o de ontem?

Trinta dias de forense mediram dois pipelines diferentes

No motor de day trading — o DT Dashboard, Python com databento e ib_async — rodei um forense de 30 dias sobre o pipeline de shadow-capture para responder a uma pergunta direta: quantos trades o sistema deixou passar sem registrar? A resposta veio limpa. 1.603 trades genuinamente perdidos.

O número estava certo. A leitura estava errada. Aqueles 1.603 não se espalhavam pela janela: se concentravam em abril e maio, antes de um fix de captura — SC-1, no jargão interno do projeto — entrar em produção. A janela cobria o antes e o depois do fix, e a soma juntou os dois sem nenhum rótulo dizendo qual registro veio de qual versão.

Do jeito que estava, o número apontava para um bug ativo no pipeline, do tipo que faz o time abrir o código na segunda de manhã. Era resíduo. O pipeline responsável pela maior parte daquela perda já não existia — e o próprio fix que eu queria avaliar era a razão de o total ter ficado tão alto.

O mesmo erro volta disfarçado de resultado bom

No Solo Trader — trading automatizado com gates de risco, stops por drawdown e trilha de auditoria versionada — fiz o cutover de uma sleeve, uma fatia da estratégia, para o novo modo de operação. No primeiro dia, o excesso de retorno sobre o benchmark apareceu em +146%. Um dia. Nenhuma estratégia faz isso.

O benchmark estava ancorado no capital inicial da conta, US$ 100 mil, e não no equity do instante exato do cutover, US$ 246 mil. A comparação media a sleeve nova contra um ponto de partida que pertencia a um sistema anterior, que já tinha rodado um bom tempo antes dela existir.

O número não estava calculado errado. Ele respondia a uma pergunta diferente da que eu achava que estava fazendo.

É o mesmo defeito do forense, com o sinal trocado. Lá, uma janela atravessou um fix e inflou um problema que já tinha sido resolvido. Aqui, uma âncora atravessou um cutover e inflou um resultado que nunca aconteceu. Nos dois casos, cada conta isolada estava correta.

LEIA TAMBÉM · Caso realUm resultado bom demais é um bug de dados até prova em contrárioQuando um número parece bom demais, quase sempre o dado está errado. Comparar campos entre si — o fechamento tem que estar entre o mínimo e o máximo do dia — revela erros que checar cada campo sozinho nunca revela.

A causa é a mesma nos dois — a métrica não sabe que o sistema mudou

Métrica calculada sobre uma janela que atravessa uma mudança de comportamento é média ponderada de dois sistemas. O peso de cada um é a fatia da janela que ele ocupou, e essa fatia não aparece em nenhum lugar do resultado.

Trading não tem exclusividade nisso. Vale para teste A/B cujo período pega um deploy no meio; para métrica de performance em janela móvel que atravessa uma troca de infraestrutura; para avaliação de modelo comparando semanas em que o prompt mudou; para qualquer KPI de série temporal em que uma alteração mexeu no comportamento medido. Taxa de conversão, latência p95, custo por chamada — todos caem na mesma armadilha.

Separe por safra antes de interpretar, e pague o custo da instrumentação

A correção nos dois casos foi a mesma: separar por safra. Definir o instante do corte — o deploy, o fix, o cutover — recalcular cada trecho por conta própria e só então comparar. No forense, isso transformou "1.603 perdidos" em duas contagens com significados distintos: o passivo do pipeline antigo e a taxa real do pipeline atual. No Solo Trader, reancorar o benchmark no equity do cutover devolveu o excesso de retorno ao território do plausível.

A contrapartida está na instrumentação, e ela precisa existir antes de o problema aparecer. Cada registro tem que sair carimbado com a versão do sistema que o gerou, ou com o instante do evento que separa as safras. Sem esse carimbo, o corte não pode ser refeito depois que o dado virou agregado — e agregado é justamente o formato em que a métrica chega para quem vai decidir alguma coisa com ela.

Carimbar versão é barato quando entra junto com o pipeline e caro quando entra depois, porque a essa altura o histórico já foi gravado sem ela. Recomendo tratar o campo de versão como obrigatório em qualquer tabela de evento que alguém um dia vá agregar, mesmo quando o sistema ainda tem uma versão só.

LEIA TAMBÉM · OpiniãoA única checagem confiável num pipeline agendado é a idade do artefatoO painel diz que a tarefa está pronta para rodar, mas isso só significa que ela existe. Para saber se ela funcionou de verdade, olhe se o resultado dela é recente: o arquivo, a linha nova, o dado do dia.

O teste cabe em uma pergunta, e eu faço antes de olhar qualquer agregado: algum deploy, fix ou cutover caiu dentro dessa janela? Se caiu, corte por safra antes de interpretar. Se a métrica sobreviver ao corte sem mudar de sinal, ela era confiável do jeito que estava — e, naquele caso específico, eu estou errado.