Análise de Risco para Ativos de Renda Variável

Autores
Afiliação

Prof. Dr. Sinézio Fernandes Maia

Departamento de Economia - Centro de Ciências Sociais Aplicadas/UFPB

Gabriel Barros Teixeira

Data de Publicação

27 de setembro de 2025

Código
# Remoção de objetos anteriores
remove(list = ls())
gc()
par(mfrow = c(1, 1))
options(scipen = 999, max.print = 100000)
date()

# Carregamento do pacote
library(tseries)
library(fBasics)
library(lmtest)
library(rbcb)
library(zoo)
library(fPortfolio)
library(corrplot)
library(lubridate)
library(quantmod)
library(dplyr)       # <--- ESSENCIAL: Carrega a função %>%
library(knitr)
library(kableExtra)


{dataini <- "2025-04-01"
datafim <- "2025-06-28"
dataini2 <- "2025-02-13"
datafim2 <- "2025-06-28"}

Introdução

O objetivo deste relatório é formular um ranking de empresas listadas na Bolsa de Valores brasileira, com base em diferentes abordagens analíticas, visando orientar decisões de investimento para um perfil de investidor avesso ao risco. Bem como montar uma carteira que tenha o risco bem gerido e otimizado. Para isso, são utilizados fundamentos da teoria microeconômica, análise fundamentalista, teoria de Dow (análise gráfica), indicadores matemáticos, conceitos da teoria de Markowitz com a Moderna Teoria da Carteira e técnicas de estatística descritiva. Todos esses aspectos estão relacionados ao objetivo principal de identificar e otimizar o risco de uma carteira, levando sempre em consideração um perfil conservador.

A história do risco remonta aos primórdios da civilização, quando o risco físico estava intrinsecamente ligado à sobrevivência. Com o passar do tempo, o risco econômico foi se desvinculando do risco físico, passando a permear o mundo financeiro especialmente as ruas de Wall Street que sempre buscou formas de quantificá-lo.

A quantificação do risco começou com o problema proposto por Luca Pacioli em 1494, que questionava como dividir de forma justa um prêmio em um jogo de dados interrompido. A partir disso, os estudos evoluíram, permitindo o desenvolvimento de conceitos como probabilidade, distribuição normal e desvio padrão. Esses avanços possibilitaram a estimativa de probabilidades não apenas para eventos simples, mas para qualquer evento com incerteza associada.

No livro Gestão Estratégica do Risco, Aswath Damodaran adota a definição de risco proposta por Holton (2004), que exige dois elementos: incerteza quanto aos resultados possíveis e relevância desses resultados em termos de utilidade (bem-estar ou riqueza). Damodaran ressalta a dualidade do risco: os seres humanos são, por vezes, atraídos por ele (como em esportes radicais ou jogos de azar), mas ao mesmo tempo buscam evitá-lo (como ao usar cinto de segurança ou ao investir de forma conservadora). Essa ambivalência pode mudar com o tempo, conforme variam a idade, a riqueza e as responsabilidades familiares.

Empresas e ativos da carteira

Apresentação dos ativos

Ao observar os gráficos de cotação dos ativos analisados, duas ações se destacam de forma evidente. A CMIG4 apresenta uma forte tendência de alta no período analisado, sinalizando um movimento comprador consistente. Em contrapartida, a CSNA3 demonstra uma trajetória oposta, com pressão vendedora predominante, caracterizando uma tendência de baixa relevante.

No entanto, além da análise gráfica, é fundamental considerar a minimamente o setor e a estrutura de cada empresa, pois, historicamente, essa sempre foi a base principal para avaliar o risco de um ativo no mercado financeiro. A análise fundamentalista, centrada em indicadores contábeis, capacidade de geração de lucro, endividamento e sustentabilidade financeira, ainda é essencial para medir a solidez da empresa e sua resiliência diante de cenários adversos. Embora estejamos posicianos em ativos que expressam códigos da bolsa, são participações em empresas, e o desempenho ou possíveis problemas impactam os preços.

Código
{dataini <- "2025-04-01"
datafim <- "2025-06-28"}
ativos <- c("CMIG4.SA", "VAMO3.SA", "BRFS3.SA", "CSNA3.SA", "LREN3.SA","^BVSP")

cotacoes <- list()
for (ativo in ativos) {
  cotacoes[[ativo]] <- get.hist.quote(instrument = ativo,
                                          quote = "Close",
                                          start = dataini,
                                          end = datafim,
                                          retclass = "zoo")
}
# Junta as séries (por data)
cotacoes <- do.call(merge, cotacoes)

length(cotacoes)  # Quantidade de observações
cotacoes  # Série de preços
colnames(cotacoes)[colnames(cotacoes) == "Close.CMIG4.SA"] <- "CMIG4"
colnames(cotacoes)[colnames(cotacoes) == "Close.LREN3.SA"] <- "LREN3"
colnames(cotacoes)[colnames(cotacoes) == "Close.CSNA3.SA"] <- "CSNA3"
colnames(cotacoes)[colnames(cotacoes) == "Close.VAMO3.SA"] <- "VAMO3"
colnames(cotacoes)[colnames(cotacoes) == "Close.BRFS3.SA"] <- "BRFS3"
colnames(cotacoes)[colnames(cotacoes) == "Close.^BVSP"] <- "IBOV"

cmig4 <- cotacoes$CMIG4
vamo3 <- cotacoes$VAMO3
brfs3 <- cotacoes$BRFS3
csna3 <- cotacoes$CSNA3
lren3 <- cotacoes$LREN3
ibov <- cotacoes$IBOV

rcmig4 <- diff(log(cmig4))
rvamo3 <- diff(log(vamo3))
rbrfs3 <- diff(log(brfs3))
rcsna3 <- diff(log(csna3))
rlren3 <- diff(log(lren3))
ribov  <- diff(log(ibov))

Cemig (CMIG4)

Começando a análise individual das empresas selecionadas, destacamos a Cemig, uma companhia do setor de energia elétrica, com forte presença no estado de Minas Gerais. A empresa atua principalmente na geração e distribuição de energia, mas vem ampliando seu portfólio com investimentos em transmissão e gás natural.

Trata-se de um setor perene, com alta previsibilidade de resultados, já que o consumo de energia elétrica é essencial em qualquer cenário macroeconômico. Em teoria, essa característica confere menor risco ao ativo, um ponto que será avaliado de forma quantitativa com o uso de dados e estatísticas mais à frente.

Além disso, a Cemig possui bons indicadores financeiros e econômicos, com lucros consistentes ao longo dos anos. Essa solidez dialoga com a filosofia de grandes investidores como Benjamin Graham, que em seu clássico O Investidor Inteligente afirmava: “A essência da gestão de investimentos é a gestão de riscos, e não a gestão de retornos.” Esse conceito será melhor explorado posteriormente na análise de risco dos ativos.

Do ponto de vista gráfico, com base na Teoria de Dow, uma das mais tradicionais e influentes teorias da análise técnica, a ação CMIG4 apresenta uma tendência de alta expressiva e bem testada. A região de suporte está próxima de R$ 9,90, ponto em que se concentram os compradores, enquanto a resistência se encontra nos R$ 11,00, faixa de atuação dos vendedores. Essa resistência está próxima do valor atual da ação considerando a data de 27/06/2025, mas com possíbilidade de ganho. Ao observar uma janela de 60 pregões, nota-se uma clara trajetória de valorização no preço da ação.

Complementando a análise com indicadores matemáticos, as médias móveis simples indicam que o preço recentemente tocou a média de curto prazo, que chegou a ser cruzada, mas retornou para um patamar acima da linha. Não há, até o momento, cruzamento entre as médias móveis de 15 e 41 períodos — números que foram escolhidos por representarem bem o comportamento de tendência no ativo. Ambas seguem convergentes, sinalizando continuidade da tendência.

O volume negociado, por sua vez, não tem fornecido sinais claros de reversão nem de confirmação da tendência. O volume está mais contido, o que pode indicar uma postura de espera por parte do mercado, possivelmente aguardando novos gatilhos de decisão.

Código
plot(cmig4)

Vamos (VAMO3)

Seguindo com a análise das cinco companhias selecionadas, agora voltamos nossa atenção para um setor distinto. O setor de transporte, mais especificamente o de locação de caminhões, máquinas e equipamentos. A Vamos Locação é líder nacional nesse segmento e faz parte do grupo SIMPAR, um conglomerado que também possui participações em outras grandes empresas do setor de mobilidade e logística.

A companhia apresenta um histórico consistente de lucros nos últimos anos, além de bons indicadores econômicos, o que demonstra solidez operacional. No entanto, um ponto de atenção é o seu nível elevado de endividamento, uma característica comum em empresas do setor de locação, que precisam renovar constantemente sua frota para manter competitividade e eficiência. Esse mesmo padrão pode ser observado em empresas de locação de veículos, como Localiza e Movida.

Apesar disso, o atual cenário de juros elevados pode representar um obstáculo à expansão e à rentabilidade da companhia, uma vez que o custo do capital se torna mais caro e impacta diretamente na alavancagem financeira.

No campo gráfico, o ativo tem sido negociado próximo à região de suporte, em torno de R$ 4,10, enquanto a resistência mais recente se encontra na faixa dos R$ 5,00. Isso representa uma margem de valorização interessante, caso o preço consiga se recuperar até o topo anterior.

No entanto, o cenário atual sugere uma continuidade da tendência de baixa. O volume de negociações nos pregões de queda tem sido alto e crescente, o que reforça a pressão vendedora e sinaliza uma possível persistência da trajetória negativa no curto prazo.

Código
plot(vamo3)

BRF (BRFS3)

A BRF S.A. é uma das maiores empresas do setor de alimentos e bebidas do Brasil, sendo a controladora de marcas icônicas como Sadia e Perdigão. Nos últimos anos, a companhia enfrentou períodos de prejuízo, em grande parte influenciados pelas condições do seu setor de atuação.

Empresas do setor de consumo costumam ser mais sensíveis a cenários macroeconômicos adversos, e em momentos de crise ou pessimismo econômico, seus resultados tendem a ser impactados negativamente. No caso da BRF, esse efeito foi agravado pelo fato de a empresa apresentar um nível elevado de endividamento, o que pressionou ainda mais seus resultados.

Outro fator relevante são as margens operacionais apertadas, influenciadas principalmente pelo custo das matérias-primas (como carne suína e de aves), que compõem grande parte do Custo das Mercadorias Vendidas (CMV). Como a demanda por esses produtos é bastante elástica, a empresa encontra dificuldades para repassar aumentos de custo ao consumidor final, sob o risco de provocar retração da demanda ou substituição por marcas menores e produtos mais baratos.

Apesar desses desafios, a BRF se mantém como uma gigante multinacional, com presença significativa no mercado interno e externo. No ano de 2024, a companhia conseguiu reverter o prejuízo e encerrou o período com um ROE (Retorno sobre o Patrimônio Líquido) aproximado de 22%, demonstrando sinais de recuperação operacional.

O comportamento dos preços da ação da BRF durante o período analisado apresentou-se lateralizado. O papel tem sido negociado dentro de uma faixa de resistência próxima a R$ 21,80 e suporte em torno de R$ 20,00. Desde o início de maio até a data de referência final desta análise, o gráfico indica pouca volatilidade direcional, refletindo um cenário de indecisão por parte do mercado.

As médias móveis acompanham esse padrão lateral, sem indicar tendências claras de alta ou de baixa, o que torna mais difícil prever movimentos futuros com base nesse indicador. Esse comportamento sugere que o mercado está em compasso de espera, aguardando novos gatilhos para definição de tendência.

Código
plot(brfs3)

CSN (CSNA3)

A Companhia atua em toda a cadeia produtiva do aço, desde a extração do minério de ferro até a produção e comercialização de uma diversificada linha de produtos siderúrgicos de alto valor agregado, como aços planos revestidos, galvanizados e folhas metálicas. Essa estrutura evidencia um elevado grau de verticalização em sua operação. No entanto, é importante destacar que a CSN Mineração atua de forma separada, sendo negociada na B3 sob o código CMIN3.

Apesar de os resultados da companhia terem ficado abaixo das expectativas do mercado nos últimos balanços, a empresa permaneceu lucrativa. O que chama atenção, contudo, é o crescimento expressivo da dívida, com um aumento de aproximadamente R$ 18 bilhões em seu passivo ao longo dos últimos quatro anos, fator que impactou negativamente sua margem de lucro. Ainda assim, trata-se de uma dívida de perfil controlado e com prazo alongado. Esse endividamento ocorreu paralelamente a uma queda na receita da companhia.

Mesmo diante desses desafios, a CSN continua sendo uma empresa de longa trajetória, atuando em um setor estratégico para a economia. Trata-se de uma multinacional com diversificação de receita, embora com maior concentração das vendas de aço no mercado doméstico.

Do ponto de vista gráfico, o ativo apresenta uma tendência de baixa clara e bem definida, atingindo seus menores níveis desde a pandemia. No curto prazo, torna-se difícil traçar suportes e resistências relevantes com base na teoria de Dow, devido à ausência de múltiplos topos ou fundos bem estabelecidos, onde se concentam regiões mais claras de vendedores ou compradores. As médias móveis estão bastante divergentes, o que reforça a falta de sinais de reversão e cruzamentos consistentes. Além disso, o volume nos pregões de alta é discreto, indicando baixo interesse comprador no momento.

Código
plot(csna3)

Lojas Renner (LREN3)

Apresentando a última empresa objeto da análise, Lojas Renner atua no setor de consumo cíclico, mais especificamente no segmento de varejo de moda e vestuário. A companhia possui um portfólio diversificado de marcas, majoritariamente compostas por lojas de departamento, com forte presença nos principais shoppings do Brasil e em processo de expansão pela América do Sul.

Por estar inserida em um setor altamente sensível ao desempenho da economia, a Renner tende a ser impactada diretamente em períodos de desaquecimento econômico. Diferente da BRF, que também pertence ao setor de consumo, mas lida com produtos perecíveis, a Renner não enfrenta grandes perdas com estoques. No entanto, a queda no volume de vendas afeta significativamente suas margens de lucro.

Esse impacto é agravado pelo elevado custo operacional da empresa, impulsionado principalmente pelo seu modelo de negócios baseado grande parte em lojas físicas, que demandam altos gastos com folha salarial e despesas administrativas. Ainda sim empresa se manteve lucrativa nos ultimos anos, embora o endividamento tenha subido bastante no periodo.

Na análise gráfica, a empresa apresenta uma valorização significativa, com uma tendência de alta forte e bem testada ao longo do período. No entanto, as médias móveis de curto e longo prazo vêm mostrando um movimento de convergência, o que pode sinalizar um cenário de possível reversão dessa tendência positiva.

O volume negociado permaneceu estável, sem oferecer sinais claros de continuidade da alta ou de início de uma reversão baixista. Diante desse comportamento mais neutro do mercado, torna-se mais difícil traçar suportes e resistências realmente relevantes para o curto e médio prazo.

Código
plot(lren3)

Estatísticas descritivas

Com base nos preços de fechamento do periodo

Código
Media.cotacoes <- sapply(cotacoes, mean) # Valor médio dos preços
Desvio.cotacoes <- sapply(cotacoes, sd) # Desvio padrão dos preços
cvcotacoes <- Desvio.cotacoes / Media.cotacoes
# Cria a tabela combinada
tabela_resumo_completa <- data.frame(
  Ativo = names(Media.cotacoes), # Assume que os nomes dos ativos estão em names(Media.cotacoes)
  Media_Precos = Media.cotacoes,
  Desvio_Precos = Desvio.cotacoes,
  CV_Precos = cvcotacoes
)

# Passo 2: Melhoria Estética (KableExtra)

# 2.1. Renomear Colunas
tabela_limpa <- tabela_resumo_completa %>%
  rename(
    `Média dos Preços` = Media_Precos,
    `Desvio Padrão` = Desvio_Precos,
    `CV (Desvio/Média)` = CV_Precos
  )

