Importação dos dados

# install.packages("BatchGetSymbols")
require(BatchGetSymbols)
data_inicial <- as.Date('2015-01-01')
data_final <- as.Date('2018-01-01')
dados_ibov <- GetIbovStocks()
head(dados_ibov)
##   tickers ticker.desc type.stock   quantity percentage.participation   ref.date
## 1   ABEV3   AMBEV S/A         ON 4355174839                    2.953 2021-07-29
## 2   ASAI3       ASSAI ON      NM  157635935                    0.554 2021-07-29
## 3   AZUL4        AZUL PN      N2  327283207                    0.645 2021-07-29
## 4   B3SA3          B3 ON      NM 1930877944                    5.167 2021-07-29
## 5   BBAS3      BRASIL ON  ERJ NM 1283197221                    1.760 2021-07-29
## 6   BBDC3    BRADESCO ON  EJ  N1 1147260246                    1.125 2021-07-29
ativos <- c('ABEV3.SA','CMIG3.SA',
            'PETR3.SA','VALE3.SA',
            '^BVSP')
df <- BatchGetSymbols(tickers = ativos,
                      first.date = data_inicial,
                      last.date = data_final)
# Informações sobre o download
df$df.control
## # A tibble: 5 x 6
##   ticker   src   download.status total.obs perc.benchmark.dat~ threshold.decisi~
##   <chr>    <chr> <chr>               <int>               <dbl> <chr>            
## 1 ABEV3.SA yahoo OK                    749               0.967 KEEP             
## 2 CMIG3.SA yahoo OK                    749               0.967 KEEP             
## 3 PETR3.SA yahoo OK                    749               0.967 KEEP             
## 4 VALE3.SA yahoo OK                    749               0.967 KEEP             
## 5 ^BVSP    yahoo OK                    743               0.960 KEEP
# Dados das ações:
dados <- df$df.tickers
head(dados)
##   price.open price.high price.low price.close   volume price.adjusted
## 1      16.14      16.56     15.77       16.02 19396500       12.61954
## 2      15.91      15.97     15.54       15.73 13795900       12.39109
## 3      15.73      16.42     15.56       16.33 18610500       12.86373
## 4      16.34      16.72     16.14       16.56 20493500       13.04491
## 5      16.43      16.68     16.26       16.54  9054500       13.83095
## 6      16.47      16.65     16.30       16.50 11695700       13.79750
##     ref.date   ticker ret.adjusted.prices ret.closing.prices
## 1 2015-01-02 ABEV3.SA                  NA                 NA
## 2 2015-01-05 ABEV3.SA         -0.01810265       -0.018102372
## 3 2015-01-06 ABEV3.SA          0.03814370        0.038143675
## 4 2015-01-07 ABEV3.SA          0.01408441        0.014084446
## 5 2015-01-08 ABEV3.SA          0.06025646       -0.001207609
## 6 2015-01-09 ABEV3.SA         -0.00241820       -0.002418440

Organizando dados gerados

# Criar data frame com data, ativo e retorno ajustado
# install.packages('tidyverse')
require(tidyverse)
n <- length(ativos)

dados <- dados[,c(7,8,9)]
head(dados)
##     ref.date   ticker ret.adjusted.prices
## 1 2015-01-02 ABEV3.SA                  NA
## 2 2015-01-05 ABEV3.SA         -0.01810265
## 3 2015-01-06 ABEV3.SA          0.03814370
## 4 2015-01-07 ABEV3.SA          0.01408441
## 5 2015-01-08 ABEV3.SA          0.06025646
## 6 2015-01-09 ABEV3.SA         -0.00241820
colnames(dados) <- c("Data","Ativo","Retorno")
dados <- na.omit(dados) # Retirando os NA's
head(dados)
##         Data    Ativo     Retorno
## 2 2015-01-05 ABEV3.SA -0.01810265
## 3 2015-01-06 ABEV3.SA  0.03814370
## 4 2015-01-07 ABEV3.SA  0.01408441
## 5 2015-01-08 ABEV3.SA  0.06025646
## 6 2015-01-09 ABEV3.SA -0.00241820
## 7 2015-01-12 ABEV3.SA  0.01272701
ABEV3 <- subset(dados,Ativo==ativos[1])[,-2]
CMIG3 <- subset(dados,Ativo==ativos[2])[,-2]
PETR3 <- subset(dados,Ativo==ativos[3])[,-2]
VALE3 <- subset(dados,Ativo==ativos[4])[,-2]
BVSP <- subset(dados,Ativo==ativos[5])[,-2]


