Previsão de vendas e Análise VaR 1% usando GARCH

Author

Marea

Análise VaR 1% dinâmico e estático + Desvio-padrão condicional de 1 SPE

O VaR de 1% significa que com 1% de chance de ter aquelas vendas naquele mês

Gerando valores aleatórios para vendas

Nota: esses valores poderiam ser negativos caso houvessem mais distratos que vendas, vamos ver isso mais para frente quando fizermos as previsões separadas por SPE.

Code
library(rmarkdown)
library(knitr)
library(dplyr)
library(rugarch)
library(forecast)
library(nloptr)

set.seed(1992)
n = 108
valores = runif(n, min = 500, max = 2000)
inteiros = round(valores)
inteiros
  [1] 1437 1732 1709 1373 1173 1569  801 1487 1460 1766  552  700 1720  777 1357
 [16] 1264 1265 1165 1310  913 1417  541 1144 1535  737 1978 1685  668 1224  967
 [31] 1673 1310 1392 1180  773  775 1522 1233  623 1495 1665 1071 1332  569  604
 [46] 1708 1292 1892 1069 1542 1727 1556 1473 1841  721  666 1428  862 1235  890
 [61] 1140  812  747  573 1251 1909  831  569 1557 1505 1126  630  788 1402  847
 [76] 1777 1397 1846  840  729 1796 1195 1421 1491 1870 1748  569  605 1962 1454
 [91] 1436 1261 1656 1605 1097  877  972 1962  905 1071 1851  570 1252 1844  675
[106] 1995 1295  595

Gerando as datas e nomeando dados

Code
library(xts)
dates <- seq(from = as.Date("2016-01-01"), by = "month", length.out = length(inteiros))
data <- xts(inteiros, order.by = dates)
names(data) <- "Vendas"

Aplicando e modelando GARCH

Code
returns <- diff(log(data$Vendas))
returns <- na.omit(returns)

spec <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(2, 2)),
                   mean.model = list(armaOrder = c(1, 1)),
                   distribution.model = "sstd")

fit <- ugarchfit(spec = spec, data = returns)

VaR de 1%

Code
VaR_1perc <- quantile(returns, probs = 0.01)

# Prever volatilidade condicional
sigma <- sigma(fit)

# Calcular VaR dinâmico de 1% ajustado para a escala dos retornos
VaR_dynamic <- -qnorm(0.01) * sigma

Plotando resultados

Code
plot(index(returns), returns, type = "l", col = "steelblue", ylab = "Retornos", xlab = "Data", main = "Retornos x VaR de 1% x DP Condicional")
abline(h = VaR_1perc, col = "purple", lty = 2)
lines(index(returns), VaR_dynamic, col = "pink", lty = 2, lwd = 2)
lines(index(returns), sigma, col = "gray")
legend("bottomright", legend = c("Retornos", "VaR de 1%", "VaR Dinâmico de 1%", "Desvio Padrao Condicional"), col = c("steelblue", "purple", "pink", "gray"), lty = c(1, 2, 2, 1))

Meses em que os retornos foram maiores que o DP

Meses vistos como oportunidades. A partir desses valores podemos comparar meses para tirar conclusões como “as vendas são melhores em épocas de férias?”.

Code
maiores_DP <- returns[returns > sigma]
maiores_DP
              Vendas
2016-08-01 0.6186550
2017-01-01 0.8989992
2017-03-01 0.5575913
2017-09-01 0.4395614
2017-11-01 0.7488669
2018-02-01 0.9872536
2018-05-01 0.6055913
2018-07-01 0.5481752
2019-01-01 0.6749175
2019-04-01 0.8753350
2019-10-01 1.0395042
2020-09-01 0.7627405
2021-05-01 0.7808128
2021-09-01 1.0066357
2022-02-01 0.5761570
2022-04-01 0.7409811
2022-09-01 0.9016435
2023-05-01 1.1764912
2024-02-01 0.7023638
2024-05-01 0.5471332
2024-07-01 0.7868612
2024-10-01 1.0836866

Meses em que os retornos foram menores que o VaR 1% estático

Representam alto risco.

Code
menores_var <- returns[returns < VaR_1perc]
menores_var
              Vendas
2016-11-01 -1.162924
2024-06-01 -1.177845

Meses em que os retornos foram maiores que o VaR 1% dinâmico

Representam boas oportunidades, já que com 1% de probabilidade de acontecer, aconteceu.

Code
maior_var <- returns[returns >= VaR_dynamic]
maior_var
             Vendas
