Motivado pela aula do dia 10/09/2020 e como é de interesse de alguns colegas, decidi realizar uma formalização a fins didáticos de como utilizar o CAPM e a teoria de otimização de carteiras usando o Rstudio.
Irei dividir o texto em algumas partes, por exemplo, como buscar os dados das ações e como aplicar nos modelos. Caso já tenha familiaridade com o uso do R para essas operações, você poderá pular esse tópico sem menores problemas. Já agradeço a leitura de vocês. Aprender uma nova linguagem de programação é sempre um passo um tanto complicado, porém é o processo de aprendizado e a sua evolução que faz valer a pena.
Espero que gostem e que possa ser útil na vida de cada um de vocês!
Partindo-se do principio que alguns nunca utilizaram o R, caso algum erro apareça na hora de execução do seu código, não há porque se apavorar, está tudo bem! Diversas pessoas utilizam o R há anos e mesmo assim erram diversos códigos, portanto é um processo natural dentro do ambiente. Não desanimem, vocês já fizeram cálculo e álgebra linear!
Para fins de praticidade não irei ensinar a fundo como fazer gráficos com o pacote ggplot2 e algumas outras funções de programação na linguagem R como, por exemplo, deep learning, mas recomendo a leitura de alguns livros:
Antes de avançarmos gostaria de ensinar alguns comandos básicos do R.
Bom, primeiros vamos verificar aonde o seu computador está salvando, através do comando:
getwd() #você terá que digitar esse código
Esse é o seu diretório atual. Para alterar o ambiente de save utilize:
setwd(Usuario/Documents/Scripts modelos estocasticos/Series temporais/CAPM) #Dentro do parenteses você irá utilizar a área que irá salvá-lo
Visto aonde é o nosso diretório de save, o comandos para salvar o script é: Ctrl+S.
Calma pequeno gafanhoto, não largue de mão, o comando para executar a linha aonde o seu percursor se encontra é: Ctrl+enter.
Para executar todo o script de uma única vez utilize: Ctrl+shift+enter
NÃO!!! Calme rapaz, o conhecimento é construido em forma de blocos, um em cima do outro! Vamos passo por passo que chegamos ao destino, ok? Ok. Vamos lá então.
Para você limpar o seu console (lugar aonde irá executar o seu código) utilize o comando Ctrl+L.
O seu environment é sua área de trabalho. Mostra todos os objetos, incluindo variáveis e funções atualmente disponiveis para o seu trabalho. Para limparmos o environment utilizamos a função: rm(list=ls())
A partir dos comandos acima, você poderá sobreviver ao R.
Dado que é complicado a importação de dados a partir do modelo copia e cola, desenvolvedores criaram um pacote que realiza essa operação para o usuário.
Iremos instalar o pacote:
install.packages('BatchGetSymbols')
Após a sua instalação vamos carregar os pacotes para brincarmos:
library(tidyverse)
## -- Attaching packages ------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2 v purrr 0.3.4
## v tibble 3.0.1 v dplyr 1.0.0
## v tidyr 1.1.0 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## -- Conflicts ---------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(ggplot2)
library(BatchGetSymbols)
## Loading required package: rvest
## Loading required package: xml2
##
## Attaching package: 'rvest'
## The following object is masked from 'package:purrr':
##
## pluck
## The following object is masked from 'package:readr':
##
## guess_encoding
##
Caso não tenha instalado o pacote Tidyverse e ggplot a função não irá ser executado, portanto instale o mesmo.
Iremos, agora, criar variáveis com datas.
# set dates
first.date <- as.Date('2015-01-01')
last.date <- Sys.Date()
freq.data <- 'weekly'
Na função ‘freq.data’ eu selecionei como opção semanal para os dados, você poderá selecionar os dados diariamente, mensalmente, anualmente e etc, porém deverá escrever em inglês.
Na variável first.date a função que utilizei foi as.Date, ela selecionará os dados a partir da data estabelecida, lembrando que é o calendário americano como base.
Na variável last.date a função utilizada foi Sys.Date(), no qual os dados serão pesquisados até o dia atual do sistema. Você poderá alterar os limites dos dados.
Vamos buscar os dados das ações que queremos, neste caso Bradesco, Iguatemi, Petrobras, Movida e Itaúsa:
Observação: Você terá que digitar o código da ação e escrever .SA no final, lembre-se de usar aspas: “código da ação.SA”.
tickers <- c('BBDC4.SA','IGTA3.SA','PETR4.SA','CYRE3.SA')
l.out <- BatchGetSymbols(tickers = tickers,
first.date = first.date,
last.date = last.date,
freq.data = freq.data,
cache.folder = file.path(tempdir(),
'BGS_Cache') )
##
## Running BatchGetSymbols for:
## tickers =BBDC4.SA, IGTA3.SA, PETR4.SA, CYRE3.SA
## Downloading data for benchmark ticker
## ^GSPC | yahoo (1|1) | Not Cached | Saving cache
## BBDC4.SA | yahoo (1|4) | Not Cached | Saving cache - Got 96% of valid prices | Nice!
## IGTA3.SA | yahoo (2|4) | Not Cached | Saving cache - Got 96% of valid prices | Looking good!
## PETR4.SA | yahoo (3|4) | Not Cached | Saving cache - Got 96% of valid prices | Nice!
## CYRE3.SA | yahoo (4|4) | Not Cached | Saving cache - Got 96% of valid prices | Good job!
Os dados das ações foram carregados, para verificar sua saída, utilize:
print(l.out$df.control)
## # A tibble: 4 x 6
## ticker src download.status total.obs perc.benchmark.dat~ threshold.decisi~
## <chr> <chr> <chr> <int> <dbl> <chr>
## 1 BBDC4.SA yahoo OK 1420 0.964 KEEP
## 2 IGTA3.SA yahoo OK 1420 0.964 KEEP
## 3 PETR4.SA yahoo OK 1420 0.964 KEEP
## 4 CYRE3.SA yahoo OK 1420 0.964 KEEP
Para ver a saída numa nova aba digite: view(l.out$df.tickers)
Vamos ver a evolução gráfica das ações:
p <- ggplot(l.out$df.tickers, aes(x = ref.date, y = price.close))
p <- p + geom_line()
p <- p + facet_wrap(~ticker, scales = 'free_y')
print(p)
Após selecionado os ativos de interesse e antes de irmos para a teoria de otimização de carteiras, vamos ajustar as nossas saídas criando vetores com os retornos dos ativos que escolhemos, neste momento iremos filtrar as ações e, após, vamos selecionar apenas os seus retornos na hora do fechamento para já termos os dados ajustados.
# Filtrando os retornos Bradesco
bradesco <- l.out$df.tickers %>%
na.omit() %>%
filter(ticker == 'BBDC4.SA') %>%
select( ret.closing.prices) %>%
rename( Bradesco = ret.closing.prices) #Observe que modificamos o nome da coluna.
#Filtrando os retornos da Cyrela
cyrela <- l.out$df.tickers %>%
na.omit() %>%
filter(ticker == 'CYRE3.SA') %>%
select( ret.closing.prices) %>%
rename(Cyrela = ret.closing.prices) #Observe que modificamos o nome da coluna.
#Filtrando os retornos do Iguatemi
iguatemi <- l.out$df.tickers %>%
na.omit() %>%
filter(ticker == 'IGTA3.SA') %>%
select( ret.closing.prices) %>%
rename(Iguatemi= ret.closing.prices) #Observe que modificamos o nome da coluna.
#Filtrando os retornos da Petrobras
petrobras <- l.out$df.tickers %>%
na.omit() %>%
filter(ticker == 'PETR4.SA') %>%
select( ret.closing.prices) %>%
rename(Petrobras = ret.closing.prices) #Observe que modificamos o nome da coluna.
#Criando os uma variável com todos os retornos
retornos <- cbind(bradesco,cyrela,iguatemi,petrobras)
Realizado a busca dos dados iremos seguir em frente.
Você já escutou a seguinte frase?:
-“Diversifique, não coloque todos os ovos em uma única cesta”.
Se você nunca ouviu, ainda irá ouvir bastante. Essa expressão começou a ser utilizada após um paper de Harry Markowitz no qual é apresentado o conceito de teoria de otimização de carteiras.
A teoria de otimização de carteiras surge a partir de uma dúvida:
O conceito de quanto maior o risco, maior será o retorno é verdadeiro, podemos verificar isso com os derivativos, por exemplo. O contrário também é verdade, quanto menor o risco, também menor será o retorno, o exemplo que temos é o CDI. A partir dessa afirmações Harry Markowitz decidiu estudar e procurar uma resposta empírica para essa dúvida. Após a teoria desenvolvida e com comprovações empíricas, Harry Markowitz ganhou o nobel de economia em 1990.
Respondendo a pergunta da diversificação proposta no inicio da seção, a teoria de Markowitz mostrou que para diminuirmos o risco devemos diversificar a nossa carteira trazendo ativos com uma correlação negativa, lembrando que a correlação varia de -1 até 1. Vamos dar um exemplo para ficar mais claro:
Suponhamos que você ganhou na loteria R$ 100.000.
Você deseja investir o seu dinheiro ganho.
Você recebe uma ligação de algum gerente com uma oportunidade que a primeira vista é única: o BTG Pactual.
Você decidi comprar R$ 100.000 em ações do BTG.
Porém acontece um imprevisto após a compra: uma lei maluca surge no Brasil que congela o preço dos juros.
As ações do BTG começam a cair.
Você se apavora e vende suas ações perdendo 9% do seu patrimônio.
Observando essa pequena história e fazendo um paralelo com a história da cesta com os ovos, você colocou todos os ovos numa única cesta. A cesta caiu e os ovos quebraram. Mas agora, vamos construir um cenário diferente com os mesmos R$ 100.000:
Você decidi investir o seu dinheiro de maneira diversificada: um pouco de renda fixa, um pouco em ações do setor de aluguéis de carros, um pouco em ações do setor báncario, um pouco em ações do setor de construção.
Enquanto a lei maluca exposta no cenário anterior baixou o preço das ações bancárias, o governo apresenta uma reforma necessária e todas as outras ações sobem.
O retorno da sua carteira foi de 15% mesmo com a queda do setor bancário.
A diversificação protegeu a sua carteira, enquanto algumas ações caiam, outras subiam, a correlação entre esses ativos foi negativa e forte (próxima de -1). Caso selecionamos ativos com correlações positivas e forte (próxima de 1) ambas as ações iriam se acompanhar na subida e na descida. O objetivo da diversificação é escolher ativos com grau de correlação mais próximos de -1 para diminuirmos os riscos.
Vamos testar essas correlações com os ativos escolhidos na seção anterior. Por exemplo, a correlação entre Bradesco e Movida
cor(bradesco, cyrela)
## Cyrela
## Bradesco 0.6067175
Observamos que a correlação é positiva e forte, ou seja, quando a ação do bradesco sobe a ação da cyrela tende a subir, também. Sinta-se livre e teste as correlações.
Vamos agora construir uma carteira otimizada.
Para começarmos vamos carregar os pacotes:
library(fPortfolio)
## Loading required package: timeDate
## Loading required package: timeSeries
## Loading required package: fBasics
## Loading required package: fAssets
Caso não tenha instalado o pacote, lembre-se de instalar o mesmo e depois carregar.
Vamos transformar, agora, os nossos retornos em séries temporais. Todos os retornos estão guardados na variável que criamos “Retornos”.
#Transformando os retornos em séries de tempo
retornos <- as.timeSeries(retornos)
Agora vamos encontrar o ponto de tangência e ver os respectivos pesos de cada ação:
# Portfolio com a melhor relação entre risco/retorno
portfolio.eficiente <- tangencyPortfolio(retornos, spec = portfolioSpec(), constraints = "LongOnly")
portfolio.eficiente
##
## Title:
## MV Tangency Portfolio
## Estimator: covEstimator
## Solver: solveRquadprog
## Optimize: minRisk
## Constraints: LongOnly
##
## Portfolio Weights:
## Bradesco Cyrela Iguatemi Petrobras
## 0.000 0.476 0.000 0.524
##
## Covariance Risk Budgets:
## Bradesco Cyrela Iguatemi Petrobras
## 0.0000 0.4278 0.0000 0.5722
##
## Target Returns and Risks:
## mean Cov CVaR VaR
## 0.0054 0.0583 0.1289 0.0790
##
## Description:
## Wed Sep 16 00:03:40 2020 by user: Usuario
Dado os ativos que escolhemos (Bradesco, Cyrela, Iguatemi e Petrobras) o nosso portfólio que apresenta o melhor risco/retorno seria composto de 47,6% em Cyrela e 52,22% em Petrobras.
A saída Mean, apresenta o retorno esperando, que no caso seria 0.5%, com um risco da carteira sendo representado pela saída VaR, de valor 7,90%.
Agora se quisermos achar os pesos da carteira com o menor risco possivel, temos:
# Portfolio com menor risco:
portfolio.menor.risco <- minvariancePortfolio(retornos,spec = portfolioSpec(), constraints = "LongOnly")
portfolio.menor.risco
##
## Title:
## MV Minimum Variance Portfolio
## Estimator: covEstimator
## Solver: solveRquadprog
## Optimize: minRisk
## Constraints: LongOnly
##
## Portfolio Weights:
## Bradesco Cyrela Iguatemi Petrobras
## 0.5261 0.0000 0.4739 0.0000
##
## Covariance Risk Budgets:
## Bradesco Cyrela Iguatemi Petrobras
## 0.5261 0.0000 0.4739 0.0000
##
## Target Returns and Risks:
## mean Cov CVaR VaR
## 0.0026 0.0430 0.1023 0.0610
##
## Description:
## Wed Sep 16 00:03:40 2020 by user: Usuario
Observamos que para o menor peso da carteira temos Bradesco representando 52,61% e Iguatemi representando 47,39%. Ou seja, casdo fossemos investir R$ 100, cerca de 52,61 reais seriam para bradesco e 47,39 reais para o iguatemi.
Resolvido os pesos da carteira, vamos ver graficamente, para isso iremos calcular antes o ponto eficiente:
# Obtenção da fronteira
fronteira <- portfolioFrontier(retornos)
Feito isso, vamos ao gráfico:
# Gráfico com a fronteira eficiente
frontierPlot(fronteira, col = c('blue', 'red'), pch = 20)
## Adicionando informações no gráfico
monteCarloPoints(fronteira, mcSteps = 5000, pch = 20, cex = 0.25 )
Podemos, também, adicionar camadas a esse gráfico como, por exemplo, todas as possiveis saídas através da Simulação de Monte Carlo, ou seja, cada saída com as linhas pretas no gráfico anterior, representam todas as possíveis saídas de Monte Carlo.
Agradeço a quem leu até aqui, caso sintam dificuldades em algum ponto do script, podem me mandar um email: lc.venturini@hotmail.com
O uso do CAPM irei disponibilizar em breve, pois é u8m script mais avançado e desejo simplificar ele para que todos possam utilizar.