Questão 1

1) Compare e analise a simulação de Backtesting semestral comparando uma carteira ativa e passiva, você pode definir a mesma da melhor forma que encontrar, mas explique bem como será formulada, e compare com o investimento ingênuo, para 6 ativos de sua preferência. Analise os resultados.

Utilizaremos o Índice IBRX100 como carteira passiva e desenvolveremos um método que fornece um maior maior peso para aqueles ativos que tiveram um retorno nos últimos meses maior. Matematicamente,

\[w_i = \frac{(n + 1 - P_i)}{\sum_{i = 1}^{n}P_i}\] Em que \(n\) é o número de ativos na amostra e \(P_i\) é a posição (\(1, 2, 3, ..., n\)) de determinado ativo em uma lista ordenada de forma decrescente com base no retorno dos últimos 12 meses.

Assim, sem mais delongas, apresentamos nossa base de dados:

dados <- read_excel("Prova2.xlsx")
## tibble[,12] [2,720 x 12] (S3: tbl_df/tbl/data.frame)
##  $ Data : POSIXct[1:2720], format: "2010-01-04" "2010-01-05" ...
##  $ IBRX : num [1:2720] 0.02224 0.00226 0.00662 -0.00336 -0.00224 ...
##  $ ABCB4: num [1:2720] 0.05827 0.02672 0.01656 -0.01474 -0.00787 ...
##  $ ABEV3: num [1:2720] 0.03729 0.00588 0.0102 0.0047 -0.00192 ...
##  $ BTOW3: num [1:2720] -0.027 -0.0239 0.011 0.0113 -0.0239 ...
##  $ B3SA3: num [1:2720] 0.05714 0.00386 0.03769 0.02372 -0.02317 ...
##  $ BPAN4: num [1:2720] 0.0212 0.0432 0.0216 0.0265 0.0137 ...
##  $ BBRK3: num [1:2720] -0.01852 -0.0173 0.0272 0.00467 -0.0062 ...
##  $ BRML3: num [1:2720] 0.00465 0.01852 0.04545 -0.01304 -0.00881 ...
##  $ BBDC4: num [1:2720] 0.03628 -0.00492 -0.008 -0.00269 -0.00108 ...
##  $ BRAP3: num [1:2720] -0.005 0.00503 0.01 0.01238 0.01222 ...
##  $ BBAS3: num [1:2720] 0.006734 -0.010033 0.001351 0.000337 0.005734 ...

Delimitamos nossa amostra para trabalharmos apenas com 6 ativos.

questao1 <- dados[,c(1,3:8)]

Portfólio Ingênuo

Calculamos o retorno do portfólio ingênuo. Poderíamos utilizar a função “Return.Portfolio”, entretanto, ela não disponibiliza um argumento para fazer o rebalanceamento semestral. Assim, criamos nossa própria função para tal.

backtest <- function(inicio_estim, fim_estim, inicio_aval, fim_aval){

dados_aval <- questao1 %>% dplyr::filter(Data > inicio_aval & Data <= fim_aval) 

dados_aval <- xts(dados_aval[,-1], dados_aval$Data)

pesos <- rep(1/6, 6)

retorno_port <- Return.portfolio(dados_aval, weights = pesos)

}
argumentos <- function(periodo_estim, hold_period){
  vetor_estim_inicial <- ymd(20121231) %m-% months(periodo_estim) %m+% months(0:200)
  vetor_estim_final <- ymd(20121231) %m+% months(0:200)
  vetor_aval_inicial <- ymd(20121231) %m+% months(0:200)
  vetor_aval_final <- ymd(20121231) %m+% months(hold_period + 0:200)
  
  vetor_estim_inicial <- vetor_estim_inicial[seq(from = 1, to = length(vetor_estim_inicial), by = hold_period)]
  vetor_estim_final <- vetor_estim_final[seq(from = 1, to = length(vetor_estim_final), by = hold_period)]
  vetor_aval_inicial <- vetor_aval_inicial[seq(from = 1, to = length(vetor_aval_inicial), by = hold_period)]
  vetor_aval_final <- vetor_aval_final[seq(from = 1, to = length(vetor_aval_final), by = hold_period)]
  
  vetor_estim_inicial <- vetor_estim_inicial[1:(interval(ymd(20121231), ymd(20201231)) %/% months(hold_period))]
  vetor_estim_final <- vetor_estim_final[1:(interval(ymd(20121231), ymd(20201231)) %/% months(hold_period))]
  vetor_aval_inicial <- vetor_aval_inicial[1:(interval(ymd(20121231), ymd(20201231)) %/% months(hold_period))]
  vetor_aval_final <- vetor_aval_final[1:(interval(ymd(20121231), ymd(20201231)) %/% months(hold_period))]
  
  estrategia_retornos <- list()
  for(i in 1:length(vetor_aval_final)){
    estrategia_retornos[[i]] <- backtest(inicio_estim = vetor_estim_inicial[i],
                                         fim_estim = vetor_estim_final[i],
                                         inicio_aval = vetor_aval_inicial[i],
                                         fim_aval = vetor_aval_final[i])}
  
  estrategia_retornos <- unlist(estrategia_retornos)
  
  tempo <-  dados %>% filter(Data > vetor_aval_inicial[1] & Data <= vetor_aval_final[length(vetor_aval_final)])
  
  estrategia_retornos <- xts(estrategia_retornos, tempo$Data)
  
  estrategia_retornos
  
}
port_ing <- argumentos(12,6)