retornos <- inner_join(ABEV3,CMIG3,by="Data")
retornos <- inner_join(retornos,PETR3,by="Data")
retornos <- inner_join(retornos,VALE3,by="Data")
retornos <- inner_join(retornos,BVSP,by="Data")

colnames(retornos) <- c("Data",ativos)

# install.packages('xts')
datas <- retornos$Data
require(xts)

retornos <- xts(retornos[,2:6],
                order.by = datas)
plot(retornos, main = "Retornos dos ativos selecionados",
     legend.loc = 'top')

Retorno médio e risco

(retornos_medio <- apply(retornos, 2, mean))
##      ABEV3.SA      CMIG3.SA      PETR3.SA      VALE3.SA         ^BVSP 
##  0.0006678302 -0.0002208844  0.0014193126  0.0016135065  0.0007185829
(desvio_p <- apply(retornos, 2, sd))
##   ABEV3.SA   CMIG3.SA   PETR3.SA   VALE3.SA      ^BVSP 
## 0.01292062 0.03252633 0.03392018 0.03520124 0.01458420
(variancia <- apply(retornos, 2, var))
##     ABEV3.SA     CMIG3.SA     PETR3.SA     VALE3.SA        ^BVSP 
## 0.0001669425 0.0010579620 0.0011505789 0.0012391271 0.0002126989

Construindo o portfólio de mínima variância

# install.packages(c('fPortfolio','PerformanceAnalytics','timeSeries'))
require(fPortfolio)
require(PerformanceAnalytics)
require(timeSeries)

serie_retornos <- as.timeSeries(retornos[,-5])

minvariancePortfolio(serie_retornos)
## 
## Title:
##  MV Minimum Variance Portfolio 
##  Estimator:         covEstimator 
##  Solver:            solveRquadprog 
##  Optimize:          minRisk 
##  Constraints:       LongOnly 
## 
## Portfolio Weights:
## ABEV3.SA CMIG3.SA PETR3.SA VALE3.SA 
##   0.9364   0.0392   0.0000   0.0244 
## 
## Covariance Risk Budgets:
## ABEV3.SA CMIG3.SA PETR3.SA VALE3.SA 
##   0.9364   0.0392   0.0000   0.0244 
## 
## Target Returns and Risks:
##   mean    Cov   CVaR    VaR 
## 0.0007 0.0128 0.0280 0.0201 
## 
## Description:
##  Thu Jul 29 16:18:46 2021 by user: WorkFranciscoNeto
portfolio <- minvariancePortfolio(serie_retornos)

# Pesos

pesos <- getWeights(portfolio)
pesos
##   ABEV3.SA   CMIG3.SA   PETR3.SA   VALE3.SA 
## 0.93635901 0.03922184 0.00000000 0.02441914
weightsPie(portfolio)

# Simulação de $1

chart.CumReturns(serie_retornos,
                 wealth.index = TRUE,
                 legend.loc = "topleft",
                 main="Simulação de $1 em cada ativo")

retornos_minvar <- c()

for (i in 1:nrow(serie_retornos)) {
  aux <- 0
  for (j in 1:ncol(serie_retornos)) {
    aux <- aux + pesos[j]*serie_retornos[i,j]
  }
  
  retornos_minvar <- c(retornos_minvar,aux)
}

retornos_minvar <- xts(retornos_minvar,
                       order.by = datas)

chart.CumReturns(retornos_minvar,
                 wealth.index = TRUE,
                 legend.loc = NULL,
                 main="Simulação de $1 no port. Min. Var")  

serie_ibov <- xts(BVSP[,2], order.by = datas)

chart.CumReturns(serie_ibov,
                 wealth.index = TRUE,
                 main = "Simulação unitária no índice IBOV")