2019-10-01 1.039504
2021-09-01 1.006636
2023-05-01 1.176491
2024-10-01 1.083687

Previsões para 2025

Fiz uma função para calcular as previsões de todas as 10 SPEs

Criando planilha

Code
library(openxlsx)
set.seed(1992)
tabela <- matrix(sample(-4:90, 10 * 108, replace = TRUE), nrow = 10)

nome_arquivo <- "planilha_exemplo.xlsx"

wb <- createWorkbook()

addWorksheet(wb, "VendasSPEs")

for (col in 1:108) {
  writeData(wb, sheet = "VendasSPEs", x = tabela[, col], startCol = col, startRow = 1)
}
saveWorkbook(wb, file = nome_arquivo, overwrite = TRUE)

Chamando planilha

Code
library(readxl)
caminho_arquivo <- "C://Users//marea.albuquerque//OneDrive - Grupo Trinus Co//Documentos//planilha_exemplo.xlsx"

criar_vetor_spe <- function(caminho_arquivo, numero_linha) {
  df <- read_excel(caminho_arquivo, sheet = 1)
  spe <- as.numeric(unlist(df[numero_linha, ]))
  return(spe)
}

Função

Code
previsao_spes <- function(total_linhas, caminho_arquivo) {
  resultados <- list()
  for (i in 1:total_linhas) {
    spe <- criar_vetor_spe(caminho_arquivo, i)
    #Adicionar 1 a todos os valores para evitar zeros
    spe <- spe + 1
    dates <- seq(from = as.Date("2016-01-01"), by = "month", length.out = length(spe))
    data <- xts(spe, order.by = dates)
    
    decomposed <- stl(ts(spe, frequency = 12), s.window = "periodic")
    trend <- decomposed$time.series[, "trend"]
    seasonal <- decomposed$time.series[, "seasonal"]
    residual <- decomposed$time.series[, "remainder"]
    
    spec <- ugarchspec(
      variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
      mean.model = list(armaOrder = c(1, 1), include.mean = TRUE),
      distribution.model = "sstd"
    )
    fit <- tryCatch({
      ugarchfit(spec = spec, data = residual, solver = "hybrid")
    }, error = function(e) {
      cat("Erro no ajuste do modelo GARCH na linha", i, ":", e$message, "\n")
      return(NULL)
    })
    
    if (is.null(fit) || fit@fit$convergence != 0) {
      cat("O ajuste do modelo GARCH falhou na linha", i, ".\n")
      next
    }
    
    n.ahead <- 12
    forecast <- tryCatch({
      ugarchforecast(fit, n.ahead = n.ahead)
    }, error = function(e) {
      cat("Erro ao fazer previsão na linha", i, ":", e$message, "\n")
      return(NULL)
    })
    
    if (is.null(forecast)) {
      cat("A previsão falhou na linha", i, ".\n")
      next
    }
    
    predicted_residuals <- tryCatch({
      as.numeric(fitted(forecast))
    }, error = function(e) {
      cat("Erro ao extrair valores previstos na linha", i, ":", e$message, "\n")
      return(NULL)
    })
    
    if (is.null(predicted_residuals)) {
      cat("Erro ao extrair valores previstos na linha", i, ".\n")
      next
    }
    
    future_dates <- seq(from = as.Date("2025-01-01"), by = "month", length.out = n.ahead)
    
    #Aqui começamos a calcular os intervalos de confiança
    trend_forecast <- tryCatch({
      forecast_result <- forecast(auto.arima(na.omit(trend)), h = n.ahead)
      trend_mean <- forecast_result$mean
      trend_lower <- forecast_result$lower[,2]
      trend_upper <- forecast_result$upper[,2]
      list(mean = trend_mean, lower = trend_lower, upper = trend_upper)
    }, error = function(e) {
      cat("Erro ao fazer previsão de tendência na linha", i, ":", e$message, "\n")
      return(NULL)
    })
    
    seasonal_forecast <- tryCatch({
      seasonal_result <- rep(seasonal[1:12], length.out = n.ahead)
      seasonal_result
    }, error = function(e) {
      cat("Erro ao fazer previsão de sazonalidade na linha", i, ":", e$message, "\n")
      return(NULL)
    })
    
    predicted_vendas <- trend_forecast$mean + seasonal_forecast + predicted_residuals - 1
    lower_bound <- trend_forecast$lower + seasonal_forecast + predicted_residuals - 1
    upper_bound <- trend_forecast$upper + seasonal_forecast + predicted_residuals - 1
    
    # Criar uma série temporal para os preços previstos
    resultados[[i]] <- data.frame(
      Data = future_dates,
      SPE = paste0("SPE", i),
      Previsao = predicted_vendas,
      IC_Lower = lower_bound,
      IC_Upper = upper_bound
    )
  }
  
  # Combinar os resultados em uma única tabela
  resultado_final <- bind_rows(resultados)
  cat("Tamanho do resultado final:", nrow(resultado_final), "linhas\n")
  return(resultado_final)
}

