As ações escolhidas foram a Gol e a Hapvida, além da utilização da Selic como o ativo livre de risco.
| Código | Nome da Empresa | Setor |
|---|---|---|
| GOLL4.SA | Gol Linhas Aereas SA | Empresas Aereas |
| HAPV3.SA | Hapvida Participações e Investimentos S.A. | Saúde Suplementar |
Hapvida Participações e Investimentos S.A. :
Perfil Corporativo: A Hapvida é uma holding domiciliada no Brasil, com sede em Fortaleza, estado do Ceará. Ela atua no setor de saúde, oferecendo planos de assistência médica e odontológica. A empresa tem se destacado como a maior empresa de planos de saúde do Brasil, conquistando todos os estados do país. Seu compromisso é assegurar o acesso à saúde de qualidade para a população.
Cotação na B3: As ações da Hapvida (código HAPV3) estão listadas no Novo Mercado da B3. A companhia realizou seu IPO em 2018 e é controlada pela Ppar Pinheiro Participações S.A., que detém mais de 77% das ações ordinárias.
Gol Linhas Aéreas S.A. :
Perfil Corporativo: A Gol é uma companhia aérea brasileira que opera voos domésticos e internacionais. Com presença relevante nas principais regiões do Brasil, a Gol é conhecida por sua conectividade e serviços de transporte aéreo. Ela desempenha um papel fundamental no setor de aviação, proporcionando mobilidade e conectando pessoas e destinos.
Foi estabelecido o ativo ‘Risk Free’ como sendo a Selic
Taxa Selic (Banco Central) A sigla Selic provém do Sistema Especial de Liquidação e de Custódia, que é uma infraestrutura do mercado financeiro administrada pelo Banco Central. Essa taxa é calculada com base nas operações de empréstimos de um dia entre os bancos, nos quais títulos públicos federais são utilizados como garantia.
| Pacote | Explicação |
|---|---|
| dplyr | Manipulação eficiente de dados |
| quantmod | Análise quantitativa de dados financeiros |
| forecast | Previsão de séries temporais |
| fImport | Importação de dados financeiros |
| tidytext | Manipulação de texto estruturado em análise de dados |
| stringr | Manipulação de strings e expressões regulares |
| ggplot2 | Criação de gráficos e plots |
| GetBCBData | API do Bacen para disponibilizar dados |
| gridExtra | Organização de plot de multiplos graficos |
A fonte dos dados é o Yahoo Finance, que é acessado por meio do pacote “quantmod”.
Ao chamar:
getSymbols(symbol, src = "yahoo", from = start_date, to = end_date),
o código está solicitando ao pacote “quantmod” para baixar os dados
históricos da ação especificada usando o símbolo correspondente como um
parâmetro de entrada.
Site de acesso a plataforma: https://finance.yahoo.com
Para as ações
O Código abaixo, em resumo, define os símbolos das ações, utiliza o
pacote "quantmod" para baixar os dados históricos dessas
ações do https://finance.yahoo.com e armazena-los
em objetos separados para análise posterior.
# Definindo as datas de início e fim do período desejado
data_inicio <- as.Date("2023-05-01")
data_fim <- as.Date("2024-02-01")
# Definindo os objetos das ações da área da saúde
chaves_acesso <- c("GOLL4.SA", "HAPV3.SA")
# Criando um loop para baixar os dados de todas as ações
for (chave in chaves_acesso) {
getSymbols(chave, src = "yahoo", from = data_inicio, to = data_fim)
# Acessar os dados usando o nome do objeto criado pelo 'getSymbols'
assign(chave, get(chave))
# Aguardar um segundo antes de baixar o próximo símbolo (para evitar sobrecarga no servidor)
Sys.sleep(1)
}
# Renomeando as bases
gol <- data.frame(GOLL4.SA) %>% mutate(data = index(GOLL4.SA))
hapv <- data.frame(HAPV3.SA) %>% mutate(data = index(HAPV3.SA))
# Limpando os nomes das variaveis
names(gol) <- gsub('^GOLL4\\.SA\\.','',names(gol))
names(hapv) <- gsub('^HAPV3\\.SA\\.','',names(hapv))Para a Selic
Para obter os dados da Selic, utilizamos um pacote que puxa a API do Banco Central brasileiro
# utilizando a API do Bacen para pegar os dados
selic_data <- gbcbd_get_series(
id = 12,
first.date = data_inicio,
last.date = data_fim
)
knitr::kable(head(selic_data),align = "c")| ref.date | value | id.num | series.name |
|---|---|---|---|
| 2023-04-28 | 0.050788 | 12 | id = 12 |
| 2023-05-02 | 0.050788 | 12 | id = 12 |
| 2023-05-03 | 0.050788 | 12 | id = 12 |
| 2023-05-04 | 0.050788 | 12 | id = 12 |
| 2023-05-05 | 0.050788 | 12 | id = 12 |
| 2023-05-08 | 0.050788 | 12 | id = 12 |
Ele trás as informações já com as porcentagens trazidas à valor diário.
As bases de dados geradas pelo código fornecido contém informações de preços históricos das ações escolhidas durante o período de 2023-05-01 a 2024-02-01. Essas bases de dados contém as seguintes variáveis:
Date:
A data correspondente ao preço de fechamento da ação.
Open:
O preço de abertura da ação no dia específico.
High:
O preço mais alto alcançado pela ação durante o dia.
Low:
O preço mais baixo alcançado pela ação durante o dia.
Close:
O preço de fechamento da ação no dia específico.
Volume:
O volume de negociações da ação no dia específico.
Adjusted:
Preço ajustado que considera eventos como divisões de ações e dividendos
Primeiramente, serão calculados os retornos anualizados de ambas as ações.
Com base nos preços diários das ações, construimos os retornos anualizados, utilizando a seguinte equação:
\[r_{i,t}= 252 \cdot \ln \left( \frac{P_{i,\ t}}{P_{i,\ t-1}} \right)\] onde:
\(P_{i,t}\) é o preço da ação;
\(i\) no período \(t\);
\(r_{i,t}\) é o retorno da ação \(i\) no período \(t\).
Para a Selic, como seus dados já estão em porcentagem a valor diário, utilizamos a seguinte equação:
\[r_{(t)} = 252 \ \cdot \ \ln \left( 1+ \frac {Selic_{(t)}}{100} \right)\]
A equação acima transforma a variação percentual dos preços diários em um retorno contínuo e depois o anualiza, multiplicando pelo número de dias úteis no ano. Isso é útil para comparar retornos de diferentes ativos ao longo do tempo em uma base anualizada.
Na prática, isso significa que a taxa de retorno contínua é mais precisa para cálculos financeiros que envolvem múltiplas composições ao longo do tempo. Ela é expressa em termos de logaritmos naturais (usando o símbolo: \(\ln\) ), o que facilita a manipulação matemática.
retornos_gol <- c()
retornos_hapvida <- c()
retornos_selic <- c()
for (i in 2:nrow(gol)) {
# calculando os retornos da GOL
retornos_gol[i] <- 252 * log(
gol$Adjusted[i] / gol$Adjusted[i-1]
)
# calculando os retornos da HAPVIDA
retornos_hapvida[i] <- 252 * log(
hapv$Adjusted[i] / hapv$Adjusted[i-1]
)
# calculando os valores da selic
retornos_selic[i] <- 252 * log( 1 + (selic_data$value[i]/100) )
}
# retirando a primeira linha da base de dados
# pois ela foi perdida no calculo dos retornos
gol <- gol[2:121,]
hapv <- hapv[2:121,]
# adicionando esses retornos nas bases de dados
gol$retornos_anualizados <- retornos_gol[2:121]
hapv$retornos_anualizados <- retornos_hapvida[2:121]
retornos_selic <- retornos_selic[-1]
# apresentando uma parte dos retornos para visualizacao
knitr::kable(
data.frame(
HAPVIDA_retornos = retornos_hapvida[2:6],
GOL_retornos = retornos_gol[2:6],
SELIC_retornos = retornos_selic[2:6]
)
)| HAPVIDA_retornos | GOL_retornos | SELIC_retornos |
|---|---|---|
| -1.8129557 | 14.618219 | 0.1279533 |
| 6.2890906 | -3.668184 | 0.1279533 |
| 7.8620028 | 5.120636 | 0.1279533 |
| -0.8615385 | 2.163101 | 0.1279533 |
| -3.4759137 | 3.210240 | 0.1279533 |
Agora iremos apresentar algumas estatísticas descritivas básicas para cada um dos conjuntos de retornos calculados anteriormente.
Calculando uma tabela com as descritivas:
# Estatísticas descritivas dos retornos
estatisticas_gol <- summary( gol$retornos_anualizados)
estatisticas_hpv <- summary(hapv$retornos_anualizados)
# Criando a tabela das estatísticas descritivas
tabela_estatisticas <- data.frame(
Empresa = c("Gol Linhas Aéreas S.A. (GOLL4.SA)", "Hapvida Investimentos S.A. (HAPV3.SA)"),
`Média` = c(estatisticas_hpv[[4]], estatisticas_gol[[4]]),
`Mediana` = c(estatisticas_hpv[[3]], estatisticas_gol[[3]]),
`Mínimo` = c(estatisticas_hpv[[1]], estatisticas_gol[[1]]),
`Máximo` = c(estatisticas_hpv[[5]], estatisticas_gol[[5]]),
`Desvio Padrão`= c(sd(retornos_gol[-1]), sd(retornos_hapvida[-1])),
`Variância` = c( ( sd(retornos_gol[-1]) )^2 , ( sd(retornos_hapvida[-1]) )^2 )
)
# Imprimindo a tabela formatada
knitr::kable( tabela_estatisticas )| Empresa | Média | Mediana | Mínimo | Máximo | Desvio.Padrão | Variância |
|---|---|---|---|---|---|---|
| Gol Linhas Aéreas S.A. (GOLL4.SA) | 0.6871471 | 0.2644217 | -14.99519 | 4.796536 | 13.399368 | 179.54307 |
| Hapvida Investimentos S.A. (HAPV3.SA) | 0.1157403 | 0.4254359 | -33.64991 | 4.982864 | 7.727512 | 59.71444 |
A curtose e a assimetria são duas medidas estatísticas que que descrevem características importantes da distribuição de dados em um conjunto de observações.
A curtose é uma medida estatística que descreve a forma da distribuição dos dados em relação à distribuição normal, também conhecida como distribuição de Gauss. Ela avalia se a distribuição tem caldas mais “pesadas” ou “leves”.
A fórmula da curtose é dada por:
\[\text{Curtose} = \frac{\sum_{i=1}^{n} (x_i - \bar{x})^4}{n \cdot s^4} - 3\] onde: - \(n\) é o número de observações;
\(x_i\) é cada observação individual;
\(xˉ\) é a média das observações;
\(s\) é o desvio padrão das observações.
# FUNCAO QUE CALCULA A CURTOSE
calculo_curtose <- function(retornos){
# Calcular a média
media <- mean(retornos)
# Calcular os desvios da média
desvios <- retornos - media
# Calcular a quarta potência dos desvios
quarta_potencia_desvios <- desvios^4
# Calcular a variância
variancia <- var(retornos)
# Calcular a curtose
curtose <- sum(quarta_potencia_desvios) / (length(retornos) * variancia^2) - 3
}
# APLICANDO A FUNCAO NOS RETORNOS
curtose_gol <- calculo_curtose(gol$retornos_anualizados)
curtose_hapvida <- calculo_curtose(hapv$retornos_anualizados)A partir dos dados, conseguimos observar que ambas as ações apresentam curtoses positivas, o que significa que ambas têm alta probabilidade de presenciarem eventos extremos, seja de perda ou ganho. A Gol, em maior grau de 0.98 e a Hapvida de menor grau com 0.42.
A assimetria mede o grau de simetria da distribuição. Uma distribuição simétrica tem assimetria zero, logo, quanto mais distante de zero, mais assimétrica esta distribuição em questão.
Além disso, o sinal deste indicador também entrega informações. Uma distribuição com uma cauda longa à direita (valores maiores) terá assimetria positiva, enquanto uma distribuição com uma cauda longa à esquerda (valores menores) terá assimetria negativa.
A partir da utilização da formula: \[ g_1=\frac{n}{(n-1)(n-2)}\sum_{i=1}^{n} \left( \frac{x_i-\bar{x}}{s} \right)^3 \] onde: - \(n\) é o número de observações;
\(x_i\) é cada valor individual;
\(\bar{x}\) é a média dos valores;
\(s\) é o desvio padrão.
# FUNCAO QUE CALCULA A ASSIMETRIA
assimetria <- function(dados){
# Calcule a média dos dados
media <- mean(dados)
# Calcule o desvio padrão dos dados
desvio_padrao <- sd(dados)
# Calcule a assimetria manualmente
assimetria <- sum((dados - media)^3) / length(dados) / desvio_padrao^3
return(assimetria)
}
# Aplicando a funcao para os retornos
assim_gol <- assimetria(gol$retornos_anualizados)
assim_hpv <- assimetria(hapv$retornos_anualizados)Desta forma, obetemos um valor de Assimetria para os retornos da Gol de: -0.0611028 e um da hapvida de 0.4531635.
Para melhor visualização dos dados, foram feitos alguns gráficos para mostrar o comportamento das ações:
# Gráfico no tempo dos preços de fechamento
historico_precos <- ggplot() +
geom_line(data = gol, aes(x = data, y =Close), color = "blue", linetype = "solid") +
geom_line(data = hapv, aes(x = data, y =Close), color = "red", linetype = "solid") +
labs(title = "Gráfico no Tempo dos Preços de Fechamento", x = "Data", y = "Pre") +
scale_x_date(date_labels = "%Y-%m", date_breaks = "1 month") +
scale_y_continuous() +
theme_classic()
historico_rentabilidade <- ggplot() +
geom_line(data = gol, aes(x = data, y =retornos_anualizados), color = "blue", linetype = "solid") +
geom_line(data = hapv, aes(x = data, y =retornos_anualizados), color = "red", linetype = "solid") +
labs(title = "Gráfico no Tempo dos retornos", x = "Data", y = "Retornos Anualizados") +
scale_x_date(date_labels = "%Y-%m", date_breaks = "1 month") +
scale_y_continuous() +
theme_classic()
# Gráfico estimando a distribuição dos retornos
dist_retornos <- ggplot() +
geom_density(data = gol, aes(x = retornos_anualizados, fill = "GOL Linhas Aéreas"), alpha = 0.5) +
geom_density(data = hapv, aes(x = retornos_anualizados, fill = "Hapvida"), alpha = 0.5) +
labs(title = "Estimativa da Distribuição dos Retornos", x = "Retornos Diários", y = "Densidade") +
# xlim(-120, 120) +
geom_vline(aes(xintercept = 0), color = "black", linetype = "dashed",size = 1) +
theme_classic()
# Combinação dos gráficos lado a lado
gridExtra::grid.arrange(historico_precos, historico_rentabilidade ,dist_retornos, ncol = 1)Os Gráficos apresentados neste Documento Web são todos clicaveis
É possível perceber que, pelo gráfico 1, a Gol possui um preço de fechamento maior quando comparada a habvida, o que faz sentido acreditar, já que por ser uma emrpesa de companhia aérea e ter maior valorilidade, isso passa a se refletir no seu preço. O gráfico 2 evidencia que ambas as ações, na média, tendem a ter o mesmo comportamento, claro que em maior ou menor grau em alguns momentos. Já o último gráfico, mostra a distribuição dos retornos diários das ações, sem diferenças extremas entre as duas.
Esta seção abordará a apresentação da carteira de risco e as diversas combinações de peso associadas a ela. Primeiramente, será delineada a fronteira de possibilidades. Em seguida, será discutida a minimização da variância da carteira, refletindo a aversão ao risco do investidor e sua busca por minimizar perdas. Por fim, será explorada a maximização da utilidade, refletindo o desejo do investidor de alcançar o maior retorno possível.
Para uma carteira com duas ações,temos: \[ r_p = w_g r_g + w_h r_h \]
onde:
\(w_g\) eh a proporcao das acoes da gol na carteira \(p\);
\(w_h\) sendo a proporcao das acoes da hapvida na carteira \(p\);
\(r_g\) é o retorno da gol.
\(r_h\) é o retorno da hapvida.
Existem inúmeras formas de encontrar os Retornos Esperados. Como há uma incerteza em relação ao cenário futuro, a melhor forma seria encontrarmos uma estimativa boa o suficiente e não viesada dessa esperança em questão. Mas para isso precisariamos de modelos que tornariam este trabalho muito extenso.
Por conta disso, iremos avaliar o \(E[r]\) como sendo a média simples dos retornos anualizados já calculados.
•Uma medida de risco usual é o desvio-padrão, que mede a dispersão dos possíveis retornos em relação ao retorno esperado.
Covariância: A covariância entre dois vetores pode ser calculada usando a seguinte fórmula: \[Cov(r_g , r_h ) = \frac{1}{n} \sum_{i=1}^n (r_g - \bar{r_g}) (r_h - \bar{r_h}) \]
Correlação: Já a correlação, esta é calculada a partir da equação: \[ Corr(r_g,r_h) = \frac{cov(r_g,r_h)}{\sigma_{r_g} \cdot \sigma_{r_h}} \]
Aplicando a função no R:
temos a função da variância como: \[\sigma^2_p = Var[r_p] = Var[w_hr_h+w_gr_g] = w_h^2\sigma_h^2+w_g^2\sigma_g^2 + 2w_hw_gCov(r_h,r_g) \] onde: \(\sigma_g^2 = Var[r_g]\); \(\sigma_h^2 = Var[r_h]\).
Percebemos neste caso que a variância da carteira diminui se o termo da covariância for negativo.
Agora, achando o Desvio Padrão utilizando a formula acima \[\sigma_p = (Var[r_p])^{1/2} = \sqrt{ \ w_h^2r_h^2+w_g^2r_g^2 + 2w_hw_gCov(r_h,r_g)} \]
Para isso, iremos criar uma tabela com os possíveis valores de de pesos das duas ações e testar suas combinações a fim de gerar um vetor com os possíveis valores de retorno esperado e desvio padrão. Com eles, iremos estabelecer o gráfico com os retornos e desvios.
Agora, iremos fazer um loop para poder calcular os valores de desvio-padrão e Retorno esperado da carteira para todos os possíveis pares de pesos \([w_g,\ w_h]\) sabendo que, \(w_g + w_h = 1\). E, a partir desses resultados, podemos encontrar o gráfico de retornos possíveis para cada desvio-padrão e construir a fronteira eficiente.:
Realizando o loop para todos os pessos possíveis:
# variaveis de armazenamento dos valores
retorno_carteira <- c()
desvio_carteira <- c()
# renomeando para melhor visualizacao
sd_g <- desvio_padrao_g
sd_h <- desvio_padrao_h
# aplicacao do loop
for ( i in 1:nrow(tabela_pesos) ) {
Wg <- tabela_pesos$w_g[i] # iterando os pesos
Wh <- tabela_pesos$w_h[i] # iterando os pesos
# utilizando a formula de retorno de p
retorno_carteira[i] <-(Wg * retorno_g) + (Wh * retorno_h)
# utilizando a formula do desvio da carteira
desvio_carteira[i] <- (
( (Wg^2 * sd_g^2) + (Wh^2 * sd_h^2) + (2*Wg*Wh*covariancia) )^(0.5)
)
}
# Criando um data.frame com os dados
tabela_retornos <- data.frame(
retorno = retorno_carteira,
desvio = desvio_carteira,
peso_gol = tabela_pesos$w_g,
peso_hpv = tabela_pesos$w_h
)
# plotando a tabela no HTML
knitr::kable( head(tabela_retornos) )| retorno | desvio | peso_gol | peso_hpv |
|---|---|---|---|
| 0.6871471 | 7.727512 | 0.000 | 1.000 |
| 0.6865757 | 7.723137 | 0.001 | 0.999 |
| 0.6860043 | 7.718785 | 0.002 | 0.998 |
| 0.6854329 | 7.714454 | 0.003 | 0.997 |
| 0.6848615 | 7.710146 | 0.004 | 0.996 |
| 0.6842900 | 7.705859 | 0.005 | 0.995 |
Agora, plotando o gráfico da fronteira eficiente, temos:
ggplot(tabela_retornos, aes(x = desvio, y = retorno)) +
geom_point(color = "darkblue", size = 1.5) +
labs(
x = "Desvio Padrão (σ)",
y = "Retorno Esperado (E[r])",
title = "Relação entre Desvio Padrão e Retorno Esperado",
subtitle = "Análise de Portfólio",
caption = "Fonte: Yahoo.finance"
) +
theme_classic() +
annotate(
"segment",
x = min(tabela_retornos$desvio)+0.1,
xend = min(tabela_retornos$desvio) + 1.2 ,
y = tabela_retornos[tabela_retornos$desvio == min(tabela_retornos$desvio),"retorno"],
yend= tabela_retornos[tabela_retornos$desvio == min(tabela_retornos$desvio),"retorno"],
arrow = arrow(length = unit(0.3, "cm"),ends = 'first', type = 'open'),
color = "black"
) +
annotate(
"text",
x = min(tabela_retornos$desvio) +1.3,
y = tabela_retornos[tabela_retornos$desvio == min(tabela_retornos$desvio),"retorno"]-0.01,
label = paste("Ponto de risco mínimo e com retorno = ",round(tabela_retornos[tabela_retornos$desvio == min(tabela_retornos$desvio),"retorno"],3)),
hjust = 0,
vjust = 0,
color = "black"
) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(face = "italic", size = 12),
plot.caption = element_text(size = 8),
axis.title.x = element_text(face = "bold", size = 12),
axis.title.y = element_text(face = "bold", size = 12),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "none"
) +
scale_x_continuous(labels = scales::comma)Como podemos ver no gráfico, temos a o valor com o menor desvio padrão como aquele ponto da curva que é tangenciado por uma linha vertical.
Temos algumas formas diferentes para poder encontrar a carteira de mínima variância.
Como foi visto no exercício anterior, calculamos todas os desvios possíveis para as carteiras. Dessa forma, encontramos o valor de menor risco e podemos usar o par de pesos gerou o menor desvio.
Contudo, podemos também resolver esse execício através de uma ótica matemática, interpretanto as formulas como um problema de minimização da equação do desvio dado a restrição de \(w_g + w_h = 1\).
fariamos isso dessa forma:
\[\sigma^2_p = w_h^2\sigma_h^2+(1 -w_h)^2\sigma_g^2 + 2w_h(1 -w_h)Cov(r_h,r_g)\]
Portando, minimizaremos a Função escolhendo o valor de \(w_h\), aplicando a CPO: \[\frac{\partial(\sigma^2_p)}{\partial w_h} = 2w_h\sigma_h^2 - 2(1 - w_h)\sigma_g^2 + 2(1 - 2w_h)Cov(r_h,r_g)\]
Portanto, ao acharmos o valor que torne a CPO = zero, teremos seu valor mínimo.
\[2w_h\sigma_h^2 - 2\sigma_g^2 + 2w_h\sigma_g^2 + 2Cov(r_h,r_g) - 4w_hCov(r_h,r_g) = 0\]
\[w_h^* = \frac{\sigma_g^2 - Cov(r_h,r_g)}{\sigma_h^2 + \sigma_g^2 - 2Cov(r_h,r_g)}\]
Aplicando:
A utilidade é dada por: \[U = E[r_p] - \frac{1}{2}A\sigma^2_p\]
Da mesma forma que achamos a carteira de mínima variância calculando os resultados para todos os pesos possíveis, podemos forçar a maximização da utilidade dessa mesma forma:
# definindo a aversao ao risco
A <- 2.5
# vetor vazio de armazenamento das utilidades
utilidades <- c()
# Calculando a utilidade para todos os possiveis pesos
for (i in 1:nrow(tabela_pesos)) {
# definindo as variaveis pelo iterador em questao
w_g <- tabela_pesos$w_g[i]
w_h <- tabela_pesos$w_h[i]
desvio <- tabela_retornos$desvio[i]
retorno_esperado <- tabela_retornos$retorno[i]
# aplicando o calculo da utilidade para cada par de pesos
utilidades[i] <- (retorno_esperado - (0.5 * A * desvio^2) )
}
# acrescentando os valores da utilidade para cada peso
tabela_retornos$utilidades <- utilidadesComo as utilidades são calculadas por meio da subtração do retorno esperado menos um produto do desvio padrão, temos boa parte das utilidades negativas. Ainda assim, como a parte importante das funções utilidades é o seu carácter ordinal e não seu valor em si, só a utilizaremos para ver qual par de pesos que a tornou máxima.
Temos:
\[U = \color{green}{E[r_p]} - 0.5 A \color{red}{ \sigma_p^2} \] \[\color{green}{E[r_p]} = w_gE[r_g] + w_hE[r_h]\]
\[\color{red}{\sigma^2_p} = w_h^2\sigma_h^2+w_g^2\sigma_g^2 + 2w_hw_gCov(r_h,r_g) \]
Portanto, a utilidade pode ser escrita como: \[U = \color{green}{w_gE[r_g]+w_hE[r_h]} - 0.5A \color{red}{[w_g^2\sigma_g^2+w_h^2\sigma_h^2+2w_gw_hCov(r_g,r_h)]}\]
Dessa forma, quando maximizamos ela, teremos:
\[w_g^* = \frac{E[r_g] - E[r_h] + A[\sigma^2_h - 2Cov(r_D, r_E)]}{A[\sigma^2_g + \sigma^2_h - 2Cov(r_g, r_h)]}\] \[w_h^* = 1 - w_g^* = \frac{E[r_g] - E[r_h] + A[\sigma^2_g 2Cov(r_g, r_h)] }{A[\sigma^2_g + \sigma^2_h - 2Cov(r_g, r_h)]}\]
Esta seção destina-se a apresentar a carteira completa do indivíduo, incluindo o ativo livre de risco. Em seguida, serão delineados os pesos ótimos que maximizam o índice de Sharpe.
Para otimizar a utilidade do consumidor, considerando o ativo livre de risco, empregamos o índice de Sharpe para determinar os pesos ideais dos ativos. O índice de Sharpe representa a relação entre retorno e risco, destacando a busca por um equilíbrio favorável. Encontrar a carteira com o máximo índice de Sharpe implica maximizar a compensação do retorno em relação ao risco assumido. Essa abordagem visa aprimorar a eficiência da alocação de recursos, priorizando investimentos que oferecem maior retorno ajustado ao risco.
dado que a \(r_f\) é a taxa do risk free, o Índice de Sharpe é dado por:
\[S = \frac{E[r_c] - r_f}{\sigma_c}\]
# Risk free
risk_free <- mean(retornos_selic)
# vetor vazio de armazenamento dos Sharpes calculados
sharpe <- c()
# Calculando a utilidade para todos os possiveis pesos
for (i in 1:nrow(tabela_pesos)) {
# definindo as variaveis pelo iterador em questao
w_g <- tabela_pesos$w_g[i]
w_h <- tabela_pesos$w_h[i]
desvio <- tabela_retornos$desvio[i]
retorno_esperado <- tabela_retornos$retorno[i]
# aplicando o calculo do sharpe para cada par de pesos
sharpe[i] <- (retorno_esperado - risk_free) / (desvio)
}
# acrescentando os valores de sharpe para cada peso
tabela_retornos$sharpe <- sharpe
# pontos que maximizam o sharpe tirando aqueles abaixo da linha de min(Variancia)
tabela_acima_min_risco <- tabela_retornos[
tabela_retornos$retorno > tabela_retornos[
tabela_retornos$desvio == min(tabela_retornos$desvio),"retorno"
],
]
# encontrando pontos de maximo sharpe
w_g_max_sharpe <- tabela_acima_min_risco[
tabela_acima_min_risco$sharpe == max(tabela_acima_min_risco$sharpe),"peso_gol"
]
w_h_max_sharpe <- 1 - w_g_max_sharpeOs pesos que maximizam o sharpe são,respectivamente: \[Max(Sharpe) \rightarrow w_g = 0; w_h = 1 \]
Agora, vamos plotar uma figura com a reta LAC, na qual sua inclinação é dada pelo índice de Sharpe, que tangencia a curva da fronteira eficiente
# adicionando os pontos de sharpe maximo
x_ponto_desvio <- tabela_retornos[tabela_retornos$peso_gol == w_g_max_sharpe,"desvio"]
y_ponto_retorno <- tabela_retornos[tabela_retornos$peso_gol == w_g_max_sharpe,"retorno"]
ggplot(tabela_retornos, aes(x = desvio, y = retorno)) +
geom_point(color = "black", size = 1) +
geom_point(data = data.frame(x = x_ponto_desvio, y = y_ponto_retorno), aes(x = x, y = y), color = "darkred", size = 3) + # Adicionando o ponto
geom_segment(x = 0, y = 0, xend = 2*x_ponto_desvio, yend = 2*y_ponto_retorno, color = "red", linetype = "solid") + # Desenhando a linha da origem ao ponto vermelho
labs(
x = "Desvio Padrão (σ)",
y = "Retorno Esperado (E[r])",
title = "Relação entre Desvio Padrão e Retorno Esperado",
subtitle = "Análise de Portfólio",
caption = "Fonte: Yahoo.finance"
) +
theme_classic() +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(face = "italic", size = 12),
plot.caption = element_text(size = 8),
axis.title.x = element_text(face = "bold", size = 12),
axis.title.y = element_text(face = "bold", size = 12),
axis.text.x = element_text(angle = 25, hjust = 1),
legend.position = "none"
) +
scale_x_continuous(
expand = c(0, 0),
limits = c(0, 2+ max(tabela_retornos$desvio)),
breaks = seq(0, 2+ max(tabela_retornos$desvio), by = 1)
) +
scale_y_continuous(
expand = c(0, 0),
limits = c(0, 0.2 + max(tabela_retornos$retorno)),
breaks = seq(0, 0.2 + max(tabela_retornos$retorno),by = 0.1)
)\[ \begin{align} \begin{cases} E[r_p] & = 0.6871471 \\ \sigma_p^2 & = 59.7144353 \\ \sigma_p & = 7.7275116 \\ S_p & = 0.0732786 \end{cases} \end{align} \]
Quando queremos maximizar o Sharpe por meio das equações escolhendo um dos pesos, teremos:
\[\max_{w_e,w_D} S_p\] \[ \begin{align} \text{s.a.} \quad & \begin{cases} w_g + w_h = 1 \\ E[r_p] = w_gE[r_g] + w_hE[r_h] \\ \sigma_p = (\sigma^2_p)^{1/2} \\ \sigma_P^2 = w_g^2\sigma_g^2 + w_h^2\sigma_h^2+ 2w_gw_h \cdot Cov(r_g,r_h) \end{cases} \end{align} \]
Se substituirmos tudo, teremos um problema de maximização dado por: \[ \max_{w_g} \frac{(1-w_g)E[r_h]+w_gE[r_g] - r_f} {\sqrt{ [w_g^2\sigma_g^2 + (1-w_g)^2\sigma_h^2+ 2w_g(1-w_g) \cdot Cov(r_g,r_h)]}} \]
Aplicando a maximização, teremos os pesos ótimos dados pela equação: \[ w_G^* =\frac{E[R_G]\sigma_H^2 - E[R_H] Cov(R_G,R_H)} {E[R_G]\sigma_H^2 - E[R_H]\sigma_G^2 - (E[R_G] - E[R_H]) \cdot Cov(R_G,R_H)} \]
onde consideramos os retornos excedentes: \[E[R_G] = E[r_g-r_f]\] \[E[R_H] = E[r_h-r_f]\] ### 3.2.1 Aplicando a formula para os pontos:
# definindo variaveis
R_G <- retorno_g - risk_free
R_H <- retorno_h - risk_free
w_g_maximo_sharpe <-
( (R_G * desvio_padrao_h^2) - (R_G * covariancia) ) / # dividido por...
(
(R_G*desvio_padrao_h^2) - (R_H*desvio_padrao_g^2) -
( (R_G - R_H) * (covariancia) )
)
w_h_maximo_sharpe <- 1 - w_g_maximo_sharpeOs pesos que maximizam o sharpe por meio das equações são, respectivamente: \[Max(Utilidade) \rightarrow w_g = 0.0019991; w_h = 0.9980009 \]
Agora, tendo a carteira ótima de títulos de risco P, usaremos o grau de aversão ao risco A, para calcular a proporção ótima da carteira completa a ser investida no componente de risco
\[Max(Utilidade Risk Free)\] \[w_g = 7.5830316\times 10^{-6};\] \[w_h = 0.0037855\] \[y = 0.9962069 \] ### calculando as variaveis de saída:
retorno_c <- (pesoselic * risk_free) + (pesoacoes*retorno_sharpe)
desvio_c <- ((pesoacoes^2 * desvio_sharpe^2) )^(0.5)
variancia_c <- ((pesoacoes^2 * desvio_sharpe^2) )
sharpe_c <- ( (retorno_sharpe - risk_free) / (desvio_sharpe) ) \[ \begin{align} \begin{cases} E[r_c] & = 0.1230336 \\ \sigma_c^2 & = 8.5916085\times 10^{-4} \\ \sigma_c & = 0.0293114 \\ S_c & = 0.0732786 \end{cases} \end{align} \]