Medidas de Risco e Volatilidade - Índice Ibovespa

Introdução e Problema

Os veículos de comunicação têm noticiado durante o ano de 2020 fortes quedas na bolsa de valores do mundo todo e em particular da B3. Em virtude disso, torna-se importante investigarmos com maior detalhes que informações podemos obter desse movimento. Qual é a volatilidade no período? Ela é a maior já experimentada na série histórica? Qual o tempo médio de recuperação em movimentos similares a esse? Nesse sentido, faremos uso das ferramentas utilizadas no mercado para dar algumas dessas possíveis respostas.

Medidas de Risco e Volatilidade

O intuito desse post é levantar as medidas de risco disponível. Nesse sentido, não iremos aprofundar a discussão sobre a diferença entre risco e incerteza, tal como apresentada na teoria keynesiana. Acerca dessas medidas de risco e volatilidade, iremos utilizar duas métricas. A primeira é o drawdown, que informa a queda percentual máxima desde o último pico no preço das ações. A segunda é a Volatilidade, que é de maneira simples e direta o grau de oscilação percentual que temos no preço desses mesmos ativos.

Drawdown

Vamos aqui conceituar o Drawdown. Ela é a medida da queda percentual partindo de um pico histórico no preço de um ativo. Matematicamente ele pode ser expresso por: \[D(T)=\max\left[\max_{t\in(0,T)}X(t)-X(T),0\right]\] onde: \(D(T)\) é a medida de drawdown no tempo \(T\), \(X(t)\) é o retorno acumulado em um processo estocástico no período \(t\), sendo \(t\in(0,T)\) e \(X(T)\) o retorno acumulado em \(T\). Isso posto, vamos obter os dados do ibovespa no script abaixo e avaliar os drawdowns de 2007 até hoje. Para isso, faremos uso dos pacotes: BatchGetSymbols, xts e PerformanceAnalytics. O primeiro é utilizado para obter o histórico de preços (no caso pontos) do Ibovespa. Os dados são obtidos do yahoo finance e o histórico é apenas de 2007 para frente. Não é a base indicada para estudos longos, mas é uma disponível gratuitamente para download! O segundo é para transformar os dados de formato data.frame da em uma série temporal descontínua. O terceiro é um pacote de ferramentas, no qual inclui as funções para calcular o retorno diário e os drawdowns.

library(BatchGetSymbols)
library(xts)
library(PerformanceAnalytics)

Dados <- BatchGetSymbols(tickers    = "^BVSP",
                         first.date = '2007-01-01', 
                         last.date  = Sys.Date(), 
                         do.cache   = FALSE)

IBOV <- xts(Dados$df.tickers$price.adjusted, order.by = Dados$df.tickers$ref.date)
IBOV <- na.omit(IBOV)

Algumas notas sobre o script acima: A função BatchGetSymbols faz o download da série solicitada. Deixei a última data para utilizar a função Sys.Date() para tentar capturar o último dado disponível, sendo ele a data de hoje (flexível). Além disso, deixo o argumento do.cache como falso para evitar erros de sobreposição de valores entre o que é baixado e o que se encontra no cache previamente baixado.

Nas duas últimas linhas do script, crio uma série chamada IBOV em formato xts (série temporal irregular). Utilizo para as observações diárias o preço ajustado para dividendos, demais emolumentos, splits e agrupamentos. São ordenadas pelo vetor datas também disponível nos dados baixados. Na última linha, solicito a remoção de dias que não há observação na série.

Na sequência, plotamos o Ibovespa, calculamos o retorno diário de forma discreta \(\Delta P_t/P_{t-1}\), pedimos o cálculo da série de drawdowns, inputando os retornos diários e na sequência o plot. Por fim, pedimos para tabelar os 10 maiores drawdowns no período.

plot(IBOV)

IBOV_ret <- Return.calculate(IBOV, method = "discrete")

IBOV_Dr <- PerformanceAnalytics::Drawdowns(IBOV_ret)

