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 =108valores =runif(n, min =500, max =2000)inteiros =round(valores)inteiros
VaR_1perc <-quantile(returns, probs =0.01)# Prever volatilidade condicionalsigma <-sigma(fit)# Calcular VaR dinâmico de 1% ajustado para a escala dos retornosVaR_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?”.
---title: "Previsão de vendas e Análise VaR 1% usando GARCH"author: "Marea"format: html: code-fold: true code-tools: truetheme: light: [pulse,custom.scss] dark: [cyborg,custom.scss]title-block-banner: trueexecute: warning: false message: false---## Análise VaR 1% dinâmico e estático + Desvio-padrão condicional de 1 SPEO VaR de 1% significa que com 1% de chance de ter aquelas vendas naquele mês### Gerando valores aleatórios para vendasNota: 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.```{r}library(rmarkdown)library(knitr)library(dplyr)library(rugarch)library(forecast)library(nloptr)set.seed(1992)n =108valores =runif(n, min =500, max =2000)inteiros =round(valores)inteiros```### Gerando as datas e nomeando dados```{r}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```{r}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%```{r}VaR_1perc <-quantile(returns, probs =0.01)# Prever volatilidade condicionalsigma <-sigma(fit)# Calcular VaR dinâmico de 1% ajustado para a escala dos retornosVaR_dynamic <--qnorm(0.01) * sigma```## Plotando resultados```{r}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 DPMeses 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?".```{r}maiores_DP <- returns[returns > sigma]maiores_DP```#### Meses em que os retornos foram menores que o VaR 1% estáticoRepresentam alto risco.```{r}menores_var <- returns[returns < VaR_1perc]menores_var```#### Meses em que os retornos foram maiores que o VaR 1% dinâmicoRepresentam boas oportunidades, já que com 1% de probabilidade de acontecer, aconteceu.```{r}maior_var <- returns[returns >= VaR_dynamic]maior_var```## Previsões para 2025Fiz uma função para calcular as previsões de todas as 10 SPEs#### Criando planilha```{r}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 in1:108) {writeData(wb, sheet ="VendasSPEs", x = tabela[, col], startCol = col, startRow =1)}saveWorkbook(wb, file = nome_arquivo, overwrite =TRUE)```#### Chamando planilha```{r}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```{r}previsao_spes <-function(total_linhas, caminho_arquivo) { resultados <-list()for (i in1: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```{r}previsao_spes(9, caminho_arquivo)```