Dados do Ibovespa

Carregando os Retornos para estimação

## # A tibble: 2,472 x 47
##    Datas                  VALE3    ITUB4    BBDC4    PETR4    ABEV3   PETR3
##    <dttm>                 <dbl>    <dbl>    <dbl>    <dbl>    <dbl>   <dbl>
##  1 2008-11-03 00:00:00  0.0215   0.163    0.0442  -0.00729 -0.0111  -0.0147
##  2 2008-11-04 00:00:00  0.0703   0.0484   0.0314   0.0847  -0.00418  0.0997
##  3 2008-11-05 00:00:00 -0.0851  -0.0877  -0.0755  -0.0339   0.00292 -0.0384
##  4 2008-11-06 00:00:00 -0.0317  -0.0618  -0.0525  -0.0557   0.0393  -0.0684
##  5 2008-11-07 00:00:00 -0.0309   0.0366  -0.00169  0.0157   0.0487   0.0158
##  6 2008-11-10 00:00:00  0.0469   0.0317   0.0114   0.0297  -0.00454  0.0383
##  7 2008-11-11 00:00:00  0.0125  -0.00962 -0.0121  -0.00167 -0.0148  -0.0184
##  8 2008-11-12 00:00:00 -0.0651  -0.0695  -0.0784  -0.138   -0.0454  -0.133 
##  9 2008-11-13 00:00:00  0.0333   0.0918   0.0920   0.0233   0.118    0.0277
## 10 2008-11-14 00:00:00 -0.00879 -0.0134   0.00842 -0.0161  -0.0388  -0.0207
## # ... with 2,462 more rows, and 40 more variables: B3SA3 <dbl>, ITSA4 <dbl>,
## #   BBAS3 <dbl>, LREN3 <dbl>, BBDC3 <dbl>, VIVT4 <dbl>, BRFS3 <dbl>,
## #   RADL3 <dbl>, GGBR4 <dbl>, BRKM5 <dbl>, JBSS3 <dbl>, EMBR3 <dbl>,
## #   WEGE3 <dbl>, PCAR4 <dbl>, EQTL3 <dbl>, HYPE3 <dbl>, RENT3 <dbl>,
## #   LAME4 <dbl>, CCRO3 <dbl>, BRML3 <dbl>, EGIE3 <dbl>, SBSP3 <dbl>,
## #   CMIG4 <dbl>, BRAP4 <dbl>, CSNA3 <dbl>, CSAN3 <dbl>, MULT3 <dbl>,
## #   GOAU4 <dbl>, BTOW3 <dbl>, TAEE11 <dbl>, ELET3 <dbl>, USIM5 <dbl>,
## #   ELET6 <dbl>, ENBR3 <dbl>, MRVE3 <dbl>, CYRE3 <dbl>, IGTA3 <dbl>,
## #   MRFG3 <dbl>, CPLE6 <dbl>, GOLL4 <dbl>

Primeiro, vamos trabalhar com dados do Ibovespa:

Dividimos os retornos em três períodos, o primeiro para estimação dos portfólios, o segundo para teste e o terceiro para verificarmos os retornos fora da amostra.

retornos_estim <- retornos[1:823,]

retornos_teste <- retornos[824:1646,]

retornos_backtest <- retornos[1647:2472,]

Gerando os portfólios

Ingênuo

Pesos_Ingênuo <- rep(1/46,46)
names(Pesos_Ingênuo) <- names(retornos[,-1])
Retorno_Ingênuo <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_Ingênuo)
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"

Portfólios Volatility Timing

var <- diag(cov(retornos_estim[,-1]))
wVT_1 <- (1/var)^1/sum((1/var)^1)
wVT_2 <- (1/var)^2/sum((1/var)^2)
wVT_4<- (1/var)^4/sum((1/var)^4)

Pesos_wVT_1 <- as.vector(wVT_1)
Pesos_wVT_2 <- as.vector(wVT_2)
Pesos_wVT_3 <- as.vector(wVT_4)
Retorno_wVT_1 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_1)
Retorno_wVT_2 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_2)
Retorno_wVT_3 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_3)


names(Retorno_wVT_1) <- "Portfólio Volatility Timing - 1"
names(Retorno_wVT_2) <- "Portfólio Volatility Timing - 2"
names(Retorno_wVT_3) <- "Portfólio Volatility Timing - 3"

