Recentemente pensei em analisar dados de empresas de petróleo da Bolsa de Valores do Brasil. Em particular, estava interessado em ver qual empresa teve a maior valorização da cotação da sua ação nos últimos cinco anos.

Para encontrar a lista de empresas de petróleo listadas na B3, eu conferi a página com a Classificação Setorial da B3, setor Petróleo, Gás e Biocombustíveis, Segmento Exploração, Refino e Distribuição. Encontrei 10 empresas, com os códigos RRRP3, CSAN3, ENAT3, PETR4, RECV3, PRIO3, RAIZ4, RPMG3, UGPA3 e VBBR3.

Isto posto, eu precisava baixar os dados das cotações das empresas. Para isso, usei o pacote yfR. Como os dados são baixados do Yahoo Finance, é importante adicionar a string .SA ao final do código de cada ação:

library(yfR)
library(lubridate)

petroleo <- c("RRRP3.SA", "CSAN3.SA", "ENAT3.SA", "PETR4.SA", "RECV3.SA", 
              "PRIO3.SA", "RAIZ4.SA", "RPMG3.SA", "UGPA3.SA", "VBBR3.SA")

dados <- yf_get(petroleo, 
                first_date = ymd("2019-01-01"), 
                last_date = ymd("2024-04-19"),
                thresh_bad_data = 0)

Como cada empresa tem um período diferente de abertura de capital na bolsa, eu preciei manter apenas os resultados a partir da abertura de capital da empresa mais recente. Assim, estaria utilizando a mesma janela temporal para todas as empresas.

library(tidyverse)
theme_set(theme_minimal())

dados |> 
  group_by(ticker) |> 
  summarise(minimo = min(ref_date)) |> 
  arrange(desc(minimo))
## # A tibble: 10 × 2
##    ticker   minimo    
##    <chr>    <date>    
##  1 RAIZ4.SA 2021-08-05
##  2 RECV3.SA 2021-05-05
##  3 RRRP3.SA 2020-11-12
##  4 CSAN3.SA 2019-01-02
##  5 ENAT3.SA 2019-01-02
##  6 PETR4.SA 2019-01-02
##  7 PRIO3.SA 2019-01-02
##  8 RPMG3.SA 2019-01-02
##  9 UGPA3.SA 2019-01-02
## 10 VBBR3.SA 2019-01-02
data_minima <- ymd("2021-08-05")

dados_filtrados <- 
  dados |> 
  filter(ref_date >= data_minima)

Como o meu interesse é descobrir qual ação valorizou mais, eu transformei o preço ajustado de cada dia de negociação de cada ação. Igualei o primeiro dia a 100 e calculei proporcionalmente todas as outras cotações em relação a este valor. O resultado está abaixo:

dados_transformados <- 
  dados_filtrados |> 
  select(ticker, ref_date, price_adjusted) |> 
  group_by(ticker) |> 
  mutate(preco_100 = price_adjusted/first(price_adjusted)*100)
  

ggplot(dados_transformados, aes(x = ref_date, y = preco_100, label = ticker, colour = ticker)) +
  geom_line() +
  scale_colour_viridis_d() + 
  labs(x = "Data", y = "Preço Normalizado", colour = "Ação")

Achei que esta visualização não está boa, porque é difícil comparar as cores entre as ações. Por isso, adicionei um label a cada ação, para que a função ggrepel::geom_label_repel pudesse identificar o nome de cada ação à direita do gráfico. Além disso, limpei o nome dos tickets retirando a string .SA de cada um deles.

library(ggrepel)

dados_transformados <- 
  dados_filtrados |> 
  select(ticker, ref_date, price_adjusted) |> 
  mutate(ticker = gsub("\\.SA", "", ticker)) |> 
  group_by(ticker) |> 
  mutate(preco_100 = price_adjusted/first(price_adjusted)*100) |> 
  mutate(label_simples = ifelse(ref_date == last(ref_date), ticker, NA))

ggplot(dados_transformados, aes(x = ref_date, y = preco_100, colour = ticker)) +
  geom_line() +
  scale_colour_viridis_d() + 
  labs(x = "Data", y = "Preço Normalizado", colour = "Ação") + 
  geom_label_repel(aes(label = label_simples),
                   nudge_x = 100,
                   na.rm = TRUE) + 
  scale_x_date(date_breaks = "3 month", date_labels = "%B/%Y") + 
  theme(legend.position = "none", 
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))

Por fim, com o uso do pacote gghighlight, destaquei apenas as ações da Petrobrás e da Petro Rio no meu gráfico, de modo a ter apenas estas duas ações em destaque.

library(gghighlight)

ggplot(dados_transformados, aes(x = ref_date, y = preco_100, colour = ticker)) +
  geom_line() +
  scale_colour_viridis_d() + 
  labs(x = "Data", y = "Preço Normalizado", colour = "Ação") + 
  gghighlight(ticker %in% c("PETR4", "PRIO3")) + 
  scale_x_date(date_breaks = "3 month", date_labels = "%B/%Y") + 
  theme(legend.position = "none", 
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))