Carregando os retornos (fonte economática):
retornos <- read_excel("Retornos_prova_2.xlsx")
summary(retornos[,-1])
## RADL3 RENT3 SANB11
## Min. :-0.1283478 Min. :-0.234218 Min. :-0.134740
## 1st Qu.:-0.0108766 1st Qu.:-0.012025 1st Qu.:-0.012464
## Median : 0.0003805 Median : 0.001069 Median : 0.001094
## Mean : 0.0009523 Mean : 0.001946 Mean : 0.001198
## 3rd Qu.: 0.0122921 3rd Qu.: 0.015767 3rd Qu.: 0.015108
## Max. : 0.0924855 Max. : 0.268212 Max. : 0.134101
## SBSP3 SULA11 TAEE11
## Min. :-0.1782996 Min. :-0.175539 Min. :-0.0830848
## 1st Qu.:-0.0127835 1st Qu.:-0.011823 1st Qu.:-0.0081272
## Median : 0.0012151 Median : 0.000000 Median : 0.0005171
## Mean : 0.0007828 Mean : 0.001253 Mean : 0.0011165
## 3rd Qu.: 0.0135266 3rd Qu.: 0.014010 3rd Qu.: 0.0093364
## Max. : 0.1746032 Max. : 0.175989 Max. : 0.0873216
## TIMS3 TOTS3 UGPA3
## Min. :-0.1477707 Min. :-0.1534360 Min. :-2.136e-01
## 1st Qu.:-0.0108992 1st Qu.:-0.0111026 1st Qu.:-1.155e-02
## Median : 0.0000000 Median : 0.0008958 Median : 0.000e+00
## Mean : 0.0007316 Mean : 0.0013619 Mean : 1.747e-05
## 3rd Qu.: 0.0120000 3rd Qu.: 0.0139104 3rd Qu.: 1.145e-02
## Max. : 0.0996310 Max. : 0.1979961 Max. : 2.338e-01
## USIM5 VALE3 VIVT3
## Min. :-0.212329 Min. :-0.245236 Min. :-0.123589
## 1st Qu.:-0.016490 1st Qu.:-0.011914 1st Qu.:-0.008732
## Median : 0.000000 Median : 0.001653 Median : 0.000000
## Mean : 0.002686 Mean : 0.002224 Mean : 0.000636
## 3rd Qu.: 0.020370 3rd Qu.: 0.016129 3rd Qu.: 0.010060
## Max. : 0.227545 Max. : 0.213579 Max. : 0.123216
## WEGE3 YDUQ3
## Min. :-0.206198 Min. :-0.2517442
## 1st Qu.:-0.010805 1st Qu.:-0.0165485
## Median : 0.001775 Median : 0.0008683
## Mean : 0.001802 Mean : 0.0016413
## 3rd Qu.: 0.013349 3rd Qu.: 0.0192366
## Max. : 0.138945 Max. : 0.2373646
Primeiro, vamos selecionar 6 ativos da amostra inicial e depois utilizar uma fração da amostra para estimação e o restante para o backtesting. O período até 30/06/2020 será utilizado para estimar os parâmetros (covariância e desvio-padrão) dos ativos e o período posterior será utilizado para avaliar os retornos com rebalanceamento anual(pacote do R não permite semestral).
retornos_estim <- retornos %>% select(Data, RADL3, RENT3, SANB11, SULA11, TAEE11, TIMS3) %>% dplyr::filter(Data >= "2016-01-01" & Data <= "2019-06-30")
retornos_backtest <- retornos %>% select(Data, RADL3, RENT3, SANB11, SULA11, TAEE11, TIMS3) %>% dplyr::filter(Data >= "2019-07-01" & Data <= "2021-12-31")
Primeiro, criamos o portfólio de Timing de Volatilidade, utilizaremos a matriz de covariâncias para o input dos parâmetros:
var <- diag(cov(retornos_estim[,-1]))
wVT <- (1/var)^6/sum((1/var)^6)
Pesos_wVT <- as.vector(wVT)
names(Pesos_wVT) <- names(wVT)
Pesos_wVT
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3
## 0.19536307 0.01266221 0.02357298 0.03774627 0.58635095 0.14430452
Agora, calculamos os retornos utilizando Return.portfolio:
Retorno_wVT <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Data), Pesos_wVT, rebalance_on = c("years"))
names(Retorno_wVT) <- "Portfólio Volatility Timing"
Pesos_Ingênuo <- rep(1/6,6)
names(Pesos_Ingênuo) <- names(wVT)
Pesos_Ingênuo
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3
## 0.1666667 0.1666667 0.1666667 0.1666667 0.1666667 0.1666667
Retorno_Ingênuo <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Data), Pesos_Ingênuo, rebalance_on = c("years"))
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"
table.AnnualizedReturns(Backtest, scale = 252, Rf = (1+0.0488)^(1/252)-1)
## Portfólio.Volatility.Timing Portfólio.Ingênuo
## Annualized Return 0.3072 0.2035
## Annualized Std Dev 0.2289 0.2999
## Annualized Sharpe (Rf=4.77%) 1.0767 0.4919
Assim, por meio dos parâmetros estipulados pela função table.AnnualizedReturns e pela análise visual dos gráficos, percebemos que ao longo do tempo o portfólio de Timing de Volatilidade apresentou, ao longo da amostra, uma rentabilidade muito próxima ao do Portfólio Ingênuo, porém com menores Drawdowns e também com menor risco. Assim, com base nessas amostras, podemos concluir que a estratégia mais elaborada de alocação de ativos nesse caso foi capaz de superar, em termos de Risco x Retorno, uma estratégia mais simples.
Em linha com o primeiro exercício, utilizaremos os mesmos períodos para estimação e para realização do backtesting, porém agora utilizar-se-á de mais ativos:
retornos_estim <- retornos %>% select(Data, RADL3, RENT3, SANB11, SULA11, TAEE11, TIMS3, TOTS3, UGPA3, USIM5) %>% dplyr::filter(Data >= "2016-01-01" & Data <= "2019-06-30")
retornos_backtest <- retornos %>% select(Data, RADL3, RENT3, SANB11, SULA11, TAEE11, TIMS3, TOTS3, UGPA3, USIM5) %>% dplyr::filter(Data >= "2019-07-01" & Data <= "2021-12-31")
var <- diag(cov(retornos_estim[,-1]))
wVT <- (1/var)^6/sum((1/var)^6)
Pesos_wVT <- as.vector(wVT)
names(Pesos_wVT) <- names(wVT)
Pesos_wVT
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3
## 1.740805e-01 1.128280e-02 2.100497e-02 3.363424e-02 5.224747e-01 1.285842e-01
## TOTS3 UGPA3 USIM5
## 5.123866e-02 5.765552e-02 4.444512e-05
Retorno_wVT <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Data), Pesos_wVT, rebalance_on = c("years"))
names(Retorno_wVT) <- "Portfólio Volatility Timing"
Pesos_Ingênuo <- rep(1/9,9)
names(Pesos_Ingênuo) <- names(wVT)
Pesos_Ingênuo
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3 TOTS3 UGPA3
## 0.1111111 0.1111111 0.1111111 0.1111111 0.1111111 0.1111111 0.1111111 0.1111111
## USIM5
## 0.1111111
Retorno_Ingênuo <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Data), Pesos_Ingênuo, rebalance_on = c("years"))
names(Retorno_Ingênuo) <- "Portfólio Ingênuo"
retornos_ts <- xts(retornos_backtest[,-1], retornos_backtest$Data)
Mport <- portfolio.spec( assets = colnames(retornos_ts))
Mport <- add.constraint( portfolio=Mport, type='box', min = 0, max=1 )
ObjSpec = add.objective( portfolio = Mport , type="risk",name="CVaR",
arguments=list(p=0.95,clean="boudt"), enabled=TRUE)
ObjSpec <- add.constraint(portfolio=ObjSpec, type="weight_sum",
min_sum=1.00, max_sum=1.00)
set.seed(15)
.storage <- new.env()
out <- optimize.portfolio(R=retornos_ts, portfolio=ObjSpec,
optimize_method="DEoptim", search_size=2000,
traceDE=5, itermax=50, trace=TRUE)
print(out)
## ***********************************
## PortfolioAnalytics Optimization
## ***********************************
##
## Call:
## optimize.portfolio(R = retornos_ts, portfolio = ObjSpec, optimize_method = "DEoptim",
## search_size = 2000, trace = TRUE, traceDE = 5, itermax = 50)
##
## Optimal Weights:
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3 TOTS3 UGPA3 USIM5
## 0.386 0.034 0.002 0.028 0.546 0.000 0.000 0.002 0.002
##
## Objective Measures:
## CVaR
## 0.03503
out$weights
## RADL3 RENT3 SANB11 SULA11 TAEE11 TIMS3 TOTS3 UGPA3 USIM5
## 0.386 0.034 0.002 0.028 0.546 0.000 0.000 0.002 0.002
Pesos_CVaR <- out$weights
names(Pesos_CVaR) <- names(wVT)
Retorno_CVaR <- Return.portfolio(xts(retornos_backtest[,-1], retornos_backtest$Data), Pesos_CVaR, rebalance_on = c("years"))
names(Retorno_CVaR) <- "Portfólio CVaR"
table.AnnualizedReturns(Backtest, scale = 252, Rf = (1+0.0488)^(1/252)-1)
## Portfólio.Volatility.Timing Portfólio.Ingênuo
## Annualized Return 0.3046 0.2677
## Annualized Std Dev 0.2390 0.3256
## Annualized Sharpe (Rf=4.77%) 1.0206 0.6410
## Portfólio.CVaR
## Annualized Return 0.3621
## Annualized Std Dev 0.2440
## Annualized Sharpe (Rf=4.77%) 1.2245
Pelos resultados, percebe-se que a estratégia mais elaborada foi a que obteve o melhor rendimento dentro do período analisando e da amostra dos ativos escolhidos. A estratégia de menor risco sendo a de Volatility Timing, seguida pelo portfólio CVaR e, com maior risco, o Portfólio Ingênuo. Portanto, contradizendo um pouco a teoria de finanças, nesse caso o investidor individual estaria melhor atendido por estratégias mais complexas.