Portfólio Variância Mínima

PMV <- inv(cov(retornos_estim[,-1])) %*% rep(1, 46)
PMV <- PMV / sum(PMV)
PMV <- as.vector(PMV)
Retorno_PMV <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), PMV)
names(Retorno_PMV) <- "Portfólio Variância Mínima"

Portfólio Tangente

Consideramos o risk_free como 8% ao ano

Risk_free <- (1.08)^(1/252) - 1

PT <- inv(cov(retornos_estim[,-1])) %*% (colMeans(retornos_estim[,-1]) - Risk_free)
PT <- PT / sum(PT)
PT <- as.vector(PT)
Retorno_PT <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), PT)
names(Retorno_PT) <- "Portfólio Tangente"

table.AnnualizedReturns(Backtest)
##                           Portfólio.Ingênuo Portfólio.Tangente
## Annualized Return                    0.0398             0.0666
## Annualized Std Dev                   0.1836           160.0016
## Annualized Sharpe (Rf=0%)            0.2166             0.0004
##                           Portfólio.Volatility.Timing...1
## Annualized Return                                  0.0554
## Annualized Std Dev                                 0.1762
## Annualized Sharpe (Rf=0%)                          0.3144
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                  0.0689
## Annualized Std Dev                                 0.1718
## Annualized Sharpe (Rf=0%)                          0.4013
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                  0.0842
## Annualized Std Dev                                 0.1716
## Annualized Sharpe (Rf=0%)                          0.4907
##                           Portfólio.Variância.Mínima
## Annualized Return                             0.1870
## Annualized Std Dev                            0.1563
## Annualized Sharpe (Rf=0%)                     1.1966

Verificando agora quais portfólios possuem Sharpe inferior ao portfólio ingênuo, já excluindo o Portfólio Tangente pois este veio à falância ao longo do processo:

table.AnnualizedReturns(Backtest)[,1] > table.AnnualizedReturns(Backtest)[,-1]
##                           Portfólio.Tangente Portfólio.Volatility.Timing...1
## Annualized Return                      FALSE                           FALSE
## Annualized Std Dev                     FALSE                            TRUE
## Annualized Sharpe (Rf=0%)               TRUE                           FALSE
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                   FALSE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                           FALSE
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                   FALSE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                           FALSE
##                           Portfólio.Variância.Mínima
## Annualized Return                              FALSE
## Annualized Std Dev                              TRUE
## Annualized Sharpe (Rf=0%)                      FALSE

Percebemos que somente o Portfólio Tangente possui índice de Sharpe inferior ao portfólio ingênuo.

Refazendo os Backtests

Calculando os retornos dos portfólios remanescentes, agora fora da amostra:

Retorno_Ingênuo <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_Ingênuo)
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"
Retorno_wVT_1 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_1)
Retorno_wVT_2 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_2)
Retorno_wVT_3 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_3)


names(Retorno_wVT_1) <- "Portfólio Volatility Timing - 1"
names(Retorno_wVT_2) <- "Portfólio Volatility Timing - 2"
names(Retorno_wVT_3) <- "Portfólio Volatility Timing - 3"
Retorno_PMV <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), PMV)
names(Retorno_PMV) <- "Portfólio Variância Mínima"

table.AnnualizedReturns(Backtest)
##                           Portfólio.Ingênuo Portfólio.Volatility.Timing...1
## Annualized Return                    0.2122                          0.1961
## Annualized Std Dev                   0.2413                          0.2403
## Annualized Sharpe (Rf=0%)            0.8794                          0.8159
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                  0.1707
## Annualized Std Dev                                 0.2321
## Annualized Sharpe (Rf=0%)                          0.7354
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                  0.1226
## Annualized Std Dev                                 0.2131
## Annualized Sharpe (Rf=0%)                          0.5754
##                           Portfólio.Variância.Mínima
## Annualized Return                             0.0405
## Annualized Std Dev                            0.2237
## Annualized Sharpe (Rf=0%)                     0.1810
table.AnnualizedReturns(Backtest)[,1] > table.AnnualizedReturns(Backtest)[,-1]
##                           Portfólio.Volatility.Timing...1
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                            TRUE
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                            TRUE
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                            TRUE
##                           Portfólio.Variância.Mínima
## Annualized Return                               TRUE
## Annualized Std Dev                              TRUE
## Annualized Sharpe (Rf=0%)                       TRUE

