O modelo do presente post refere-se a um trabalho desenvolvido durante a disciplica de Laboratório em Economia ministrado pelo prof. Dr. Matheus Wemerson.

1 O modelo CAPM teórico

O Modelo de Precificação de Ativos Financeiros (CAPM – Capital Asset Pricing Model) é uma teoria fundamental em finanças que descreve a relação entre o retorno esperado de um ativo de risco e o seu risco sistêmico. Ele oferece uma estrutura para determinar a taxa de retorno exigida adequada para um ativo, considerando o seu risco, a fim de auxiliar nas decisões de inclusão de ativos em um portfólio bem diversificado.

A equação do modelo CAPM é dada por:

\[ E(R_i) = R_f + \beta_i \left[ E(R_m) - R_f \right] \] Explicação dos termos:

2 Aplicação do modelo CAPM tradicional para a empresa B3

2.1 Carregando os pacotes necessários

library(tidyverse)
## Warning: pacote 'tidyr' foi compilado no R versão 4.4.3
## Warning: pacote 'readr' foi compilado no R versão 4.4.2
## Warning: pacote 'purrr' foi compilado no R versão 4.4.3
## Warning: pacote 'dplyr' foi compilado no R versão 4.4.3
## Warning: pacote 'lubridate' foi compilado no R versão 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyquant)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo 
## ── Attaching core tidyquant packages ──────────────────────── tidyquant 1.0.9 ──
## ✔ PerformanceAnalytics 2.0.4      ✔ TTR                  0.24.4
## ✔ quantmod             0.4.26     ✔ xts                  0.14.1── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## ✖ zoo::as.Date()                 masks base::as.Date()
## ✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
## ✖ dplyr::filter()                masks stats::filter()
## ✖ xts::first()                   masks dplyr::first()
## ✖ dplyr::lag()                   masks stats::lag()
## ✖ xts::last()                    masks dplyr::last()
## ✖ PerformanceAnalytics::legend() masks graphics::legend()
## ✖ quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(timetk)
## 
## Anexando pacote: 'timetk'
## 
## O seguinte objeto é mascarado por 'package:tidyquant':
## 
##     FANG
library(broom)

2.2 Puxando e organizando os dados

Inicialmente, foi extraído por meio do código getSymbols() a série temporal da cotação da empresa B3, cujo ticker é B3SA3.SA. Este código extrai os dados do Yahoo finance.

# Define os ativos que irão ser coletados ------
Acao <- c("B3SA3.SA")

# Define a data de início da coleta
start <- as.Date("2011-06-01")

# Realiza a coleta dos preços diários
price <- getSymbols(Acao,
                     auto.assign = TRUE,
                     warnings = FALSE,
                     from = start,
                     src = "yahoo") %>%
  map(~Ad(get(.))) %>%
  reduce(merge) %>%
  `colnames<-`(Acao)
plot(price)

O modelo CAPM, por lidar com a regressão entre séries temporais, exige que as séries sejam estacinárias. Para tal, será aplicada o método log nos preços mensais da contação da empresa. Este método também entrega uma proxy da rentabilidade mensal do ativo. Assim, é mantida a intuiçã econômica e fundamento estatístico para que o modelo seja rodado com sucesso.

# Transfroma os preços diários em mensais
price_monthly <- to.monthly(price,
                             indexAt = "lastof",
                             OHLC = FALSE)

print(price_monthly)
##             B3SA3.SA
## 2011-06-30  2.125391
## 2011-07-31  1.859973
## 2011-08-31  1.946725
## 2011-09-30  1.834053
## 2011-10-31  2.184589
## 2011-11-30  2.085068
## 2011-12-31  2.068185
## 2012-01-31  2.319323
## 2012-02-29  2.424842
## 2012-03-31  2.396901
##        ...          
## 2024-10-31 10.508837
## 2024-11-30  9.163073
## 2024-12-31 10.211976
## 2025-01-31 11.072869
## 2025-02-28 10.291139
## 2025-03-31 12.074153
## 2025-04-30 13.416830
## 2025-05-31 13.874334
## 2025-06-30 14.580000
## 2025-07-31 14.650000
# Calcula os retornos mensais

