Aqui está uma linha de um arquivo diário de ações. NVDA, sexta-feira, 7 de junho de 2024, a última sessão antes de o desdobramento de 10 para 1 entrar em vigor.
| Coluna | Valor |
|---|---|
| data | 2024-06-07 |
| fechamento | 1208.88 |
| volume | 42,800,000 (arredondado) |
| split_factor | 1.0 |
| dividendo | 0.00 |
| adj_close | 120.8781 |
Deixei as colunas OHLC fora desta visualização de propósito. Elas voltam perto do fim e são justamente as que causam problemas sem chamar atenção.
Tudo o que importa nesta linha está no intervalo entre a segunda e a sexta coluna. Em 7 de junho, o mercado registrou 1208.88. Ninguém mais vai negociar por esse preço, porque a ação a que ele se referia já não existe como unidade. O valor 120.8781 é uma reconstrução, e não é simplesmente 1208.88 dividido por dez. Vamos examinar cada coluna.
data: 2024-06-07, e as outras 2 datas que importam mais
O desdobramento foi anunciado em 22 de maio de 2024, junto com os resultados.
A data de registro foi 6 de junho. As negociações começaram com os preços
ajustados pelo desdobramento na segunda-feira, 10 de junho. São 3 datas, e a
coluna split_factor do seu fornecedor de dados corresponde a
exatamente uma delas, normalmente a primeira sessão com o ajuste aplicado. Um
erro de 1 dia aqui é o bug de eventos corporativos mais comum que vejo, e
passa despercebido nos agregados: a curva de patrimônio sofre uma queda de 90%
ou um salto de 900% em um único dia. Um Sharpe calculado ao longo de 2,000
dias mal percebe isso, mas o drawdown máximo ou uma regra de stop-loss
certamente percebe.
O dividendo tem seu próprio problema de datas, e isso mudou para todo mundo em 2024. O dividendo trimestral da NVDA de $0.01 após o desdobramento teve data de registro em 11 de junho. A liquidação nos EUA passou para T+1 em 28 de maio de 2024, o que significa que a data ex-dividendo e a data de registro agora coincidem. Qualquer carregador que calcula a data ex-dividendo como "data de registro menos 1 dia útil", o que esteve correto por décadas, passou a aplicar silenciosamente os ajustes de dividendo 1 sessão antes do devido em junho de 2024. Nada gera erro. O fator simplesmente cai na linha errada.
Falhas em código de eventos corporativos nunca aparecem como exceções. Aparecem como um número deslocado em 1 dia que parece perfeitamente plausível.
fechamento: 1208.88 — o preço que não aparece no arquivo
Este é o preço bruto registrado e, na maioria dos pipelines de pesquisa, só
existe como uma coluna que ninguém lê. Os sinais são calculados com base em
adj_close. E qualquer regra que use um nível de preço por ação em
dólares passa a usar um número que nenhum participante do mercado jamais viu.
A escalada da NVDA rumo a $1,000 na primavera de 2024 foi real e teve fluxo de ordens de verdade por trás: números redondos atraíam o preço, os strikes de opções se concentravam em 950 e 1000, e cada aproximação trazia risco de manchetes. Nos dados ajustados, tudo isso acontece a $100. Se você está testando o comportamento em níveis psicológicos, a lógica de preenchimento de gaps perto de números redondos ou um recurso de proximidade de strike, está testando contra uma série de preços reescalada por um evento que ainda não havia acontecido.
O mesmo vale para os filtros do universo. "Excluir ações abaixo de $5" é um indicador válido de um conjunto real de problemas de microestrutura: spreads relativos amplos, regras de margem e regimes de tick. Se você aplica o filtro ao histórico ajustado, exclui empresas em períodos em que eram negociadas a $30 e que depois passaram por desdobramento reverso. Com o filtro "preço acima de $500", a NVDA some silenciosamente de todos os anos anteriores a junho de 2024. Filtros de preço devem usar preços brutos registrados. Ponto final.
split_factor: 1.0 — e o 0.1 na linha seguinte
O fator é um produto acumulado calculado retroativamente a partir de hoje. Cada linha anterior a 10 de junho de 2024 carrega um 0.1 deste desdobramento, multiplicado pelo 0.25 do desdobramento de 4 para 1 em 2021, multiplicado pelo que veio antes. O histórico da NVDA anterior a 2021 é escalado por 0.025; assim, uma barra registrada a $200 em 2019 aparece como $5.00.
Vale guardar 2 consequências. Primeiro, o histórico ajustado muda sempre que ocorre um novo evento corporativo. Um backtest que você rodou em maio de 2024 e outro que roda hoje produzem números diferentes com o mesmo código e as mesmas datas. Se você armazenou recursos em cache usando o símbolo e a data como chave, sem registrar a versão dos dados, agora tem um cache que mistura duas escalas. Incluímos a época do ajuste na chave do recurso exatamente por esse motivo; aprendemos isso depois de uma tarde bastante confusa.
Segundo, com um fator de escala de 0.025, uma ação que era negociada em incrementos de $0.01 agora se move em incrementos de $0.00025. Sua lógica de arredondamento ao tick, suas comparações de "esta é uma nova máxima" e suas verificações de igualdade entre números de ponto flutuante: tudo isso passa a operar muito abaixo da resolução que o mercado realmente tinha.
dividendo: 0.01 — o valor que tira todos os preços anteriores da grade de centavos
1 centavo. Parece ruído, mas é por isso que adj_close mostra
120.8781 em vez de um valor redondo como 120.888.
O fechamento de 10 de junho foi 121.79. O fator ex-dividendo é (121.79 − 0.01) / 121.79 = 0.99991789. Esse fator multiplica todos os preços anteriores a 11 de junho, então o valor 120.888, ajustado pelo desdobramento, passa a 120.878074. É pouco, mas permanente, e o mesmo ajuste se aplica em cada uma das mais de 60 datas ex-dividendo ao longo do histórico da NVDA. O efeito acumulado é o que importa: quando você chega a 2015, está olhando para um preço multiplicado por dezenas de fatores um tanto irracionais. Nenhum preço histórico ajustado permanece na grade de centavos.
Isso significa que toda comparação de == com um nível redondo é
falsa, toda verificação de "tocamos o preço limite?" precisa de uma
tolerância, e seu OHLC reconstruído deixa de satisfazer a invariável de que
low ≤ open ≤ high depois de um arredondamento ingênuo para 4 casas decimais.
Também significa que adj_close é uma série de retorno total,
enquanto close é uma série de retorno de preço; se você calcula
os retornos com uma e os drawdowns com a outra, mistura duas definições
diferentes do que aconteceu.
volume: 42,800,000 — o divisor que nem todo mundo aplica da mesma forma
É preciso multiplicar o volume de ações por 10 para compará-lo com as sessões após o desdobramento. Alguns fornecedores fazem isso. Outros não. Alguns ajustam o OHLC e deixam o volume bruto, o pior dos 3 casos, porque o arquivo parece coerente até você multiplicar o preço pelo volume.
A decisão mais sensata é parar de usar o volume de ações como recurso e usar o volume financeiro, que por definição não muda com desdobramentos. Um filtro de liquidez baseado na média de 20 dias do volume financeiro não precisa de nenhuma lógica de ajuste e não pode ser quebrado por um evento corporativo. Recursos invariantes são melhores que código de ajuste correto, porque é preciso continuar acertando esse código de ajuste.
3 formatos de arquivo de fornecedores, 3 modos de falha.
| O que é fornecido | O que falha |
|---|---|
| Somente fechamento ajustado, OHLC bruto | A lógica de gaps e intradiária calcula com 2 escalas de preço |
| OHLC ajustado, volume bruto | Volume financeiro desviado pela proporção do desdobramento; filtros de ADV falham |
| OHLCV bruto mais colunas de fatores | Nada, se você aplicá-los. Tudo, se aplicá-los na linha errada |
As colunas que não estão aqui: adj_open, adj_high, adj_low
Agora vamos recolocar o OHLC. Se um feed ajusta apenas o fechamento e sua
estratégia calcula um gap noturno como open / prev_adj_close − 1,
então, em 10 de junho de 2024, calcula 120.37 / 120.8781 − 1, um valor
razoável, por volta de −0.4%. Se você volta o mesmo código para 7 de junho de
2024, ele usa a abertura do arquivo bruto (cerca de 1207) contra um fechamento
ajustado por 0.025 devido a desdobramentos anteriores, e produz um gap de
vários milhares por cento.
Qualquer operação que misture uma coluna bruta com uma ajustada faz contas entre dois sistemas de coordenadas. Agora trato as leituras que misturam ajustes como uma verificação obrigatória no carregador, em vez de algo de que cada pesquisador precisa se lembrar, porque ninguém vai se lembrar, eu inclusive.
O que nenhuma coluna informa: quantas ações você realmente teria comprado
Este é o ponto que custa dinheiro no modelo de custos do backtest e é o motivo de eu estar escrevendo sobre um desdobramento de ações.
As comissões sobre ações nos EUA costumam ser cobradas por ação. Vamos considerar $0.005, com um mínimo de $1.00 por ordem, uma faixa fixa comum em corretoras de varejo. Agora faça o backtest de uma posição de $400,000 em NVDA 1 ano antes do desdobramento, quando o preço bruto estava perto de $400 e o preço ajustado aparece como $40.
| Ações | Comissão | |
|---|---|---|
| O que aconteceu de fato (bruto $400) | 1,000 | $5.00 |
| O que o backtest calcula (ajustado $40) | 10,000 | $50.00 |
Mesma exposição, mesma operação, custo modelado 10 vezes maior. São $45 fictícios por perna, $90 por operação completa, e uma estratégia com giro diário acumula cerca de $22,000 por ano em custos que nunca existiram. Em uma carteira de $400k, isso representa 5.6 pontos percentuais do retorno anual, inteiramente fabricados por um divisor. Neste caso, você parece ter resultados piores que os reais, o que dá para tolerar.
Desdobramentos reversos operam na direção oposta, e esse é o sentido perigoso. Um desdobramento reverso de 1 para 10 faz o histórico ajustado mostrar preços 10 vezes maiores e quantidades de ações 10 vezes menores do que você teria negociado. Seu modelo de custos divide silenciosamente por 10 a comissão por ação. Desdobramentos reversos são comuns no universo de small caps abaixo de $5, com spreads amplos, onde as tarifas por ação são o maior item individual na estrutura de custos. O backtest favorece justamente os nomes que deveria penalizar.
A solução é simples e estrutural: dimensione as posições em dólares, converta para ações usando o preço não ajustado daquela data e cobre as tarifas por ação com base nessa quantidade. Mantenha a coluna de preço bruto no carregador para sempre, não como registro para auditoria, mas como entrada ativa do mecanismo de execução.
- Sinais e retornos: série ajustada.
- Quantidades de ações, tarifas por ação, arredondamento ao tick e filtros de nível de preço: série não ajustada.
- Liquidez e capacidade: volume financeiro, que não precisa de nenhum dos dois ajustes.
6 colunas, 1 linha, 1 evento corporativo bastante comum, anunciado com 3 semanas de antecedência e que não surpreendeu ninguém. O mercado lidou com isso em uma manhã. Reproduzir fielmente esse evento em um pipeline de pesquisa é bem mais difícil, e quase nunca dá para perceber que o pipeline falhou por uma mensagem de erro.
← Todos os artigos