plot(IBOV_Dr, main = "Drawdown no Ibovespa")

PerformanceAnalytics::table.Drawdowns(IBOV_ret, top = 10)
##          From     Trough         To   Depth Length To Trough Recovery
## 1  2008-05-21 2008-10-27 2017-09-11 -0.5996   2306       112     2194
## 2  2020-01-24 2020-03-23       <NA> -0.4682     49        39       NA
## 3  2018-02-27 2018-06-18 2018-11-01 -0.2035    172        77       95
## 4  2007-12-07 2008-01-21 2008-04-30 -0.1836     95        28       67
## 5  2007-07-20 2007-08-16 2007-09-24 -0.1739     46        20       26
## 6  2007-02-23 2007-03-05 2007-04-04 -0.1135     29         7       22
## 7  2019-03-19 2019-05-17 2019-06-19 -0.1000     65        42       23
## 8  2007-11-01 2007-11-26 2007-12-06 -0.0957     23        15        8
## 9  2019-07-11 2019-08-26 2019-10-21 -0.0887     73        33       40
## 10 2017-10-16 2017-11-14 2018-01-02 -0.0800     53        21       32

Sobre a tabela acima, algumas observações podem ser feitas. A maior queda histórica se deu em quem comprou na máxima, datada no dia 21/05/2008. Seu prejuízo só foi recuparado (em termos nominais) em 11/09/2017. A duração foi de 2306 dias, algo em torno de 10 anos. O tempo de mergulho durou 112 dias, algo em torno de 4 meses. A recuperação em si foi de 2194 dias de pregão. Outros casos são apontados na tabela, sendo o primeiro o maior -59,96%. Um detalhe importante tabelado é que o segundo maior drawdown foi aberto recentemente no dia 24/01/2020. Houve um mergulho de 39 dias, está durando 49 e não fechou a recuperação.

PerformanceAnalytics::AverageDrawdown(IBOV_ret)
##                        [,1]
## Average Drawdown 0.04592626
PerformanceAnalytics::AverageLength(IBOV_ret)
##                    [,1]
## Average Length 50.20312

Sobre as informações relativas ao drawdown médio e duração média deles, temos: 4,59% e 50,20 dias de pregão.

Volatilidade Histórica

Na literatura de finças, a volatilidade é medida através do desvio-padrão de uma série de retornos de um ativo. tomando como base a curva normal, quando maior for o desvio-padrão do retorno de uma série, maior o risco envolvido nela. Evidentemente, há críticas a essa forma de mensuração. Todavia, esse é um assunto mais extenso que não será explorado aqui, especificamente.

Antes de apresentar os modelos que serão utilizados, segue aqui uma ideia: Se o risco pode ser medido através do desvio-padrão do retorno de uma ação, o que aconteceria se essa medida variasse no tempo? Certamente, precisaríamos de um método que possua a flexibilidade de ser tempo variante.

Alias, para mostrar como o desvio-padrão é tempo variante, veja a série de retornos diários do Ibovespa:

plot(IBOV_ret)

Pode-se perceber na figura acima que períodos entre 2008 e 2009 houve forte aumento da variação percentual diária nos preços, bem como em 2020. Chamamos isso na literatura de Clusters de Volatilidade ou (Agrupamento de Volatilidade).

Modelos ARCH/GARCH

O termo ARCH é uma abreviação traduzida de Modelo de Heterocedasticidade Condicional Auto Regressiva. Intuitivamente, o modelo captura o aumento da variância (heterocedasticidade) no tempo a partir termos autoregressivos. Ná prática é como se dias de calmaria chamassem novos dias de calmaria e dias de turbulência chamassem novos dias de turbulência. O modelo ARCH(1) pode ser representado matematicamente como1: \[y_t=\phi+e_t\] \[e_t|I_{t-1} \sim N(0,h_t)\] \[h_t=\alpha_0+\alpha_1.e^2_{t-1},  \alpha_0>0,  0\leq\alpha_1<1 \]