Assim, por meio do índice de retorno ajustado ao risco, mais conhecido como índice de Sharpe, concluímos que os portfólios mais elaborados não foram superiores ao portfólio ingênuo na amostra.

Dados do SP100

## # A tibble: 2,516 x 93
##    Datas                   AAPL      ABT     ACN     ADBE      AIG      ALL
##    <dttm>                 <dbl>    <dbl>   <dbl>    <dbl>    <dbl>    <dbl>
##  1 2008-11-03 00:00:00 -0.00587  0.0153  -0.0264  0.0193   0.114    0.0738 
##  2 2008-11-04 00:00:00  0.0370   0.00729  0.0267  0.0711   0.119    0.0376 
##  3 2008-11-05 00:00:00 -0.0718  -0.0220  -0.0525 -0.0688  -0.157   -0.0601 
##  4 2008-11-06 00:00:00 -0.0415  -0.0264  -0.0638 -0.103   -0.0968  -0.0662 
##  5 2008-11-07 00:00:00 -0.00872  0.0286   0.0360  0.00122  0.121    0.0337 
##  6 2008-11-10 00:00:00 -0.0243   0.00145 -0.0162  0.0137   0.0775  -0.0472 
##  7 2008-11-11 00:00:00 -0.0116  -0.00380 -0.0154 -0.0531  -0.00881  0.00311
##  8 2008-11-12 00:00:00 -0.0503  -0.0122  -0.0510 -0.0769  -0.107   -0.0667 
##  9 2008-11-13 00:00:00  0.0678   0.0473   0.0446  0.104    0.0147   0.196  
## 10 2008-11-14 00:00:00 -0.0664  -0.0371  -0.0241 -0.0841   0.00966 -0.0788 
## # ... with 2,506 more rows, and 86 more variables: AMGN <dbl>, AMT <dbl>,
## #   AMZN <dbl>, AXP <dbl>, BA <dbl>, BAC <dbl>, BIIB <dbl>, BK <dbl>,
## #   BKNG <dbl>, BLK <dbl>, BMY <dbl>, BRK.B <dbl>, C <dbl>, CAT <dbl>,
## #   CL <dbl>, CMCSA <dbl>, COF <dbl>, COP <dbl>, COST <dbl>, CRM <dbl>,
## #   CSCO <dbl>, CVS <dbl>, CVX <dbl>, DD <dbl>, DHR <dbl>, DIS <dbl>,
## #   DUK <dbl>, EMR <dbl>, EXC <dbl>, F <dbl>, FDX <dbl>, GD <dbl>, GE <dbl>,
## #   GILD <dbl>, GOOG <dbl>, GOOGL <dbl>, GS <dbl>, HD <dbl>, HON <dbl>,
## #   IBM <dbl>, INTC <dbl>, JNJ <dbl>, JPM <dbl>, KO <dbl>, LLY <dbl>,
## #   LMT <dbl>, LOW <dbl>, MA <dbl>, MCD <dbl>, MDLZ <dbl>, MDT <dbl>,
## #   MET <dbl>, MMM <dbl>, MO <dbl>, MRK <dbl>, MS <dbl>, MSFT <dbl>, NEE <dbl>,
## #   NFLX <dbl>, NKE <dbl>, NVDA <dbl>, ORCL <dbl>, PEP <dbl>, PFE <dbl>,
## #   PG <dbl>, PM <dbl>, QCOM <dbl>, RTX <dbl>, SBUX <dbl>, SLB <dbl>, SO <dbl>,
## #   SPG <dbl>, T <dbl>, TGT <dbl>, TMO <dbl>, TXN <dbl>, UNH <dbl>, UNP <dbl>,
## #   UPS <dbl>, USB <dbl>, V <dbl>, VZ <dbl>, WBA <dbl>, WFC <dbl>, WMT <dbl>,
## #   XOM <dbl>
retornos_estim <- retornos[1:838,]

retornos_teste <- retornos[839:1676,]

retornos_backtest <- retornos[1677:2516,]

Gerando os portfólios

Ingênuo

Pesos_Ingênuo <- rep(1/92,92)
names(Pesos_Ingênuo) <- names(retornos[,-1])
Retorno_Ingênuo <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_Ingênuo)
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"

