Volatilidade das empresas do setor de energia listadas no Ibovespa

Gisele Lucas, Kaua Victor e Sandrielly Ferreira

Introdução

Este trabalho analisa a volatilidade das ações de empresas do setor de energia listadas no IBOVESPA, com base nos dados dos últimos três anos.
Utilizando a linguagem R, foram aplicadas técnicas de tratamento de dados, cálculo de retornos logarítmicos e geração de gráficos para visualizar o comportamento dos ativos.
O estudo reforça os conhecimentos adquiridos na disciplina e fornece uma visão prática sobre risco e oscilação dos preços no mercado de energia.

Preparação do Ambiente no R

rm(list = ls())
date()
[1] "Tue Apr 29 10:27:53 2025"
options(scipen = 9999)
options(max.print = 100000)
par(mfrow = c(1,1))

  • rm(list = ls())
    Limpa todos os objetos da memória para evitar interferência de dados anteriores.

  • date()
    Exibe a data e hora da execução, útil para controle de versões e atualização de dados.

  • options(scipen = 9999)
    Desativa a notação científica, tornando os números mais legíveis (ex: mostra 100000 em vez de 1e+05).

  • options(max.print = 100000)
    Permite visualizar grandes volumes de dados no console, ideal para séries temporais extensas.

  • par(mfrow = c(1,1))
    Organiza a área de gráficos para mostrar apenas um por vez, mantendo a visualização limpa.

Carregamento / Instalação de Pacotes

#install.packages("readxl")
#install.packages("dplyr")
#install.packages("tidyr")
#install.packages("ggplot2")
#install.packages("writexl")
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(writexl)

Seleção de Pasta e Definição dos Arquivos

Caminho do arquivo

setwd("C:/Users/Sandrielly/Documents/Ciencias Economicas/P5 - 2024.2/Introducao a Ciencia de Dados no R/ICDR_Aulas")

Definir o arquivo

CEMIG <- read_excel("CMIG3.xlsx")
ISAENERGIA <- read_excel("ISAE4.xlsx")
CPFL <- read_excel("CPFE3.xlsx")
ENGIE <- read_excel("EGIE3.xlsx")
TAESA <- read_excel("TAEE11.xlsx")
ELETROBRAS <- read_excel("ELET3.xlsx")
ENEVA <- read_excel("ENEV3.xlsx")
EQUATORIAL <- read_excel("EQTL3.xlsx")
COPEL <- read_excel("CPLE6.xlsx")
ENERGISA <- read_excel("ENEG11.xlsx")
IBOVESPA <- read_excel("IBOV.xlsx")

Tratamento da Base de Dados

Ajustar nomes

CEMIG <- CEMIG %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

COPEL <- COPEL %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

CPFL <- CPFL %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

ELETROBRAS <- ELETROBRAS %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

ENERGISA <- ENERGISA %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

ENEVA <- ENEVA %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

ENGIE <- ENGIE %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

EQUATORIAL <- EQUATORIAL %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

IBOVESPA <- IBOVESPA %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

ISAENERGIA <- ISAENERGIA %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

TAESA <- TAESA %>%
  rename(
    data = `DATA`,          
    fechamento = `FECHAMENTO`
  )

 O que esse código faz? Estamos apenas trocando os nomes das colunas DATA e FECHAMENTO para data e fechamento em cada uma das bases.

 Por quê? Porque o R é sensível a maiúsculas e minúsculas. Trabalhar com nomes padronizados (em minúsculas) evita erros e facilita o código.

 Como isso é feito? Com a função rename() do pacote dplyr:

Converter número para data real

CEMIG <- CEMIG %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

COPEL <- COPEL %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

CPFL <- CPFL %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

ELETROBRAS <- ELETROBRAS %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

ENERGISA <- ENERGISA %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

ENEVA <- ENEVA %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

ENGIE <- ENGIE %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

EQUATORIAL <- EQUATORIAL %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

IBOVESPA <- IBOVESPA %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

ISAENERGIA <- ISAENERGIA %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

TAESA <- TAESA %>%
  mutate(
    data = as.Date(data, origin = "1899-12-30"),
    fechamento = as.numeric(fechamento)
  )