O primeiro passo para verificar se os nossos dados sofrem influência do efeito de heterocedasticidade condicional é realizar o teste ARCH. Tal como proposto por Colonesco (2016), iremos fazê-lo de duas formas: (1) Abrindo o teste no passo-a-passo e; (2) Teste direto apenas obtendo o report.

Dessa forma, faremos uso dos pacotes: dynlm, broom, FinTS e tseries.

library(dynlm)
library(broom)
library(FinTS)
library(tseries)

Ibov_Med <- dynlm(as.zoo(IBOV_ret)~1)
summary(Ibov_Med)
## 
## Time series regression with "zoo" data:
## Start = 2007-01-03, End = 2020-04-03
## 
## Call:
## dynlm(formula = as.zoo(IBOV_ret) ~ 1)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.148092 -0.008748  0.000384  0.009256  0.146265 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0002952  0.0003168   0.932    0.351
## 
## Residual standard error: 0.01813 on 3274 degrees of freedom
##   (1 observation deleted due to missingness)
ehatsq    <- ts(resid(Ibov_Med)^2)
IBOV.ARCH <- dynlm(ehatsq~L(ehatsq))
summary(IBOV.ARCH)
## 
## Time series regression with "ts" data:
## Start = 2, End = 3275
## 
## Call:
## dynlm(formula = ehatsq ~ L(ehatsq))
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -0.0079604 -0.0002326 -0.0001733  0.0000076  0.0205867 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 2.047e-04  1.879e-05   10.89   <2e-16 ***
## L(ehatsq)   3.774e-01  1.619e-02   23.31   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.001031 on 3272 degrees of freedom
## Multiple R-squared:  0.1424, Adjusted R-squared:  0.1421 
## F-statistic: 543.2 on 1 and 3272 DF,  p-value: < 2.2e-16
T     <- nobs(Ibov_Med)
q     <- length(coef(IBOV.ARCH))-1
Rsq   <- glance(IBOV.ARCH)[[1]]
LM    <- (T-q)*Rsq
alpha <- 0.05
Chicr <- qchisq(1-alpha, q)

# Report das Variáveis
LM
## [1] 466.1533
Chicr
## [1] 3.841459

O script acima abre o chamado teste ARCH de heterocedasticidade condicional. Começamos o script carregando os pacotes, estimamos através da função dynlm a série de retornos diários do IBOV contra uma constante. Reportamos o resultado. Na sequência, montamos uma série da variância da série, elevando ao quadrado o resíduo obtido da equação anterior.

Tendo sido estimada a variância, estimamos a variância em \(t\) frente suas primeira defasagem. Reportamos e separamos os valores \(T\) (tamanho da série); \(q\) a quantidade de coeficientes estimados; \(R^2\) da Regressão (variável Rsq). O valor \(LM\) obtido é igual a \((T-q).R^2\); o alpha será de 5%; Obtemos o valor de \(\chi^2\) para os parâmetros \((1-\alpha,q)\).

O resultado da Estatística \(LM=466,15\), que deve ser comparada com o valor crítico \(\chi^2_{(0.95,1)}=(3,84)\). Isso indica que a hipótese nula deve ser rejeitada, concluindo que a série sofre de efeito \(ARCH\).

Mais formalmente, o teste se baseia em testar as seguintes hipóteses: \[\hat{e}_t^2=\gamma_0+\gamma_1.\hat{e}_{t-1}^2+...+\gamma_q.\hat{e}_{t-q}+v_t\] No qual as Hipóteses Nula e Alternativa do Teste ARCH: \[H_0:\gamma_1=...=\gamma_q=0\] \[H_A:\gamma_i \neq0 \forall i\in \left[ 1,2,...,q\right] \] Portanto, aceitar a hipótese nula é admitir que a série não sofra de heterocedasticidade condicional autoregressiva, enquanto que rejeitar a hipótese nula é aceitar que sofra de heterocedasticidade condicional autoregressiva.

