O objetivo do post é mostrar como explorar os múltiplos das empresas listadas na B3, com o uso do software R. Os dados serão obtidos do site Fundamentus.
Ao clicar em empresa, no canto superior direito do site, você será direcionado para uma “busca avançada por empresa”, onde poderá inserir uma série de filtros à sua escolha, com valores mínimos e máximos, a fim de buscar as empresas que se encaixam neles.
Neste projeto, contudo, nós queremos obter os dados de todas as empresas da B3. Deixaremos, portanto, os filtros em branco, e clicaremos em “buscar” (embaixo da tabela, na parte inferior da página).
Pois bem, basta copiar e colar a tabela inteira para o Excel, atribuir nomes apropriados às colunas (o sinal de barra (“/”), bem como acentos e cedilhas, não são muito apropriados para comporem nomes de variáveis no R), e carregar o arquivo Excel para o ambiente de trabalho do R.
Contudo, antes de avançarmos, é necessário darmos um passo atrás, para preparar o nosso ambiente de trabalho no R:
# limpar tudo o que foi feito antes no ambiente de trabalho do R
rm(list=ls())
# pacotes que serão utilizados
packages <- c("xlsx", "janitor", "inspectdf", "data.table", "DataExplorer", "dplyr", "RColorBrewer", "corrplot")
# instalar pacotes, se necessário
installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) {
install.packages(packages[!installed_packages])
}
Feito isso, e tendo obtido a tabela com os múltiplos das empresas, em formato “.xlsx”, carregaremos a planilha para dentro do ambiente R:
# carregar o arquivo no R
library(xlsx)
data <- read.xlsx("./data2103.xlsx", sheetName = "Planilha1")
Vejamos a estrutura dos dados:
# obter dimensões
dim(data)
## [1] 451 21
# visualizar a estrutura dos dados
str(data)
## 'data.frame': 451 obs. of 21 variables:
## $ Papel : chr "CTSA3" "CTSA4" "BIDI3" "BIDI11" ...
## $ Price : num 2.55 1.79 56.06 167.29 55.33 ...
## $ P.L : num -17738 -12452 -5955 -5923 -5877 ...
## $ P.VP : num 0.99 0.7 12.98 12.91 12.81 ...
## $ PSR : num 0.63 0.442 0 0 0 ...
## $ DY : num 0.0119 0.0187 0.0009 0.0009 0.0009 0.0029 0.0018 0.0024 0 0 ...
## $ P.Ativo : num 0.446 0.313 0 0 0 ...
## $ P.Cap.Giro : num 14.23 9.99 0 0 0 ...
## $ P.EBIT : num 11.4 8 0 0 0 ...
## $ P.At.Circ.Liq : num -4.6 -3.23 0 0 0 ...
## $ EV.EBIT : num 20.2 16.8 0 0 0 ...
## $ EV.EBITDA : num 20.2 16.8 0 0 0 ...
## $ Margem.EBIT : num 0.0553 0.0553 0 0 0 ...
## $ Margem.Liq : num 0 0 0 0 0 -0.0055 -0.032 -0.0197 0 -0.0192 ...
## $ LC : num 1.07 1.07 0 0 0 2.26 1.5 4.39 0 2.49 ...
## $ ROIC : num 0.0441 0.0441 0 0 0 0.0725 0.0027 0.0053 -0.199 0.0392 ...
## $ ROE : num -0.0001 -0.0001 -0.0022 -0.0022 -0.0022 -0.0028 -0.0489 -0.0085 0.0304 -0.0184 ...
## $ Liq.2m : num 1.27e+05 9.33e+04 2.18e+07 2.86e+08 1.40e+08 ...
## $ Patrimonio : num 2.85e+08 2.85e+08 3.30e+09 3.30e+09 3.30e+09 ...
## $ Div.Bruta.Patrimonio: num 0.83 0.83 0 0 0 0.31 1.22 0.21 0 0.53 ...
## $ Cresc.Receita.5a : num 0.0642 0.0642 0.3445 0.3445 0.3445 ...
O banco de dados é composto por 451 observações (os papeis das empresas listadas) e 21 variáveis (os indicadores que serão explorados). Cabem algumas explicações sucintas sobre os múltiplos (as definições foram extraídas do próprio site Fundamentus):
Verifiquemos se há observações duplicadas no banco de dados:
# número de dados duplicados
uv <- unique(data)
cbind(c("Valores Únicos","Observações Totais"),
rbind(dim(uv),dim(data)))
## [,1] [,2] [,3]
## [1,] "Valores Únicos" "449" "21"
## [2,] "Observações Totais" "451" "21"
# identificar as observações repetidas
library(janitor)
dupv <- get_dupes(data)
dupv[,1:5]
## Papel Price P.L P.VP PSR
## 1 MRSA3B 51.09 59.78 4.03 5.238
## 2 MRSA3B 51.09 59.78 4.03 5.238
## 3 MRSA5B 33.00 38.62 2.61 3.383
## 4 MRSA5B 33.00 38.62 2.61 3.383
# localizar as linhas dos valores repetidos
which(data$Papel == "MRSA5B")
## [1] 400 401
which(data$Papel == "MRSA3B")
## [1] 420 421
Há dois papeis repetidos, um deles nas linhas 400 e 401, e outro, nas linhas 420 e 421. Excluiremos duas observações, portanto.
# excluir papeis repetidos
data <- data[-c(401,421)]
Agora podemos começar a explorar os dados. A função “inspect_num” do pacote “inspectdf” traz informações sobre valores mínimos, primeiro quartil, mediana, média, terceiro quartil, valores máximos e desvio-padrão. Os códigos adicionais abaixo são apenas para tornar os resultados mais apresentáveis para o formato “html”:
library(inspectdf)
summary <- data.frame(inspect_num(data[,c(3:17,20:21)]))
rownames(summary) <- summary[,1]
summary[,1] <- NULL
summary[,9] <- NULL
summary[,8] <- NULL
library(data.table)
setnames(summary, new = c("Min", "Q1", "Mediana", "Média", "Q3", "Max", "DesvPad"))
format(summary, scientific = FALSE, digits=2)
## Min Q1 Mediana Média Q3 Max DesvPad
## P.L -17738.30 0.0000 8.3500 256.825 20.31 152092.00 7257.908
## P.VP -17.25 0.6800 1.5000 10.037 3.13 2010.69 99.708
## PSR -9.15 0.1580 1.0570 60.996 2.67 8057.89 601.600
## DY 0.00 0.0000 0.0059 0.023 0.03 0.72 0.057
## P.Ativo 0.00 0.2240 0.6050 3.210 1.12 709.58 34.001
## P.Cap.Giro -11487.50 0.0000 2.6900 7.097 7.42 10604.70 738.284
## P.EBIT -1444.62 0.0000 4.5300 52.996 12.49 21679.30 1035.072
## P.At.Circ.Liq -1984.08 -2.8300 -0.6000 -7.843 0.00 204.27 116.093
## EV.EBIT -1288.20 0.0000 6.8700 51.687 15.71 21694.10 1036.799
## EV.EBITDA -1209.02 0.0000 6.4300 30.848 11.40 12317.90 593.899
## Margem.EBIT -135.49 0.0000 0.0679 -0.977 0.17 4.64 8.309
## Margem.Liq -448.13 0.0000 0.0391 0.589 0.12 350.03 36.920
## LC 0.00 0.8400 1.5000 1.858 2.26 30.55 2.298
## ROIC -1.13 0.0000 0.0502 0.064 0.11 5.22 0.279
## ROE -3.26 0.0000 0.0821 0.133 0.17 5.27 0.652
## Div.Bruta.Patrimonio -16.89 0.0000 0.4000 1.116 1.09 90.46 6.581
## Cresc.Receita.5a -0.65 -0.0084 0.0464 0.177 0.11 39.14 1.912
O fato é que já temos muita informação aqui com que trabalhar. O ponto que mais se destaca é a variabilidade das distribuições. O desvio-padrão é, na maior parte das vezes, alto. Os valores mínimos e máximos são bastante elásticos. As médias são bem diferentes das medianas. Em suma, nada mais distante de uma distribuição normal. Visualmente, num gráfico de densidade, é muito mais fácil perceber as distribuições:
library(DataExplorer); library(dplyr)
plot_density(select(data,-"Price"))
É nítido agora como as distribuições são enviesadas, como se fossem apenas um pico. Isso acontece devido à existência de outliers em ambos os lados das distribuições, na maioria das vezes. Assim, uma medida mais confiável parece ser a mediana. Vamos a ela então.
Uma empresa mediana na B3, atualmente, parece ter múltiplos bastante saudáveis. P/L de 8.35 (em linha com dados históricos), P/VP de 1.5 (Benjamin Graham, pai da análise fundamentalista, recomendaria compra nesses níveis), P/EBIT de 4.53, EV/EBIT de 6.87, EV/Ebitda de 6.43. A Liquidez Corrente de 1.5 significa que os ativos de curto prazo da empresa cobrem uma vez e meia as obrigações de curto prazo. Benjamin Graham recomenda que um dos filtros para a compra de ações seja justamente uma liquidez corrente mínima de 1.50. A dívida bruta sobre o patrimônio (de 40%) significa que o endividamento está sob controle.
Em termos de métricas de crescimento, contudo, os dados não são tão animadores. O crescimento da receita nos últimos 5 anos de apenas 4.64% não parece particularmente atraente, apesar de compreensível, dado o fato de que, nos últimos anos, o Brasil passou por duas das maiores recessões de sua história (os anos de 2015/2016 e, por último, o ano de 2020, com a pandemia de Covid-19). Quanto ao ROE (de 8,21%), apesar de não poder ser classificado como brilhante, não se deve desconsiderar que ele está aproximadamete 6 pontos percentuais acima da SELIC atual (de 2% ao ano). Assim, diríamos que, na média, as empresas brasileiras têm tudo para ter um bom desempenho na bolsa brasileira, quando os entraves para um maior crescimento forem devidamente equacionados (neste momento, vacinação em massa, arranjo fiscal, desemprego e ruídos políticos).
Agora vejamos visualmente como as variáveis correlacionam-se entre si. Ou seja, construiremos um correlograma:
# matriz de correlação
cor <- round(cor(data[,-c(1:2)], method ="pearson"),2)
# função para computar a matriz de valores p
cor.mtest <- function(mat, ...) {
mat <- as.matrix(mat)
n <- ncol(mat)
p.mat<- matrix(NA, n, n)
diag(p.mat) <- 0
for (i in 1:(n - 1)) {
for (j in (i + 1):n) {
tmp <- cor.test(mat[, i], mat[, j], ...)
p.mat[i, j] <- p.mat[j, i] <- tmp$p.value
}
}
colnames(p.mat) <- rownames(p.mat) <- colnames(mat)
p.mat
}
# matriz de valores p da correlação
p.mat <- cor.mtest(data[,-c(1:2)])
# correlograma
library(RColorBrewer)
col <- colorRampPalette(c("red", "white", "blue"))(20)
library(corrplot)
corrplot(cor, method="pie", type="upper", order="hclust", p.mat = p.mat, sig.level = 0.05, insig = "blank", tl.col="black", tl.srt=75, col=brewer.pal(n=8,name="RdYlBu"))
Primeiro vamos entender o gráfico antes de comentá-lo. As correlações que apresentaram valor p abaixo de 0.05, ou seja, que não se revelaram estatisticamente significativas, foram preenchidas com a cor branca. Assim, alguns indicadores não estão associados a nenhum outro deste banco de dados, quais sejam: Dividend Yield; Liquidez Corrente; e Crescimento da Receita nos últimos 5 anos. As correlações negativas tendem às cores quentes (quanto mais próxima de -1, mais vermelha); as correlações positivas tendem às cores frias (quanto mais próxima de 1, mais azul). Além disso, os múltiplos foram agrupados por clusteres, de modo que métricas vizinhas apresentam comportamento semelhante entre si.
Pois bem, há um grupo de múltiplos que são muito parecidos entre si, aqueles que representam a razão entre o valor de mercado (ou o valor da firma) e algum indicador de resultado financeiro (seja a receita líquida, o Ebit, o Ebitda, o lucro líquido ou até mesmo o ativo ou o patrimônio líquido). De fato, esses múltiplos, apesar de diferentes, seguem a mesma lógica.
Outra associação evidente é entre o patrimônio líquido e o volume financeiro negociado em bolsa nos últimos 2 meses. Essa não é uma regra, mas em geral companhias maiores são diariamente mais negociadas no pregão.
A margem operacional, ou margem Ebit, não se mostrou um bom indicador para prever crescimento ou preço, pois se apresentou negativamente associada a retorno sobre o capital (ROIC), preço sobre receita (PSR), preço sobre ativo e, inclusive, a margem líquida. Margem líquida também se associou negativamente a ROIC, mas ao menos apresentou uma correlação moderadamente positiva com PSR (ou seja, quanto mais lucro líquido a companhia consegue extrair de suas vendas, mais o mercado pagará por essas mesmas vendas ou, simplificadamente, mais cara ou mais bem avaliada será a companhia).
O que investidores normalmente querem numa empresa é crescimento (a capacidade de extrair muito lucro de seus recursos). Isso é geralmente expresso pelo ROIC (retorno sobre o capital) ou ROE (retorno sobre o patrimõnio). E, de fato, empresas com um ROIC alto tendem a apresentar um Preço/Ativo também elevado.
Por fim, outra associação muito interessante foi entre ROE e dívida bruta sobre o patrimônio. Quanto menor o endividamento bruto da companhia, maior o retorno sobre o patrimônio.
Assim, ao menos com base nesse banco de dados, se fosse para escolher papeis para comprar com base nessa análise, eu escolheria empresas com endividamento bruto controlado (o terceiro quartil está em 109%), ROIC alto (o terceiro quartil aponta um ROIC de 11%), ROE alto (o terceiro quartil apresenta um ROE de 17%), margem líquida alta (no terceiro quartil, a margem líquida é de 12%), e cujos PSR e Preço/Ativo não sejam muito elevados (terceiro quartil em 2.67 e 1.12, respectivamente). Apenas por curiosidade, vamos verificar quais empresas atendem a essas condições?
filtro <- filter(data,
Div.Bruta.Patrimonio <= 1.09,
ROIC >= 0.11,
ROE >= 0.17,
Margem.Liq >= 0.12,
PSR <= 2.67,
P.Ativo <= 1.12)
select(filtro, Papel, LC, Patrimonio, Liq.2m, Cresc.Receita.5a)
## Papel LC Patrimonio Liq.2m Cresc.Receita.5a
## 1 CORR4 13.09 5563000 205.00 0.3705
## 2 PATI3 2.60 604626000 44865.20 0.1900
## 3 PATI4 2.60 604626000 10073.40 0.1900
## 4 RSUL4 0.62 18338000 7618.38 0.1357
## 5 ETER3 2.20 214900000 28357100.00 -0.0668
## 6 MTSA4 3.13 279084000 145088.00 0.1088
## 7 EQMA3B 1.70 3230000000 12335.20 0.0652
Correa Ribeiro (CORR4) é uma empresa do setor de exploração de imóveis; pesa contra ela o fato de o volume financeiro médio negociado diariamente nos últimos 2 meses ser muito baixo (apenas 205 reais). Panatlântica (PATI3 / PATI4) produz artefatos de ferro e aço, e tem esse mesmo problema de liquidez (a mais negociada é a PATI3, com apenas 44.8 mil reais). Metalúrgica Riosulense produz materiais rodoviários; sua liquidez corrente é muito baixa (apenas 0.62). Eternit (ETER3) fabrica produtos para a construção civil, é uma empresa que está em recuperação judicial, em processo de turnaround. Recentemente, Luiz Barsi, o maior acionista pessoa física da B3, desfez-se de suas posições na companhia. Metisa é uma empresa do setor de máquinas e equipamentos, com presença no agronegócio. Cemar é uma empresa do setor elétrico do Estado do Maranhão; também tem esse problema de liquidez (12 mil reais negociados diariamente em média).
Evidentemente, essa análise está muito longe de representar uma recomendação de investimento, mas é um jeito útil, penso eu, de selecionar algumas ações, dentre as mais de 350 empresas de capital aberto na B3, para analisar mais profundamente. Seguindo essa lógica, Metisa (MTSA4) poderia ser mais bem analisada (inspecionando balanços, modelando fluxo de caixa descontado), no intuito de verificarmos se se trata de um bom investimento em potencial ou não.
Vimos como obter e tratar os dados, e como analisar de forma exploratória os múltiplos das empresas listadas na B3. Apresentamos estatística descritiva, correlograma, e utilizamos essas informações para selecionar alguns papeis que poderiam ser úteis para uma análise posterior mais aprofundada.