Portfólios Volatility Timing

var <- diag(cov(retornos_estim[,-1]))
wVT_1 <- (1/var)^1/sum((1/var)^1)
wVT_2 <- (1/var)^2/sum((1/var)^2)
wVT_4<- (1/var)^4/sum((1/var)^4)

Pesos_wVT_1 <- as.vector(wVT_1)
Pesos_wVT_2 <- as.vector(wVT_2)
Pesos_wVT_3 <- as.vector(wVT_4)
Retorno_wVT_1 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_1)
Retorno_wVT_2 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_2)
Retorno_wVT_3 <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), Pesos_wVT_3)


names(Retorno_wVT_1) <- "Portfólio Volatility Timing - 1"
names(Retorno_wVT_2) <- "Portfólio Volatility Timing - 2"
names(Retorno_wVT_3) <- "Portfólio Volatility Timing - 3"

Portfólio Variância Mínima e PT

risk_free <- (1.05)^(1/252) - 1

Data = timeSeries(ts(retornos_estim[,-1], frequency=12, start=c(2010,1)))

(ndm=dim(Data))
## [1] 838  92
Spec = portfolioSpec() #Novo portf´olio
setTargetReturn(Spec) = mean(colMeans(Data,na.rm=T))
#barplot(colMeans(Data))
setRiskFreeRate(Spec) =  risk_free
setNFrontierPoints(Spec) = 50 # padrão 50
Constraints = "NULL" 

PMV=minvariancePortfolio(Data, Spec, Constraints)
PT=tangencyPortfolio(Data, Spec, Constraints)

PMV<- getWeights(PMV)
PT <- getWeights(PT)
Retorno_PMV <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), PMV)
names(Retorno_PMV) <- "Portfólio Variância Mínima"

Portfólio Tangente

Consideramos o risk_free como 8% ao ano

Retorno_PT <- Return.portfolio(xts(retornos_teste[,-1], retornos_teste$Datas), PT)
names(Retorno_PT) <- "Portfólio Tangente"

table.AnnualizedReturns(Backtest)
##                           Portfólio.Ingênuo Portfólio.Tangente
## Annualized Return                    0.1753             0.1619
## Annualized Std Dev                   0.1209             0.2012
## Annualized Sharpe (Rf=0%)            1.4496             0.8045
##                           Portfólio.Volatility.Timing...1
## Annualized Return                                  0.1591
## Annualized Std Dev                                 0.1075
## Annualized Sharpe (Rf=0%)                          1.4811
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                  0.1387
## Annualized Std Dev                                 0.1001
## Annualized Sharpe (Rf=0%)                          1.3850
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                  0.1047
## Annualized Std Dev                                 0.0963
## Annualized Sharpe (Rf=0%)                          1.0865
##                           Portfólio.Variância.Mínima
## Annualized Return                             0.0955
## Annualized Std Dev                            0.0977
## Annualized Sharpe (Rf=0%)                     0.9769

Verificando agora quais portfólios possuem Sharpe inferior ao portfólio ingênuo, já excluindo o Portfólio Tangente pois este veio à falância ao longo do processo:

table.AnnualizedReturns(Backtest)[,1] > table.AnnualizedReturns(Backtest)[,-1]
##                           Portfólio.Tangente Portfólio.Volatility.Timing...1
## Annualized Return                       TRUE                            TRUE
## Annualized Std Dev                     FALSE                            TRUE
## Annualized Sharpe (Rf=0%)               TRUE                           FALSE
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                            TRUE
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                            TRUE
##                           Portfólio.Variância.Mínima
## Annualized Return                               TRUE
## Annualized Std Dev                              TRUE
## Annualized Sharpe (Rf=0%)                       TRUE

Percebemos que somente o Volatility Timing 1 possui índice de Sharpe superior ao portfólio ingênuo.

Refazendo os Backtests

Calculando os retornos dos portfólios remanescentes, agora fora da amostra:

Retorno_Ingênuo <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_Ingênuo)
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"
Retorno_wVT_1 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_1)
Retorno_wVT_2 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_2)
Retorno_wVT_3 <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), Pesos_wVT_3)