asset_returns <- Return.calculate(price_monthly,
                                  method = "log") %>%
  na.omit()
print(asset_returns)
##                B3SA3.SA
## 2011-07-31 -0.133393553
## 2011-08-31  0.045586713
## 2011-09-30 -0.059620300
## 2011-10-31  0.174899354
## 2011-11-30 -0.046626201
## 2011-12-31 -0.008130122
## 2012-01-31  0.114603699
## 2012-02-29  0.044491361
## 2012-03-31 -0.011590007
## 2012-04-30 -0.047367827
##        ...             
## 2024-10-31 -0.008438867
## 2024-11-30 -0.137034940
## 2024-12-31  0.108379597
## 2025-01-31  0.080936755
## 2025-02-28 -0.073214710
## 2025-03-31  0.159783848
## 2025-04-30  0.105442846
## 2025-05-31  0.033530789
## 2025-06-30  0.049610039
## 2025-07-31  0.004789588
plot(asset_returns)

Em seguida, será realizado o mesmo processo, mas, agora, com os dados do índice IBOVESPA, que será utilizado como proxy do mercado brrasileiro no modelo.

# Coleta do portfólio de mercado (Ibovespa)
ibov <- getSymbols('^BVSP',
             from = start,
             auto.assign = TRUE,
             warnings = FALSE,
             src = 'yahoo')

# Transformar os dados em mensais e em retornos
ibov_returns <-
  BVSP$BVSP.Adjusted %>%
  `colnames<-`('BVSP') %>%
  to.monthly(indexAt = 'lastof', OHLC = FALSE) %>%
  Return.calculate(method = "log") %>%
  na.omit()
## Warning in to.period(x, "months", indexAt = indexAt, name = name, ...): missing
## values removed from data
plot(ibov_returns)

2.3 Regressão entre a rentabilidade do IBOVESPA e a B3

A partir dos dados organizados faz se necessárias rodar uma regressão linear simples para encontrar o coeficiente \(\beta\) do ativo sob análise, que será posteriormente usado para o cálculo do custo de capital da B3.

##Rodando regressão entre o ativo e o mercado
Regressao <- lm(asset_returns ~ ibov_returns)
summary(Regressao)
## 
## Call:
## lm(formula = asset_returns ~ ibov_returns)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.190229 -0.041571 -0.000429  0.036055  0.190140 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.005943   0.004615   1.288      0.2    
## ibov_returns 1.151382   0.073338  15.700   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.05982 on 167 degrees of freedom
## Multiple R-squared:  0.5961, Adjusted R-squared:  0.5937 
## F-statistic: 246.5 on 1 and 167 DF,  p-value: < 2.2e-16
##Rodando o beta do CAPM por meio de outra função
Beta <- CAPM.beta(Ra=asset_returns,Rb=ibov_returns,Rf = 0)

Ainda, para uma melhor visualização, os dados podem ser agrupados para a plotagem de um gráfico de dispersão.

##Plotando o gráfico de dispersão do dados
serie_combinada <- cbind(asset_returns, ibov_returns)
serie_combinada_tbl <- serie_combinada %>%
  tk_tbl(preserve_index = TRUE,
         rename_index = "date")
DaFra <- as.data.frame(serie_combinada_tbl)

ggplot(DaFra,aes(x = BVSP, y = B3SA3.SA))+
  geom_point(color = "#282f6b")+
  geom_smooth(method = "lm",
              se = FALSE,
              color = "red",
              size = .5)+
  labs(title = "Retornos da B3 x Retornos da Ibovespa",
       x = "Ibovespa",
       y = "B3",
       caption = "Elaborado com dados do Yahoo Finance")+
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'

2.4 Cálculo do custo de capital da B3

Com o \(\beta\) à disposição, as duas variáveis que faltam para a aplicação da fórmula do CAPM são o \(R_f\) e o \(E(R_m)\).

Em suma para encontrar o \(E(R_m)\) foi feita uma média geométrica do retorno do mercado furante o período.