Resultados

Code
previsao_spes(9, caminho_arquivo)
Tamanho do resultado final: 108 linhas
          Data  SPE  Previsao    IC_Lower  IC_Upper
1   2025-01-01 SPE1 26.830819  25.8741999 27.787439
2   2025-02-01 SPE1 15.512849  13.4698544 17.555843
3   2025-03-01 SPE1 22.141414  18.6088540 25.673973
4   2025-04-01 SPE1 26.660353  21.4888069 31.831899
5   2025-05-01 SPE1 13.065881   6.1966206 19.935141
6   2025-06-01 SPE1  9.578751   0.9993171 18.158185
7   2025-07-01 SPE1 35.915827  25.6406199 46.191033
8   2025-08-01 SPE1 15.319134   3.3787389 27.259530
9   2025-09-01 SPE1 18.249285   4.6839459 31.814624
10  2025-10-01 SPE1  8.988833  -6.1557358 24.133401
11  2025-11-01 SPE1 23.016819   6.3414416 39.692196
12  2025-12-01 SPE1 28.357637  10.2007408 46.514533
13  2025-01-01 SPE2 38.999376  37.8455686 40.153184
14  2025-02-01 SPE2 26.625691  24.2339510 29.017431
15  2025-03-01 SPE2 25.389710  21.6986009 29.080820
16  2025-04-01 SPE2 46.480440  41.5276995 51.433181
17  2025-05-01 SPE2 28.986089  22.8764433 35.095734
18  2025-06-01 SPE2 33.725825  26.6065559 40.845095
19  2025-07-01 SPE2 21.530786  13.5719121 29.489659
20  2025-08-01 SPE2 51.465506  42.8433569 60.087656
21  2025-09-01 SPE2 36.619308  27.5030830 45.735533
22  2025-10-01 SPE2 46.193654  36.7349419 55.652365
23  2025-11-01 SPE2 38.550519  28.8758419 48.225197
24  2025-12-01 SPE2 29.682214  19.8887019 39.475726
25  2025-01-01 SPE3 44.355356  43.3496101 45.361102
26  2025-02-01 SPE3 46.664691  44.6051894 48.724193
27  2025-03-01 SPE3 45.542339  41.7778266 49.306851
28  2025-04-01 SPE3 39.125141  33.4950084 44.755273
29  2025-05-01 SPE3 40.225425  32.7522248 47.698626
30  2025-06-01 SPE3 41.969841  32.7760707 51.163612
31  2025-07-01 SPE3 46.446003  35.7138916 57.178114
32  2025-08-01 SPE3 55.344185  43.2887341 67.399636
33  2025-09-01 SPE3 37.607857  24.4565271 50.759186
34  2025-10-01 SPE3 39.860660  25.8376214 53.883698
35  2025-11-01 SPE3 47.589857  32.9039618 62.275752
36  2025-12-01 SPE3 42.506675  27.3427653 57.670586
37  2025-01-01 SPE4 39.002971  37.8715496 40.134391
38  2025-02-01 SPE4 43.311998  40.9466640 45.677333
39  2025-03-01 SPE4 52.992182  49.0040363 56.980328
40  2025-04-01 SPE4 33.228562  27.4482163 39.008908
41  2025-05-01 SPE4 58.967705  51.5062681 66.429142
42  2025-06-01 SPE4 31.786768  22.7547495 40.818787
43  2025-07-01 SPE4 30.863739  20.4794163 41.248062
44  2025-08-01 SPE4 34.966819  23.4305959 46.503043
45  2025-09-01 SPE4 27.290486  14.7669769 39.813996
46  2025-10-01 SPE4 44.386440  31.0152332 57.757646
47  2025-11-01 SPE4 44.256586  30.1266618 58.386509
48  2025-12-01 SPE4 32.096991  17.2708123 46.923170
49  2025-01-01 SPE5 14.064217  12.2025697 15.925865
50  2025-02-01 SPE5 16.174939  12.2647365 20.085141
51  2025-03-01 SPE5 18.017757  11.8464975 24.189017
52  2025-04-01 SPE5 18.132206   9.5903068 26.674106
53  2025-05-01 SPE5 11.566413   0.6081487 22.524678
54  2025-06-01 SPE5 13.760491   0.3810851 27.139897
55  2025-07-01 SPE5 29.336809  13.5581904 45.115428
56  2025-08-01 SPE5 31.760002  13.6214931 49.898512
57  2025-09-01 SPE5 10.395840 -10.0521280 30.843809
58  2025-10-01 SPE5 14.897898  -7.8023209 37.598117
59  2025-11-01 SPE5 31.248167   6.3566654 56.139669
60  2025-12-01 SPE5 23.035618  -3.9845517 50.055788
61  2025-01-01 SPE6 46.687006  45.7578139 47.616197
62  2025-02-01 SPE6 43.795150  41.8042204 45.786080
63  2025-03-01 SPE6 43.344484  40.0262625 46.662705
64  2025-04-01 SPE6 57.504375  52.6559984 62.352751
65  2025-05-01 SPE6 63.401718  57.1201188 69.683316
66  2025-06-01 SPE6 54.308287  46.7334135 61.883161
67  2025-07-01 SPE6 53.345863  44.6068379 62.084887
68  2025-08-01 SPE6 44.143221  34.3486623 53.937779
69  2025-09-01 SPE6 52.835004  42.0740931 63.595916
70  2025-10-01 SPE6 63.334650  51.6805144 74.988787
71  2025-11-01 SPE6 51.502429  39.0155120 63.989345
72  2025-12-01 SPE6 55.792602  42.5234506 69.061753
73  2025-01-01 SPE7  5.704552   4.6272503  6.781853
74  2025-02-01 SPE7 15.341693  13.0155427 17.667843
75  2025-03-01 SPE7 21.404080  17.6385963 25.169563
76  2025-04-01 SPE7 23.176911  17.8394042 28.514418
77  2025-05-01 SPE7 34.463524  27.4603777 41.466671
78  2025-06-01 SPE7 30.062983  21.3284990 38.797468
79  2025-07-01 SPE7 24.498760  13.9879960 35.009524
80  2025-08-01 SPE7 23.250070  10.9339217 35.566218
81  2025-09-01 SPE7 13.351264  -0.7870778 27.489606
82  2025-10-01 SPE7  3.628490 -12.3392072 19.596187
83  2025-11-01 SPE7 22.600163   4.8035733 40.396753
84  2025-12-01 SPE7 23.359649   3.7406715 42.978625
85  2025-01-01 SPE8 66.821098  65.8169984 67.825199
86  2025-02-01 SPE8 64.982204  62.9164637 67.047945
87  2025-03-01 SPE8 63.249847  59.6107387 66.888955
88  2025-04-01 SPE8 47.213746  41.8811516 52.546341
89  2025-05-01 SPE8 52.616102  45.6292921 59.602912
90  2025-06-01 SPE8 36.856030  28.3452793 45.366781
91  2025-07-01 SPE8 28.091315  18.2417712 37.940858
92  2025-08-01 SPE8 49.946415  38.9723340 60.920495
93  2025-09-01 SPE8 25.973439  14.0978886 37.848990
94  2025-10-01 SPE8 42.924595  30.3632227 55.485968
95  2025-11-01 SPE8 37.304021  24.2524674 50.355574
96  2025-12-01 SPE8 34.047679  20.6725366 47.422821
97  2025-01-01 SPE9 41.838142  40.5628832 43.113400
98  2025-02-01 SPE9 39.504859  36.9967962 42.012922
99  2025-03-01 SPE9 49.253408  44.9115246 53.595291
100 2025-04-01 SPE9 38.452162  32.3238836 44.580440
101 2025-05-01 SPE9 46.824190  39.1312227 54.517156
102 2025-06-01 SPE9 41.510439  32.5233225 50.497556
103 2025-07-01 SPE9 55.181562  45.1687103 65.194413
104 2025-08-01 SPE9 44.234866  33.4385340 55.031198
105 2025-09-01 SPE9 57.281454  45.9072935 68.655614
106 2025-10-01 SPE9 42.743032  30.9574395 54.528624
107 2025-11-01 SPE9 53.800420  41.7324310 65.868409
108 2025-12-01 SPE9 64.414566  52.1602567 76.668875