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,]
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"
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"
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"
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.
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.
## # 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,]
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"
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"
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"
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.
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)
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.