Os dados de datas estavam em formato numérico do Excel. Essa função converte corretamente para o formato de data no R, usando como origem o dia 30 de dezembro de 1899.

Preço de Fechamento - CMIG4

# Criando um gráfico de linha com os preços de fechamento da ação CMIG4 ao longo do tempo
ggplot(CEMIG, aes(x = data, y = fechamento)) +
  # Adiciona uma linha azul que representa a variação do preço ao longo das datas
  geom_line(color = "blue") +
  # Define os títulos do gráfico e dos eixos
  labs(
    title = "Preço de Fechamento ao Longo do Tempo - CMIG4",  # Título principal do gráfico
    x = "Data",                                               # Rótulo do eixo X (horizontal)
    y = "Preço de Fechamento (R$)"                            # Rótulo do eixo Y (vertical)
  ) +
  # Aplica um tema limpo e minimalista ao gráfico
  theme_minimal()

Calculando a volatilidade durante o período de 3 anos

Selecionando a coluna de preços de fechamento

precos_fechamento_CEMIG <- CEMIG$fechamento
precos_fechamento_CEMIG
  [1]  7.4940  7.3154  7.4047  7.4734  7.4734  7.6657  7.7069  8.0229  7.9473
 [10]  7.8443  7.7687  8.0023  8.0366  8.0229  7.8100  7.6932  7.8374  8.0504
 [19]  7.8237  7.6932  7.6726  7.8718  7.8443  7.8443  7.6726  7.7825  7.5352
 [28]  7.6520  7.4596  7.5283  7.5627  7.4940  7.4871  7.5146  7.5146  7.3360
 [37]  7.3429  7.2467  7.2467  7.1986  7.1711  7.1093  7.0612  7.1711  7.2330
 [46]  7.3772  7.1917  7.2192  7.2536  7.3841  7.5009  7.4459  7.2261  7.1986
 [55]  7.1505  7.1711  7.2261  7.3017  7.4802  7.5817  7.7203  7.8658  7.9282
 [64]  8.0252  8.0876  8.1015  8.1015  8.2262  8.3717  8.6420  8.5519  8.5311
 [73]  8.6143  8.6420  8.5727  8.6905  8.6697  8.6489  8.5935  8.6697  8.5589
 [82]  8.5658  8.4688  8.4272  8.2262  8.2054  8.3024  8.4133  8.5381  8.4341
 [91]  8.5658  8.4480  8.2816  8.2955  8.3995  8.3579  8.3163  8.3163  8.3440