ArchTest(IBOV_ret, lags=1, demean=TRUE)
## 
##  ARCH LM-test; Null hypothesis: no ARCH effects
## 
## data:  IBOV_ret
## Chi-squared = 466.15, df = 1, p-value < 2.2e-16
IBOV.GARCH <- invisible(garch(na.omit(IBOV_ret),c(1,1)))
## 
##  ***** ESTIMATION WITH ANALYTICAL GRADIENT ***** 
## 
## 
##      I     INITIAL X(I)        D(I)
## 
##      1     2.958252e-04     1.000e+00
##      2     5.000000e-02     1.000e+00
##      3     5.000000e-02     1.000e+00
## 
##     IT   NF      F         RELDF    PRELDF    RELDX   STPPAR   D*STEP   NPRELDF
##      0    1 -1.164e+04
##      1    7 -1.166e+04  1.25e-03  1.88e-03  3.3e-04  2.1e+10  3.3e-05  1.96e+07
##      2    8 -1.166e+04  6.63e-05  9.68e-05  3.0e-04  2.0e+00  3.3e-05  1.26e+02
##      3    9 -1.166e+04  1.33e-05  1.39e-05  3.2e-04  2.0e+00  3.3e-05  1.24e+02
##      4   16 -1.174e+04  6.79e-03  1.15e-02  4.4e-01  2.0e+00  7.9e-02  1.23e+02
##      5   19 -1.183e+04  7.81e-03  9.03e-03  6.4e-01  2.0e+00  2.2e-01  9.46e+00
##      6   25 -1.183e+04  1.38e-04  6.94e-04  2.7e-05  1.4e+02  1.5e-05  2.69e-01
##      7   26 -1.183e+04  6.89e-05  6.06e-05  2.5e-05  2.0e+00  1.5e-05  2.88e-02
##      8   27 -1.183e+04  1.39e-06  1.42e-06  2.6e-05  2.0e+00  1.5e-05  2.96e-02
##      9   36 -1.193e+04  7.86e-03  7.40e-03  3.0e-01  5.7e-01  2.5e-01  2.93e-02
##     10   38 -1.195e+04  1.84e-03  1.73e-03  4.4e-02  2.0e+00  4.9e-02  1.72e-01
##     11   40 -1.198e+04  3.06e-03  3.29e-03  7.8e-02  1.9e+00  9.9e-02  4.63e-01
##     12   42 -1.199e+04  3.92e-04  5.39e-04  1.4e-02  1.8e+00  2.0e-02  5.88e-03
##     13   44 -1.200e+04  8.72e-04  1.09e-03  2.9e-02  1.6e+00  4.1e-02  6.12e-03
##     14   45 -1.200e+04  4.42e-04  5.35e-04  2.7e-02  7.2e-01  4.1e-02  7.74e-04
##     15   46 -1.201e+04  6.24e-04  3.47e-04  1.8e-02  0.0e+00  3.6e-02  3.47e-04
##     16   47 -1.202e+04  5.74e-04  2.23e-03  6.2e-02  7.3e-01  1.5e-01  3.38e-03
##     17   58 -1.202e+04  1.13e-04  3.69e-03  2.3e-06  2.4e+00  4.2e-06  5.69e-03
##     18   59 -1.203e+04  9.53e-04  6.77e-04  8.8e-07  2.0e+00  2.1e-06  2.74e-03
##     19   60 -1.203e+04  8.71e-05  1.37e-04  9.7e-07  2.0e+00  2.1e-06  9.67e-04
##     20   61 -1.203e+04  1.56e-05  1.76e-05  1.1e-06  2.0e+00  2.1e-06  8.29e-04
##     21   62 -1.203e+04  2.28e-07  2.21e-07  1.1e-06  2.0e+00  2.1e-06  8.00e-04
##     22   69 -1.203e+04  1.42e-04  2.68e-04  4.7e-03  1.1e+00  8.6e-03  7.98e-04
##     23   71 -1.204e+04  8.72e-05  1.38e-04  7.6e-03  8.7e-01  1.7e-02  2.65e-04
##     24   72 -1.204e+04  3.94e-06  3.19e-06  1.4e-03  0.0e+00  2.7e-03  3.19e-06
##     25   73 -1.204e+04  2.95e-07  2.78e-07  4.5e-04  0.0e+00  8.7e-04  2.78e-07
##     26   74 -1.204e+04  3.05e-09  2.93e-09  3.1e-05  0.0e+00  6.1e-05  2.93e-09
##     27   75 -1.204e+04  1.38e-10  1.39e-10  3.3e-07  0.0e+00  7.3e-07  1.39e-10
##     28   76 -1.204e+04  3.72e-12  3.21e-12  3.9e-07  1.4e+00  7.3e-07  4.46e-12
## 
##  ***** RELATIVE FUNCTION CONVERGENCE *****
## 
##  FUNCTION    -1.203567e+04   RELDX        3.876e-07
##  FUNC. EVALS      76         GRAD. EVALS      29
##  PRELDF       3.207e-12      NPRELDF      4.457e-12
## 
##      I      FINAL X(I)        D(I)          G(I)
## 
##      1    6.676347e-06     1.000e+00    -1.118e+02
##      2    8.252343e-02     1.000e+00    -4.013e-02
##      3    8.943420e-01     1.000e+00    -4.761e-02
summary(IBOV.GARCH)
## 
## Call:
## garch(x = na.omit(IBOV_ret), order = c(1, 1))
## 
## Model:
## GARCH(1,1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -7.06093 -0.56924  0.04532  0.62291  4.18402 
## 
## Coefficient(s):
##     Estimate  Std. Error  t value Pr(>|t|)    
## a0 6.676e-06   1.133e-06     5.89 3.85e-09 ***
## a1 8.252e-02   7.226e-03    11.42  < 2e-16 ***
## b1 8.943e-01   9.609e-03    93.07  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Diagnostic Tests:
##  Jarque Bera Test
## 
## data:  Residuals
## X-squared = 662.09, df = 2, p-value < 2.2e-16
## 
## 
##  Box-Ljung test
## 
## data:  Squared.Residuals
## X-squared = 1.0251, df = 1, p-value = 0.3113
hhat <- ts(2*IBOV.GARCH$fitted.values[-1,1]^2)
plot(hhat, main = "Série Estimada por GARCH(1,1) da Variância Condicional", 
        col = "red", ylab = "Variância do Retorno Diário", xlab = "Tempo")
