De acordo com o manual de referência do pacote PerformanceAnalytics, “qualquer período no qual os retornos acumulados de um ativo caem em relação ao retorno acumulado máximo, configura-se um drawdown.” Ainda, “drawdowns são medidos como uma porcentagem deste retorno acumulado máximo, em efeito, medido desde o pico do ativo”.
Nesse post, levantaremos os drawdowns do Ibovespa desde 1995, ou seja, após o Plano Real, a partir do qual a hiperinflação deixou de afetar sistematicamente o valor dos ativos nacionais.
A importância de estudar drawdowns reside na ideia de que o passado pode fornecer pistas sobre o futuro, neste caso, sobre os riscos a que está sujeito o patrimônio do investidor exposto, por exemplo, a ETFs que buscam replicar o desempenho do Ibovespa.
Para tanto, usaremos o pacote PerformanceAnalytics, de Brian G. Peterson e colaboradores.
Primeiro, prepararemos o ambiente de trabalho…
# limpar o ambiente de trabalho
rm(list = ls())
# deletar gráficos anteriormente criados
graphics.off()
# desativar pacotes previamente em uso
lapply(names(sessionInfo()$otherPkgs), function(pkgs)
detach(
paste0('package:', pkgs),
character.only = T,
unload = T,
force = T
))
# instalar (se necessário) e carregar os pacotes que serão utilizados
if (!require("pacman")) install.packages("pacman")
p_load(tidyquant, tidyverse, ggthemes, scales, knitr, kableExtra)
… para em seguida importar os dados do site Yahoo Finance:
# importar dados
ibov1995 <- tq_get("^BVSP", from = "1995-01-01", get = "stock.prices")
kable(head(ibov1995), digits = 0) %>%
kable_styling("striped", "bordered")
symbol | date | open | high | low | close | volume | adjusted |
---|---|---|---|---|---|---|---|
^BVSP | 1995-01-02 | 4354 | 4398 | 4300 | 4301 | 0 | 4301 |
^BVSP | 1995-01-03 | 4370 | 4386 | 4094 | 4098 | 0 | 4098 |
^BVSP | 1995-01-04 | 4098 | 4098 | 3861 | 3968 | 0 | 3968 |
^BVSP | 1995-01-05 | 3968 | 4040 | 3944 | 4037 | 0 | 4037 |
^BVSP | 1995-01-06 | 4037 | 4106 | 3813 | 3827 | 0 | 3827 |
^BVSP | 1995-01-09 | 3827 | 3836 | 3570 | 3628 | 0 | 3628 |
Na continuidade, converteremos os preços ajustados (coluna adjusted, acima) em retornos diários:
# calcular retornos diários
ibov1995_daily <- ibov1995 %>%
tq_transmute(adjusted, periodReturn, period = "daily", col_rename = "return")
kable(head(ibov1995_daily), digits = 4) %>%
kable_styling("striped", "bordered")
date | return |
---|---|
1995-01-02 | 0.0000 |
1995-01-03 | -0.0472 |
1995-01-04 | -0.0317 |
1995-01-05 | 0.0173 |
1995-01-06 | -0.0518 |
1995-01-09 | -0.0522 |
Como o pacote PerformanceAnalytics requer o uso de dados de séries temporais (na maior parte das vezes, objetos de classe ts, xts ou zoo), converteremos nosso objeto de classe tibble em zoo.
# converter tibble em zoo
class(ibov1995_daily)
## [1] "tbl_df" "tbl" "data.frame"
ibov1995_daily_zoo <- ibov1995_daily %>%
read.zoo()
class(ibov1995_daily_zoo)
## [1] "zoo"
Drawdowns têm uma duração total, compreendida pela duração da profundidade (período de queda) e da recuperação (intervalo de alta). Com base nisso, podemos extrair parâmetros que sintetizam drawdowns (no caso, médias):
# retornar parâmetros médios de drawdowns
averages <- tibble(
"Parâmetro" = c("Duração Média do Drawdown",
"Duração Média da Recuperação",
"Drawdown Médio"),
"Valor" = c(AverageLength(ibov1995_daily_zoo),
AverageRecovery(ibov1995_daily_zoo),
AverageDrawdown(ibov1995_daily_zoo))
)
kable(head(averages)) %>%
kable_styling("striped", "bordered")
Parâmetro | Valor |
---|---|
Duração Média do Drawdown | 38.9940120 |
Duração Média da Recuperação | 26.2155689 |
Drawdown Médio | 0.0486941 |
Drawdowns duraram em média 39 dias, levaram aproximadamente 26 dias para completarem a recuperação e, considerando todas as quedas no período, o Ibovespa perdeu quase 5% de seu valor de pico. Mas, como sabemos, a média pode significar muito pouco, pois os valores extremos podem diferir muito dela, e os investidores estão, de fato, mais interessados nas maiores quedas. O drawdown máximo pode ser obtido rapidamente com a função abaixo:
# retornar máximo drawdown
maximum <- ibov1995_daily %>%
tq_performance(Ra = return, performance_fun = maxDrawdown)
kable(head(maximum)) %>%
kable_styling("striped", "bordered")
maxDrawdown.1 |
---|
0.6503635 |
Antes de investir todo o seu patrimônio em renda variável brasileira, faça a você mesmo(a) a seguinte pergunta: você aguentaria 65% de queda? Suportaria, por exemplo, R$ 100 mil se transformar em R$ 35 mil (ou R$ 1 milhão virar R$ 350 mil)? Por outro lado, a duração da queda e da recuperação são tão importantes quanto a perda em si. A função table.Drawdowns() cria uma tabela com parâmetros para os piores drawdowns. Podemos controlar o número de elementos que desejamos obter. O padrão são os 5 piores:
# retornar tabela com os piores drawdowns
table <- table.Drawdowns(ibov1995_daily_zoo)
kable(head(table)) %>%
kable_styling("striped", "bordered")
From | Trough | To | Depth | Length | To Trough | Recovery |
---|---|---|---|---|---|---|
1997-07-10 | 1998-09-10 | 1999-11-26 | -0.6504 | 591 | 293 | 298 |
2008-05-21 | 2008-10-27 | 2017-09-11 | -0.5996 | 2305 | 112 | 2193 |
2000-03-28 | 2002-10-16 | 2003-11-14 | -0.5583 | 904 | 634 | 270 |
1995-01-03 | 1995-03-09 | 1995-08-07 | -0.5028 | 146 | 44 | 102 |
2020-01-24 | 2020-03-23 | 2021-01-06 | -0.4682 | 235 | 40 | 195 |
O pior drawdown teve início em 1997, época da crise asiática, e levou 591 dias para a recuperação total (aproximadamente 1 ano e meio). Mas houve um drawdown muito pior, em termos de duração da recuperação: o da crise do subprime norte-americano. A perda foi parecida, de aproximadamente 60%, mas a duração foi muito pior, tendo levado ao todo 2.305 dias (pouco mais que 6 anos!). Então, na verdade, a pergunta deve ser essa: você aguentaria perder mais da metade do seu patrimônio, e levar mais de 6 anos para recuperar o dinheiro?
Outra forma de olhar para drawdowns é por meio de gráficos. A função chart.Drawdown() faz isso facilmente:
# gráfico de drawdowns
chart.Drawdown(ibov1995_daily_zoo, geometric = TRUE, plot.engine = "plotly")
O gráfico é interativo, o que significa que você pode “brincar” com ele de diversas formas nos botões acima do eixo x. Ao passar o botão do mouse acima do gráfico, é possível visualizar a data e a queda até aquele período do último pico.
Por fim, selecionaremos as datas trazidas pela função table.Drawdowns() e coloriremos um gráfico do Ibovespa com as 5 piores quedas (de vermelho), suas respectivas recuperações (de laranja), e os momentos em que o Ibovespa deixou o último drawdown para trás (de verde).
### gráfico com os 5 piores drawdowns
ibov1995_daily %>%
left_join(ibov1995 %>% select(date, close)) %>%
mutate(color = case_when(date >= '1995-01-03' & date <= '1995-03-09' ~ "red",
date >= '1997-07-10' & date <= '1998-09-10' ~ "red",
date >= '2000-03-28' & date <= '2002-10-16' ~ "red",
date >= '2008-05-21' & date <= '2008-10-27' ~ "red",
date >= '2020-01-24' & date <= '2020-03-23' ~ "red",
date > '1995-03-09' & date <= '1995-08-07' ~ "orange",
date > '1998-09-10' & date <= '1999-11-26' ~ "orange",
date > '2002-10-16' & date <= '2003-11-14' ~ "orange",
date > '2008-10-27' & date <= '2017-09-11' ~ "orange",
date > '2020-03-23' & date <= '2021-01-06' ~ "orange",
TRUE ~ "green")) %>%
ggplot(aes(x = date, y = close, color = color, group = 1)) +
geom_line() +
theme_economist_white() +
scale_color_manual(values = c("green4","orange","red")) +
labs(x = "Ano", y = "Cotação de fechamento",
title = "Drawdowns do Ibovespa desde 1995 ") +
theme(legend.position = "none") +
scale_y_continuous(labels = comma)