Como ajustar as cotações históricas dos ativos?

Usando Python para calcular os preços ajustados de ações na bolsa.

O preço ajustado é o preço da ação descontado os dividendos e outros eventos corporativos que aconteceram depois (bonificações, grupamentos, desdobramentos, etc).

Quando uma empresa paga dividendos aos seus acionistas esse valor pago sai do caixa de empresa e passa para a mão dos investidores, ou seja, após o dividendo a empresa tem menos dinheiro e consequentemente sua cotação é corrigida para refletir isso.

Esse post esta dividido em duas partes. Na primeira parte eu tento explicar sem muita complicaçao como calcular os fatores de ajustes para dividendos, JSCP, bonificações e grupamentos. Na segunda parte tem o código Pytho para fazer o ajuste no histórico de cotações.

Por que ajustar os preços?

Ajustar as cotações históricas de uma ação ou fundo imobiliário é importante para calcular o retorno real do ativo levando em conta os dividendos, bonificaões, grupamentos e desdobramentos.

Vamos pegar um exemplo para entender a importância de se ajustar os preços.

No final do mês de abril de 2018 as ações da EZTEC fecharam nos seguintes preços:

Data Ação Preço (R$)
2018-04-26 EZTC3 20,27
2018-04-27 EZTC3 20,45
2018-04-30 EZTC3 20,10

Olhando para esses preços você consegue responder qual foi o retorno de quem comprou a ação por R$ 20,27 no dia 26/abr e a vendeu por R$ 20,10 no dia 30/abr?

Fazendo uma rápida conta de padeiro, subtraindo o preço de compra pelo preço de venda, temos:

20.10 - 20.27 = -0.17

Um prejuízo de R$ 0,17 por ação.

O que os preços de fechamento sozinhos não mostram é que no dia 27/abr quem tinha ações da EZTEC (EZTC3) recebeu R$ 0,52 de dividendos.

Data Ação Preço (R$)
26/04/2018 EZTC3 20,27
27/04/2018 EZTC3 20,45
27/04/2018 EZTC3 (dividendo) +0,52
30/04/2018 EZTC3 20,10

Refazendo a conta considerando o dividendo que o investidor recebeu, o resultado na verdade é:

20.10 - 20.27 + 0.52 = 0.35

Um retorno positivo de R$ 0.35 por ação, ou +1.73%!

Como ajustar o histórico de preços?

Os eventos mais comuns que influenciam nos preços históricos são: dividendos, juros sobre capital próprio (JSCP), bonificações em ações, grupamentos e desdobramentos. Vamos ver com ajustar os preços para cada um deles.

No geral é bem simples. Tudo o que precisamos fazer é encontrar o fator de ajuste de cada evento e aplicar esse fator aos preços anteriores a esse evento.

Ajustando histórico de preços para dividendos e JSCP

Quando uma empresa paga dividendos ou JSCP é como se esse valor fosse descontado das cotações anteriores a esse pagamento. Então o fator de ajuste é:

$$ F = (1 - \frac{D}{P_{d_{-1}}}) $$

Nessa equação $$P_{d_{-1}}$$ é o preço do ativo na data-ex dividendos.

No exemplo anterior, do dividendo pago pela EZTEC em 27/abr/2018, temos:

$$ F = (1 - \frac{0.52}{20.45}) = 0.97 $$

Para ajustar os preços anteriores a esse dividendo temos que multiplicar eles por esse fator de ajuste de 0.97.

Data Ação Preço (R$) Fator Ajustado
26/04/2018 EZTC3 20,27 0.97 19,75
27/04/2018 EZTC3 20,45 0.97 19,93
27/04/2018 EZTC3 (dividendo) +0,52
30/04/2018 EZTC3 20,10 1.0 20,10

Usando os valores ajustados nós podemos calcular o retorno corretamente! 🎉

20.10 - 19.75 = 0.35

Ajustando o histórico de preços para bonificações em ações

As empresas podem optar por incorporar parte dos lucros no seu capital social. Quando isso é feito é distribuido novas ações aos acionistas.

Para calcular o fator de ajute de bonificações é só pegar a quantidade ganha de novas ações para cada ação possuída e subtrair de 1.

Por exemplo, em 26/abr/2019 quem tinha ações da EZTEC recebeu uma bonificação de 21.21 ações para cada 100 ações, ou 0.2121 ações para cada 1 ação.

$$ F = 1.0 - \frac{21.21}{100} = 1.0 - 0.2121 = 0.79 $$

Para ajustar os preços anteriores a esse evento basta multiplicar eles por esse fator de ajuste.

Ajustando histórico de preços para grupamentos e desdobramentos

Em algumas situações as empresas podem optar por desdobrar suas ações em em mais ações, geralmente para reduzir o preço do lote no mercado secundário. Ou então fazer o grupamento de várias ações em uma só, para aumentar o preço e evitar ser uma penny stock (empresas com ações negociadas abaixo de 5 USD).

Tanto no grupamento quanto no desdobramento o valor da empresa não muda. O que muda é apenas a quantidade de ações em circulação. Uma empresa que tinha ações cotadas à R$ 10 e decide fazer um grupamento de 3 para 1 vai passar a ter suas ações cotadas à R$ 30 e os acionistas passarão a ter um terço das quantidade de ações que tinham antes, apesar do valor final ser o mesmo.