grid(nx = NULL, ny = NULL, lty = "dotted", col = "grey")

plot(hhat^(0.5), main = "Volatilidade Estimada por GARCH(1,1)", 
        col = "blue", ylab = "Desvio-Padrão do Retorno Diário", xlab = "Tempo")
grid(nx = NULL, ny = NULL, lty = "dotted", col = "grey")

O último gráfico com título de Volatilidade Estimada por GARCH(1,1) é o que nos interessa ao fim. Ele aponta como a volatilidade do IBOV hoje pode ser comparada a que tivemos no passado. Nesse momento, podemos ver que já passamos o valor observado no período da crise Subprime. Portanto, não seria exagero falar que os últimos dias já podem ser considerados como a maior crise financeira (no sentido de impacto aos mercados financeiros) das duas últimas décadas.

Referências

COLONESCU, C. Principles of Econometrics with R. Disponível em https://bookdown.org/ccolonescu/RPoE4/time-varying-volatility-and-arch-models.html. 2016.


  1. É mais intuitivo entender a especificação de uma defasagem. Evidentemente, podemos expandir a notação para \(q\) defasagens, bem como \(y_t\) pode ter um processo estilo \(ARMA(p,q)\).

Júlio Fernando Costa Santos
Júlio Fernando Costa Santos
Professor of Economics

My research interests include Finance, Macroeconomics and Econometric techniques.

Related