##Enontrandi i retirno médio do mercado
Rm_compounded <- (prod(1 + ibov_returns, 
          na.rm = TRUE)^(1/length(ibov_returns)))^(12)-1
print(Rm_compounded)
## [1] 0.03259575

Por última, a taxa livre de risco \(R_f\) foi encontrada a partir de uma média geométrica da taxa SELIC do período analisado. Este é o método que foi adotado para atenuar os efeitos de choques de polpiticas monetárias ao longo do período. Os dasdos da taxa selic foram extraídos a partir do Banco Central.

##taxa livre de risco do Brasil
selic <- c(
  15.00, 14.75, 14.25, 13.25, 12.25, 11.25, 10.75, 10.5, 10.5, 10.5,
  10.75, 11.25, 11.75, 12.25, 12.75, 13.25, 13.75, 13.75, 13.75, 13.75,
  13.75, 13.75, 13.75, 13.75, 13.25, 12.75, 11.75, 10.75, 9.25, 7.75,
  6.25, 5.25, 4.25, 3.5, 2.75, 2.00, 2.00, 2.00, 2.00, 2.00, 2.25,
  3.00, 3.75, 4.25, 4.5, 5.0, 5.5, 6.0, 6.5, 6.5, 6.5, 6.5, 6.5, 6.5,
  6.5, 6.5, 6.5, 6.5, 6.5, 6.75, 7.0, 7.5, 8.25, 9.25, 10.25, 11.25,
  12.25, 13.0, 13.75, 14.0, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25,
  14.25, 14.25, 14.25, 14.25, 13.75, 13.25, 12.75, 12.25, 11.75, 11.25,
  11.0, 11.0, 11.0, 11.0, 10.75, 10.5, 10.0, 9.5, 9.0, 8.5, 8.0, 7.5,
  7.25, 7.25, 7.25, 7.25, 7.5, 8.0, 8.5, 9.0, 9.75, 10.5, 11.0, 11.5,
  12.0, 12.5, 12.25
)
Rf <- prod(1+selic/100)^(1 / length(selic))-1
print(Rf)
## [1] 0.09657245

Com todas as variáveis organizadas é possível fazer o cálculo do CAPM da B3.

##CAPM trdicional
Ra = Rf+Beta*(Rm_compounded-Rf)
print(Ra)
## [1] 0.02291081

O modelo indicou que o custo de capital da B3 é de 2,19%, isto é um retorno esperado insatisfatório, tendo em vista taxa livre de risco. Vale ressaltar que o modelo CAPM, sofre vários problemas ao ser aplicado no Brasil, cujo mercado possui um retorno historicamente baixo em relação a taxa livre de risco, de tal modo que o modelo sofre com um prêmio de risco negativo, elemento este qe é incongruente com os fundamentos teóricos do modelo. Outrossim, vale destacar a alta volatilidade do juros e do mercado brasileiro que tornam as suas métricas financeiras complexas de serem modeladas. Portanto, o modelo CAPM convencional sofre com vários problemas ao ser aplicado a um mercado emegente como é o caso d o Brasil.

3 Modelo CAPM alternativo: proposta de ASSAF NETO et al (2008)

Percebe-se que o modelo CAPM, em sua forma pura, sofre diversos problemas ao ser aplicado no Brasil Nesse sentido, Assaf Neto et al. (2008) no artigo Uma proposta metodológica para o cálculo do custo de capital no Brasil destacamcomo que o modelo CAPM não é adequado para países emergentes que possuem mercados voláteis e com altas taxas de juros, como é o caso brasileiro. Para lidar com estes problemas Assad Neto et al. (2008) fazem a proposta de um modelo alternativo em que coloca uma economia estável como benchmark e há a adiçãopara de um prêmio de risco-país para calcular o custo de capital de uma empresa em um mercado emergente, tal qual o Brasil.

Esta proposta é esboçada pela seguinte fórmula:

\[ E(R_i) = R_F + \beta \left[ (E(R_M) - R_F) + \alpha_{BR} \right] \]

Onde:

3.1 Retorno esperado do mercado no país benchamark (EUA)

O \(E(R_M)\) será estipulado como a média geométrica taxa de retorno do S&P 500 durante o período de análise do presente trabalho.

###Calculando o retornos do mercado americano
SeP <- getSymbols('^GSPC',
                   from = start,
                   auto.assign = TRUE,
                   warnings = FALSE,
                   src = 'yahoo',)
###Plot da série histórico do S&P 500
plot(GSPC$GSPC.Adjusted)

###Calculando o retorno mensal
SeP_returns <-
  GSPC$GSPC.Adjusted %>%
  `colnames<-`('GSPC') %>%
  to.monthly(indexAt = 'lastof', OHLC = FALSE) %>%
  Return.calculate(method = "log") %>%
  na.omit()
print(SeP_returns)
##                    GSPC
## 2011-07-31 -0.021708356
## 2011-08-31 -0.058467502
## 2011-09-30 -0.074467101
## 2011-10-31  0.102306592
## 2011-11-30 -0.005071554
## 2011-12-31  0.008496565
## 2012-01-31  0.042660044
## 2012-02-29  0.039787345
## 2012-03-31  0.030851476
## 2012-04-30 -0.007525700
##        ...             
## 2024-10-31 -0.009946042
## 2024-11-30  0.055719714
## 2024-12-31 -0.025307692
## 2025-01-31  0.026657806
## 2025-02-28 -0.014344485
## 2025-03-31 -0.059266785
## 2025-04-30 -0.007654162
## 2025-05-31  0.059705448
## 2025-06-30  0.048415655
## 2025-07-31  0.004025727
###Plot do retorno
plot(SeP_returns)

##Retorno medio do mercado americano
RmSeP_compounded <- (prod(1 + SeP_returns, 
                       na.rm = TRUE)^(1/length(SeP_returns)))^(12)-1

print(RmSeP_compounded)
## [1] 0.1044567

3.2 A taxa livre de risco

A taxa livre de risco neste modelo CAPM alternativo será considerada como a taxa de juros do tresury bond com vencimento de 10 anos dos Estado Unidos que pode ser encontrado no site do Federal Reserve Bank of St. Luis. Esta taxa está atualmente no patamar de 4,35%

##Taxa livre de risco dos EUA
RfUS <- 0.0435

3.3 Beta do indústria de serviços fnanceiros nos EUA

Por último faz-se necessários encontrar o Beta do setor em que a B3 faz parte no mercado americano. Para isso, será usada a base de dados disponibilizada por Damodaran, que atualiza e fornece periodicamente métricas financeiras dos mercado americado, tal qual o coeficiente beta dos diversos setores presentes no EUA. Atualmente, o beta da indústria de serviços financeiros, em que a empresa B3 faz parte, é de 1,07.

##Beta do setor de serviços financeiro no mercado americano
BetaUS <- 1.07

3.4 Prêmio de risco-país

o prêmio de risco-país \(\alpha_{BR}\) é dado pela diferença entre as taxas livres de risco do brasil e dos EUA

##CAPM adaptado considerando o mercado americano e o risco país
alfa <- Rf - RfUS
print(alfa)
## [1] 0.05307245

3.5 Cálculo do custo de capital alternativo da B3

Com os dados consolidados, pode-se aplicar o modleo apresentado por Assaf Neto et et al. (2008). No novo modelo, foi encontrada uma taxa de custo de capital de 16,55% para empresa B3, neste caso, encontrou-se uma taxa maior que a taxa livre de risco.

##CAPM adaptado considerando o mercado americano e o risco país
Ra_alternativo = RfUS +BetaUS*(RmSeP_compounded- RfUS + alfa)
print(Ra_alternativo)
## [1] 0.1655112

4 Referência

ASSAF NETO, Alexandre; LIMA, Fabiano Guasti; ARAÚJO, Adriana Maria Procópio de. Uma proposta metodológica para o cálculo do custo de capital no Brasil. Revista de Administração, São Paulo, v. 43, n. 1, p. 72–83, jan./fev./mar. 2008.​