Portfólio “Tilted Towards Momentum”

backtest <- function(inicio_estim, fim_estim, inicio_aval, fim_aval){

dados_estim <- questao1 %>% dplyr::filter(Data > inicio_estim & Data <= fim_estim) %>% select(!Data)

ret_acumul <- apply(dados_estim, 2, function(x) prod(x + 1) - 1)
ret_acumul <- as.data.frame(ret_acumul)
ret_acumul<- ret_acumul[order(-ret_acumul$ret_acumul),,drop = FALSE]
ret_acumul$ordem <- 1:6

pesos <- (7 - ret_acumul$ordem)/sum(ret_acumul$ordem)
names(pesos) <- rownames(ret_acumul)

dados_aval <- questao1 %>% dplyr::filter(Data > inicio_aval & Data <= fim_aval)
dados_aval <- dados_aval %>% select(Data, names(pesos))
dados_aval <- xts(dados_aval[,-1], dados_aval$Data)


retorno_port <- Return.portfolio(dados_aval, weights = pesos)


}
port_ttm <- argumentos(12,6)

Análise dos resultados

Desse modo, temos o IBRX como nosso portfólio passivo, a estratégia “Tilted Towards Momentum” como nosso portfólio ativo e o portfólio ingênuo para termos uma ideia da relação simplicidade e performance. Assim, apresentamos, agora, o resultado desses portfólios:

##                             IBRX Ingênuo    TTM
## Annualized Return         0.1114  0.1487 0.1961
## Annualized Std Dev        0.2515  0.2920 0.3036
## Annualized Sharpe (Rf=0%) 0.4429  0.5092 0.6458

Questão 2

2) Mostrar uma análise de desempenho obtido por Backtesting de estratégias, volatility timing, ingênua e uma carteira com paridade baseada em risco.

Agora, trabalhamos com nossa amostra completa de ativos excluindo o IBRX apenas.

questao2 <- dados[,-2]

Além disso, iremos dividir nossa base de dados em um período de estimação e um período de avaliação.

questao2_estim <- questao2["/2017"]
questao2_aval <- questao2["2018/"]

Ingênua

Criamos uma carteira em que cada ativo recebe o mesmo peso e é rebalanceada trimestralmente.

pesos_ing <- rep(0.1, 10)

ret_port2 <- Return.portfolio(questao2_aval, pesos_ing)

Volatility Timing`

var <- apply(questao2_estim, 2, function(x) var(x, na.rm = TRUE))

pesos_vt <- (1/var)^4/sum((1/var)^4)

port_vt <- Return.portfolio(questao2_aval, pesos_vt, rebalance_on = "quarters")

CVar

Mport <- portfolio.spec( assets = colnames(questao2_estim))

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=0.99, max_sum=1.01)
set.seed(15)
out <- optimize.portfolio(R=questao2_estim, portfolio=ObjSpec,
  optimize_method="DEoptim", search_size=2000,
  traceDE=5, itermax=50, trace=TRUE)
## ***********************************
## PortfolioAnalytics Optimization
## ***********************************
## 
## Call:
## optimize.portfolio(R = questao2_estim, portfolio = ObjSpec, optimize_method = "DEoptim", 
##     search_size = 2000, trace = TRUE, traceDE = 5, itermax = 50)
## 
## Optimal Weights:
## ABCB4 ABEV3 BTOW3 B3SA3 BPAN4 BBRK3 BRML3 BBDC4 BRAP3 BBAS3 
## 0.156 0.598 0.000 0.100 0.062 0.010 0.072 0.000 0.000 0.000 
## 
## Objective Measures:
##    CVaR 
## 0.02535

Apresentamos o gráfico de pesos,

Assim, com os pesos em mãos, podemos calcular o retorno do portfólio otimizado.

port_cvar <- Return.portfolio(questao2_aval, out$weights, rebalance_on = "months")

Realizando uma comparação com todas as outras estratégias,

##                           Ingênuo Volatility Timing   CVar
## Annualized Return          0.2780           -0.0324 0.0596
## Annualized Std Dev         0.3755            0.3140 0.2972
## Annualized Sharpe (Rf=0%)  0.7404           -0.1030 0.2006