[100]  8.3371  8.2955  8.2539  8.1084  8.1569  8.2331  8.2331  8.4410  8.4549
[109]  8.6975  8.8569  8.6975  8.8361  8.8430  8.6004  8.6836  8.8291  8.9331
[118]  8.6559  8.9469  8.8266  8.8127  8.7428  8.8266  8.9803  8.9593  8.8825
[127]  8.8546  8.7289  8.7987  8.7568  8.7289  8.7219  8.8755  8.7847  8.7847
[136]  8.6940  8.6591  8.6451  8.7778  8.8546  8.8476  8.9104  8.7428  8.7987
[145]  8.8476  8.8197  8.8197  8.7079  8.5054  8.3937  8.3867  8.4775  8.5054
[154]  8.6521  8.6311  8.3518  8.3588  8.3867  8.3867  8.5264  8.5543  8.5334
[163]  8.5753  8.5473  8.6102  8.6730  8.8057  8.6102  8.7009  8.6730  8.5683
[172]  8.4565  8.4915  8.6521  8.7359  8.7778  8.8685  8.9384  8.9314  9.0152
[181]  9.1828  9.0431  9.0012  9.0361  8.7799  8.7025  8.7236  8.7306  8.7025
[190]  8.5055  8.5899  8.5829  8.5266  8.7025  8.7869  8.8080  8.5477  8.6040
[199]  8.4492  8.2171  8.2874  8.3085  8.3789  8.3930  8.3367  8.5548  8.3930
[208]  8.2804  8.2593  8.6110  8.8291  8.9206  8.9839  8.9136  9.0050  9.0472
[217]  8.9487  9.2161  9.4412  9.4060  9.1387  8.8432  7.9849  7.7316  7.4291
[226]  7.4713  7.5347  7.6120  7.7879  7.7387  7.7598  7.8231  7.8301  7.7879
[235]  7.6824  7.6261  7.7246  7.9638  8.0342  7.9849  8.1045  8.2241  8.1327
[244]  8.0834  7.9537  8.1054  8.1343  8.2932  8.1921  8.2860  8.2499  8.3366
[253]  8.4883  8.6689  8.6761  8.7339  8.7411  8.7773  8.5605  8.5750  8.4088
[262]  8.3294  8.2571  8.3438  8.3799  8.4233  8.4088  8.4160  8.3077  8.3221
[271]  8.4666  8.2065  8.2138  8.2932  8.2210  8.1126  8.2210  8.1560  8.2716
[280]  8.4233  8.5894  8.6761  8.5027  8.4955  8.3799  8.4088  8.4883  8.5678
[289]  8.6472  8.7267  8.6183  8.6111  8.6761  8.5316  8.6472  8.5605  8.6400
[298]  8.3655  8.0187  8.2571  8.3655  8.3438  8.5966  8.7122  8.9217  8.9867
[307]  9.0084  9.1023  9.0734  9.1674  9.1601  9.1962  9.3480  9.2974  9.4274
[316]  9.6152  9.4924  9.4708  9.2829  9.3696  9.2613  9.3046  9.4346  9.4708
[325]  9.3768  9.2974  9.2540  9.1096  9.0951  9.1674  9.2921  9.8818 10.0054
[334]  9.9198  9.8152  9.8913  9.7772  9.6345  9.6725  9.8247  9.9674  9.8247
[343]  9.8818  9.9864 10.1861  9.9388  9.8723  9.8723  9.8818  9.7106  9.6060
[352]  9.4633  9.6725  9.7486  9.7962  9.9293  9.6821  9.6535  9.7391  9.4823
[361]  9.6440  9.5204  9.5774  9.6155  9.7011  9.7486  9.9959 10.0054 10.0054
[370]  9.8342  9.5489  9.4062  9.7011  9.5869  9.8532  9.8628  9.8628 10.0244
[379]  9.9959  9.9484 10.1766 10.1576 10.1956 10.3383 10.6331 10.3954 10.0340
[388] 10.2812 10.1576 10.1196 10.1100 10.2527 10.4049 10.3383 10.3288 10.3193
[397] 10.1576 10.2147 10.2242 10.2717 10.1766 10.3288 10.4619 10.5571 11.3845
[406] 10.9470 11.0516 11.2704 11.3179 11.3940 11.4130 11.4225 10.9375 10.7378
[415] 10.9850 11.0326 11.0611 11.1182 11.0516 11.3655 11.3274 11.2609 11.2704
[424] 11.2133 11.1848 11.1277 11.1943 11.1657 11.1467 11.1372 11.0421 11.0041
[433] 10.9660 10.9324 10.9421 11.0579 10.9228 11.0000 11.0193 11.0000 10.8456
[442] 10.7684 10.7974 10.7684 10.6526 10.7298 10.6333 10.7202 10.7009 10.7588
[451] 10.7105 10.6526 10.7298 10.6719 10.6719 10.8263 10.7588 10.8938 10.9710
[460] 10.9807 10.9710 10.9614 11.2123 11.1833 11.0289 10.9710 10.8938 11.1061
[469] 10.9614 11.0868 11.6658 11.1833 11.5307 11.1833 11.2895 11.3570 11.6175
[478] 11.4535 11.0675 11.4824 11.2412 11.1640 11.0289 11.2702 11.0965 11.2219
[487] 11.2509 11.4053 11.0965 11.0193 10.9903 11.0772 10.7588 10.9035 11.1351
[496] 10.7105 10.8537 10.8439 10.9127 10.8832 10.6475 10.6573 10.9127 10.6475
[505] 10.5689 10.2840 10.3037 10.2448 10.4019 10.0974 10.2742 10.3921 10.4216
[514] 10.3430 10.3921 10.3135 10.5591 10.5885 10.4903 10.7261 10.7653 10.9913
[523] 10.9029 10.8734 10.7653 10.7752 10.8341 10.9323 10.8537 10.8930 11.1779
[532] 11.1975 11.1975 11.0895 11.0011 11.0502 10.9913 11.1877 11.0895 11.0600
[541] 10.9323 10.9618 11.1190 11.1582 10.9421 10.9716 11.0109 11.0502 10.7850
[550] 10.9913 11.1288 11.2859 11.1484 10.6082 10.5493 10.4609 10.4600 10.4200
[559] 10.3600 10.2600 10.0900 10.0900 10.1500 10.0000 10.0000 10.0100 10.1500
[568] 10.0500 10.1100 10.2000 10.3000 10.2400 10.3500 10.2900 10.4500 10.6400
[577] 10.9300

