library(fpp2)
library(tidyverse)
library(TSstudio)
library(tseries)
library(BETS)
library(dplyr)
Índice de Atividade Econômica do Banco Central do Brasil
df.res <- BETSsearch("Central Bank Economic Activity Index",
view = FALSE)
df.res %>%
kable() %>%
kableExtra::kable_styling(
bootstrap_options = c("striped", "hover", "condensed"))
| code | description | unit | periodicity | start | last_value | source |
|---|---|---|---|---|---|---|
| 24363 | Central Bank Economic Activity Index | Index | M | 01/01/2003 | feb/2018 | BCB-Depec |
| 24364 | Central Bank Economic Activity Index (IBC-Br) - seasonally adjusted | Index | M | 01/01/2003 | feb/2018 | BCB-Depec |
id <- 24364 # série ajustada sazonalmente
inicio = '2003-01-01'
fim = as.character(Sys.Date() - 1) # ontem
df.BETS <- BETSget(code = id,
data.frame = TRUE,
from = inicio,
to = fim)
df <- df.BETS
head(df)
## date value
## 1 2003-01-01 100.39
## 2 2003-02-01 102.06
## 3 2003-03-01 102.03
## 4 2003-04-01 100.92
## 5 2003-05-01 99.76
## 6 2003-06-01 100.31
tail(df)
## date value
## 206 2020-02-01 140.01
## 207 2020-03-01 131.76
## 208 2020-04-01 119.41
## 209 2020-05-01 121.63
## 210 2020-06-01 128.10
## 211 2020-07-01 130.85
ibc <- df$value
ts.ibc <- ts(ibc, frequency = 12, start = c(2003,01), end = c(2020,06))
ts.ibc
## Jan Feb Mar Apr May Jun Jul Aug Sep Oct
## 2003 100.39 102.06 102.03 100.92 99.76 100.31 99.06 99.72 101.77 101.85
## 2004 103.51 104.52 105.99 106.43 106.31 107.25 107.82 108.20 109.41 108.71
## 2005 109.54 110.21 110.45 110.98 110.95 110.60 110.63 111.26 110.91 111.09
## 2006 113.37 113.63 113.54 114.31 115.63 114.70 116.94 116.60 116.83 118.09
## 2007 119.65 120.18 119.42 121.24 122.33 123.38 124.26 124.26 125.35 126.29
## 2008 127.23 126.75 126.46 127.80 129.41 131.13 130.93 130.99 130.92 128.12
## 2009 120.90 122.19 123.01 123.64 124.88 125.92 126.23 128.09 129.08 129.80
## 2010 133.61 135.18 136.57 137.17 136.46 136.19 136.94 137.71 139.26 138.67
## 2011 140.22 140.77 141.08 140.88 141.30 142.14 142.25 141.95 141.79 141.64
## 2012 138.97 140.38 140.06 141.02 142.61 143.55 144.05 144.29 143.70 144.88
## 2013 144.96 143.82 144.94 146.29 146.81 146.33 147.18 147.14 148.05 148.01
## 2014 148.29 147.99 147.80 146.95 146.25 143.55 144.84 145.61 146.19 145.41
## 2015 145.28 144.33 144.07 142.46 141.19 139.93 138.98 139.12 137.84 138.74
## 2016 135.65 135.59 134.67 134.72 134.16 134.67 134.43 133.83 133.65 133.20
## 2017 133.73 136.01 135.84 135.86 134.99 136.10 136.44 135.62 135.44 135.56
## 2018 137.35 137.36 137.35 138.45 133.05 137.63 137.95 139.02 137.92 137.73
## 2019 139.29 137.76 137.54 137.32 138.19 138.92 137.82 138.42 139.05 139.52
## 2020 139.30 140.01 131.76 119.41 121.63 128.10
## Nov Dec
## 2003 101.97 101.64
## 2004 109.62 108.79
## 2005 111.81 112.36
## 2006 118.86 119.91
## 2007 126.18 126.90
## 2008 124.96 120.88
## 2009 130.03 131.26
## 2010 140.11 138.17
## 2011 142.28 140.43
## 2012 144.61 144.11
## 2013 148.37 148.65
## 2014 145.64 146.10
## 2015 136.91 136.21
## 2016 133.07 132.09
## 2017 135.89 137.47
## 2018 138.32 138.63
## 2019 139.53 139.17
## 2020
autoplot(ts.ibc, lwd = 1.2, col = "steelblue") +
labs(y = 'IBC-BR',
x = 'Data',
title = 'Índice de Atividade do Banco Central do Brasil',
caption = 'Fonte: BACEN')
O impacto da Covid-19 em números
ibc.2020 <- window(ts.ibc, 2020)
covid <- data.frame(Data = time(ibc.2020),
Valor = as.matrix(ibc.2020))
arit.ret <- function(precos) {
#### Calcula o retorno aritmético de uma série de preços ####
c(NA, precos[2:length(precos)]/ precos[1:length(precos)-1] - 1)
}
covid$delta <- arit.ret(as.numeric(covid$Valor)) * 100
covid
## Data Valor delta
## 1 2020.000 139.30 NA
## 2 2020.083 140.01 0.5096913
## 3 2020.167 131.76 -5.8924363
## 4 2020.250 119.41 -9.3731026
## 5 2020.333 121.63 1.8591408
## 6 2020.417 128.10 5.3194113
autoplot(ibc.2020, lwd = 1.2, col = "steelblue") +
labs(y = 'IBC-BR',
x = 'Data',
title = 'Índice de Atividade do Banco Central do Brasil em 2020',
caption = 'Fonte: BACEN')
TSstudiots_seasonal(ts.ibc,
type = 'box',
title = 'Sazonalidade - Índice de Atividade do BCB')
acf <- ggAcf(ts.ibc)
acf
pacf <- ggPacf(ts.ibc)
pacf
A série é claramente não estacionária. O Pacf sugere que a séria ficaria estacionária no lag = 3.
Utlizaremos os testes de estacionariedade com o pacote tseries.
\(H_0\): A série não é estacionária
\(H_1\): A série é estacionária
adf.test(ts.ibc)
##
## Augmented Dickey-Fuller Test
##
## data: ts.ibc
## Dickey-Fuller = -0.5433, Lag order = 5, p-value = 0.9791
## alternative hypothesis: stationary
Note a diferença da hipótese básica do teste
\(H_0\): A série é estacionária
\(H_1\): A série não é estacionária
kpss.test(ts.ibc)
##
## KPSS Test for Level Stationarity
##
## data: ts.ibc
## KPSS Level = 2.9662, Truncation lag parameter = 4, p-value = 0.01
Rejeita-se a hipótese nula (p-value smaller than printed p-value).
pp.test(ts.ibc)
##
## Phillips-Perron Unit Root Test
##
## data: ts.ibc
## Dickey-Fuller Z(alpha) = -1.6139, Truncation lag parameter = 4, p-value
## = 0.9774
## alternative hypothesis: stationary
Não se pode rejeitar a hipótese nula a menos de \(\alpha\) = 21%: p-valor = 0.2136
diff <- diff(ts.ibc)
lim <- 1.96/sqrt(length(ibc))
autoplot(diff, col ="blue", lwd = 1.1) +
geom_hline(yintercept = 0,
colour = 'darkred',
linetype = 'solid',
size = 0.75) +
xlab('Data') +
ylab('Diff')
acf.diff <- ggAcf(diff, lag.max = 24)
acf.diff
Uma diferenciação de lag = 2, mas observa-se a sazonalidade nos instantes 6 e 12 e 18 e 24. O teste sugere 4 lags (5-1).
O Acf é útil para medir o Modelo MA(q).
pacf.diff <- ggPacf(diff, lag.max = 24)
pacf.diff
Conte os primeiros spikes do PACF para o lag do AR(p).
adf.test(diff)
##
## Augmented Dickey-Fuller Test
##
## data: diff
## Dickey-Fuller = -5.8767, Lag order = 5, p-value = 0.01
## alternative hypothesis: stationary
\(H_0\): A série é estacionária
\(H_1\): A série não é estacionária
kpss.test(diff)
##
## KPSS Test for Level Stationarity
##
## data: diff
## KPSS Level = 0.58481, Truncation lag parameter = 4, p-value = 0.02402
pp.test(diff)
##
## Phillips-Perron Unit Root Test
##
## data: diff
## Dickey-Fuller Z(alpha) = -145.61, Truncation lag parameter = 4, p-value
## = 0.01
## alternative hypothesis: stationary
ar <- arima(ts.ibc, order = c(2,1,0))
ar
##
## Call:
## arima(x = ts.ibc, order = c(2, 1, 0))
##
## Coefficients:
## ar1 ar2
## 0.2421 -0.1646
## s.e. 0.0710 0.0711
##
## sigma^2 estimated as 2.343: log likelihood = -385.59, aic = 777.18
fit <- forecast(ar, h = 12) # IC level = 95
autoplot(ts.ibc, series = "Série_Observada") +
autolayer(fit$fitted, series = "Série Predita_AR") +
autolayer(fit, series = "Projeção h = 12") +
xlab('Data')
ma <- arima(ts.ibc, order = c(0,1,2))
ma
##
## Call:
## arima(x = ts.ibc, order = c(0, 1, 2))
##
## Coefficients:
## ma1 ma2
## 0.2228 -0.0512
## s.e. 0.0772 0.0773
##
## sigma^2 estimated as 2.372: log likelihood = -386.86, aic = 779.71
fit <- forecast(ma, h = 12) # SE QUISER FIXAR IC level = 95)
autoplot(ts.ibc, series = "Série_Observada") +
autolayer(fit$fitted, series = "Série Predita_MA") +
autolayer(fit, series = "Projeção h = 12") +
xlab('Data')
#$ ARIMA(p,d,q)
arima <- arima(ts.ibc, order = c(2,1,2))
arima
##
## Call:
## arima(x = ts.ibc, order = c(2, 1, 2))
##
## Coefficients:
## ar1 ar2 ma1 ma2
## 0.0112 -0.8059 0.2272 0.7382
## s.e. 0.3419 0.2230 0.3075 0.3748
##
## sigma^2 estimated as 2.275: log likelihood = -382.75, aic = 775.49
fit <- forecast(arima, h = 12) # IC 95% padrão
autoplot(ts.ibc, series = "Série_Observada") +
autolayer(fit$fitted, series = "Série Predita_ARIMA") +
autolayer(fit, series = "Projeção h = 12") +
xlab('Data')
sarima <- arima(ts.ibc,
order= c(2,1,0),
seasonal = list(order = c(0,1,1),
period = 12))
sarima
##
## Call:
## arima(x = ts.ibc, order = c(2, 1, 0), seasonal = list(order = c(0, 1, 1), period = 12))
##
## Coefficients:
## ar1 ar2 sma1
## 0.1953 -0.1432 -0.7691
## s.e. 0.0738 0.0730 0.0814
##
## sigma^2 estimated as 2.579: log likelihood = -378.25, aic = 764.51
fit <- forecast(sarima, h = 12)
autoplot(ts.ibc, series = "Serie_Observada") +
autolayer(fit$fitted, series = "Série Predita_ SARIMA") +
autolayer(fit, series = "Projeção h = 12", showgap = FALSE) +
xlab('Data')
auto.arima <- auto.arima(ts.ibc, seasonal = TRUE,
stepwise = FALSE,
approximation = FALSE)
auto.arima
## Series: ts.ibc
## ARIMA(0,2,4)
##
## Coefficients:
## ma1 ma2 ma3 ma4
## -0.7566 -0.3146 -0.1080 0.2055
## s.e. 0.0681 0.0855 0.0946 0.0722
##
## sigma^2 estimated as 2.34: log likelihood=-383.14
## AIC=776.28 AICc=776.58 BIC=792.97
print('Modelo -> SARIMA(3,1,0)(0,1,1)[12]')
## [1] "Modelo -> SARIMA(3,1,0)(0,1,1)[12]"
fit <- forecast(auto.arima, h = 12)
autoplot(ts.ibc, series = "Série_Observada") +
autolayer(fit$fitted, series = "Série Predita_AUTO.ARIMA") +
autolayer(fit, series = "Projeção h = 12") +
xlab('Data')
round(accuracy(ar), 4)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.1229 1.5271 0.9583 0.1015 0.7473 1.0108 -0.017
round(accuracy(ma), 4)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.1157 1.5365 0.9543 0.0955 0.7444 1.0066 0.0027
round(accuracy(arima), 4)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.1187 1.5048 0.925 0.0984 0.7235 0.9756 7e-04
round(accuracy(sarima), 4)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set -0.123 1.5556 0.9669 -0.0916 0.7419 1.0199 -0.0129
round(accuracy(auto.arima), 4)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set -0.1099 1.5077 0.9185 -0.0832 0.7145 0.1946 -0.0071
auto.arima): SARIMA(3,1,0)(0,1,1)[12]t_test(model = auto.arima)
## Coeffs Std.Errors t Crit.Values Rej.H0
## ma1 -0.7565757 0.06810458 11.109028 1.971661 TRUE
## ma2 -0.3145982 0.08554356 3.677637 1.971661 TRUE
## ma3 -0.1080443 0.09458919 1.142248 1.971661 FALSE
## ma4 0.2054761 0.07221053 2.845514 1.971661 TRUE
Os parâmetros são significativos.
Teste Ljung-Box
IMPORTANTE:
\[fitdf = p + q + P + Q = 3 + 0 + 0 + 1 = 4\]
Box.test(x = auto.arima$residuals,
lag = 24,
type = "Ljung-Box",
fitdf = 4)
##
## Box-Ljung test
##
## data: auto.arima$residuals
## X-squared = 15.607, df = 20, p-value = 0.7407
Não podemos rejeitar \(H_0\). A série aparenta ser iid.
Resíduos
checkresiduals(auto.arima, col ="blue")
##
## Ljung-Box test
##
## data: Residuals from ARIMA(0,2,4)
## Q* = 15.607, df = 20, p-value = 0.7407
##
## Model df: 4. Total lags used: 24
Teste proposto por Engle (1982) - GARCH
\(H_0\): Os resíduos ao quadrado são uma sequência de ruídos brancos, ou seja, os resíduos são homocedásticos.
\(H_1\): A série é heterocedástica
library(FinTS)
ArchTest(auto.arima$residuals, lags = 36)
##
## ARCH LM-test; Null hypothesis: no ARCH effects
##
## data: auto.arima$residuals
## Chi-squared = 133.21, df = 36, p-value = 4.442e-13
Não rejeitamos a hipótese nula.
library(normtest)
jb.norm.test(auto.arima$residuals, nrepl = 2000)
##
## Jarque-Bera test for normality
##
## data: auto.arima$residuals
## JB = 2084.1, p-value < 2.2e-16
shapiro.test(auto.arima$residuals)
##
## Shapiro-Wilk normality test
##
## data: auto.arima$residuals
## W = 0.79599, p-value = 7.544e-16
hist(auto.arima$residuals,
main = 'Histograma dos resíduos',
xlab = 'resíduos',
ylab = 'Frequências')
round(summary(auto.arima$residuals), digits = 4)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -10.2346 -0.6319 0.0336 -0.1099 0.6295 6.0551
moda <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
result <- moda(as.numeric(auto.arima$residuals))
print(result)
## [1] 0.04489577
mean(auto.arima$residuals, trim = 0.05)
## [1] -0.02832715
Estamos violando esse diagóstico, porém se efetuarmos o arrendondamento, \[média \approx mediana \approx moda \approx zero\]
fit
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## Jul 2020 130.2386 128.2783 132.1990 127.2405 133.2368
## Aug 2020 128.8342 125.7061 131.9623 124.0502 133.6182
## Sep 2020 127.9480 124.0665 131.8295 122.0118 133.8842
## Oct 2020 127.7077 123.3654 132.0500 121.0667 134.3487
## Nov 2020 127.4674 122.6874 132.2474 120.1571 134.7778
## Dec 2020 127.2272 122.0262 132.4281 119.2730 135.1813
## Jan 2021 126.9869 121.3776 132.5962 118.4082 135.5656
## Feb 2021 126.7466 120.7385 132.7548 117.5579 135.9353
## Mar 2021 126.5064 120.1067 132.9061 116.7189 136.2939
## Apr 2021 126.2661 119.4805 133.0517 115.8885 136.6437
## May 2021 126.0258 118.8588 133.1929 115.0648 136.9869
## Jun 2021 125.7856 118.2404 133.3307 114.2463 137.3248