# 2.2. Formatar e Estilizar a Tabela
tabela_final <- tabela_limpa %>%
  kable(
    caption = "Estatísticas Descritivas de Preços das Cotações",
    align = "c",
    digits = 3, # 3 casas decimais (mais apropriado para níveis de preço)
    format.args = list(big.mark = ".", decimal.mark = ",") # Formato brasileiro
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Estatísticas Descritivas de Preços das Cotações
Ativo Média dos Preços Desvio Padrão CV (Desvio/Média)
CMIG4 CMIG4 10,461 0,274 0,026
VAMO3 VAMO3 4,660 0,314 0,067
BRFS3 BRFS3 20,745 0,873 0,042
CSNA3 CSNA3 8,652 0,568 0,066
LREN3 LREN3 16,166 2,495 0,154
IBOV IBOV 134.947,867 4.059,662 0,030

Esse indicador mensura a oscilação, ou, mais precisamente, o intervalo de oscilação padrão dos preços. Por exemplo, um coeficiente de variação de 15% indica que o preço costuma variar aproximadamente 15% para cima ou 15% para baixo em relação à média do período avaliado. Por tando quanto maior esse valor mais o preço do ativo tende a ser volatil, indicando incerteza e risco.

Com base nessa perspectiva, a empresa que apresentou o maior risco foi a Lojas Renner, com um coeficiente de variação de 15,44%. Isso nos permite inferir que seus preços apresentam maior oscilação em comparação às demais empresas, como demonstrado no gráfico abaixo.

Por outro lado, a Cemig se destacou por apresentar uma oscilação significativamente menor, com um coeficiente de apenas 2,62%, sendo considerada, dentro do conjunto analisado, a empresa com menor risco relativo. Seguida pela BRF, CSN e Vamos. Em comparação ao IBOV no geral as empresas indicaram maior oscilação, exceto a Cemig como mencionamos.

Análise dos retornos

Código
rcotacoes <-lapply(cotacoes, function(x) diff(log(x))) 
rcotacoes <- do.call(cbind, rcotacoes)

rcotacoes <- na.omit(rcotacoes)
rcotacoes  # Retornos logarítmicos
plot(rcotacoes)

Código
rcotacoes <-lapply(cotacoes, function(x) diff(log(x))) 
rcotacoes <- do.call(cbind, rcotacoes)

rcotacoes <- na.omit(rcotacoes)
rcotacoes  # Retornos logarítmicos

mrcotacoes <- sapply(rcotacoes, mean, na.rm = TRUE)
mrcotacoes * 100  # Retorno médio diário em %

Drcotacoes <-  sapply(rcotacoes, sd, na.rm = TRUE)
Drcotacoes  # Desvio padrão dos retornos

cvrcotacoes <- (Drcotacoes / (mrcotacoes * 100)) # Cálculo do CV
cvrcotacoes <- abs(cvrcotacoes) * 100 

tabela_resumo_completa <- data.frame(
  Ativo = names(mrcotacoes), # Assume que os nomes dos ativos estão em name (mrcotacoes)
  Media_Retorno = mrcotacoes * 100, # Média em %
  Desvio_Padrao = Drcotacoes,
  Coeficiente_Variacao = cvrcotacoes
)

# 2.1. Renomear Colunas
tabela_limpa <- tabela_resumo_completa %>%
  rename(
    `Retorno Médio (%)` = Media_Retorno,
    `Desvio Padrão` = Desvio_Padrao,
    `CV (Desvio/Média)` = Coeficiente_Variacao
  )

# 2.2. Formatar e Estilizar a Tabela
tabela_final <- tabela_limpa %>%
  kable(
    caption = "Estatísticas Descritivas de Risco e Retorno",
    align = "c",
    digits = 4, # 4 casas decimais para todas as métricas
    format.args = list(big.mark = ".", decimal.mark = ",") # Formato brasileiro
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )

Cálculo do risco (CV) dos retornos

Conforme analisado anteriormente, o coeficiente de variação com base nos preços nos forneceu uma visão da volatilidade relativa dos ativos. Agora, a comparação será feita com base nos retornos diários, o que proporciona uma análise mais adequada do risco associado aos investimentos.

Antes de mencionar o coeficiente de variação, importanto mencionar os ativos que apresentaram retornos postivos durante o periodo, trata-se da CMIG4 e da LREN3, com destaque maior para Lojas Renner, com expressivo retorno médio diario.

Esse indicador também mensura a amplitude da oscilação, mas, neste caso, considera a variação dos retornos diários ao redor de sua média. Ele mede o risco relativo do ativo em relação ao retorno médio esperado, sendo particularmente útil para decisões de investimento, pois revela quanto risco o investidor assume por unidade de retorno. Quanto maior o coeficiente, maior a oscilação dos retornos diários, ou seja, maior a incerteza sobre o retorno futuro.

Com base nessa métrica, a BRF (BRFS) se destaca negativamente, apresentando um coeficiente de variação superior a 120%, indicando uma alta instabilidade nos retornos em torno da média. Por outro lado, a Lojas Renner apresenta o menor coeficiente de variação, seguida por CSN, Cemig e Vamos, refletindo um comportamento mais estável e previsível dos retornos.

Esse resultado contrasta com a análise baseada nos preços, na qual a Lojas Renner havia apresentado o maior coeficiente de variação, indicando elevada volatilidade dos preços. Isso reforça a importância de considerar os retornos, e não apenas os preços, na análise de risco.

Vale ressaltar que preços de ações não são estacionários, ou seja, possuem tendência ao longo do tempo. Isso pode fazer com que a média e o desvio padrão cresçam, mesmo sem grandes oscilações momentâneas. Portanto, utilizar o preço como base para análise de risco pode ser enganoso, já que um ativo pode ter uma trajetória de alta ou baixa consistente com baixa variabilidade aparente, mas sem refletir a verdadeira incerteza dos retornos que ele gera.

Estatísticas Descritivas de Risco e Retorno
Ativo Retorno Médio (%) Desvio Padrão CV (Desvio/Média)
CMIG4 CMIG4 0,0643 0,0150 23,3449
VAMO3 VAMO3 -0,1189 0,0458 38,5306
BRFS3 BRFS3 -0,0203 0,0248 121,9698
CSNA3 CSNA3 -0,3971 0,0307 7,7265
LREN3 LREN3 0,7441 0,0237 3,1836
IBOV IBOV 0,0723 0,0098 13,6021

Distribuição dos preços e retornos

Histogramas

Um fator importante na análise de risco com base na média e variância é o comportamento da distribuição da variável utilizada. Para que os cálculos e os resultados tenham significância estatística, é necessário que os dados sigam uma distribuição normal. Isso é apontado no material teórico, que indica que a variável que melhor atende a esse critério é o retorno, ao inves dos preços.

Ainda assim, o teste foi realizado para observar, dentro dos ativos selecionados, como a variável se comporta em cada caso verificando, tanto para os retornos quanto para os preços, se há aderência à distribuição normal em cada empresa analisada.

Código
library(fBasics)
par(mfrow = c(2, 3))
# Todos os Histogramas
hist(cmig4, nclass = 30, col = "blue", main = "Histograma CMIG4", xlab = "Preço")

jarqueberaTest(cmig4, title = "CMIG4")

hist(vamo3, nclass = 30, col = "blue", main = "Histograma VAMO3", xlab = "Preço")

jarqueberaTest(vamo3, title = "VAMO3")

hist(brfs3, nclass = 30, col = "blue", main = "Histograma BRFS3", xlab = "Preço")

jarqueberaTest(brfs3, title = "BRFS3")

hist(csna3, nclass = 30, col = "blue", main = "Histograma CSNA3", xlab = "Preço")

jarqueberaTest(csna3, title = "CSNA3")

hist(lren3, nclass = 30, col = "blue", main = "Histograma LREN3", xlab = "Preço")

jarqueberaTest(lren3, title = "LREN3")

hist(ibov, nclass = 30, col = "red", main = "Histograma IBOV", xlab = "Preço")

Código
plot

 #Retorno

Conforme o verificado acima atraves dos gráficos e do jarquer bere test, A interpretação do teste de Jarque-Bera é feita com base na hipótese nula (H0) e no p-valor,Se p-valor > nível de significância (alfa): Você não rejeita a hipótese nula. Isso significa que não há evidências estatísticas suficientes para afirmar que os dados não seguem uma distribuição normal.

Os gráficos em maior parte dos casos não indicam uma distribuição muita empiricamente consistente, mas os Jarque-Bera test so rejitou a hispote nula de distribuição normal no ativo LREN3

Código
par(mfrow = c(2, 3))
hist(rcmig4, nclass = 30, col = "darkgreen", main = "Hist Ret CMIG4", xlab = "Retorno")
jarqueberaTest(rcmig4, title = "CMIG4")
hist(rvamo3, nclass = 30, col = "darkgreen", main = "Hist Ret VAMO3", xlab = "Retorno")
jarqueberaTest(rvamo3, title = "VAMO3")
hist(rbrfs3, nclass = 30, col = "darkgreen", main = "Hist Ret BRFS3", xlab = "Retorno")
jarqueberaTest(rbrfs3, title = "BRFS3")
hist(rcsna3, nclass = 30, col = "darkgreen", main = "Hist Ret CSNA3", xlab = "Retorno")
jarqueberaTest(rcsna3, title = "CSNA3")
hist(rlren3, nclass = 30, col = "darkgreen", main = "Hist Ret LREN3", xlab = "Retorno")
jarqueberaTest(rlren3, title = "LREN3")
hist(ribov,  nclass = 30, col = "brown", main = "Hist Ret IBOV",  xlab = "Retorno")

Código
plot

Seguindo a teoria, o histograma dos retornos dão maiores evidencias de distribuição normal, embora o teste de jarque bere rejeite essa hipote para a CMIG4 e CSNA3, em outros ativos a significancia foi ainda maior. No entanto, não rejeitar a hipótese nula não prova que os dados são perfeitamente normais. Significa apenas que não há evidências suficientes para rejeitar essa suposição. Por tanto, adotaremos como medida padrão os retornos, seguindo a teoria, pois a distribuição dos preços não deram eveidencias suficiente que confirmem a mudança do metodo. Porém, com podenrações aos dois ativos que rejeitaram a hipotese nula de que a distribuição é normal.

Medida de volatilidade anualizada (amostra)

Com os avanços e estudo no campo das finanças a volatilidade se tornou, em grande parte, sinônimo de risco nas finanças por uma razão fundamental: ela representa a incerteza sobre o retorno de um investimento. Quanto maior a volatilidade de um ativo financeiro, maior a amplitude de suas oscilações de preço. Embora no livro (Desafio aos Deuses: a Fascinante História do Risco de Peter L. Bernstein) aborde também que há quem não se preocupe com a volatilidade, mesmo que ela esteja ligada ao risco há chance de mais coisas acontecerem do que o previsto. Isso porque essa relação não considera o tempo. Quando o tempo entra em jogo, a conexão entre risco e volatilidade diminui, já que o tempo afeta o risco de várias maneiras, não apenas em sua ligação com a volatilidade. Isso é adotado por investidores Fundamentalista w buy-and-hold como Warren Buffet, Ben Graham e Howard Marks.

O autor também aponta que esse pensamento prevalece para aqueles investidores que compram ações para longos periodos de tempo, para o investidor que eventualmente possam querer sacar seu capital rapidamente a volatilidade de fato importa e é fundamental. Ele sintetiza essa questão citando um ex-executivo e administrador de patrimonio Robert Jeffrey “O verdadeiro risco de uma carteira é ela não conseguir fornecer ao proprietário, quer em sua duração, em alguma data terminal ou em ambos, o dinheiro de que ele precisa para desembolsos essenciais.”, podemos interpretar mais uma vez como a incerteza.

Levando em consideração um investidor avesso ao risco, compreender a volatilidade torna-se essencial. Esse perfil de investidor, muitas vezes, não tolera ver seu patrimônio perdendo valor, mesmo que temporariamente, especialmente quando a intensidade da oscilação é significativa. Essa aversão pode levá-lo a retirar os recursos prematuramente, em momentos de queda, o que pode comprometer sua estratégia de longo prazo.

Código
Volcotacoes <- (Drcotacoes * 100) * sqrt(252)
Volcotacoes  # Volatilidade anualizada em %
barplot(Volcotacoes)

A volatilidade de um ativo é medida pelo desvio padrão dos seus retornos, anualizado com base nos 252 dias úteis do ano. Essa métrica oferece uma estimativa da amplitude de variação que os retornos do ativo podem apresentar, funcionando como um indicativo de risco: quanto maior a volatilidade, maior a incerteza quanto ao comportamento futuro do papel.

Ao analisar os cinco ativos em questão, todos apresentaram uma volatilidade anualizada superior à do principal índice de referência do mercado brasileiro, o Ibovespa, que registra uma volatilidade de 15,62%.

Entre os ativos avaliados, CMIG4 se destacou com a menor volatilidade entre eles: 23,82%, indicando oscilações mais controladas nos retornos e, portanto, menor risco relativo. Na sequência, temos LREN3, BRFS3 e CSNA3, com volatilidades bem acima do reportado pela companhia eletrica. A segundo colocada apresentou uma volatilidade quase 15% a mais, corroborando com a ideia de que o setor de energia eletrica envolve menores riscos e imprevibilidade.

Por outro lado, VAMO3 apresentou uma volatilidade anualizada de 72,69%, um valor consideravelmente elevado. Esse nível de volatilidade implica em altíssima incerteza quanto aos retornos futuros, refletindo uma ampla faixa de possíveis variações no preço do ativo o que, para investidores avessos ao risco, representa um cenário de grande exposição.

Portanto, de maneira geral, um valor mais elevado de volatilidade anualizada está associado a maior instabilidade e menor previsibilidade nos retornos, o que implica um risco superior para o investidor. Essa avaliação é crucial ao considerar a compatibilidade do ativo com o perfil de risco do investidor, especialmente em contextos de alta volatilidade de mercado ou incerteza econômica.

Teorias Microeconomicas

Dentro do campo dos estudos da economia, compreender o comportamento do indivíduo sempre foi uma das áreas centrais, especialmente no que diz respeito às escolhas. É justamente nesse aspecto que parte da microeconomia se dedica, com destaque para autores como Hal Varian, que explora temas como a escolha sob incerteza e a escolha intertemporal.

Esses conceitos são desenvolvidos a partir da teoria das escolhas do consumidor, onde o indivíduo busca maximizar sua função de utilidade ao escolher entre diferentes combinações de bens (como cestas dos bens A e B ou produtos A e B), dadas suas restrições orçamentárias. A partir dessa base, surge o conceito de escolha intertemporal, no qual um indivíduo possui uma dotação de renda e pode optar por consumir tudo no tempo presente (t) ou postergar parte do consumo para o futuro (t+1). Nessa lógica, o indivíduo pode:

  • Tomar empréstimos a uma determinada taxa de juros, permitindo um consumo maior no presente (t) com a expectativa de maior utilidade imediata;

  • Ou emprestar parte de sua renda, postergando o consumo para o futuro e obtendo retorno com juros, caso isso traga maior utilidade ao longo do tempo.

Essas decisões dependem da função de utilidade intertemporal de cada indivíduo, que será maximizada no ponto onde a curva de indiferença tange a restrição orçamentária intertemporal, a qual, nesse caso, tem inclinação determinada pela taxa de juros. Portanto, a taxa de juros passa a ser um fator determinante nas escolhas que maximizam a utilidade do indivíduo ao longo do tempo influenciando diretamente a preferência entre consumir agora ou no futuro.

Diante disso, o momento atual da economia brasileira se mostra bastante propício para o perfil de investidor (emprestador), aquele que prefere emprestar seus recursos em troca de uma taxa de juros atrativa. Com a taxa Selic elevada, os investimentos de renda fixa oferecem retornos consideráveis com baixo risco, tornando-se naturalmente mais atrativos para quem busca segurança e previsibilidade. Por outro lado, esse cenário representa um desafio para o mercado de ações. A alta taxa de juros impõe um custo de oportunidade elevado para o investidor que considera migrar para ativos de maior risco. Surge, então, uma pergunta essencial:
Qual taxa de retorno seria suficiente para compensar o investidor pela assunção de maior risco no mercado acionário?

Essa resposta se torna ainda mais complexa quando a taxa Selic está em patamares como 15% ao ano. Nesse contexto, é possível obter retornos semelhantes ou superiores na renda fixa, de forma contratada e com muito menos incerteza. Já o investimento em ações envolve uma camada significativa de risco e imprevisibilidade, o que exige uma compensação maior em termos de retorno esperado. É nesse ponto que entra a teoria da escolha sob incerteza. Cada indivíduo possui uma função de utilidade própria, que representa como ele atribui valor a diferentes resultados possíveis diante de eventos incertos. Essa função leva em conta não apenas o retorno esperado, mas também a probabilidade de sua ocorrência.

Assim, para um investidor disposto a assumir mais risco, a utilidade aumenta diante da possibilidade de obter um retorno futuro mais elevado, mesmo com incerteza. Já para o investidor avesso ao risco, a utilidade é maximizada em cenários com maior previsibilidade, mesmo que o retorno seja mais modesto.

Um elemento central nessa análise é a probabilidade associada aos retornos, e é justamente aí que a função de densidade de probabilidade acumulada se torna uma ferramenta valiosa. Ela permite mensurar o risco e a incerteza dos ativos, ajudando a identificar quais investimentos melhor se alinham ao perfil conservador, considerando a distribuição dos retornos esperados e a chance de ocorrência de perdas ou ganhos extremos.

Probabilidade de preços

Relacionando a teoria de escolha sobre incerteza, como mencionamos um ponto importante é a probabilidade de ocorrência. E exatamente isso que será feito a partir da função de densidade e probabilidade acumulada. E para os testes a seguir, vamos considerar como preço-alvo de cada ativo uma valorização de 7%, pois esse percentual corresponde aproximadamente à taxa necessária para dobrar o capital em 10 períodos. A partir disso, buscaremos medir a probabilidade de cada ativo alcançar esse preço.

Código
# Valores específicos para os quais você quer calcular a probabilidade acumulada
valores_observados <- c(
  "CMIG4" = 11.21,
  "VAMO3" = 4.41,
  "BRFS3" = 20.53,
  "CSNA3" = 8.025,
  "LREN3" = 20.93
)

# Criar vetores para armazenar os resultados

ativos_nomes <- names(valores_observados)
precos_referencia <- as.numeric(valores_observados) # Os preços que você forneceu
probabilidades_calculadas <- numeric(length(ativos_nomes))
names(probabilidades_calculadas) <- ativos_nomes

probabilidades_calculadas["CMIG4"] <- pnorm(valores_observados["CMIG4"], mean(cmig4, na.rm = TRUE), sd(cmig4, na.rm = TRUE), lower.tail = T)
probabilidades_calculadas["VAMO3"] <- pnorm(valores_observados["VAMO3"], mean(vamo3, na.rm = TRUE), sd(vamo3, na.rm = TRUE), lower.tail = T)
probabilidades_calculadas["BRFS3"] <- pnorm(valores_observados["BRFS3"], mean(brfs3, na.rm = TRUE), sd(brfs3, na.rm = TRUE), lower.tail = T)
probabilidades_calculadas["CSNA3"] <- pnorm(valores_observados["CSNA3"], mean(csna3, na.rm = TRUE), sd(csna3, na.rm = TRUE), lower.tail = T)
probabilidades_calculadas["LREN3"] <- pnorm(valores_observados["LREN3"], mean(lren3, na.rm = TRUE), sd(lren3, na.rm = TRUE), lower.tail = T)

tabela_completa <- data.frame(
  Ativo = ativos_nomes,
  Preco = precos_referencia,
  Probabilidade = probabilidades_calculadas
)

# Passo 1: Formatação de Dados e Nomes
tabela_final_formatada <- tabela_completa %>%
  # 1.1. Aplicar digits e format.args para Preço e Probabilidade ANTES da concatenação
  mutate(
    `Preço de Referência` = format(round(Preco, 2), big.mark = ".", decimal.mark = ",", nsmall = 2),
    `Probabilidade (%)` = format(round(Probabilidade * 100, 2), big.mark = ".", decimal.mark = ",", nsmall = 2) # Multiplica por 100 e formata
  ) %>%
  # 1.2. Concatena R$ e %
  mutate(
    `Preço de Referência` = paste("R$", `Preço de Referência`),
    `Probabilidade (%)` = paste0(`Probabilidade (%)`, "%")
  ) %>%
  # 1.3. Seleciona e Renomeia as Colunas Finais
  select(
    Ativo,
    `Preço de Referência`,
    `Probabilidade (%)`
  )

# Passo 2: Aplicação do Kable 
tabela_final <- tabela_final_formatada %>%
  kable(
    caption = "Probabilidade de Ocorrência de Evento de Risco",
    align = "c",
    # NOTA: Removemos digits e format.args daqui porque já formatamos com mutate()
  ) %>%
  # 2.3. Estilizar
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Probabilidade de Ocorrência de Evento de Risco
Ativo Preço de Referência Probabilidade (%)
CMIG4 CMIG4 R$ 11,21 99,68%
VAMO3 VAMO3 R$ 4,41 21,25%
BRFS3 BRFS3 R$ 20,53 40,29%
CSNA3 CSNA3 R$ 8,03 13,47%
LREN3 LREN3 R$ 20,93 97,19%

Considerações da primeira etapa

A análise dos ativos no período entre abril e junho de 2025, considerando um perfil de investidor avesso ao risco, evidenciou:

  • O mercado de ações talvez não esteja no melhor momento para investidores com perfil mais avesso ao risco. A elevada volatilidade, somada aos prêmios atrativos oferecidos pela renda fixa, e ao fato de que, como vimos, esse perfil tende a ter uma maior utilidade em cenários com maior previsibilidade e valor esperado, indicam que, no momento, há uma vantagem considerável em manter-se fora da renda variável;
  • Para o investidor que, mesmo ciente de seu perfil, deseje investir no mercado de ações, segue abaixo o ranking dos ativos do menos arriscado ao mais arriscado, com base em toda a análise realizada ao longo deste relatório:
    1. CMIG4
    2. LREN3
    3. BRFS3
    4. CSNA3
    5. VAMO3;
  • A CMIG4 se destaca principalmente por apresentar uma baixa volatilidade anualizada, diferenciando-se de forma significativa das demais empresas analisadas. Além disso, o setor em que a companhia está inserida proporciona maior previsibilidade, conforme os fatores anteriormente mencionados;
  • A média dos retornos logarítmicos foi positiva tanto para CMIG4 quanto para LREN3, o que garante a elas uma vantagem na ocupação das primeiras posições do ranking, observando não só menores risco, mas também melhores retornos. Contrapondo nesses casos a teoria de que aponta quanto maior o risco maior o retorno esperado;
  • A análise técnica indica uma tendência de baixa bastante acentuada para CSNA3, assim como para VAMO3, que apresentou um cruzamento de médias móveis de cima para baixo, acompanhado de um alto volume durante os pregões de queda, o que reforça a expectativa de continuidade desse movimento;
  • As medidas probabilísticas também indicaram maior atratividade para os dois primeiros ativos do ranking, reforçando a percepção de menor risco e maior previsibilidade de retorno positivo
  • Embora não descarte a volatilidade como medida de risco, os autores destacam a importância de considerar outros fatores, especialmente diante do caráter não estacionário da volatilidade e da influência do tempo nos investimentos.

Portanto, os ativos analisados apresentaram incertezas e riscos, com uma disparidade significativa entre os mais e os menos arriscados. Essa diferença pôde ser observada por meio de diferentes métodos de análise. Os ativos que figuraram entre as primeiras posições podem ser adequados ao perfil de alguns investidores avessos ao risco ainda que com ressalvas, já que esse perfil tende a ter maior aderência a investimentos em renda fixa.

Moderna Teoria da Carteira

O foco inicial do relatório foi ranquear e identificar os melhores ativos de acordo com seus níveis de risco. Agora, a análise avança ao incorporar outros fatores e componentes que asseguram e reforçam esse ranking. Além disso, busca-se compreender como aproveitar os cinco ativos selecionados para a construção de uma carteira capaz de maximizar o retorno e minimizar o risco, combinando-os a partir da teoria de Markowitz, que revolucionou o mercado há décadas e permanece amplamente reconhecida e validada até os dias atuais.

É verdade que existem críticas quanto a algumas de suas hipóteses, como a simetria de informações e a premissa de mercado eficiente. Ainda assim, não há como negar a utilidade e relevância dos conceitos de Markowitz para a gestão de portfólios. Sua teoria tem como ponto de partida justamente os elementos explorados na primeira parte do relatório: o uso de cálculos estatísticos para mensurar a volatilidade como principal indicador de risco e o retorno esperado de cada ativo. A partir disso, a decisão de investimento deve sempre observar a melhor relação entre risco e retorno, algo viável por meio da combinação de ativos em uma carteira diversificada.

Segundo a teoria, a verdadeira diversificação consiste em além de uma quantidade maior de ativos, mas em selecionar investimentos com comportamentos distintos, sobretudo em relação ao risco e à correlação entre eles. Assim, ao assumir mais risco, o investidor de fato tem a possibilidade de alcançar retornos maiores. O objetivo central, no entanto, é identificar a combinação ótima de ativos que maximize o retorno esperado dentro de um nível de risco aceitável para o perfil do investidor. 

Nesse contexto, a teoria distingue dois tipos de risco: 

  • risco sistemático: afeta o mercado todo e não há como eliminá-lo pela diversificação, por exemplo, mudanças econômicas amplas;
  • risco não sistemático: atinge empresas ou setores específicos e pode ser limitado com a diversificação. 

Vejamos por parte, cada pilar essencial da teoria e como ela impacta e auxilia na nossa carteira.

Diversificação

A moderna teoria da carteira tem como pilar, na gestão e administração do risco, a diversificação dos ativos, alocando os recursos em mais de um ou em vários ativos. Pensando em ações, com base nessa teoria, é possível reduzir o risco setorial, o risco operacional das empresas e todos os demais riscos não sistemáticos por meio da diversificação, chegando ao ponto em que restaria apenas o risco sistemático, o qual não pode ser eliminado pela diversificação.

O gráfico ilustra essa ideia: à medida que mais ativos são incluídos na carteira, o risco diminui até o limite do risco de mercado, fazendo com que a carteira tenda a esse limite, mas nunca o ultrapasse. Esse conceito está em linha com o ditado popular de que não se deve colocar todos os ovos na mesma cesta.

A ideia é exatamente essa: quanto maior o número de ativos e mais distribuída estiver a “cesta de ovos”, menor será o risco.

Correlação dos ativos

Para que a diversificação ocorra de forma eficiente, reduzindo o risco e a volatilidade de uma carteira, é essencial compreender a correlação entre os ativos. Quando dois ativos apresentam correlação positiva, ambos tendem a se movimentar no mesmo sentido; ou seja, caso o ativo X suba, espera-se que o ativo Y também suba.

Na diversificação de ativos, busca-se a relação inversa: uma correlação significativa e negativa. Nesse caso, a movimentação em sentidos opostos reduz o risco da carteira, pois diminui o impacto das oscilações.

Vejamos um exemplo: um investidor possui duas ações que atuam no setor de papel e celulose. Empiricamente, entende-se que o preço das commodities impacta diretamente essas empresas. Portanto, uma queda ou valorização da commodity tende a influenciar ambas na mesma direção, o que justificaria, em parte, a correlação positiva.

Assim, deter apenas essas duas ações no mesmo portfólio não significa diversificação adequada, já que uma oscilação negativa, a menos desejada, não seria compensada por um ativo que pudesse apresentar oscilação positiva, capaz de reduzir as perdas e a volatilidade.

Ao observarmos essa relação dentro da carteira sugerida neste relatório, a correlação negativa mais forte identificada é entre CSNA3 e LREN3. Isso ocorre principalmente porque as empresas atuam em setores bastante distintos da economia. Em momentos de melhora do consumo interno, com queda nos juros e aumento da confiança do consumidor, o varejo (LREN3) tende a se valorizar. Por outro lado, nesse mesmo cenário, o dólar pode se desvalorizar e pressionar as receitas de exportadoras como a CSN. Já em períodos de dólar forte ou de valorização de commodities, a CSNA3 tende a se beneficiar, enquanto o consumo interno enfraquecido prejudica a LREN3.

Embora essa dinâmica não tenha se confirmado exatamente no período analisado, já que o dólar permaneceu em patamares elevados e as taxas de juros também, o que em teoria teria favorecido a CSNA3 em relação à LREN3, o que se observou foi o contrário: LREN3 se valorizando enquanto CSNA3 apresentava queda. Isso se deveu a outros fatores, como os preços do minério de ferro e do aço, entre outras variáveis. O ponto central, no entanto, é destacar a importância da diversificação, especialmente entre setores distintos. Caso o investidor tivesse concentrado seus recursos em empresas fortemente influenciadas pelas mesmas variáveis que impactam a CSNA3, teria sofrido uma desvalorização significativa e, possivelmente, prejuízos mais expressivos.

Esse raciocínio se evidencia, por exemplo, na BRFS3, que apresentou a maior correlação positiva, ainda que com pouca significância estatística. Ambas as empresas, CSNA3 e BRFS3, sofrem impactos relevantes do mercado externo por serem grandes exportadoras e, em meio à turbulência tarifária vivida no período, foram afetadas de maneira semelhante.

De forma geral, as correlações positivas prevaleceram entre os ativos, em especial CMIG4, VAMO3 e BRFS3. Esse movimento provavelmente decorre mais de fatores macroeconômicos comuns e fluxos de capital do que de semelhança setorial. Em outras palavras, é possível interpretar uma influência mais marcante do risco sistêmico. A análise dos gráficos dessas empresas reforça essa percepção: todas indicam sinais de lateralização, característica típica de períodos em que o mercado aguarda um direcionamento mais claro. No caso em questão, a expectativa estava voltada especialmente para definições sobre a taxa de juros, inflação e incertezas externas.

Código
#Transformar a tabela em Data.frame para Aplicar a CORREL
Correl=cbind.data.frame(cmig4,vamo3,brfs3,csna3,lren3);Correl
names(Correl)<-c("cmig4","vamo3","brfs3","csna3","lren3");Correl
attach(Correl)
class(Correl)

#Cáculo do Coeficiente de Correlação 
# Pearson: Variáveis Numéricas e Paramétricas)

# Crie a matriz de correlação
Correl <- merge(cmig4, vamo3, brfs3, csna3, lren3, all = FALSE)
colnames(Correl) <- c('CMIG4', 'VAMO3', 'BRFS3', 'CSNA3', 'LREN3')
cor_matrix <- cor(Correl)

# Gere o gráfico de correlação
corrplot(cor_matrix,
         method = "color",       # Usa cores para representar a correlação
         type = "upper",         # Mostra apenas a metade superior da matriz
         addCoef.col = "black",  # Adiciona o coeficiente de correlação em preto
         tl.col = "black",       # Cor do texto do ticker
         tl.srt = 45,            # Gira o texto do ticker em 45 graus
         diag = FALSE)           # Não mostra os valores da diagonal

Fronteira Eficiente

A diversificação e correlação nos levam a esse nova etapa da teoria. Em suma, a Fronteira Eficiente é construída a partir de cálculos matemáticos que definem conjuntos de portfólios otimizados, capazes de oferecer o maior retorno possível para cada nível de risco ou o menor risco para cada nível de retorno. Onde até mesmo o ativo com menor risco ao ser combinado com um ativo mais arriscado podem reduzir o risco e aumentar o retorno da carteira

O ponto central da teoria da Fronteira Eficiente é que, ao realizar esses cálculos para uma série de carteiras possíveis, considerando um determinado conjunto de ativos, torna-se viável traçar um gráfico em que o retorno aparece no eixo vertical e o risco no eixo horizontal. O resultado assume o formato de uma linha curva.

Essa combinação tem como objetivo ponderar cada ativo de modo a reduzir a variância e maximizar o retorno esperado, permitindo a distribuição percentual do investimento entre diferentes ativos de forma eficiente.

Carteira mínima variância

Com base no que foi descrito a respeito da Fronteira Eficiente e dos ativos da carteira sugerida, identificamos a carteira de mínima variância, isto é, o ponto que representa as combinações de risco e retorno que oferecem a menor variância para uma determinada taxa de retorno.

Os gráficos abaixo ilustram esse resultado: o primeiro mostra a curva gerada com todas as combinações possíveis considerando os cinco ativos, em que o ponto azul destacado corresponde exatamente ao ponto mais à esquerda do eixo X, representando o risco medido pela variância. O segundo gráfico apresenta a forma como os ativos ficam distribuídos dentro do portfólio e a participação percentual de cada um.

O destaque, sem dúvidas, vai para a Cemig (CMIG4), com um percentual bastante elevado. Esse peso reflete a previsibilidade, a segurança do setor elétrico e a solidez da própria empresa, características evidenciadas ao longo de todo o relatório e que se destacaram nos critérios de mensuração do risco. Embora o retorno médio diário não tenha sido o mais elevado, a relação risco-retorno mostrou-se relevante, trazendo consistência e estabilidade ao portfólio.

Na sequência, a Lojas Renner (LREN3) também se destacou com participação significativa. Durante o período analisado, apresentou o menor risco entre os ativos e, ao mesmo tempo, o maior retorno médio, contribuindo de forma decisiva para otimizar o desempenho da carteira.

Já VAMO3 e CSNA3 tiveram participações discretas, o que é justificável tanto pelo risco mais elevado quanto pelos retornos negativos observados no período.

Código
# Calcular e plotar a fronteira de portfólio
Basico <- data.frame(na.omit(merge(cmig4, vamo3, brfs3, csna3, lren3, all = FALSE)))

# Renomear as colunas
names(Basico) <- c("cmig4", "vamo3", "brfs3", "csna3", "lren3")
length(lren3) # Para verificar o tamanho

# Transformar em objeto timeSeries para uso com fPortfolio
dados <- timeSeries(Basico)
# Calcular os retornos logarítmicos
Retornos <- returns(dados)

fronteira<-portfolioFrontier(Retornos)
fronteira
frontierPlot(fronteira, auto=F)

# Adicionar pontos específicos ao gráfico (exemplo, pontos que representam portfólios)
# Estes são exemplos fictícios e precisam ser ajustados com base nos seus próprios dados de retorno e risco
points(0.0293,-0.0037 ,pch=19, cex=1.5, col="green")
points(0.0161,-0.0009,pch=19, cex=1.5, col="green")
points(0.0136,0.0019 ,pch=19, cex=1.5, col="green")
points(0.0166,0.0046 ,pch=19, cex=1.5, col="green")
points(0.0237,0.0074,pch=19, cex=1.5, col="red") # Ponto de alto risco


MinimaVariancia<-minvariancePortfolio(Retornos)
PesosMinimos<-getWeights(MinimaVariancia);PesosMinimos
RetornoCalculado<-getTargetReturn(MinimaVariancia);RetornoCalculado
RiscoMinimo<-getTargetRisk(MinimaVariancia);RiscoMinimo
points(0.0136 ,0.0016,pch=19, cex=1.5, col="blue")

Código
GraficoPizza<-weightsPie(MinimaVariancia);GraficoPizza

Código
#--------------------------------------------------------------

Carteira ótima

Na próxima combinação de ativos, contamos com um novo componente: a linha de mercado de capitais (CML). Ela representa o novo conjunto eficiente, e todos os investidores racionais preferirão portfólios situados ao longo dela.

Intercepto: o ponto em que a CML intercepta o eixo vertical dos retornos corresponde à taxa livre de risco. Esse é o retorno que um investidor pode obter sem assumir risco algum. No caso da nossa carteira, essa linha é representada pela Taxa Selic.

Qualquer ponto sobre a CML representa uma combinação ótima entre um ativo livre de risco e um portfólio de ativos arriscados, conhecido como portfólio de mercado. Nessa estrutura, os investidores podem tomar emprestado ou aplicar recursos à taxa livre de risco, de modo que a CML se torna o verdadeiro conjunto eficiente. O ponto de tangência com a Fronteira Eficiente indica justamente o portfólio de ativos de risco que todos os investidores racionais deveriam manter em sua carteira, a carteria ótima.

Ao identificarmos o ponto de tangência, observamos mudanças relevantes na composição do portfólio. Ainda assim, os ativos de maior peso continuam sendo LREN3 e CMIG4. A diferença é que, agora, a LREN3 assume participação bem maior. Isso se explica pelo fato de que, nesse ponto, estamos mais acima no eixo dos retornos, ou seja, diferentemente da carteira de mínima variância, o retorno esperado é mais alto e ótimo. Esse resultado foi ainda mais acentuado devido à taxa livre de risco elevada, e a LREN3 foi justamente o ativo com maior retorno médio no período analisado.

Contudo, o aumento do retorno no ponto de tangência também elevou o risco da carteira, o que já era esperado. Ainda assim, a análise ilustra bem a relação proposta por Markowitz, entre risco e retorno, e como a introdução de um ativo livre de risco redefine a fronteira eficiente.

Código
library(fPortfolio)
CarteiraCustom<-portfolioSpec(portfolio=list(
  weights=NULL,targetReturn=0.006, 
  targetRisk=NULL, riskFreeRate=0.0055131,nFrontierPoints=50))
CarteiraCustom


CarteiraCustomizada<-efficientPortfolio(Retornos, spec=CarteiraCustom)
CarteiraCustomizada

getWeights(CarteiraCustomizada)
getTargetReturn(CarteiraCustomizada)
getTargetRisk(CarteiraCustomizada)
frontierPlot(portfolioFrontier(Retornos))
points(frontierPoints(CarteiraCustomizada)[,1], frontierPoints(CarteiraCustomizada)[,2], col="blue", pch=17, cex=1.5)

singleAssetPoints(fronteira, col="pink", pch=19)
tangencyLines(fronteira, col="green", pch=19)

Código
GraficoPizzaCustom<-weightsPie(CarteiraCustomizada);GraficoPizzaCustom

Carteira com mínimo de retorno de 0,40% médio diario

Essa teoria nos dá a possibilidade de estipular um retorno mínimo esperado diário, que neste caso foi definido em 0,40%. Contudo, um ponto importante que surgiu na análise é a nova linha traçada em vermelho. Essa linha, representa a inclinação do Índice de Sharpe máximo alcançado pela carteira de tangência. Em outras palavras, ela funciona como uma referência visual da melhor relação possível entre risco e retorno: quanto maior a distância de um portfólio em relação a essa linha, menor sua eficiência em termos de Sharpe. Já a linha verde, conhecida como Capital Market Line (CML), mostra as combinações entre o ativo livre de risco e a carteira de tangência, indicando o conjunto de carteiras mais eficientes disponíveis.

Mais uma vez observamos uma mudança na composição da carteira, embora os ativos que a compõem permaneçam os mesmos. Isso evidencia que a formação de um portfólio deve estar alinhada ao retorno desejado e, principalmente, ao nível de risco que o investidor está disposto a assumir, o que inevitavelmente altera sua exposição em ativos mais ou menos arriscados

Código
CarteiraCustom<-portfolioSpec(portfolio=list(
  weights=NULL,targetReturn=0.004, 
  targetRisk=NULL, riskFreeRate=0.000053131,nFrontierPoints=50))
CarteiraCustom

CarteiraCustomizada<-efficientPortfolio(Retornos, spec=CarteiraCustom)
CarteiraCustomizada

getWeights(CarteiraCustomizada)
getTargetReturn(CarteiraCustomizada)
getTargetRisk(CarteiraCustomizada)
frontierPlot(portfolioFrontier(Retornos))
points(frontierPoints(CarteiraCustomizada)[,1], frontierPoints(CarteiraCustomizada)[,2], col="blue", pch=17, cex=1.5)

singleAssetPoints(fronteira, col="pink", pch=19)
tangencyLines(fronteira, col="green", pch=19)
sharpeRatioLines(fronteira, col="red")

Código
tailoredFrontierPlot(portfolioFrontier(Retornos))

Código
GraficoPizzaCustom<-weightsPie(CarteiraCustomizada);

Código
GraficoPizzaCustom

Beta Mercado

A partir da teoria desenvolvida por Markowitz, Willian Sharpe e Jhon Litner desenvolveram a teoria do CAPM e do beta de mercado que mede a exposição de um ativo ao risco sistemático. Quando está próximo de 1, os retornos do ativo tendem a acompanhar os retornos do mercado; quando é superior a 1, uma variação no mercado gera uma volatilidade ainda maior no ativo; e, quando é inferior a 1, o ativo apresenta menor volatilidade em relação ao mercado.

O beta é um componente central do modelo CAPM, que estima o retorno esperado de um ativo a partir do prêmio de risco, definido pela diferença entre o retorno do mercado e a taxa livre de risco. O modelo assume a inexistência de custos de transação e a disponibilidade das mesmas informações para todos os investidores. Nessas condições, o risco de qualquer ativo corresponde ao risco incremental que ele adiciona ao portfólio de mercado (Damodaran).

Formula do Beta-Mercado:

\[ \beta_i = \frac{\text{Cov}(R_i, R_m)}{\text{Var}(R_m)} \]

Formula do CAPM:

\[ E(R_i) = r_f + \beta_i \cdot[E(R_m) - r_f] \]

  • E(Ri​) = retorno esperado do ativo

  • Rf = taxa livre de risco

  • βi= beta do ativo i, que mede sua sensibilidade em relação ao mercado

  • E(Rm)= retorno esperado do mercado (benchmark)

  • (E(Rm​)−Rf​) = prêmio de risco do mercado

Os diferentes betas observado nas janelas se explica por dois motivos principais:

Se a covariância muda (ativo passa a se mover mais ou menos junto ao mercado), o Beta muda, com as diferentes volatilidades. Ou Se a variância do mercado muda (mercado fica mais ou menos volátil).

Para avaliar a teoria, inclusive testar a crítica em relação ao período observado e ao número de observações, o Beta de mercado foi calculado para os 60 pregões padrão do relatório e, adicionalmente, considerando mais 30 pregões, totalizando 90 dias de observação, a fim de verificar se haveria mudanças significativas no valor do Beta.

O resultado mostrou que não houve alterações relevantes entre os diferentes períodos. O nível de risco mensurado, considerando o parâmetro analisado, manteve-se estável: os ativos com Beta superior a 1 permaneceram nessa condição, assim como aqueles com Beta inferior a 1.

Dentre os ativos avaliados, destacam-se CMIG4 e BRFS3, as duas únicas empresas com Beta inferior a 1, o que lhes confere o título de menos arriscadas. Isso significa que, em momentos de queda ou de alta do mercado, esses ativos tendem a apresentar menor volatilidade em relação ao Ibovespa.

Por outro lado, VAMO3 e CSNA3 se sobressaíram novamente como os ativos de maior risco, com Beta bem acima de 1, a principal referência. Isso indica que apresentam elevada sensibilidade aos movimentos do índice, amplificando tanto ganhos quanto perdas.

Código
selic <- get_series(11, start_date = dataini,end_date =datafim);

Selic=zoo(selic$'11')
index(Selic)=selic$date
Selic <- Selic; 

Ativos=na.omit(merge(cmig4, vamo3, brfs3, csna3,lren3,ibov,Selic))
length(na.omit(Ativos[,1]))
Data1=index(na.omit(Ativos));length(Data1)
Ativos


RIbov = ribov; RIbov
RSelic = Ativos$Selic[-1];
RSelic
RIbov = (ribov - RSelic); length(RIbov); RIbov

Rcmig4 = rcmig4 - RSelic
Rvamo3 = rvamo3 - RSelic
Rbrfs3 = rbrfs3 - RSelic
Rcsna3 = rcsna3 - RSelic
Rlren3 = rlren3 - RSelic

# Cálculo do Beta cmig4, vamo3, brfs3, csna3 e lren3
# As regressões agora funcionarão pois os vetores estão alinhados
Betacmig4 = lm(Rcmig4 ~ RIbov); Betacmig4
Betavamo3 = lm(Rvamo3 ~ RIbov); Betavamo3
Betabrfs3 = lm(Rbrfs3 ~ RIbov); Betabrfs3
Betacsna3 = lm(Rcsna3 ~ RIbov); Betacsna3
Betalren3 = lm(Rlren3 ~ RIbov); Betalren3

# Extrair os valores de R² de cada modelo
r2_cmig4 <- summary(Betacmig4)$r.squared
r2_vamo3 <- summary(Betavamo3)$r.squared
r2_brfs3 <- summary(Betabrfs3)$r.squared
r2_csna3 <- summary(Betacsna3)$r.squared
r2_lren3 <- summary(Betalren3)$r.squared

# Criar um data.frame com os resultados
tabela_r60 <- data.frame(
  Modelo = c("CMIG4", "VAMO3", "BRFS3", "CSNA3", "LREN3"),
  R2_60 = c(r2_cmig4, r2_vamo3, r2_brfs3, r2_csna3, r2_lren3)
)


TREYNOR=c(mean(Rcmig4)*100/Betacmig4$coef[2],mean(Rvamo3)*100/Betavamo3$coef[2],mean(Rbrfs3)*100/Betabrfs3$coef[2],mean(Rcsna3)*100/Betacsna3$coef[2],mean(Rlren3)*100/Betalren3$coef[2])

SHARPE=c(mean(Rcmig4)/sd(Rcmig4),mean(Rvamo3)/sd(Rvamo3),mean(Rbrfs3)/sd(Rbrfs3),mean(Rcsna3)/sd(Rcsna3),mean(Rlren3)/sd(Rlren3))

JENSEN=c(Betacmig4$coef[1],Betavamo3$coef[1],Betabrfs3$coef[1],Betacsna3$coef[1],Betalren3$coef[1])
Código
# 90 dias
cmig4 <- get.hist.quote("cmig4.sa", quote = "Close", start = dataini2, end = datafim2)
vamo3 <- get.hist.quote("vamo3.sa", quote = "Close", start = dataini2, end = datafim2)
brfs3 <- get.hist.quote("brfs3.sa", quote = "Close", start = dataini2, end = datafim2);
csna3 <- get.hist.quote("csna3.sa", quote = "Close", start = dataini2, end = datafim2)
lren3 <- get.hist.quote("lren3.sa", quote = "Close", start = dataini2, end = datafim2)
Ibov <- get.hist.quote("^BVSP",quote = "Close", start = dataini2, end = datafim2)

library(rbcb)

selic <- get_series(11, start_date = dataini2,end_date =datafim2);selic
Selic=zoo(selic$'11')
index(Selic)=selic$date
Selic <- Selic; 

Ativos=merge(cmig4, vamo3, brfs3, csna3,lren3,Ibov,Selic)
length(na.omit(Ativos[,1]))
Data1=index(na.omit(Ativos));length(Data1)

CarteiraBETA=data.frame(na.omit(Ativos),na.omit(Data1))
names(CarteiraBETA)=c("cmig4", "vamo3", "brfs3", "csna3", "lren3","Ibovespa","Selic", "Data1")
n=length(CarteiraBETA[,1]); n
CarteiraBETA[n,]
write.table(CarteiraBETA, file="BetaCarteira.txt")

CarteiraBETA <- read.table("BetaCarteira.txt", head=T)
names(CarteiraBETA) <- c("cmig4", "vamo3", "brfs3", "csna3", "lren3", "Ibovespa", "Selic", "Data")

rIbov = diff(log(CarteiraBETA$Ibovespa));
RIbov = rIbov * 100; RIbov; mean(RIbov)
RSelic = CarteiraBETA$Selic[-1];
RSelic

rcmig4 = diff(log(CarteiraBETA$cmig4)); length(rcmig4)
rvamo3 = diff(log(CarteiraBETA$vamo3)); length(rvamo3)
rbrfs3 = diff(log(CarteiraBETA$brfs3)); length(rbrfs3)
rcsna3 = diff(log(CarteiraBETA$csna3)); length(rcsna3)
rlren3 = diff(log(CarteiraBETA$lren3)); length(rlren3)

RIbov = (rIbov - RSelic);

Rcmig4 = rcmig4 - RSelic
Rvamo3 = rvamo3 - RSelic
Rbrfs3 = rbrfs3 - RSelic
Rcsna3 = rcsna3 - RSelic
Rlren3 = rlren3 - RSelic

# Cálculo do Beta cmig4, vamo3, brfs3, csna3 e lren3
Beta2cmig4 = lm(Rcmig4 ~ RIbov);
Beta2vamo3 = lm(Rvamo3 ~ RIbov);
Beta2brfs3 = lm(Rbrfs3 ~ RIbov);
Beta2csna3 = lm(Rcsna3 ~ RIbov);
Beta2lren3 = lm(Rlren3 ~ RIbov);

# Extrair os valores de R² de cada modelo
r2_cmig4 <- summary(Beta2cmig4)$r.squared
r2_vamo3 <- summary(Beta2vamo3)$r.squared
r2_brfs3 <- summary(Beta2brfs3)$r.squared
r2_csna3 <- summary(Beta2csna3)$r.squared
r2_lren3 <- summary(Beta2lren3)$r.squared

# Criar um data.frame com os resultados
tabela_r90 <- data.frame(
  Modelo = c("CMIG4", "VAMO3", "BRFS3", "CSNA3", "LREN3"),
  R2_90 = c(r2_cmig4, r2_vamo3, r2_brfs3, r2_csna3, r2_lren3)
)


TREYNOR2=c(mean(Rcmig4)*100/Beta2cmig4$coef[2],mean(Rvamo3)*100/Beta2vamo3$coef[2],mean(Rbrfs3)*100/Beta2brfs3$coef[2],mean(Rcsna3)*100/Beta2csna3$coef[2],mean(Rlren3)*100/Beta2lren3$coef[2])

SHARPE2=c(mean(Rcmig4)/sd(Rcmig4),mean(Rvamo3)/sd(Rvamo3),mean(Rbrfs3)/sd(Rbrfs3),mean(Rcsna3)/sd(Rcsna3),mean(Rlren3)/sd(Rlren3))

JENSEN2=c(Beta2cmig4$coef[1],Beta2vamo3$coef[1],Beta2brfs3$coef[1],Beta2csna3$coef[1],Beta2lren3$coef[1])
Código
par(mfrow = c(1, 2))

# Perido 1
names = c("cmig4", "vamo3", "brfs3", "csna3", "lren3")
BETA.Mercado = c(Betacmig4$coef[2], Betavamo3$coef[2], Betabrfs3$coef[2], Betacsna3$coef[2], Betalren3$coef[2])
names; BETA.Mercado

bpb <- barplot(BETA.Mercado, main = "Beta-Mercado 60 DIAS", ylim = c(0,4.0), names.arg = names, ylab = "Percentual %", cex.names = 0.7, col = "darkgreen")
text(x = as.vector(bpb), y = BETA.Mercado,
     label = round(BETA.Mercado, 2), pos = 3,
     col = "black", cex = 0.8)

# Periodo 2

names = c("cmig4", "vamo3", "brfs3", "csna3", "lren3")
BETA.Mercado = c(Beta2cmig4$coef[2], Beta2vamo3$coef[2], Beta2brfs3$coef[2], Beta2csna3$coef[2], Beta2lren3$coef[2])
names; BETA.Mercado

bpb <- barplot(BETA.Mercado, main = "Beta-Mercado 90 DIAS", ylim = c(0,4.0), names.arg = names, ylab = "Percentual %", cex.names = 0.7, col = "darkgreen")
text(x = as.vector(bpb), y = BETA.Mercado,
     label = round(BETA.Mercado, 2), pos = 3,
     col = "black", cex = 0.8)

Como mencionado por Damodaran, o Beta representa o risco sistemático e, na teoria , é utilizado considerando uma carteira diversificada, uma vez que os riscos específicos de cada ativo já foram eliminados pela diversificação. Na equação do CAPM, a diversificação está refletida no termo de erro; quando a carteira não é diversificada, esse termo, que sintetiza as variáveis omitidas no modelo, tende a se elevar.

Não é por acaso que o Beta estimado de um ativo individual apresenta, na maioria dos casos, um R² baixo, indicando que apenas uma pequena parcela de seu retorno é explicada pelas variáveis do modelo.

Como observado na tabela abaixo, o principal gargalo da teoria está justamente no baixo R², que mostra que há pouco do resultado obtido na variável dependente explicado pela variável independente do modelo, sinalizando a existência de variáveis omitidas na equação. Para a maioria dos papéis, a mudança no espaço amostral acarretou variações mais expressivas no termo de erro; entretanto, para BRFS3 isso não ocorreu, mantendo-se praticamente constante e em patamar baixo, o que evidencia que a estimação do retorno via CAPM para a empresa tem pouca significância estatística.

Por outro lado, a CSNA3 apresentou maior eficiência, com termo de erro mais baixo entre as cinco empresas analisadas, destacando-se de forma consistente nos dois períodos observados. Logo em seguida, merece menção a LREN3, que também demonstrou desempenho relevante e maior ajuste.

Comparativo do Poder Explicativo (R²) em Diferentes Janelas de Tempo
Poder Explicativo do Modelo
Modelo R² (60 Dias) R² (90 Dias)
BRFS3 0,1049 0,1057
CMIG4 0,2425 0,1840
CSNA3 0,4603 0,5096
LREN3 0,5395 0,3283
VAMO3 0,2976 0,3555

Indicadores de Performance

Os indicadores de performance de Treynor, Sharpe e Jensen têm como propósito auxiliar investidores e gestores de carteiras a mensurar o retorno de um ativo ou de uma carteira, levando em consideração não apenas sua valorização individual, mas também a relação com a taxa livre de risco e o risco assumido. Assim, é possível identificar se houve geração de alfa no período, ou seja, se o retorno superou o benchmark, e se o prêmio de risco compensou adequadamente a volatilidade ou se o risco tomado foi desproporcional ao ganho obtido.

Embora todos compartilhem desse objetivo, cada indicador adota características distintas, resultando em valores diferentes. Tanto o Índice de Treynor quanto o Índice de Sharpe mensuram o retorno em excesso em relação à taxa livre de risco, mas se diferenciam na medida de risco utilizada no denominador:

  • O Treynor considera o beta de mercado, avaliando o risco sistemático do ativo.

  • O Sharpe, por sua vez, utiliza o desvio-padrão total, capturando a volatilidade própria do ativo em torno de sua média de retornos.

No processo de seleção de ativos e performance, isso implica que o Índice de Treynor ocupa uma posição secundária, já que se restringe ao risco sistemático e ao beta individual. Por outro lado, o Índice de Sharpe mostra-se mais adequado neste contexto, uma vez que reflete diretamente a volatilidade observada no ativo, justificando sua prioridade na avaliação.

Apesar dessas diferenças metodológicas, ambos os índices apresentaram valores negativos, sinalizando desempenho insatisfatório. Contudo, apenas ao detalhar as fórmulas e decompor cada componente torna-se possível compreender as razões dos resultados tão abaixo do esperado.

O Índice de Sharpe, que mede o retorno ajustado ao risco, é dado pela seguinte fórmula:

\[ Sharpe = \frac{R_p - R_f}{\sigma_p} \]

Por outro lado, o Índice de Treynor foca no risco sistemático (beta):

\[ Treynor = \frac{R_p - R_f}{\beta_p} \]

Como já mencionado, o ponto comum entre os indicadores é que ambos mensuram o retorno excedente em relação a um benchmark. A teoria estabelece como referência a taxa livre de risco, que no contexto brasileiro pode ser representada pela titúlos do tesouro Selic - LFT, por se tratar de risco soberano.

O cenário atual de juros elevados faz com que os ativos observados apresentem pouco ou nenhum prêmio em relação à taxa livre de risco. Consequentemente, o numerador das fórmulas torna-se negativo. Nesse caso, interpretar e ranquear os resultados exige cautela: ordenar simplesmente pelo “maior” ou pelo “mais próximo de zero” pode gerar uma leitura distorcida.

Por exemplo, um ativo com retorno negativo elevado pode parecer relativamente melhor que outro, apenas porque possui também um risco (denominador) elevado, o que reduz o índice e o aproxima de zero. Isso, entretanto, não significa uma performance superior, pelo contrário, o ativo pode ter apresentado retorno inferior e maior risco.

Portanto, esses indicadores tornam-se mais eficientes e de fácil interpretação quando há prêmio positivo, permitindo verificar de forma clara quanto de alfa foi gerado por unidade de risco.

Ainda quando mudamos o espaço de tempo para os 90 dias, assim como no Beta-Mercado, não observamos mudanças significativas, ou ativos que apresentem resutados positivos nos indicadores.

Código
par(mfrow = c(2, 2))
bpTreynor<-barplot(TREYNOR, main="Treynor 60 DIAS", ylim=c(-7,1),names.arg=names, ylab="Percentual %", cex.names=0.7, col='blue')
text(x = as.vector(bpTreynor), y = TREYNOR, 
     label =  round(TREYNOR, 4), pos = 3, 
     col = "black", cex = 0.8)


bpTreynor<-barplot(TREYNOR2, main="Treynor 90 DIAS", ylim=c(-8,1),names.arg=names, ylab="Percentual %", cex.names=0.7, col='blue')
text(x = as.vector(bpTreynor), y = TREYNOR2, 
     label =  round(TREYNOR2, 4), pos = 3, 
     col = "black", cex = 0.8)

bpSharpe<-barplot(SHARPE, main="Sharpe 60 DIAS", ylim=c(-7,1),names.arg=names, ylab="Percentual %", cex.names=0.7)
text(x = as.vector(bpSharpe), y = SHARPE, 
     label =  round(SHARPE, 4), pos = 3, 
     col = "black", cex = 0.8)

bpSharpe<-barplot(SHARPE2, main="Sharpe 90 DIAS", ylim=c(-7,1),names.arg=names, ylab="Percentual %", cex.names=0.7)
text(x = as.vector(bpSharpe), y = SHARPE2, 
     label =  round(SHARPE2, 4), pos = 3, 
     col = "black", cex = 0.8)

O Índice de Jensen é obtido ao se isolar o alfa na equação do CAPM, observando exatamente o retorno acima do retorno de mercado, considerado como o alfa. Seu cálculo corresponde à diferença entre o retorno efetivamente apresentado pela carteira e o retorno que deveria ter sido alcançado segundo as condições previstas pelo CAPM. Assim, mede o excesso de retorno em relação ao retorno esperado, avaliando se o ativo ou a carteira conseguiu gerar retorno adicional para o nível de risco sistemático assumido. Nesse sentido, o Índice de Jensen constitui um bom indicador para analisar o prêmio de risco obtido e a capacidade do ativo de superar as expectativas do próprio modelo.

\(alpha_J = R_p - [R_f + \beta_p(R_m - R_f)]\)

À luz dos resultados, apenas CMIG4 e BRFS3 não superaram os retornos esperados. Coincidentemente, esses também foram os únicos ativos com beta inferior a 1. Embora tenham apresentado desempenho positivo, em um contexto de forte valorização do mercado o retorno obtido foi insuficiente para acompanhar o nível projetado pelo CAPM. Em outras palavras, por serem ativos defensivos, sua sensibilidade às oscilações do mercado é menor, assim, quando o índice de referência se valoriza com intensidade, esses papéis tendem a ficar para trás, gerando um alfa de Jensen negativo.

Código
par(mfrow = c(1, 2))
bpJensen<-barplot(JENSEN, main="Jensen 60 DIAS", ylim=c(-0.03,0.11),names.arg=names, ylab="Percentual %", cex.names=0.7)
text(x = as.vector(bpJensen), y = JENSEN, 
     label =  round(JENSEN, 4), pos = 3, 
     col = "black", cex = 0.7)

bpJensen<-barplot(JENSEN2, main="Jensen 90 DIAS", ylim=c(-0.03,0.11),names.arg=names, ylab="Percentual %", cex.names=0.7)
text(x = as.vector(bpJensen), y = JENSEN2, 
     label =  round(JENSEN2, 4), pos = 3, 
     col = "black", cex = 0.7)

O que acontece quando utilizamos dados mensais?

Com o objetivo de validar ainda mais a teoria a respeito do Beta de mercado, o modelo agora foi estimado com dados mensais. Essa abordagem permite testar não apenas o CAPM, mas também outros modelos que confrontam e aprimoram as críticas fundamentadas à teoria de Sharpe.

Diferentemente do observado anteriormente com os Betas de 60 e 90 dias, a estimação com dados mensais utiliza um horizonte muito maior de observação, no qual os ativos atravessam diferentes cenários econômicos. Nesse contexto, o principal destaque vai para a CMIG4: a única empresa que permaneceu consistentemente com Beta abaixo de 1. O relevante não é apenas estar abaixo desse patamar, mas sim ter mantido essa condição mesmo quando ampliamos a análise para dados mensais, abrangendo diferentes anos.

As demais empresas, de modo geral, convergiram entre si. As que antes apresentavam maior risco, medido pelo Beta de mercado, tiveram redução significativa nesse indicador, enquanto a BRFS3, por exemplo, apresentou elevação, aproximando-se das demais. A intuição sugere que houve uma aproximação da volatilidade dos ativos em relação ao Ibovespa, todos situando-se consideravelmente acima de 1.

A CMIG4, por sua vez, manteve o comportamento oposto: Beta consistentemente abaixo de 1, reforçando seu perfil de menor volatilidade em relação ao índice de mercado, e consequentemente menor risco.

Código
# Define o período de 60 meses
datafim <- ymd("2025-06-28")
dataini <- datafim - months(60)

# Lista de ativos
ativos <- c("CMIG4.SA", "VAMO3.SA", "BRFS3.SA", "CSNA3.SA", "LREN3.SA","^BVSP")

# Lista para armazenar apenas os fechamentos
cotacoes_fechamento <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini, 
                                to = datafim,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_fechamento[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_fechamento)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos
cotacoes <- cotacoes_combinadas; cotacoes

colnames(cotacoes)[colnames(cotacoes) == "CMIG4.SA"] <- "CMIG4"
colnames(cotacoes)[colnames(cotacoes) == "LREN3.SA"] <- "LREN3"
colnames(cotacoes)[colnames(cotacoes) == "CSNA3.SA"] <- "CSNA3"
colnames(cotacoes)[colnames(cotacoes) == "VAMO3.SA"] <- "VAMO3"
colnames(cotacoes)[colnames(cotacoes) == "BRFS3.SA"] <- "BRFS3"
colnames(cotacoes)[colnames(cotacoes) == "^BVSP"] <- "IBOV"

# Remova todas as linhas que contenham NA
cotacoes <- na.omit(cotacoes)

# Selecionando cada coluna por nome e atribuindo a uma variável
cmig4 <- cotacoes$CMIG4
vamo3 <- cotacoes$VAMO3
brfs3 <- cotacoes$BRFS3
csna3 <- cotacoes$CSNA3
lren3 <- cotacoes$LREN3
ibov <- cotacoes$IBOV

rcmig4 <- diff(log(cmig4))
rvamo3 <- diff(log(vamo3))
rbrfs3 <- diff(log(brfs3))
rcsna3 <- diff(log(csna3))
rlren3 <- diff(log(lren3))
ribov  <- diff(log(ibov))

Média dos retornos e desvio padrão

Código
rcotacoes <-lapply(cotacoes, function(x) diff(log(x))) 
rcotacoes <- do.call(cbind, rcotacoes)

rcotacoes <- na.omit(rcotacoes)
rcotacoes  # Retornos logarítmicos

mrcotacoes <- sapply(rcotacoes, mean, na.rm = TRUE)
mrcotacoes * 100  # Retorno médio mensal em %


Drcotacoes <-  sapply(rcotacoes, sd, na.rm = TRUE)
Drcotacoes  # Desvio padrão dos retornos

cvrcotacoes <- Drcotacoes / mrcotacoes 
cvrcotacoes * 100  # Coeficiente de variação dos retornos em %
cvrcotacoes <- abs(cvrcotacoes)

tabela_resumo_completa <- data.frame(
  Ativo = names(mrcotacoes), # Assume que os nomes dos ativos estão em name (mrcotacoes)
  Media_Retorno = mrcotacoes * 100, # Média em %
  Desvio_Padrao = Drcotacoes
)

# 2.1. Renomear Colunas
tabela_limpa <- tabela_resumo_completa %>%
  rename(
    `Retorno Médio (%)` = Media_Retorno,
    `Desvio Padrão` = Desvio_Padrao
  )

# 2.2. Formatar e Estilizar a Tabela
tabela_final <- tabela_limpa %>%
  kable(
    caption = "Estatísticas Descritivas de Risco e Retorno",
    align = "c",
    digits = 4, # 4 casas decimais para todas as métricas
    format.args = list(big.mark = ".", decimal.mark = ",") # Formato brasileiro
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Estatísticas Descritivas de Risco e Retorno
Ativo Retorno Médio (%) Desvio Padrão
CMIG4 CMIG4 1,0222 0,0636
VAMO3 VAMO3 -1,3670 0,1368
BRFS3 BRFS3 -0,0434 0,1490
CSNA3 CSNA3 -2,8571 0,1337
LREN3 LREN3 -0,8145 0,1318
IBOV IBOV 0,4474 0,0495

Beta Mercado (Dados Mensais)

Código
selic <- get_series(4390, start_date = dataini,end_date =datafim);selic

Selic=zoo(selic$'4390')
index(Selic)=selic$date
Selic <- Selic/100;

Ativos=na.omit(merge(cmig4, vamo3, brfs3, csna3,lren3,ibov,Selic))
length(na.omit(Ativos[,1]))
Data1=index(na.omit(Ativos));length(Data1)
Ativos


RIbov = ribov; RIbov
RSelic = Ativos$Selic[-1]; length(Ativos$Selic[-1])
RSelic

RIbov = (ribov - RSelic); length(RIbov); RIbov

Rcmig4 = rcmig4 - RSelic
Rvamo3 = rvamo3 - RSelic
Rbrfs3 = rbrfs3 - RSelic
Rcsna3 = rcsna3 - RSelic
Rlren3 = rlren3 - RSelic

# Cálculo do Beta cmig4, vamo3, brfs3, csna3 e lren3
# As regressões agora funcionarão pois os vetores estão alinhados
Betacmig4 = lm(Rcmig4 ~ RIbov); Betacmig4
Betavamo3 = lm(Rvamo3 ~ RIbov); Betavamo3
Betabrfs3 = lm(Rbrfs3 ~ RIbov); Betabrfs3
Betacsna3 = lm(Rcsna3 ~ RIbov); Betacsna3
Betalren3 = lm(Rlren3 ~ RIbov); Betalren3

# Extrair os valores de R² de cada modelo
r2_cmig4 <- summary(Betacmig4)$r.squared
r2_vamo3 <- summary(Betavamo3)$r.squared
r2_brfs3 <- summary(Betabrfs3)$r.squared
r2_csna3 <- summary(Betacsna3)$r.squared
r2_lren3 <- summary(Betalren3)$r.squared

# Criar um data.frame com os resultados
tabela_mensal <- data.frame(
  Modelo = c("CMIG4", "VAMO3", "BRFS3", "CSNA3", "LREN3"),
  R2_mensal = c(r2_cmig4, r2_vamo3, r2_brfs3, r2_csna3, r2_lren3)
)

names = c("cmig4", "vamo3", "brfs3", "csna3", "lren3")
BETA.Mercado = c(Betacmig4$coef[2], Betavamo3$coef[2], Betabrfs3$coef[2], Betacsna3$coef[2], Betalren3$coef[2])
names; BETA.Mercado

bpb <- barplot(BETA.Mercado, main = "Gráf.4:Cálculo do Beta-Mercado da Carteira 27/10/2023 - 26/01/2024", ylim = c(0,3.0), names.arg = names, ylab = "Percentual %", cex.names = 1, col = "darkgreen")
text(x = as.vector(bpb), y = BETA.Mercado,
     label = round(BETA.Mercado, 2), pos = 3,
     col = "black", cex = 0.8)

Ao observar novamente o R², verificamos valores consistentemente baixos, mantendo o mesmo padrão identificado na análise com retornos diários. Esse resultado reforça a evidência de que faltam variáveis explicativas na estimação.

Ainda assim, LREN3 e CSNA3 continuam se destacando, apresentando os maiores níveis de ajuste entre as regressões. Isso sugere que esses ativos possuem características que os tornam relativamente mais sensíveis e bem capturados pelos modelos considerados, mesmo que os resultados permaneçam distantes dos parâmetros ideais.

Poder Explicativo do Modelo (R²) em Janela Mensal
R-Quadrado
Modelo R² Mensal
CMIG4 0,1660
VAMO3 0,2696
BRFS3 0,3044
CSNA3 0,3642
LREN3 0,5349

Quando observamos os indicadores de performance mensais e os comparamos aos diários, o panorama muda significativamente. Nesse horizonte já é possível identificar a existência de prêmio e resultados positivos em relação ao risco. A CMIG4 se destacou em todos os indicadores, mostrando que a empresa conseguiu, durante o período, apresentar um retorno positivo suficiente para superar a taxa livre de risco. Já os demais ativos não apresentaram prêmio no período, o que indica que o investidor teria retorno menor do que a taxa livre de risco, ou até mesmo negativo, o que é esperado tendo em vista o retorno médio mensal de cada ativo.

Código
TREYNOR=c(mean(Rcmig4)*100/Betacmig4$coef[2],mean(Rvamo3)*100/Betavamo3$coef[2],mean(Rbrfs3)*100/Betabrfs3$coef[2],mean(Rcsna3)*100/Betacsna3$coef[2],mean(Rlren3)*100/Betalren3$coef[2]);names;

SHARPE=c(mean(Rcmig4)/sd(Rcmig4),mean(Rvamo3)/sd(Rvamo3),mean(Rbrfs3)/sd(Rbrfs3),mean(Rcsna3)/sd(Rcsna3),mean(Rlren3)/sd(Rlren3));names;

JENSEN=c(Betacmig4$coef[1],Betavamo3$coef[1],Betabrfs3$coef[1],Betacsna3$coef[1],Betalren3$coef[1]);names;JENSEN

par(mfrow = c(2, 2))
bpTreynor<-barplot(TREYNOR, main="Treynor - Dados Mensais", ylim=c(-3,1.5),names.arg=names, ylab="Percentual %", cex.names=1, col='blue')
text(x = as.vector(bpTreynor), y = TREYNOR, 
     label =  round(TREYNOR, 4), pos = 3, 
     col = "black", cex = 0.8)

bpSharpe<-barplot(SHARPE, main="Sharpe - Dados Mensais", ylim=c(-0.5,0.5),names.arg=names, ylab="Percentual %", cex.names=1)
text(x = as.vector(bpSharpe), y = SHARPE, 
     label =  round(SHARPE, 4), pos = 3, 
     col = "black", cex = 0.8)

bpJensen<-barplot(JENSEN, main="Jensen - Dados Mensais", ylim=c(-0.04,0.02),names.arg=names, ylab="Percentual %", cex.names=0.7)
text(x = as.vector(bpJensen), y = JENSEN, 
     label =  round(JENSEN, 4), pos = 3, 
     col = "black", cex = 0.7)

Crítica ao Beta-Mercado e modelo APT

Como observado anteriormente, o problema do CAPM e do Beta Mercado está justamente no termo de erro, que evidencia a falta de variáveis no modelo. Apenas o prêmio de risco, expresso pela diferença entre o retorno do mercado e a taxa livre de risco, não é suficiente para capturar todos os riscos sistemáticos que impactam o retorno de um ativo ou de uma carteira.

Foi nesse contexto que Stephen Ross aprimorou o modelo de precificação de ativos, ao incluir variáveis macroeconômicas capazes de explicar melhor o retorno de um ativo ou portfólio. A Arbitrage Pricing Theory (APT) sustenta a ideia de que os retornos oferecidos pelos ativos podem ser analisados a partir de diversos fatores econômicos.

Em outras palavras, a Teoria de Precificação por Arbitragem é um modelo multifatorial de precificação de ativos. Ela se baseia na relação linear entre o retorno esperado de um ativo e várias variáveis macroeconômicas que capturam diferentes dimensões do risco sistemático.

O modelo APT é um modelo de múltiplos fatores dado por:

\[ R_{p} = \alpha + \beta_1 F_1 + \beta_2 F_2 + \dots + \beta_k F_k + \epsilon \]

Um ponto essencial da APT é que a teoria admite a possibilidade de haver erros de precificação por parte do mercado, justamente o oposto do pressuposto do CAPM, que parte da ideia de mercados totalmente eficientes na formação de preços.

Para a estimação do modelo, mantivemos o premio (Ibov - Rf) como risco de mercado e foram selecionadas as principais variáveis macroeconômicas com potencial de impacto sobre a economia como um todo. Entre elas:

  • Taxa Selic: considerada tanto em seu valor absoluto (Selic-meta) quanto em suas variações, refletindo o custo do capital e a política monetária.

  • IPCA: como medida oficial da inflação, fundamental para capturar a perda de poder de compra e o comportamento dos preços.

  • IBC-Br: indicador de atividade econômica mensal, servindo como proxy do PIB.

  • Variação cambial e variação das reservas internacionais: para captar os impactos do setor externo, especialmente em um país emergente e dependente de fluxos de capitais.

  • VIX: conhecido como “índice do medo”, representando a aversão ao risco dos investidores e a percepção de volatilidade nos mercados globais.

  • Petróleo WTI: a principal commodity energética, cuja variação de preços impacta diretamente diversos setores da economia, tanto na produção quanto nos custos de insumos.

Código
selic_meta <- get_series(432, start_date = dataini,end_date =datafim);selic_meta
selic_meta <- zoo(selic_meta$`432`, order.by = selic_meta$date)
#index(selic_meta)=selic_meta$date
#selic_meta <- diff(log(selic_meta))
vselic_meta <- selic_meta

ibc <- get_series(24363, start_date = dataini,end_date =datafim);ibc
ibc <- zoo(ibc$`24363`, order.by = ibc$date)
vibc <- diff(log(ibc))
vibc

ipca <- get_series(433, start_date = dataini,end_date =datafim);ipca
ipca <- zoo(ipca$`433`, order.by = ipca$date)
vipca <- ipca

cambio <- get_series(3695, start_date = dataini,end_date =datafim);
cambio <- zoo(cambio$`3695`, order.by = cambio$date)
vcambio <- diff(log(cambio))


reservas <- get_series(3546, start_date = dataini,end_date =datafim);reservas

# 1. Leia o arquivo
dados <- read.csv("VIX.csv", sep = ",")

# 2. Selecione as colunas e mude os nomes
vix <- dados[, c("Data", "Último")]
names(vix) <- c("Data", "vix")

# 3. Limpe e converta a coluna 'vix' para numérica
vix$vix <- as.numeric(gsub(",", ".", gsub("\\.", "", vix$vix)))
# 4. Converta a coluna 'Data' para o formato de data (Date)
vix$Data <- as.Date(vix$Data, format = "%d.%m.%Y")
# 5. Transforme o data.frame em um objeto xts com 'Data' como índice
vix <- xts(vix$vix, order.by = vix$Data)

# 1. Leia o arquivo
dados <- read.csv("wti.csv", sep = ",")

# 2. Selecione as colunas e mude os nomes
wti <- dados[, c("Data", "Último")]
names(wti) <- c("Data", "wti")

# 3. Limpe e converta a coluna 'vix' para numérica
wti$wti <- as.numeric(gsub(",", ".", gsub("\\.", "", wti$wti)))
# 4. Converta a coluna 'Data' para o formato de data (Date)
wti$Data <- as.Date(wti$Data, format = "%d.%m.%Y")
# 5. Transforme o data.frame em um objeto xts com 'Data' como índice
wti <- xts(wti$wti, order.by = wti$Data)
wti



apt =na.omit(merge(cmig4, vamo3, brfs3, csna3,lren3,ibov,Selic, selic_meta, vselic_meta, vibc, ipca, reservas, vcambio, vix, wti))
apt$vselic_meta <- diff(apt$vselic_meta)
apt$ipca <- diff(log(apt$ipca))
apt$reservas <- diff(log(apt$reservas))
apt$vix <- diff(log(apt$vix))
apt$wti <- diff(log(apt$wti))

names(apt)=c("cmig4", "vamo3", "brfs3", "csna3", "lren3","Ibovespa","Selic", "Selic_Meta", "Variacao_Selic" , "IBC", "IPCA", "RESERVAS", "CAMBIO", "VIX", "WTI")

BetaAPTcmig4 = lm(Rcmig4 ~ RIbov + apt$Selic_Meta[-1] + apt$Variacao_Selic[-1] + apt$IPCA[-1] + apt$IBC[-1] + apt$RESERVAS[-1] + apt$CAMBIO[-1] + apt$VIX[-1] + apt$WTI[-1])

BetaAPTvamo3 = lm(Rvamo3 ~ RIbov + apt$Selic_Meta[-1]+ apt$Variacao_Selic[-1] + apt$IPCA[-1] + apt$IBC[-1] + apt$RESERVAS[-1]+ apt$CAMBIO[-1] + apt$VIX[-1] + apt$WTI[-1])

BetaAPTbrfs3 = lm(Rbrfs3 ~ RIbov + apt$Selic_Meta[-1]+ apt$Variacao_Selic[-1] + apt$IPCA[-1] + apt$IBC[-1] + apt$RESERVAS[-1]+ apt$CAMBIO[-1] + apt$VIX[-1] + apt$WTI[-1])

BetaAPTcsna3 = lm(Rcsna3 ~ RIbov + apt$Selic_Meta[-1]+ apt$Variacao_Selic[-1] + apt$IPCA[-1] + apt$IBC[-1] + apt$RESERVAS[-1]+ apt$CAMBIO[-1]+ apt$VIX[-1] + apt$WTI[-1])

BetaAPTlren3 = lm(Rlren3 ~ RIbov + apt$Selic_Meta[-1]+ apt$Variacao_Selic[-1] + apt$IPCA[-1] + apt$IBC[-1] + apt$RESERVAS[-1]+ apt$CAMBIO[-1]+ apt$VIX[-1] + apt$WTI[-1])
Código
# Passo 2: Extraia os coeficientes e os R-Quadrado de cada modelo

# Usamos o summary() para obter uma lista com o R-Quadrado e o R-Quadrado Ajustado
s_cmig4 <- summary(BetaAPTcmig4)
s_vamo3 <- summary(BetaAPTvamo3)
s_brfs3 <- summary(BetaAPTbrfs3)
s_csna3 <- summary(BetaAPTcsna3)
s_lren3 <- summary(BetaAPTlren3)
# Usamos coef() para obter um vetor com os coeficientes (betas)

beta_cmig4 <- coef(BetaAPTcmig4)
beta_vamo3 <- coef(BetaAPTvamo3)
beta_brfs3 <- coef(BetaAPTbrfs3)
beta_csna3 <- coef(BetaAPTcsna3)
beta_lren3 <- coef(BetaAPTlren3)

# [Seu código de definição e extração de modelos permanece aqui]

# Passo 2: Extraia os coeficientes e os R-Quadrado de cada modelo
# ... (Seu código de extração s_cmig4 a s_lren3 e beta_cmig4 a beta_lren3 permanece inalterado)

# Passo 3: Crie a tabela (data.frame) com os resultados (Código Original)
tabela_betas <- data.frame(
  Ativos = c("CMIG4", "VAMO3", "BRFS3", "CSNA3", "LREN3"),
  Beta_Ibov = c(beta_cmig4["RIbov"], beta_vamo3["RIbov"], beta_brfs3["RIbov"], beta_csna3["RIbov"], beta_lren3["RIbov"]),
  Beta_Selic = c(beta_cmig4["apt$Selic_Meta[-1]"], beta_vamo3["apt$Selic_Meta[-1]"], beta_brfs3["apt$Selic_Meta[-1]"], beta_csna3["apt$Selic_Meta[-1]"], beta_lren3["apt$Selic_Meta[-1]"]),
  Beta_Variacao_Selic = c(beta_cmig4["apt$Variacao_Selic[-1]"], beta_vamo3["apt$Variacao_Selic[-1]"], beta_brfs3["apt$Variacao_Selic[-1]"], beta_csna3["apt$Variacao_Selic[-1]"], beta_lren3["aapt$Variacao_Selic[-1]"]),
  Beta_IPCA = c(beta_cmig4["apt$IPCA[-1]"], beta_vamo3["apt$IPCA[-1]"], beta_brfs3["apt$IPCA[-1]"], beta_csna3["apt$IPCA[-1]"], beta_lren3["apt$IPCA[-1]"]),
  Beta_IBC = c(beta_cmig4["apt$IBC[-1]"], beta_vamo3["apt$IBC[-1]"], beta_brfs3["apt$IBC[-1]"], beta_csna3["apt$IBC[-1]"], beta_lren3["apt$IBC[-1]"]),
  Beta_Cambio = c(beta_cmig4["apt$CAMBIO[-1]"], beta_vamo3["apt$CAMBIO[-1]"], beta_brfs3["apt$CAMBIO[-1]"], beta_csna3["apt$CAMBIO[-1]"], beta_lren3["apt$CAMBIO[-1]"]),
  Beta_Reservas = c(beta_cmig4["apt$RESERVAS[-1]"], beta_vamo3["apt$RESERVas[-1]"], beta_brfs3["apt$RESERVAS[-1]"], beta_csna3["apt$RESERVAS[-1]"], beta_lren3["apt$RESERVAS[-1]"]),
  Beta_Vix = c(beta_cmig4["apt$VIX[-1]"], beta_vamo3["apt$VIX[-1]"], beta_brfs3["apt$VIX[-1]"], beta_csna3["apt$VIX[-1]"], beta_lren3["apt$VIX[-1]"]),
  Beta_WTI = c(beta_cmig4["apt$WTI[-1]"], beta_vamo3["apt$WTI[-1][-1]"], beta_brfs3["apt$WTI[-1]"], beta_csna3["apt$WTI[-1]"], beta_lren3["apt$WTI[-1]"]),
  R_Quadrado = c(s_cmig4$r.squared, s_vamo3$r.squared, s_brfs3$r.squared, s_csna3$r.squared, s_lren3$r.squared)
)

# Passo 4: Melhoria Estética

# 4.1. Limpar e Renomear Colunas
tabela_limpa <- tabela_betas %>%
  rename(
    `Beta (Mercado)` = Beta_Ibov,
    `Beta (Selic)` = Beta_Selic,
    `Beta (Var. Selic)` = Beta_Variacao_Selic,
    `Beta (IPCA)` = Beta_IPCA,
    `Beta (IBC)` = Beta_IBC,
    `Beta (Câmbio)` = Beta_Cambio,
    `Beta (Reservas)` = Beta_Reservas,
    `Beta (VIX)` = Beta_Vix,
    `Beta (WTI)` = Beta_WTI,
    `` = R_Quadrado
  )

# 4.2. Formatar e Estilizar a Tabela
tabela_final <- tabela_limpa %>%
  # 4.2.1. Cria a tabela básica do kable
  kable(
    caption = "Matriz de Betas e R-Quadrado (Modelo APT)",
    align = "c",
    digits = 4, # Quatro casas decimais para os Betas
    format.args = list(big.mark = ".", decimal.mark = ",") # Formato brasileiro
  ) %>%
  # 4.2.2. Adiciona o estilo visual (ex: light)
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  ) %>%
  # 4.2.3. Adiciona uma linha de cabeçalho mais clara
  add_header_above(c(" " = 1, "Sensibilidade a Fatores Macroeconômicos" = 9, "Ajuste do Modelo" = 1))

Quando incluímos as novas variáveis na estimação, observamos uma melhora significativa no ajuste do modelo. A CMIG4, por exemplo, embora ainda permaneça abaixo, praticamente dobrou o seu R², indicando um avanço relevante. Além disso, três dos cinco ativos passaram a apresentar valores próximos ou acima de 0,5, com destaque mais uma vez para a LREN3.

Em relação aos fatores de câmbio e exportação, verificamos que a BRFS3 e a LREN3 se beneficiam diretamente da valorização do dólar, dado que a primeira é uma exportadora de alimentos e a segunda também apresenta impacto positivo nesse cenário. Já VAMO3, CSNA3 e CMIG4 apresentaram betas negativos em relação ao câmbio, o que sugere que esses ativos tendem a ser prejudicados pela desvalorização do real.

No que diz respeito à inflação, medida pelo Beta IPCA, a maioria dos ativos mostrou sensibilidade negativa, especialmente a LREN3, o que indica que o aumento da inflação pressiona negativamente seus retornos. A CMIG4 foi a única a apresentar uma relação positiva, possivelmente explicada pelos reajustes regulatórios indexados que beneficiam o setor de energia, oferecendo uma certa proteção contra a inflação. Já em relação à variação da taxa Selic, a VAMO3 se destacou com a maior sensibilidade positiva, um resultado incomum que pode refletir expectativas de crescimento associadas a mudanças na política monetária.

Por fim, analisando a exposição ao preço do petróleo WTI, observamos que a BRFS3 apresentou a relação positiva mais forte, com sensibilidade de 0,1803, o que sugere que aumentos no preço da commodity estão associados a melhores retornos para a empresa, algo comum para exportadoras que se beneficiam de cenários de crescimento econômico global ou de choques de commodities. Em contraste, CSNA3, LREN3 e CMIG4 mostraram exposição negativa ao WTI, já que a elevação do petróleo atua como um fator de custo, impactando energia, logística e transporte e pressionando margens. Entre elas, a CSNA3 apresentou a maior vulnerabilidade, com -0,1415, o que é esperado para uma indústria pesada fortemente dependente de insumos energéticos.

Matriz de Betas e R-Quadrado (Modelo APT)
Sensibilidade a Fatores Macroeconômicos
Ajuste do Modelo
Ativos Beta (Mercado) Beta (Selic) Beta (Var. Selic) Beta (IPCA) Beta (IBC) Beta (Câmbio) Beta (Reservas) Beta (VIX) Beta (WTI)
CMIG4 0,2258 -0,0042 -0,0003 0,0118 0,1439 -0,2245 0,7143 -0,0219 -0,0600 0,2921
VAMO3 1,4033 -0,0084 0,0215 -0,0136 0,2234 -0,2553 NA 0,0467 NA 0,3927
BRFS3 2,6850 -0,0008 -0,0160 -0,0177 0,2538 2,2336 -0,5937 -0,0291 0,1803 0,5002
CSNA3 1,4008 -0,0018 -0,0266 -0,0079 -0,0208 -0,7376 0,3255 -0,0594 -0,1415 0,4951
LREN3 2,5085 0,0033 NA -0,0339 0,1608 0,9122 0,1447 0,0362 -0,0635 0,6545

Beta 3 fatores de Fama & French

Seguindo com teste de outras teorias que avançaram e aprimoram o modelo CAPM com o intuito de incluir outras variaveis que pudessem melhorar o ajuste e a estimação do modelo, o Modelo de Três Fatores de Fama-French é uma extensão que busca explicar os retornos das ações por meio de três fatores, risco de mercado, desempenho superior de empresas de pequena capitalização em relação às de grande capitalização e desempenho superior de empresas com alto valor contábil em relação ao valor de mercado quando comparadas às de baixo índice. A lógica do modelo é que, historicamente, companhias de menor porte e com elevado valor contábil, em relação ao valor de mercado, tendem a apresentar resultados superiores de forma consistente em comparação ao mercado como um todo.

O modelo de Três Fatores é dado pela Equação da Linha Característica de Três Fatores:

\[ R_{p} - R_{f} = \alpha + \beta_M (R_{m} - R_{f}) + \beta_{SMB} (SMB) + \beta_{HML} (HML) + \epsilon \]

Metodologia

Para estimar os betas, a primeira etapa foi selecionar um novo ativo que completasse exatamente 60 meses de histórico, substituindo a VAMO3, que não permite a análise em todos os períodos desejados por ter iniciado sua negociação posteriormente. Para isso, foi escolhida a MILS3, por atuar no mesmo setor. Os demais ativos foram mantidos a fim de possibilitar comparações com os outros modelos e contribuir para a definição final. Em seguida, procedeu-se à coleta dos dados.

Para o fator SMB, utilizamos carteiras teóricas já existentes elaboradas pela B3, tomando como referência o retorno do índice SMLL11, que representa empresas de menor capitalização de mercado (small caps), e do índice MLCX, que contempla empresas de médio e grande porte (mid e large caps). Reconhecemos que essa metodologia não é a ideal, mas foi adotada em função das limitações na disponibilidade de dados.

Já para o fator HML, inicialmente obtivemos o Valor Patrimonial por Ação (VPA) das empresas a partir das informações disponibilizadas pela CVM. Em seguida, calculamos o indicador P/VPA, que corresponde à relação inversa do índice book-to-market (B/M). Dessa forma, as empresas com maior valor contábil relativo são aquelas que apresentam menores valores de P/VPA. A partir desse critério, realizamos a separação das empresas em grupos e efetuamos o rebalanceamento anual, de acordo com os níveis de P/VPA, classificando-as entre aquelas com maior e menor valor contábil.

Código
#MODELO DE 3 FATORES

#SMB
# ------------------------------------------------------------------------------
dados <- read.csv("dados.csv", sep = ",")
dados
# Seleciona apenas a coluna 'Último'
mlcx <- dados[, c("Data","Último")]
mlcx <- mlcx[-(1:3), ]
mlcx <- mlcx[-nrow(mlcx), ]
names(mlcx)= c('Data', 'MLCX')

dados2 <- read.csv("dados2.csv", sep = ",")
dados2
# Seleciona apenas a coluna 'Último'
smll <- dados2[, c("Data","Último")]
names(smll)= c('Data', 'SMLL')
smll

smb=data.frame(na.omit(smll),na.omit(mlcx))
smb <- smb[, -3]
rownames(smb) <- smb$Data
smb <- smb[, -1]
rownames(smb) <- as.Date(rownames(smb), format = "%d.%m.%Y")
smb <- smb[order(rownames(smb)), ]
smb

# Corrige a coluna 'SMLL'
smb$SMLL <- as.numeric(gsub(",", ".", gsub("\\.", "", smb$SMLL)))

# Corrige a coluna 'MLCX'
smb$MLCX <- as.numeric(gsub(",", ".", gsub("\\.", "", smb$MLCX)))
smb

rmlcx <- diff(log(smb$MLCX))
rsmll <- diff(log(smb$SMLL))
rmlcx
rsmll
smb <- (rsmll-rmlcx)
smb
{
# HML
# ---------------------------------------------------------------------------------------
# 2020
datafim2020 <- ymd("2021-01-28")
dataini2020 <- datafim2020 - months(7)

# Alto valor contábil
ativos_alto2020 <- c("PCAR3.SA","AURA33.SA","CPLE6.SA","IGTI3.SA","KEPL3.SA","CSMG3.SA","EMBR3.SA", "CMIG4.SA","PRIO3.SA","SLCE3.SA","ENEV3.SA","ELET3.SA","PETR4.SA","CSAN3.SA","GOAU4.SA","GGBR4.SA","LOGG3.SA","CEAB3.SA","PSSA3.SA","POMO4.SA","VULC3.SA","AMBP3.SA","ITSA4.SA","USIM5.SA","AGRO3.SA","NEOE3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto2020) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2020, 
                                to = datafim2020,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto2020
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor

# Baixo valor contábil
ativos_baixo2020 <- c("VBBR3.SA","LIGT3.SA","SUZB3.SA","YDUQ3.SA","ABEV3.SA","FLRY3.SA",
                      "VIVA3.SA","ALUP11.SA","BRKM5.SA","LREN3.SA","EGIE3.SA","ODPV3.SA","QUAL3.SA","AZZA3.SA","RENT3.SA","AMAR3.SA",
                      "WEGE3.SA","BBSE3.SA","LWSA3.SA","LJQQ3.SA","ENGI11.SA","KLBN11.SA","MRFG3.SA","MGLU3.SA",
                      "MDNE3.SA","IRBR3.SA"
)

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo2020) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2020, 
                                to = datafim2020,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo2020
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2020 <- (rhigh-rlow)
rhigh
rlow
hml2020
length(RIbov)

#----------------------------------------------------------------------------

#2021

datafim2021 <- ymd("2022-01-28")
dataini2021 <- datafim2021 - months(13)

# Alto valor contábil
ativos_alto2021 <- c("PCAR3.SA","KEPL3.SA","IGTI3.SA","AMBP3.SA","SHUL4.SA","EMBR3.SA","CMIG4.SA","ELET3.SA","PRIO3.SA","ENEV3.SA","CSAN3.SA","POMO4.SA","SLCE3.SA","PSSA3.SA","AURA33.SA","PETR4.SA","CSMG3.SA","CPLE6.SA","GOAU4.SA","NEOE3.SA","GGBR4.SA","LOGG3.SA","ITSA4.SA","JHSF3.SA","ALOS3.SA","MILS3.SA","ZAMP3.SA","AGRO3.SA","JSLG3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto2021) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2021, 
                                to = datafim2021,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto2021
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor


# Baixo valor contábil
ativos_baixo2021 <- c("SMTO3.SA",
                      "ABEV3.SA","YDUQ3.SA","MRFG3.SA","CSNA3.SA","LOGN3.SA","FLRY3.SA","EGIE3.SA",
                      "LREN3.SA","AZZA3.SA","ALUP11.SA","VIVA3.SA","BEEF3.SA","ODPV3.SA","QUAL3.SA",
                      "LJQQ3.SA","GMAT3.SA","WEGE3.SA","RENT3.SA","BBSE3.SA","AMAR3.SA","RADL3.SA",
                      "RDOR3.SA","SUZB3.SA","ENGI11.SA","LWSA3.SA","KLBN11.SA","TASA4.SA","IRBR3.SA",
                      "CVCB3.SA","ECOR3.SA","MGLU3.SA"
)

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo2021) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2021, 
                                to = datafim2021,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo2021
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2021 <- (rhigh-rlow)
hml2021
#-------------------------------------------------------------------------------

#2022

datafim2022 <- ymd("2023-01-28")
dataini2022 <- datafim2022 - months(13)

# Alto valor contábil
ativos_alto2022 <- c("PCAR3.SA","KEPL3.SA","AMBP3.SA","CMIG4.SA","CEAB3.SA","CSMG3.SA","ELET3.SA","AURA33.SA","ALOS3.SA","NEOE3.SA","LOGG3.SA","SHUL4.SA","POMO4.SA","AGRO3.SA","GOAU4.SA","GGBR4.SA","JHSF3.SA","USIM5.SA","PETR4.SA","CPLE6.SA","EMBR3.SA","CYRE3.SA","ITSA4.SA","EZTC3.SA","JSLG3.SA","ZAMP3.SA","MDIA3.SA","CAML3.SA","MRVE3.SA","MILS3.SA","SLCE3.SA","PSSA3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto2022) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2022, 
                                to = datafim2022,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto2022
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor


# Baixo valor contábil
ativos_baixo2022 <- c("ABEV3.SA","PRIO3.SA","TASA4.SA","FLRY3.SA","SMTO3.SA","LJQQ3.SA","MRFG3.SA","ALUP11.SA","B3SA3.SA","EGIE3.SA","VAMO3.SA","QUAL3.SA","VIVA3.SA","GMAT3.SA","AMAR3.SA","ODPV3.SA","AZZA3.SA","SUZB3.SA","LOGN3.SA","INTB3.SA","RENT3.SA","BBSE3.SA","RDOR3.SA","BRKM5.SA","RAIZ4.SA","BEEF3.SA","RADL3.SA","CVCB3.SA","ENGI11.SA","IGTI11.SA","WEGE3.SA","KLBN11.SA","IRBR3.SA","MGLU3.SA","AZUL4.SA"
)

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo2022) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2022, 
                                to = datafim2022,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo2022
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2022 <- (rhigh-rlow)

#-------------------------------------------------------------------------------

#2023

datafim2023 <- ymd("2024-01-28")
dataini2023 <- datafim2023 - months(13)

# Alto valor contábil
ativos_alto <- c("MRFG3.SA","PCAR3.SA","CEAB3.SA","MRVE3.SA","AMBP3.SA","LOGG3.SA","USIM5.SA","AURA33.SA","LIGT3.SA","JHSF3.SA","KEPL3.SA","NEOE3.SA","TEND3.SA","POMO4.SA","ELET3.SA","EZTC3.SA","BRFS3.SA","CSMG3.SA","CMIG4.SA","CYRE3.SA","ALOS3.SA","PETR4.SA","YDUQ3.SA","EMBR3.SA","JSLG3.SA","DXCO3.SA","ITSA4.SA","GGBR4.SA","MOVI3.SA","GOAU4.SA","CAML3.SA","ZAMP3.SA","CPLE6.SA","SLCE3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2023, 
                                to = datafim2023,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor


# Baixo valor contábil
ativos_baixo2023 <- c("RAIL3.SA","SIMH3.SA","VALE3.SA","CMIN3.SA","RENT3.SA","RAIZ4.SA","ABEV3.SA","HYPE3.SA","STBP3.SA","RDOR3.SA","VIVA3.SA","VAMO3.SA","AZZA3.SA","EGIE3.SA","CVCB3.SA","PRIO3.SA","B3SA3.SA","ALUP11.SA","GMAT3.SA","LOGN3.SA","INTB3.SA","AMAR3.SA","ODPV3.SA","IGTI11.SA","ENGI11.SA","BEEF3.SA","RADL3.SA","BRKM5.SA","KLBN11.SA","BBSE3.SA","WEGE3.SA","IRBR3.SA","MGLU3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo2023) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2023, 
                                to = datafim2023,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo2023
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2023 <- (rhigh-rlow)

#-------------------------------------------------------------------------------

#2024

datafim2024 <- ymd("2025-01-28")
dataini2024 <- datafim2024 - months(13)

# Alto valor contábil
ativos_alto <- c("PCAR3.SA","MRVE3.SA","QUAL3.SA","AURA33.SA","MRFG3.SA","LOGG3.SA","USIM5.SA","JHSF3.SA","GOAU4.SA","GGBR4.SA","CMIG4.SA","EZTC3.SA","CEAB3.SA","LIGT3.SA","ELET3.SA","IRBR3.SA","NEOE3.SA","ALOS3.SA","DXCO3.SA","ZAMP3.SA","CSMG3.SA","AGRO3.SA","LWSA3.SA","ITSA4.SA","CYRE3.SA","BRFS3.SA","EMBR3.SA","CPLE6.SA","PETR4.SA","SIMH3.SA","MOVI3.SA","PSSA3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2024, 
                                to = datafim2024,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor


# Baixo valor contábil
ativos_baixo <- c("RENT3.SA","ECOR3.SA","MULT3.SA","AZZA3.SA","ABEV3.SA","INTB3.SA","RAIL3.SA","RDOR3.SA","PRIO3.SA","SMFT3.SA","RAIZ4.SA","CSAN3.SA","CMIN3.SA","CXSE3.SA","EGIE3.SA","STBP3.SA","B3SA3.SA","ALUP11.SA","VIVA3.SA","LOGN3.SA","ODPV3.SA","BRKM5.SA","BEEF3.SA","BBSE3.SA","IGTI11.SA","RADL3.SA","WEGE3.SA","KLBN11.SA","ENGI11.SA","MGLU3.SA","MNDL3.SA","AMAR3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2024, 
                                to = datafim2024,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2024 <- (rhigh-rlow)


#-----------------------------------------------------------------------------

#2025

datafim2025 <- ymd("2025-06-28")
dataini2025 <- datafim2025 - months(6)

# Alto valor contábil
ativos_alto <- c("USIM5.SA","CSAN3.SA","LIGT3.SA","MRVE3.SA","PCAR3.SA","JHSF3.SA","CSNA3.SA","MGLU3.SA","AMBP3.SA","LOGG3.SA",
                     "GOAU4.SA","ZAMP3.SA","AZZA3.SA","EZTC3.SA","GGBR4.SA","ELET3.SA","DXCO3.SA","NEOE3.SA","LWSA3.SA","TASA4.SA",
                     "MOVI3.SA","ALOS3.SA","LOGN3.SA","LJQQ3.SA","CYRE3.SA","IRBR3.SA","VBBR3.SA","CEAB3.SA","JSLG3.SA","YDUQ3.SA",
                     "HYPE3.SA","ECOR3.SA","QUAL3.SA"
                     )

# Lista para armazenar apenas os fechamentos
cotacoes_alto <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_alto) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2025, 
                                to = datafim2025,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_alto[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_alto)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_alto
cotacoes_alto <- cotacoes_combinadas; cotacoes_alto
# Mantém colunas onde a soma dos NA é zero
cotacoes_alto <- cotacoes_alto[, colSums(is.na(cotacoes_alto)) == 0]
cotacoes_alto

rcotacoes_alto <-lapply(cotacoes_alto, function(x) diff(log(x))) 
rcotacoes_alto <- do.call(cbind, rcotacoes_alto);rcotacoes_alto

# Média de cada linha (retorno médio da carteira)
alto_valor <- rowMeans(rcotacoes_alto, na.rm = TRUE)
alto_valor


# Baixo valor contábil
ativos_baixo <- c("CVCB3.SA","VIVA3.SA","VULC3.SA","RAIZ4.SA","SMFT3.SA","EMBR3.SA","POMO4.SA",
                      "VAMO3.SA","RAIL3.SA","MULT3.SA","KEPL3.SA","RDOR3.SA","EGIE3.SA","SUZB3.SA","BRFS3.SA","CMIN3.SA","CXSE3.SA",
                      "B3SA3.SA","ALUP11.SA","ODPV3.SA","ENGI11.SA","IGTI11.SA","RADL3.SA","BBSE3.SA","WEGE3.SA","ENEV3.SA","STBP3.SA",
                      "KLBN11.SA","BEEF3.SA")

# Lista para armazenar apenas os fechamentos
cotacoes_baixo <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos_baixo) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini2025, 
                                to = datafim2025,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_baixo[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_baixo)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos_baixo
cotacoes_baixo <- cotacoes_combinadas; cotacoes_baixo
# Mantém colunas onde a soma dos NA é zero
cotacoes_baixo <- cotacoes_baixo[, colSums(is.na(cotacoes_baixo)) == 0]
cotacoes_baixo

rcotacoes_baixo <-lapply(cotacoes_baixo, function(x) diff(log(x))) 
rcotacoes_baixo <- do.call(cbind, rcotacoes_baixo);rcotacoes_baixo

# Média de cada linha (retorno médio da carteira)
baixo_valor <- rowMeans(rcotacoes_baixo, na.rm = TRUE)
baixo_valor

hml=data.frame(na.omit(alto_valor),na.omit(baixo_valor))
names(hml)=c("HIGH", "LOW")
length(hml$HIGH)

rhigh <- hml$HIGH
rlow <- hml$LOW

hml2025 <- (rhigh-rlow)
}

hml <- list(as.vector(hml2020), as.vector(hml2021), as.vector(hml2022), as.vector(hml2023), as.vector(hml2024), as.vector(hml2025))
hml <- do.call(c, hml)
hml
Código
# --------------------------------------------------------------------------------------
# Lista de ativos
ativos <- c("CMIG4.SA", "MILS3.SA", "BRFS3.SA", "CSNA3.SA", "LREN3.SA","^BVSP")

# Lista para armazenar apenas os fechamentos
cotacoes_fechamento <- list()

# Baixa as cotações e extrai apenas o fechamento
for (ativo in ativos) {
  # Baixa os dados usando getSymbols()
  dados_completos <- getSymbols(ativo, 
                                src = "yahoo", 
                                from = dataini, 
                                to = datafim,
                                periodicity = "monthly",
                                auto.assign = FALSE)
  
  # Extrai a coluna de fechamento e armazena na lista
  if (!is.null(dados_completos)) {
    cotacoes_fechamento[[ativo]] <- Cl(dados_completos)
  }
}

# Combina todos os objetos da lista em um único data.frame
cotacoes_combinadas <- do.call(merge, cotacoes_fechamento)

# Limpe os nomes das colunas 
names(cotacoes_combinadas) <- ativos
cotacoes <- cotacoes_combinadas;

colnames(cotacoes)[colnames(cotacoes) == "CMIG4.SA"] <- "CMIG4"
colnames(cotacoes)[colnames(cotacoes) == "MILS3.SA"] <- "MILS3"
colnames(cotacoes)[colnames(cotacoes) == "BRFS3.SA"] <- "BRFS3"
colnames(cotacoes)[colnames(cotacoes) == "CSNA3.SA"] <- "CSNA3"
colnames(cotacoes)[colnames(cotacoes) == "LREN3.SA"] <- "LREN3" # CMIG4.SA agora é LREN3
colnames(cotacoes)[colnames(cotacoes) == "^BVSP"] <- "IBOV"

# Remova todas as linhas que contenham NA
cotacoes <- na.omit(cotacoes)

# Selecionando cada coluna por nome e atribuindo a uma variável
cmig4 <- cotacoes$CMIG4
mils3 <- cotacoes$MILS3 
brfs3 <- cotacoes$BRFS3 
csna3 <- cotacoes$CSNA3  
lren3 <- cotacoes$LREN3 
ibov <- cotacoes$IBOV

rcmig4 <- diff(log(cmig4))
rmils3 <- diff(log(mils3))
rbrfs3 <- diff(log(brfs3))
rcsna3 <- diff(log(csna3))
rlren3 <- diff(log(lren3))
ribov  <- diff(log(ibov))

Ativos = na.omit(merge(cmig4, mils3, brfs3, csna3, lren3, ibov, Selic))
length(na.omit(Ativos[,1]))
Data1 = index(na.omit(Ativos)); length(Data1)
Ativos


RIbov = ribov; RIbov
RSelic = Ativos$Selic[-1]; length(Ativos$Selic[-1])
RSelic

RIbov = (ribov - RSelic); length(RIbov); RIbov

Rcmig4 = rcmig4 - RSelic   # Novo CMIG4
Rmils3 = rmils3 - RSelic
Rbrfs3 = rbrfs3 - RSelic
Rcsna3 = rcsna3 - RSelic
Rlren3 = rlren3 - RSelic

# Tabela FM com o primeiro ativo
FM = data.frame(Rcmig4, hml, smb)

# Regressões
BetaFMcmig4 = lm(Rcmig4 ~ RIbov + FM$hml + FM$smb)
coef(BetaFMcmig4)
summary(BetaFMcmig4)

BetaFMmils3 = lm(Rmils3 ~ RIbov + FM$hml + FM$smb)
coef(BetaFMmils3)
summary(BetaFMmils3)

BetaFMbrfs3 = lm(Rbrfs3 ~ RIbov + FM$hml + FM$smb)
coef(BetaFMbrfs3)
summary(BetaFMbrfs3)

BetaFMcsna3 = lm(Rcsna3 ~ RIbov + FM$hml + FM$smb)
coef(BetaFMcsna3)
summary(BetaFMcsna3)

BetaFMlren3 = lm(Rlren3 ~ RIbov + FM$hml + FM$smb)
coef(BetaFMlren3)
summary(BetaFMlren3)
Tabela de Regressão do Modelo Fama & French (Três Fatores)
Alpha
Exposição a Fatores
Ajuste do Modelo
Ativos Interceptor Beta (Mercado) Beta (SMB) Beta (HML)
CMIG4 0,0047 0,7609 0,0217 -0,0334 0,3080
MILS3 0,0054 1,1446 1,4891 0,4358 0,5103
BRFS3 0,0089 1,4599 0,7969 -0,3640 0,3545
CSNA3 -0,0059 1,6410 -0,4471 -0,5449 0,3154
LREN3 -0,0090 1,4474 1,1557 0,2837 0,5885

Resultados

Avaliando o resultado da tabela, notamos que o modelo oferece ajustes R² melhores para alguns ativos em comparação com estudos anteriores, embora os valores ainda estejam abaixo do que seria ideal para capturar a totalidade da variação de risco.

Entre os ativos com os melhores ajustes, destacamos mais uma vez a LREN3 (R2 de 0,5885) e a MILS3 (R2 de 0,5103). A alta qualidade do ajuste para ambas as empresas está diretamente ligada à sua forte e positiva exposição ao fator SMB (Small Minus Big), com Betas de 1,1557 e 1,4891, respectivamente. Essa alta sensibilidade ao risco de tamanho de mercado (SMB) indica que a volatilidade dessas ações é amplamente explicada pela dinâmica entre empresas de baixa e alta capitalização. Além de se destacarem pelo ajuste, LREN3 e MILS3 compartilham características semelhantes de risco, ambas apontando Betas SMB e HML para a mesma direção (positiva) e com Beta SMB de significativa magnitude e valor elevado, sendo este o principal motor de seu alto R².

O desempenho inferior do modelo em outras ações, contudo, reforça a necessidade de variáveis adicionais. CMIG4, por exemplo, registrou Betas SMB (0,0217) e HML (-0,0334) próximos de zero e um R2 baixo (0,3080), o que sugere que o Modelo de Três Fatores não é a ferramenta mais eficaz para capturar sua variação de risco. Da mesma forma, BRFS3 e CSNA3 também apontaram sensibilidades menores e, consequentemente, menores R2 (0,3545 e 0,3154, respectivamente). Essa disparidade de resultados aponta para a ideia de que ainda faltam fatores para explicar as sensibilidades não capturadas, sugerindo a evolução natural para modelos multifatoriais mais complexos, como os modelos de cinco fatores (que adicionam risco de prazo e inadimplência) ou até mesmo além, para modelar o universo completo dos retornos.

Conclusões sobre o modelo

Os resultados e as conclusões observados em nosso estudo não foram satisfatórios como esperado, o que atribuímos, além, da falta de mais fatores, a duas fontes principais: limitações na obtenção de dados e uma abordagem metodológica diferente da empregada por Fama e French em seu artigo seminal de 1993.

A metodologia de Fama e French é notavelmente rigorosa ao tentar isolar fatores de risco. Para testar seu modelo, os autores usam 25 portfólios de ações como variáveis dependentes, formados a partir das interseções de 5 quintis de tamanho de mercado e 5 quintis de índice B/M.

Isso contribui para a principal diferença metodológica reside na construção dos fatores de risco. O rigor de Fama e French está em isolar cada prêmio de risco, minimizando a contaminação mútua:

  • Fator SMB (Small Minus Big): É calculado pela diferença entre a média dos retornos de portfólios de empresas pequenas e a média dos retornos de portfólios de empresas grandes. Crucialmente, esse cálculo é feito de forma que os portfólios tenham o mesmo índice B/M médio ponderado. Isso garante que o SMB represente o risco de tamanho puro, neutralizando a influência do risco de valor.

  • Fator HML (High Minus Low): De forma análoga, é a diferença entre os retornos médios de portfólios de alto B/M (valor) e baixo B/M (crescimento). Essa construção isola o risco de valor ao ser realizada com portfólios que possuem o mesmo tamanho médio ponderado, minimizando o efeito do risco de tamanho.

Nossa abordagem mais simples diverge significativamente e provavelmente contribuiu para as deficiências nos resultados.

Simplificação Fatorial: Enquanto Fama e French utilizam múltiplos portfólios (seis, em sua construção primária) para neutralizar o ruído, simplificamos a geração de fatores. Para o fator HML, separamos apenas duas carteiras (alto valor e baixo valor), o que dificulta a remoção do viés de tamanho. Para o fator SMB, utilizamos uma carteira definida pela B3 (através dos índices SMLL11 e MLCX11), o que pode não refletir a exposição pura ao risco de tamanho que a metodologia de Fama e French busca capturar.

Teste de Precisão (O Intercepto): É vital destacar a natureza do teste de precisão de Fama e French. Eles testam seus modelos não com ativos específicos, mas com os retornos dos 32 portfólios elaborados por sua metodologia (os 25 de ações mais 7 de títulos de dívida). A precisão do modelo é avaliada pelo intercepto (a) dessas regressões. Se o modelo estiver correto, o intercepto deve ser indistinguível de zero, indicando que o prêmio de risco médio é totalmente explicado pelos fatores.

Em suma, a falta de resultados satisfatórios em nosso estudo parece estar ligada à nossa abordagem simplificada na construção dos fatores e às limitações nos dados, impedindo-nos de replicar a robustez dos portfólios miméticos de investimento zero que permitem a Fama e French isolar os riscos de SMB e HML.

Classificação Final

Ranking:

  1. CMIG4

  2. LREN3

  3. BRFS3

  4. VAMO3

  5. CSNA3

Portanto, a leitura do relatório apresenta evidências claras do ranking ideal para as empresas analisadas. Ressalta-se que a análise foi conduzida sob a ótica de um investidor avesso ao risco e conservador. Nesse contexto, a Cemig (CMIG4) confirmou sua permanência em primeiro lugar, destacando-se por apresentar menor volatilidade, retorno médio positivo e consideravel probabilidade de valorização. Além disso, esteve presente em todas as carteiras propostas pela fronteira eficiente, sobretudo na carteira de mínima variância, a ideal escolhida para esse relatório, o que reforça a aderência ao perfil conservador adotado neste relatório.

Outro ponto relevante é que o beta da CMIG4 foi consistentemente inferior a 1, tanto nas janelas de 60 quanto de 90 dias, bem como na análise com dados mensais. Embora, em teoria, um beta menor que 1 indique que o ativo tende a valorizar menos em momentos de alta do mercado, a CMIG4 apresentou índices de Sharpe e Treynor positivos sobre a optica mensal. Em contraste, os demais ativos não geraram alfa para o investidor, o que consolida ainda mais a superioridade da empresa no período analisado.

O segundo lugar ficou com a LREN3, embora por uma margem estreita, já que a BRFS3 quase assumiu essa posição por apresentar um beta de mercado menor em todos os períodos analisados. Ainda assim, a LREN3 se destacou em outros aspectos, especialmente pelo retorno gerado e pela expressiva presença nas carteiras de Markowitz. O ponto negativo está relacionado ao beta mais elevado, que indica maior volatilidade; contudo, mesmo próxima à BRFS3 nesse quesito, a LREN3 sobressaiu nos demais pontos mencionados.

Na análise com dados mensais, esse desempenho não se repete da mesma forma, o que pode ser explicado pela característica do setor, extremamente sensível a mudanças econômicas, como evidenciado pelos resultados obtidos no modelo APT. Além disso, a LREN3 apresentou melhores ajustes nos modelos, reforçando sua posição de destaque no ranking.

Como já mencionado, a BRFS3 também apresentou bons resultados na mensuração de risco, especialmente nos cálculos de beta. Contudo, quando a análise passa para a base mensal, o cenário muda consideravelmente: a empresa deixa de se enquadrar no grupo de ativos com beta inferior a 1, perdendo a consistência observada em outros períodos. Além disso, os retornos negativos registrados contribuíram para que o ativo ocupasse uma posição mais abaixo no ranking.

Chegamos à única mudança em relação à primeira parcial mencionada: a CSNA3 deixa de ocupar a 4ª colocação, cedendo lugar à VAMO3. Embora ambas tenham apresentado características de risco, a segunda etapa do relatório evidenciou para a VAMO3 um melhor Alfa de Jensen, além de um beta menor na comparação mensal, indicando maior capacidade de gerar retorno ao investidor. Ainda assim, o perfil conservador da análise contribuiu para que a empresa permanecesse em posições mais baixas, já que sua elevada volatilidade e um beta acima de 2 não são características compatíveis com o esperado por um investidor avesso ao risco.

Simulação da carteira

Com base nas análises realizadas ao longo do relatório, foi possível identificar as empresas que mais se destacam para o perfil do investidor-alvo e, a partir disso, chegar a conclusões que orientam a composição ideal da carteira. Optou-se pela carteira de mínima variância, por oferecer o menor nível de risco possível ao investidor, mantendo um retorno médio diário estimado em 0,20%. Essa carteira apresenta uma boa diversificação entre os ativos, com maior concentração naquele que demonstrou, de forma consistente em diferentes critérios, ser o menos arriscado. Para avaliar de forma mais concreta o desempenho dessa estratégia, será realizada uma simulação com valores reais, considerando um investimento inicial de R$ 200.000,00. A alocação seguirá a compra de lotes fechados, distribuídos conforme as proporções definidas pela teoria da fronteira eficiente.

Código
library(dplyr)
library(knitr)
library(kableExtra)
library(scales) # Necessário para a função percent()

# Função para limpar números no formato brasileiro
limpar_num <- function(x) {
  x <- gsub("R\\$", "", x)
  x <- gsub("%", "", x)
  x <- gsub("\\.", "", x)  # Remove ponto de milhar
  x <- gsub(",", ".", x)   # Troca vírgula por ponto decimal
  return(as.numeric(x))
}

# 1. Definição dos vetores de dados
dados_tabela <- data.frame(
  Acao = c("CMIG4", "LREN3", "BRFS3", "CSNA3", "VAMO3", "Totais"),
  Preco_RS = c("10,48", "19,56", "18,00", "7,50", "4,13", NA), 
  Pct_Alvo = c("68,5", "17,5", "11,4", "1,2", "1,5", "100"), 
  Valor_Alvo_RS = c("137.000,00", "35.000,00", "22.800,00", "2.400,00", "3.000,00", "200.200,00"),
  Custo_Lote = c("1.048,00", "1.956,00", "1.800,00", "750,00", "413,00", NA),
  Lotes_Comprados = c("130", "17", "12", "3", "7", "169"),
  Quant_Acoes = c("13.000", "1.700", "1.200", "300", "700", "16.900"),
  Custo_Total_RS = c("136.240,00", "33.252,00", "21.600,00", "2.250,00", "2.891,00", "196.233,00")
)


# 2. Limpeza e Formatação para a Tabela de Exibição
tabela_limpa <- dados_tabela %>%
  # Limpa todas as colunas de valor
  mutate(across(c(Preco_RS, Pct_Alvo, Valor_Alvo_RS, Custo_Lote, 
                  Custo_Total_RS, Lotes_Comprados, Quant_Acoes), limpar_num)) %>%
  
  # Formata colunas numéricas para exibição (R$ e %)
  mutate(
    `Preço (R$)` = paste("R$", format(round(Preco_RS, 2), big.mark = ".", decimal.mark = ",", nsmall = 2)),
    `% Alvo` = scales::percent(Pct_Alvo / 100, accuracy = 0.01, decimal.mark = ","),
    
    # Valores R$ e Lotes/Ações formatados (incluindo as colunas que mantiveram os números puros para formatação)
    `Custo Total (R$)` = paste("R$", format(round(Custo_Total_RS, 2), big.mark = ".", decimal.mark = ",", nsmall = 2)),
    `Lotes Comprados` = format(Lotes_Comprados, big.mark = ".", decimal.mark = ",", trim = TRUE, scientific = FALSE),
    `Quantidade de Ações` = format(Quant_Acoes, big.mark = ".", decimal.mark = ",", trim = TRUE, scientific = FALSE)
  ) %>%
  
  # Seleciona e ordena as colunas finais
  select(
    Acao, 
    `Preço (R$)`, 
    `% Alvo`, 
    # REMOVIDAS: Valor_Alvo_RS e Custo_Lote
    `Lotes Comprados`, 
    `Quantidade de Ações`, 
    `Custo Total (R$)`
  )

# 3. Aplica o Kable e Estiliza
tabela_final <- tabela_limpa %>%
  kable(
    caption = "Tabela Final de Alocação do Portfólio (Base R$ 200.000)",
    align = "c"
  ) %>%
  # Destaca a linha de totais
  row_spec(nrow(tabela_limpa), bold = T, background = "#f0f0f0") %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = TRUE,
    position = "center"
  )

tabela_final
Tabela Final de Alocação do Portfólio (Base R$ 200.000)
Acao Preço (R$) % Alvo Lotes Comprados Quantidade de Ações Custo Total (R$)
CMIG4 R$ 10,48 68,50% 130 13.000 R$ 136.240,00
LREN3 R$ 19,56 17,50% 17 1.700 R$ 33.252,00
BRFS3 R$ 18,00 11,40% 12 1.200 R$ 21.600,00
CSNA3 R$ 7,50 1,20% 3 300 R$ 2.250,00
VAMO3 R$ 4,13 1,50% 7 700 R$ 2.891,00
Totais R$ NA 100,00% 169 16.900 R$ 196.233,00

Proteção com derivativos

O avanço do mercado financeiro possibilitou o surgimento e a negociação de instrumentos que derivam de um ativo subjacente, como ações, índices e commodities. Esses ativos, conhecidos como derivativos, permitem negociar contratos com liquidação em uma data futura, seja por meio do mercado a termo, de futuros, de opções ou de swaps. Tais instrumentos podem ser utilizados com diferentes finalidades, como hedge (proteção), arbitragem ou especulação.

No contexto deste relatório, o objetivo é proteger a carteira apresentada anteriormente, adotando uma postura conservadora para evitar que o investidor sofra grandes desvalorizações em seu portfólio. Assim, a estratégia escolhida será de hedge, utilizando opções como principal ferramenta.

As opções, em essência, são contratos que conferem ao titular (comprador da opção) o direito, mas não a obrigação, de comprar (CALL) ou vender (PUT) um ativo subjacente em uma data futura por um preço previamente estabelecido, denominado preço de exercício ou strike. Já o lançador (vendedor da opção) assume a obrigação de realizar a operação contrária caso o titular decida exercer o contrato. Como toda operação no mercado, esse direito tem um custo, chamado de prêmio da opção.

Esses contratos podem estar “in the money” (ITM), quando há vantagem em exercer a opção, ou “out of the money” (OTM), quando não há benefício econômico em fazê-lo. O break-even point é o ponto em que o lucro da operação começa a superar o custo do prêmio pago.

Por exemplo: suponha que um investidor compre opções de compra (CALLs) de ABCD3, pagando um prêmio de R$0,50 por ação, com strike de R$20,00 e vencimento em 10/07/2025. No dia do vencimento, o preço da ação está em R$21,00. Nesse caso, o investidor pode exercer seu direito de compra a R$20,00, adquirindo o ativo R$1,00 abaixo do preço de mercado. Considerando o prêmio pago, seu lucro líquido será de R$0,50 por ação.

Agora, vejamos um exemplo utilizando uma opção de venda (PUT), que é a ferramenta mais comum para proteção (hedge) de uma carteira.

Suponha que o investidor possua ações da ABCD4 em sua carteira, atualmente cotadas a R$10,00, e queira se proteger contra uma possível desvalorização. Para isso, ele compra opções de venda (PUTs) com preço de exercício (strike) de R$10,00, pagando um prêmio de R$0,30 por ação, com vencimento em 10/07/2025.

Se, na data de vencimento, o preço da ação cair para R$9,00, o investidor poderá exercer seu direito de vender as ações a R$10,00, evitando a perda de R$1,00 por ação que teria se tivesse vendido no mercado à vista. Considerando o prêmio pago (R$0,30), o investidor limita sua perda total a apenas R$0,30 por ação, em vez de R$1,00 ou seja, a opção funcionou como um seguro contra a queda.

Por outro lado, se o preço da ABCD4 permanecer acima de R$10,00, o investidor não exercerá a opção, perdendo apenas o valor do prêmio (R$0,30), que representa o custo da proteção.

Portanto, para proteger a carteira recomendada, será realizada a compra de uma opção de venda (PUT) sobre o ativo de maior peso na composição, a CMIG4. Como esse ativo representa a principal posição do portfólio e foi destacado anteriormente como o de menor risco, é fundamental adotar uma estratégia de hedge que minimize o impacto de eventuais desvalorizações, evitando que quedas expressivas no preço da CMIG4 comprometam o desempenho total da carteira.

A opção escolhida para essa proteção é a GMIGS115, com vencimento em 18/07/2025, preço de exercício (strike) de R$10,50 e prêmio de R$0,17. O valor teórico calculado pelo modelo de Black & Scholes para essa opção é de R$0,20, considerando a volatilidade estimada neste relatório, bem como a taxa de juros livre de risco e o preço à vista (spot) da ação em 27/06/2025. Isso indica que a opção foi adquirida a um preço abaixo do valor teórico, representando uma oportunidade de compra vantajosa.

Dessa forma, considerando o preço de aquisição do ativo em R$10,48 e o custo do prêmio de R$0,17, o prejuízo máximo potencial fica limitado a aproximadamente -1,45%, garantindo que o investidor esteja protegido contra quedas mais acentuadas no preço da CMIG4. Essa estratégia torna o portfólio ainda mais adequado ao perfil conservador e avesso ao risco, que norteia toda a construção e análise desta carteira.

O payoff dessa operação de hedge considera que o investidor está comprado em CMIG4 e, simultaneamente, comprado em uma opção de venda (PUT) sobre o mesmo ativo. Essa estrutura, conhecida como protective put, tem o objetivo de limitar as perdas em caso de queda no preço da ação, sem restringir o potencial de ganho caso o ativo se valorize.

Ao adquirir a PUT com strike de R$10,50 e prêmio de R$0,17, o investidor garante o direito de vender suas ações de CMIG4 por R$10,50, mesmo que o preço de mercado caia abaixo disso. Assim, caso a ação — atualmente cotada a R$10,48 — desvalorize, a perda na posição comprada é compensada pela valorização da opção.

Por exemplo, se no vencimento a CMIG4 estiver valendo R$9,80, o investidor exercerá sua PUT, vendendo as ações a R$10,50. O ganho com a opção será de R$0,70 por ação, que compensará quase integralmente a perda de R$0,68 na ação (10,48 - 9,80). Considerando o prêmio pago de R$0,17, o prejuízo líquido total será de apenas R$0,15 por ação, o que representa uma perda máxima limitada a aproximadamente -1,43%.

Em contrapartida, se o preço da ação subir acima de R$10,50, a PUT expira sem valor, e o investidor perde apenas o prêmio pago (R$0,17). No entanto, o ganho proveniente da valorização da ação supera facilmente o custo do hedge, mantendo o potencial de lucro aberto.

Dessa forma, o payoff final da operação assume o formato típico de uma curva de proteção: as perdas são limitadas a partir do strike, enquanto os ganhos permanecem ilimitados à medida que o preço do ativo sobe. Essa estrutura garante estabilidade e previsibilidade ao portfólio, perfeitamente alinhada ao perfil conservador e avesso ao risco que orienta este relatório.

Código
# Parâmetros (mantidos)
S0      <- 10.48    # preço de compra da ação (R$)
strike <- 10.50    # strike da PUT (R$)
premium<- 0.17     # prêmio pago pela PUT (R$)
qnt    <- 13000    # QUANTIDADE TOTAL DE AÇÕES/CONTRATOS
COR_PRINCIPAL <- "#003087"

# Grid de preços no vencimento (Amplo para cálculo)
ST <- seq(0, 25, by = 0.1) 

# Payoffs e Data frame para ggplot
payoff_stock     <- (ST - S0) * qnt
payoff_put       <- (pmax(strike - ST, 0) - premium) * qnt
payoff_combined  <- payoff_stock + payoff_put
df <- data.frame(
  ST = ST,
  Stock = payoff_stock,
  Put = payoff_put,
  Combined = payoff_combined
)

# Carregamento de pacotes
if (!requireNamespace("ggplot2", quietly = TRUE)) install.packages("ggplot2")
library(ggplot2)
if (!requireNamespace("scales", quietly = TRUE)) install.packages("scales")
library(scales)

# Calcula o Ponto de Breakeven e Perda Máxima Total
breakeven <- S0 + premium
perda_maxima_total <- ((strike - S0) - premium) * qnt 

# Plota o gráfico
p_final_total <- ggplot(df, aes(x = ST)) +
  
  # 2. Linha de Zero (Ponto de Equilíbrio)
  geom_hline(yintercept = 0, color = "black", linetype = "solid", alpha = 0.7) +
  
  # 3. Linha da Estratégia Combinada (Protective Put)
  geom_line(aes(y = Combined, color = "Estratégia (Protective Put)"), 
            size = 1.8, show.legend = TRUE) + # Linha mais grossa para destaque
  
  # 4. Linhas de Componentes (Adicionadas para contexto)
  geom_line(aes(y = Stock, color = "Ação (Long)"), size = 1, linetype = "dashed", alpha = 0.7) +
  geom_line(aes(y = Put, color = "Opção de Venda (Put)"), size = 1, linetype = "dotted", alpha = 0.7) + # Mais visível
  
  # 5. Linhas de Referência Chave
  geom_vline(xintercept = strike, color = COR_PRINCIPAL, linetype = "dotted") +
  geom_vline(xintercept = breakeven, color = "darkgreen", linetype = "dashed") +
  

  # Rótulos de Anotação (Posicionamento ajustado)
  annotate("text", x = strike - 0.2, y = perda_maxima_total + (max(df$Combined)/15), # Posição mais acima da linha
           label = paste0("Strike (R$", format(strike, nsmall=2), ")"), 
           color = COR_PRINCIPAL, hjust = 1, size = 4) + # Ajuste hjust para alinhar à direita
  
  annotate("text", x = breakeven + 0.2, y = 0 + (max(df$Combined)/15), # Posição mais acima da linha de Breakeven
           label = paste0("Breakeven (R$", format(breakeven, nsmall=2), ")"), 
           color = "darkgreen", hjust = 0, size = 4) +
  
  # *** AJUSTE DE ESCALA OTIMIZADO ***
  coord_cartesian(xlim = c(8, 18), # Foco mais estreito nos preços relevantes
                  ylim = c(perda_maxima_total - 1000, max(df$Combined[df$ST <= 18]) + 5000)) + # Y_lim dinâmico e mais espaçoso
  
  # 7. Estilo e Cores Finais
  scale_color_manual(values = c("Protective Put" = COR_PRINCIPAL, 
                                "Ação (Long)" = "#7570b3",
                                "Put" = "#d95f02")) +
  scale_y_continuous(labels = scales::dollar_format(prefix = "R$")) + 
  scale_x_continuous(breaks = seq(8, 18, by = 2)) + # Quebras mais espaçadas no eixo X
  
  labs(
    title = paste("Payoff Total para", format(qnt, big.mark = "."), "Ações"),
    subtitle = paste0("Parâmetros: Ação a R$ ", format(S0, nsmall=2), 
                      " | PUT Strike R$ ", format(strike, nsmall=2), 
                      " | Prêmio Pago: R$ ", format(premium * qnt, big.mark = ".", decimal.mark = ",", nsmall = 2)),
    x = "Preço da Ação no Vencimento (R$)",
    y = paste0("Payoff / Lucro e Prejuízo Líquido TOTAL (R$) \n (Perda Máxima: ", scales::dollar(perda_maxima_total, prefix = "R$"), ")"), # Informa perda máxima no eixo
    color = "Legenda" 
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "bottom",
    plot.title = element_text(face = "bold", color = COR_PRINCIPAL, size = 16),
    plot.subtitle = element_text(color = "grey30", size = 11),
    axis.title.y = element_text(size = 12, margin = margin(r = 10)), # Ajusta espaçamento do título do eixo Y
    axis.title.x = element_text(size = 12, margin = margin(t = 10))
  )

print(p_final_total)

Referências Bibliográficas