CEMIG$fechamento : acessa a coluna de preços de fechamento do data frame CEMIG.

precos_fechamento_CEMIG <- … : armazena essa coluna como um vetor separado.

precos_fechamento_CEMIG : imprime o vetor de preços de fechamento na tela.

Continuação

#->  Calculando os retornos logarítmicos
retornos_log_CEMIG <- diff(log(precos_fechamento_CEMIG))

#->  Calculando a volatilidade
volatilidade_CEMIG <- sd(retornos_log_CEMIG, na.rm = TRUE)

#->  Exibindo o resultado
print(paste("A volatilidade histórica da CMIG3:", round(volatilidade_CEMIG, 6)))
[1] "A volatilidade histórica da CMIG3: 0.015823"

A função ‘paste()’ junta o texto explicativo com o valor arredondado da volatilidade, formando uma frase completa

A função ‘print()’ mostra essa frase no console ou no documento final

Continuação

# Criando uma tabela com a volatilidade da ação CMIG3
tabela_volatilidade <- data.frame(
  Empresa = c("CMIG3"),                       # Nome da empresa
  Volatilidade = c(volatilidade_CEMIG)       # Valor da volatilidade calculado anteriormente
)

# Arredondando o valor da volatilidade para até 6 casas decimais
tabela_volatilidade$Volatilidade <- round(tabela_volatilidade$Volatilidade, 6)

# Organizando a tabela da maior para a menor volatilidade (nesse caso só tem uma linha, mas o código já fica pronto para outras empresas)
tabela_volatilidade <- tabela_volatilidade %>%
  arrange(desc(Volatilidade))

# Mostrando a tabela no console ou no relatório
print(tabela_volatilidade)
  Empresa Volatilidade
1   CMIG3     0.015823

Continuação

#-> Normalizando a volatilidade e classificando as empresas
tabela_volatilidade <- tabela_volatilidade %>%
  mutate(
    # Cria uma nova coluna "Volatilidade_Normalizada" que transforma a volatilidade para uma escala de 0 a 100
    Volatilidade_Normalizada = (Volatilidade - min(Volatilidade)) / (max(Volatilidade) - min(Volatilidade)) * 100,

    # Cria a coluna "Classificacao" para classificar empresas cuja volatilidade normalizada está entre 40% e 60%
    Classificacao = case_when(
      Volatilidade_Normalizada >= 40 & Volatilidade_Normalizada <= 60 ~ "Média (40%-60%)",
      TRUE ~ "Fora do intervalo"  # Para todas as outras fora desse intervalo
    )
  )

#-> Criando gráfico de barras com cores diferentes conforme a classificação
ggplot(tabela_volatilidade, aes(x = reorder(Empresa, -Volatilidade), y = Volatilidade, fill = Classificacao)) +
  # Cria as colunas do gráfico (barras)
  geom_col() +
  
  # Adiciona o valor da volatilidade arredondado acima de cada barra
  geom_text(aes(label = round(Volatilidade, 4)), vjust = -0.5, size = 3.5) +

  # Títulos e rótulos do gráfico
  labs(
    title = "Volatilidade dos últimos Três anos das Empresas",  # Título do gráfico
    x = "Ativo",                                                 # Rótulo do eixo X
    y = "Volatilidade",                                          # Rótulo do eixo Y
    fill = "Classificação"                                       # Título da legenda de cores
  ) +

  # Define manualmente as cores usadas para cada classificação
  scale_fill_manual(values = c("Média (40%-60%)" = "orange", "Fora do intervalo" = "steelblue")) +

  # Aplica um tema limpo e minimalista ao gráfico
  theme_minimal() +

  # Ajusta detalhes visuais do gráfico (título centralizado, texto rotacionado, tamanhos de fonte)
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),  # Centraliza e estiliza o título
    axis.text.x = element_text(angle = 45, hjust = 1),                 # Rotaciona os nomes no eixo X
    axis.title = element_text(size = 14),                              # Tamanho dos títulos dos eixos
    axis.text = element_text(size = 12),                               # Tamanho dos textos nos eixos
    legend.title = element_text(size = 13),                            # Tamanho do título da legenda
    legend.text = element_text(size = 12)                              # Tamanho do texto da legenda
  )

Continuação

#->  Calculando os retornos logarítmicos
retornos_log_CEMIG <- diff(log(precos_fechamento_CEMIG))

#->  Calculando a volatilidade diária
volatilidade_diaria_CEMIG <- sd(retornos_log_CEMIG, na.rm = TRUE)

#->  Anualizando a volatilidade
volatilidade_anualizada_CEMIG <- volatilidade_diaria_CEMIG * sqrt(252)

#->  Exibindo o resultado
print(paste("A volatilidade anualizada da ação da CMIG3:", round(volatilidade_anualizada_CEMIG, 6)))

tabela_volatilidade_anualizada <- data.frame(
  Ativo = c("CMIG3"),
  VolatilidadeA = c(volatilidade_anualizada_CEMIG)
)

#->  Arredondando a coluna de volatilidade
tabela_volatilidade_anualizada$VolatilidadeA <- round(tabela_volatilidade_anualizada$VolatilidadeA, 6)

#->  Ordenando do maior para o menor
tabela_volatilidade_anualizada <- tabela_volatilidade_anualizada %>%
  arrange(desc(VolatilidadeA))

#->  Mostrar a tabela ordenada
print(tabela_volatilidade_anualizada)

#-> Normalizando a volatilidade
tabela_volatilidade_anualizada <- tabela_volatilidade_anualizada %>%
  mutate(
    Volatilidade_anualizada_Normalizada = (VolatilidadeA - min(VolatilidadeA)) / (max(VolatilidadeA) - min(VolatilidadeA)) * 100,
    Classificacao = case_when(
      Volatilidade_anualizada_Normalizada >= 40 & Volatilidade_anualizada_Normalizada <= 60 ~ "Média (40%-60%)",
      TRUE ~ "Fora do intervalo"
    )
  )

#-> Criando Tabela com uma média de 40% a 60% de volatilidade em Laranja
ggplot(tabela_volatilidade_anualizada, aes(x = reorder(Ativo, -VolatilidadeA), y = VolatilidadeA, fill = Classificacao)) +
  geom_col() +
  geom_text(aes(label = round(VolatilidadeA, 4)), vjust = -0.5, size = 3.5) +
  labs(
    title = "Volatilidade dos últimos três anos do Ativo",
    x = "Ativo",
    y = "Volatilidade",
    fill = "Classificação",
  ) +
  scale_fill_manual(values = c("Média (40%-60%)" = "orange", "Fora do intervalo" = "steelblue")) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    axis.title = element_text(size = 14),
    axis.text = element_text(size = 12),
    legend.title = element_text(size = 13),
    legend.text = element_text(size = 12)
  )
[1] "A volatilidade anualizada da ação da CMIG3: 0.251176"
  Ativo VolatilidadeA
1 CMIG3      0.251176

Gráfico

Conclusão

Com base na análise realizada, foi possível identificar que o setor de energia apresenta uma dinâmica de volatilidade nos preços bastante significativa. Essa característica se reflete na presença de empresas com diferentes perfis de risco, o que permite atender tanto investidores avessos ao risco quanto aqueles mais propensos a assumi-lo. Dessa forma, o setor se mostra atrativo por oferecer opções diversificadas de investimento, contribuindo para a composição de carteiras com diferentes estratégias e objetivos financeiros.