names(Retorno_wVT_1) <- "Portfólio Volatility Timing - 1"
names(Retorno_wVT_2) <- "Portfólio Volatility Timing - 2"
names(Retorno_wVT_3) <- "Portfólio Volatility Timing - 3"
Retorno_PMV <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Datas), PMV)
names(Retorno_PMV) <- "Portfólio Variância Mínima"

table.AnnualizedReturns(Backtest)
##                           Portfólio.Ingênuo Portfólio.Volatility.Timing...1
## Annualized Return                    0.1077                          0.0960
## Annualized Std Dev                   0.1347                          0.1164
## Annualized Sharpe (Rf=0%)            0.7992                          0.8251
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                  0.0897
## Annualized Std Dev                                 0.1083
## Annualized Sharpe (Rf=0%)                          0.8281
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                  0.0886
## Annualized Std Dev                                 0.1080
## Annualized Sharpe (Rf=0%)                          0.8208
##                           Portfólio.Variância.Mínima
## Annualized Return                             0.1053
## Annualized Std Dev                            0.1143
## Annualized Sharpe (Rf=0%)                     0.9216
table.AnnualizedReturns(Backtest)[,1] > table.AnnualizedReturns(Backtest)[,-1]
##                           Portfólio.Volatility.Timing...1
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                           FALSE
##                           Portfólio.Volatility.Timing...2
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                           FALSE
##                           Portfólio.Volatility.Timing...3
## Annualized Return                                    TRUE
## Annualized Std Dev                                   TRUE
## Annualized Sharpe (Rf=0%)                           FALSE
##                           Portfólio.Variância.Mínima
## Annualized Return                               TRUE
## Annualized Std Dev                              TRUE
## Annualized Sharpe (Rf=0%)                      FALSE

No caso do SP100, percebe-se que os portfólios foram capazes de produzir retornos ajustados ao risco superiores ao portfólio ingênuo, o que é estranho,uma vez que o mercado americano normalmente é mais eficiente do que o mercado brasileiro. Isso demonstraria, também, que portfólios “aleatórios” podem superar estratégias pela simples sorte e aleatoriedade dos mercados.

###Kenneth French (para S%P e KF) #Import Dataset -> from txt (reader) -> F-F_Research_Data_5_Factors_2x3_daily fat_rf_KNa <- F_F_Research_Data_5_Factors_2x3_daily head(fat_rf_KNa) meses_ft_rf_KN<-fat_rf_KNa$X1 fat_rf_KN <- fat_rf_KNa[,-1] meses_ft_rf_KN<-ymd(meses_ft_rf_KN) fat_rf_KN<-data.frame(fat_rf_KN) rownames(fat_rf_KN)=meses_ft_rf_KN head(fat_rf_KN) dim(fat_rf_KN)

###NEFIN (para IBOVESPA) #Import Dataset -> from Excel -> FatoresRF fat_rf_Nefina <- FatoresRF dias1 <- fat_rf_Nefina[,1:3] head(dias1) fat_rf_Nefinb <- fat_rf_Nefina[,-1] fat_rf_Nefinc <- fat_rf_Nefinb[,-1] fat_rf_Nefin <- fat_rf_Nefinc[,-1] head(fat_rf_Nefin) #install.packages(“tidyverse”) library(tidyverse) library(lubridate)

dias2 <- dias1 %>% mutate(date = make_date(year, month, day))

head(dias2) dias3<-dias2[,-1] dias4<-dias3[,-1] dias<-dias4[,-1] head(dias)

dias<-as.Date(dias$date,format=“%Y/%m/%d”)

fat_rf_Nefin<-data.frame(fat_rf_Nefin) rownames(fat_rf_Nefin)=dias head(fat_rf_Nefin)

dim(fat_rf_Nefin) dim(ret_ibovespa)

Conclusões

Embora não tenhamos conseguido replicar o artigo como um todo, obtivemos resultados divergentes.

Como expresso nas linhas acima, não fomos capazes de realizar os testes utilizando os fatores de risco por desconhecimento dos autores deste código, embora os tenhamos tratado para tentativas.

Como críticas ao paper, destacamos que, mesmo com os ajustes do autor original, os portfólios são muito pouco replicáveis pela grande quantitade de ativos que foram trabalhos. Além disso, o autor não cita qual a frequência do rebalanceamento dos ativos, mas conclui-se que ocorreu pela presença do turnover.