O modelo abaixo utiliza a biblioteca Facebook Prophet. Esta biblioteca Open Source ajuda a prever dados de série temporal com base em um modelo em que tendências não lineares são ajustadas com sazonalidade anual, semanal e diária, além de efeitos de feriados. Funciona melhor com séries temporais que têm fortes efeitos sazonais e várias temporadas de dados históricos. O Prophet é robusto para dados ausentes e mudanças na tendência, e normalmente lida bem com outliers.
O código pode ser utilizado para qualquer ação, já que utiliza os dados do Yahoo Finance. Nas linhas abaixo vamos descrever as linhas de código que desenham o modelo.
library(dplyr)
library(prophet)
library(quantmod)
nome_acao <- 'MGLU3.SA'
cotacao_historica <- '2018-01-01'
dias_de_previsao <- 360
# Cria um dataframe e importa a série histórica da ação escolhida a partir de uma data
valor_da_acao <- getSymbols(nome_acao, from = cotacao_historica, to = Sys.Date(), auto.assign = FALSE)
# Cria outro dataframe e isola somente a data e o valor que vai ser plotado no eixo Y
df <- data.frame(matrix(ncol = 2, nrow = nrow(valor_da_acao)))
# Atribue nomes às colunas do datraframe 'df'
names_colunas <- c('ds', 'y')
colnames(df) <- names_colunas
# Normaliza a coluna da data
df$ds <- as.Date(index(valor_da_acao), "%y/%m/%d %H:%M")
# Renomeia o nome das colunas do dataframe 'valor_da_acao'
colnames(valor_da_acao) <- c("Abertura", "Máxima", "Mínima", "Fechamento", "Volume", "Ajustado")
# Atribue ao eixo Y do dataframe 'df' o valor do fechamento do datraframe 'valor_da_acao'
df$y <- valor_da_acao$Fechamento
# Roda os modelos de previsão do Prophet (base histórica e futuro)
modelo <- prophet::prophet(df, daily.seasonality = TRUE)
futuro <- prophet::make_future_dataframe(modelo, periods = dias_de_previsao)
# Cria um dataframe com o resultado
forecast <- stats::predict(modelo, futuro)
prophet::dyplot.prophet(modelo, forecast)
# Cria a tabela com as previsões de valor
previsao <- tail(forecast[c('ds', 'yhat', 'yhat_lower', 'yhat_upper')], dias_de_previsao)
# Renomeia o nome das colunas
colnames(previsao) <- c("Data", "Média", "Mínima", "Máxima")
# Arredonda o valor para duas casas decimais
previsao %>% mutate(across(c(Média, Mínima, Máxima), ~ round(., 2)))