Para os casos de grupamentos o fator de correção é o próprio fator de grupamento, e para casos de desdobramentos é 1 - fator de grupamento.

Ajustando os preços históricos com Python

Vamos ver na prática como faz para calcular os preços ajustados usando Python. Para isso montei 3 arquivos com dados que peguei do site da B3 sobre a EZTEC e Itaúsa. Faça o download deles para seu computador.

CSV Cotações CSV Dividendos CSV Eventos Corporativos

Se for sua primeira vez com o Python você pode seguir as instruções desse link para instalar o Python. Nós vamos usar também a biblioteca Pandas para ler os arquivos CSV e fazer as contas, você pode instalar ela com o comando pip install --user pandas.

import pandas as pd

O primeiro passo é ler os arquivos CSV.

O arquivo cotacoes.csv tem os preços de fechamento das ações ITSA4 e EZTC3.

cotacoes = pd.read_csv('./cotacoes.csv', index_col=['data', 'acao'], parse_dates=True)
cotacoes.head()
preco
data acao
2020-06-16 EZTC3 38.41
ITSA4 9.76
2020-06-15 EZTC3 37.50
ITSA4 9.56
2020-06-12 EZTC3 37.00

O arquivo dividendos.csv contém os dividendos e JSCP pagos por essas empresas.

dividendos = pd.read_csv('./dividendos.csv', index_col=['data', 'acao'], parse_dates=True)
dividendos.head()
dividendo preco_ex yield
data acao
2020-05-29 ITSA4 0.020000 10.43 0.191755
ITSA4 0.020000 8.86 0.225734
2020-04-28 EZTC3 0.294084 33.40 0.880490
2020-02-28 ITSA4 0.020000 12.74 0.156986
ITSA4 0.020000 12.01 0.166528

Por último a lista de eventos coporativos (bonificações, grupamentos e desdobramentos) que ocorreram.

eventos = pd.read_csv('./eventos_corporativos.csv', index_col=['data', 'acao'], parse_dates=True)
eventos.head()
evento fator_grupamento
data acao
2019-04-26 EZTC3 BONIFICACAO 0.787892
2018-05-30 ITSA4 BONIFICACAO 0.900000

O próximo passo é calcular os fatores de ajustes para os dividendos, bonificações, grupamentos e desdobramentos que ocorreram.

dividendos['fator_dividendo'] = 1.0 - dividendos['dividendo'] / dividendos['preco_ex']
eventos[eventos['evento'] == 'DESDOBRAMENTO']['fator_grupamento'] = 1.0 / eventos[eventos['evento'] == 'DESDOBRAMENTO']['fator_grupamento']
eventos[eventos['evento'] == 'BONIFICACAO']['fator_grupamento'] = 1.0 - eventos[eventos['evento'] == 'BONIFICACAO']['fator_grupamento'] / 100

Com todos os valores em mãos nós podemos unir tudo em um único dataframe. Isso vai ajudar no próximo passo na hora de calcular os históricos ajustados.

df = cotacoes.join(dividendos).join(eventos)

# se não houve dividendo ou evento corporativo o fator é 1 (nada muda)
df['fator_dividendo'].fillna(1.0, inplace=True)
df['fator_grupamento'].fillna(1.0, inplace=True)
df[(df['fator_dividendo'] != 1.0) | (df['fator_grupamento'] != 1.0)].tail(10)
preco dividendo preco_ex yield fator_dividendo evento fator_grupamento
data acao
2019-12-12 ITSA4 13.60 0.005950 13.60 0.043750 0.999563 NaN 1.0
2020-02-20 ITSA4 13.25 0.226000 13.68 1.652047 0.983480 NaN 1.0
ITSA4 13.25 0.217400 13.68 1.589181 0.984108 NaN 1.0
ITSA4 13.25 0.226000 13.25 1.705660 0.982943 NaN 1.0
ITSA4 13.25 0.217400 13.25 1.640755 0.983592 NaN 1.0
2020-02-28 ITSA4 12.01 0.020000 12.74 0.156986 0.998430 NaN 1.0
ITSA4 12.01 0.020000 12.01 0.166528 0.998335 NaN 1.0
2020-04-28 EZTC3 33.40 0.294084 33.40 0.880490 0.991195 NaN 1.0
2020-05-29 ITSA4 8.86 0.020000 10.43 0.191755 0.998082 NaN 1.0
ITSA4 8.86 0.020000 8.86 0.225734 0.997743 NaN 1.0

Antes de calcular vamos ordenar os regsitros de maneira descendente, por data (a cotação mais nova primeiro).

df.sort_index(ascending=False, inplace=True)

E então, para cada ação, vamos ajustar o histórico de preços dela.

def calcula_preco_ajustado(g):
    return g['preco'] * (g['fator_dividendo'] * g['fator_grupamento']).cumprod()

cotacao_aj = df.groupby('acao').apply(calcula_preco_ajustado)

Respondendo de novo a pergunta: qual foi o retorno de quem comprou a ação da EZTEC por RS 20,27 no dia 26/abr e a vendeu por RS 20,10 no dia 30/abr?

cotacao_aj.loc[('EZTC3', '2018-04-30')] / cotacao_aj.loc[('EZTC3', '2018-04-26')]
acao
EZTC3    1.017307
dtype: float64

🎉 retorno positivo de 1.73%!

Referências: