start_time <- Sys.time()
Algoritmos de Deep Learning para forecasting de Séries Temporais Financeiras
Neste post demonstraremos brevemente como podemos utilizar algoritmos de Deep Learning para série temporal financeira da commoditie milho negociada na bolsa de valores de Chicago. Com o objetivo de fornecer uma boa coerência no que diz respeito ao movimento esperado pelo mercado no futuro, este método é útil para direcionar as estratégias de investimento e de compra e venda para os negociadores deste importante ativo. Os dados foram extraídos com um delay de um dia do Yahoo!Finance para os preços de fechamento e de volume de negociação (oferta e demanda) na bolsa de Chicago (CBOT) considerando que os dias de trade no mercado americano não contemplam os feriados nacionais e sábados e domingos. Destacamos aqui que nenhum método econométrico adequado inferencial foi estimado com outras variáveis fora o volume de negociação, como por exemplo, condições climáticas, ciclos de safra, preços de bens substitutos e complementares, variáveis relacionadas as expectativas do mercado (crítica de Lucas) e movimentos especulativos (modelos da família GARCH e volatilidades condicionais) demanda chinesa e dos principais players. Os resultados apresentados nas projeções carecem de uma avaliação relativamente subjetiva ao se observar as projeções para fora da amostra total ao se considerar que o exercício de validação cruzada das séries temporais analisadas não foram implementadas por uma questão de economia de recursos computacionais.
Carrega os pacotes do R:
# Loading R packages
library(tidymodels)
library(modeltime)
library(modeltime.ensemble)
library(tidyverse)
library(dplyr)
library(tidyr)
library(lubridate)
library(magrittr)
library(timetk)
library(quantmod)
library(tsibble)
library(tsibbledata)
library(data.table)
library(dygraphs)
library(sarbcurrent)
library(strucchange)
library(changepoint)
library(xts)
library(zoo)
library(flipTime)
library(fpp3)
CORN <- getSymbols("CORN", auto.assign = FALSE,
from = "2010-06-09", end = Sys.Date()) # Extrai os dados desde jun-2010 até ontem
tail(CORN) # Ultimas 5 observacoes do dataset
CORN.Open CORN.High CORN.Low CORN.Close CORN.Volume CORN.Adjusted
2022-10-25 27.10 27.43 27.10 27.31 201200 27.31
2022-10-26 27.39 27.46 27.28 27.29 102600 27.29
2022-10-27 27.33 27.40 27.10 27.18 188500 27.18
2022-10-28 27.07 27.24 26.98 27.09 140600 27.09
2022-10-31 27.59 27.64 27.22 27.41 215300 27.41
2022-11-01 27.47 27.74 27.42 27.73 121600 27.73
O primeiro passo para uma análise de uma série temporal consiste na sua inspeção visual
# Função log retornos
ret<-function(x,k=1){
return(diff(log(x),k))
}
grupo <- cbind( Cl(CORN), ret(Cl(CORN),1), Vo(CORN), ret(Vo(CORN), 1 ) )
dygraph(Cl(CORN), group = "grupo" ) %>% dyRangeSelector() # Grafico das cotacoes de Fechamento
dygraph(ret(Cl(CORN), 1 ), group = "grupo") %>% dyRangeSelector() # Grafico dos retornos do Fechamento
E para o volume de negociação
dygraph(Vo(CORN), group = "grupo") %>% dyRangeSelector() # Grafico do Volume negociado
dygraph(ret(Vo(CORN),1), group = "grupo") %>% dyRangeSelector() # Grefico dos retornos do Volume de negociacao
Este teste busca encontrar em quais pontos houveram quebras estruturais na série temporal dos preços (alvo) com o objetivo futuro de criação de features para cada reversão de tendência/trajetória identificada.
Quando utilizamos um modelo de regressão que envolve o uso de séries temporais, pode acontecer que se verifique uma mudança estrutural na relação entre o regressando e os regressores.
Por mudança estrutural entendemos que os valores dos parâmetros do modelo não se mantêm iguais durante todo o período de tempo. Às vezes, a mudança estrutural decorre de forças externas (por exemplo, os embargos do petróleo impostos pela Opep em 1973 e 1979 ou a Guerra do Golfo de 1990-1991) ou por mudanças na política econômica (como a passagem de um sistema de câmbio fixo para outro de taxa flutuante por volta de 1973) ou por ações tomadas pelo Congresso (como as mudanças tributárias promovidas pelo presidente Reagan ou alterações do salário mínimo) ou várias outras causas. (Gujarati, 2000, p. 268)
dygraph( CORN$CORN.Close ) %>%
dyShading(from = "2011-06-30", to = "2011-09-01") %>%
dyAnnotation("2011-08-01", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2011-06-30", "JUl 2011", labelLoc = "bottom") %>%
dyEvent("2011-09-01", "Set 2011", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2012-05-13", to = "2012-09-21") %>%
dyAnnotation("2012-07-13", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2012-05-13", "Maio de 2012", labelLoc = "bottom") %>%
dyEvent("2012-09-21", "Set 2012", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2014-04-15", to = "2014-10-22") %>%
dyAnnotation("2014-07-09", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2014-04-15", "Abril de 2014", labelLoc = "bottom") %>%
dyEvent("2014-10-22", "Out 2014", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2015-06-01", to = "2015-09-04") %>%
dyAnnotation("2015-07-01", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2015-06-01", "Jun 2015", labelLoc = "bottom") %>%
dyEvent("2015-09-04", "Set 2015", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2016-05-05", to = "2016-07-18") %>%
dyAnnotation("2016-07-01", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2016-05-05", "Jul 2015", labelLoc = "bottom") %>%
dyEvent("2016-07-18", "Jul 2016", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2020-06-25", to = "2021-05-28") %>%
dyAnnotation("2021-01-12", text = "X", tooltip = "Exemplo de provável quebra estrutural") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2020-06-25", "Jun 2020", labelLoc = "bottom") %>%
dyEvent("2021-05-28", "Mai 2021", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyRangeSelector()
Iniciamos rodando o teste de Bai & Perron, para múltiplas quebras estruturais com o auxílio dos seguintes comandos:
CORN_tsibble <- CORN %>% as.data.table() %>% as_tsibble() %>%
fill_gaps() %>%
fill(c(CORN.Open, CORN.High, CORN.Low, CORN.Close, CORN.Volume, CORN.Adjusted), .direction = "down")
fstats_CORN <- Fstats(CORN_tsibble$CORN.Close ~ 1)
breakpoints(fstats_CORN)
Optimal 2-segment partition:
Call:
breakpoints.Fstats(obj = fstats_CORN)
Breakpoints at observation number:
1484
Corresponding to breakdates:
0.3274454
O teste de Chow pode ser confirmado ao rodarmos:
sctest(CORN_tibble[,"CORN.Close"] ~ 1, type = "Chow", point = 1489)
O ponto de quebra apontado pelo resultado do teste acima refere-se a data:
CORN_tibble <- CORN %>%
as.data.table() %>%
as_tibble() %>%
mutate(
obs = seq_along(CORN.Close)
)
CORN_tibble %>%
filter(
obs == "1489"
)
Mas conforme anotamos no gráfico da série de preço do milho acima, esperamos que tenhamos mais pontos de quebra. O procedimento de datação de Bai e Perron (2003) emprega um algoritmo de programação dinâmico baseado no princípio de Bellman para encontrar aqueles \(m\) pontos de interrupção que minimizam a soma residual dos quadrados (RSS) de um modelo com \(m+1\) segmentos, dado algum tamanho mínimo de segmento de \(h⋅n\) observações. Aqui, \(h\) é um parâmetro de largura de banda/horizonte a ser escolhido pelo usuário.
bp.CORN <- breakpoints(CORN$CORN.Close ~ 1)
summary(bp.CORN)
Optimal (m+1)-segment partition:
Call:
breakpoints.formula(formula = CORN$CORN.Close ~ 1)
Breakpoints at observation number:
m = 1 1023
m = 2 823 1291
m = 3 833 1366 2655
m = 4 823 1291 1813 2655
m = 5 783 1251 1719 2187 2655
Corresponding to breakdates:
m = 1 0.327569644572526
m = 2 0.263528658341338 0.413384566122318
m = 3 0.266730707652898 0.437399935959014
m = 4 0.263528658341338 0.413384566122318 0.580531540185719
m = 5 0.250720461095101 0.400576368876081 0.550432276657061 0.70028818443804
m = 1
m = 2
m = 3 0.85014409221902
m = 4 0.85014409221902
m = 5 0.85014409221902
Fit:
m 0 1 2 3 4 5
RSS 347189 79746 64143 53890 46785 45931
BIC 23591 19014 18350 17822 17396 17355
Mais claramente nas datas:
CORN_tibble %>%
filter(
obs == "1141" |
obs == "1149" |
obs == "1209" |
obs == "1256" |
obs == "1489"
)
CORN <- CORN %>%
mutate(
obs = seq_along()
)
CORN %>%
filter(
obs == "1141" |
obs == "1149" |
obs == "1209" |
obs == "1256" |
obs == "1489"
)
Marcando no gráfico visualizamos:
dygraph( CORN$CORN.Close ) %>%
dyShading(from = "2014-12-17", to = "2014-12-17") %>%
dyAnnotation("2014-12-17", text = "X", tooltip = "Quebra") %>%
dyAxis("x", drawGrid = TRUE) %>%
dyEvent("2014-12-17", "Quebra Estrutural", labelLoc = "bottom") %>%
# dyEvent("2015-01-23", ".", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2015-02-27", to = "2015-04-27") %>%
dyAnnotation("2015-03-27", text = "X", tooltip = "Quebra") %>%
dyAxis("x", drawGrid = TRUE) %>%
# dyEvent("2015-02-27", "Quebra Estrutural", labelLoc = "bottom") %>%
# dyEvent("2015-04-27", ".", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2015-05-04", to = "2015-07-04") %>%
dyAnnotation("2015-06-04", text = "X", tooltip = "Quebra") %>%
dyAxis("x", drawGrid = TRUE) %>%
# dyEvent("2015-05-04", "Quebra Estrutural", labelLoc = "bottom") %>%
# dyEvent("2015-07-04", ".", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyShading(from = "2015-04-04", to = "2015-07-04") %>%
dyAnnotation("2015-06-04", text = "X", tooltip = "Quebra") %>%
dyAxis("x", drawGrid = TRUE) %>%
# dyEvent("2015-04-04", "Quebra Estrutural", labelLoc = "bottom") %>%
dyEvent("2015-07-04", ".", labelLoc = "bottom") %>%
dyOptions(drawPoints = FALSE, pointSize = 2) %>%
dyRangeSelector()
Note que estes resultados marcados neste gráfico diferem do que marcamos anteriormente. Conforme elucidado conceitualmente entende-se por mudança estrutural, uma mudança significativa do patamar de preços para outro nível/estado.
Consideraremos aqui o volume de negociação do ativo CORN
como proxy do resultado do fluxo diário de oferta e demanda na
CBOT. Para os modelos de deep learning que iremos implementar
construiremos features não de modo automático mas sim com base
em critério econômicos onde eventos (variáveis de confusão como diria
Josh Angrist) se mostraram causadores de deslocamentos (picos, vales e
quebras/inversões de tendências) na série de preço.
Inicialmente precisamos construir um dataframe contendo as variáveis necessárias e para tal finalidade iniciamos mensalizando nossos dados, ou seja, utilizaremos somente os valores de fechamento de cada mês.
CORN_df <- CORN_tibble %>%
select(
index,
CORN.Close,
CORN.Volume,
#obs
)
CORN_df <- data.frame(
CORN_df,
ret(CORN$CORN.Close),
ret(CORN$CORN.Volume)
) %>%
rename(
"Datas" = index,
"ret_precos" = CORN.Close.1,
"ret_volume" = CORN.Volume.1
)
dataset_xts <- xts(CORN_df[,-1], order.by = CORN_df[,1])
dataset_monthly <- aggregate(dataset_xts, as.Date(as.yearmon(time(dataset_xts))), last) # Using the last value in each month
dataset_monthly <- fortify.zoo(dataset_monthly)
names(dataset_monthly)[1] <- "Datas" # Renomeio a primeira coluna no zoo
CORN_df <- dataset_monthly %>% as.data.frame() %>%
# mutate(
# Datas = yearmonth(Datas)
#) %>%
as_tibble()
# colnames(CORN_df)[1] <- "Datas" # renomeio a primeira coluna do df
head(CORN_df)
Pivoteamos o dataframe mensalizado para criarmos a feature dos ranges de tendências e inversões de trajetórias
CORN_df <- CORN_df %>%
pivot_longer(
cols = -c(Datas),
names_to = "Target",
values_to = "value",
names_prefix = "index_"
) %>%
mutate( id = Target )
Graficamente:
CORN_df %>%
group_by(id) %>%
plot_time_series(
Datas,
value,
.facet_ncol = 1,
.interactive = TRUE
)
Construindo um dataframe para o forecast 24 meses à frente:
HORIZON <- 12*2 # 24 meses à frente
new_data <- CORN_df %>%
group_by(id) %>%
future_frame(.length_out = HORIZON) %>%
ungroup()
#new_data
Separo 80% para treino e outros 20% para teste:
CORN_splits <- initial_time_split(CORN_df, prop = 0.8)
Este é conhecido como o modelo de Deep Learning Autoregressivo de Inteligência Artificial para Séries Temporais
# Deep Learning packages
library(modeltime.gluonts)
library(modeltime.h2o)
install_gluonts()
model_fit_deepar <- deep_ar(
id = "id",
freq = "M", # M, Y, W, D
prediction_length = HORIZON, # 24 meses
lookback_length = 2*HORIZON, # 2*24 meses
epochs = 5
) %>%
set_engine("gluonts_deepar") %>%
fit(value ~ Datas + id , training(CORN_splits))
model_fit_deepar
parsnip model object
DeepAR
--------
Model: <gluonts.mx.model.predictor.RepresentableBlockPredictor object at 0x0000013F422AA470>
gluonts.model.deepar._network.DeepARPredictionNetwork(cardinality=[1], cell_type="lstm", context_length=48, default_scale=None, distr_output=gluonts.mx.distribution.student_t.StudentTOutput(), dropout_rate=0.1, dropoutcell_type="ZoneoutCell", dtype=numpy.float32, embedding_dimension=[1], history_length=85, impute_missing_values=False, lags_seq=[1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 23, 24, 25, 35, 36, 37], minimum_scale=1e-10, num_cells=40, num_imputation_samples=1, num_layers=2, num_parallel_samples=100, prediction_length=24, scaling=True)
Este modelo é um ensemble de Deep Learning conhecido como N-BEATS: Neural basis expansion analysis for interpretable time series forecasting.
model_fit_nbeats_ensemble <- nbeats(
id = "id",
freq = "M", # D
prediction_length = HORIZON,
lookback_length = 2*HORIZON,
epochs = 5,
num_batches_per_epoch = 15,
batch_size = 1
) %>%
set_engine("gluonts_nbeats_ensemble") %>%
fit(value ~ Datas + id, training(CORN_splits))
model_fit_nbeats_ensemble
parsnip model object
NBEATS ENSEMBLE
--------
Model: <gluonts.model.n_beats._ensemble.NBEATSEnsemblePredictor object at 0x0000013F5A79A358>
# Forecast with 95% Confidence Interval using GluonTS DeepAR Model and N-Beats Ensemble Deep Learning Model
modeltime_table(
model_fit_deepar,
model_fit_nbeats_ensemble
) %>%
modeltime_calibrate(new_data = testing(CORN_splits)) %>%
modeltime_forecast(
new_data = testing(CORN_splits),
actual_data = CORN_df,
conf_interval = 0.95
) %>%
plot_modeltime_forecast(
.conf_interval_show = TRUE,
.facet_ncol = 1,
.facet_scales = "free",
.interactive = TRUE)
Ressalta-se que os valores negativos projetados pelo modelo referem-se aos dados de retornos.
E comparando com o auxílio das métricas de perfomance podemos avaliar:
models_tbl <- modeltime_table(
model_fit_deepar,
model_fit_nbeats_ensemble
)
models_tbl %>%
modeltime_calibrate(new_data = testing(CORN_splits)) %>%
modeltime_accuracy(
metric_set = metric_set(
smape,
mae,
rmse,
rsq # R^2
)
)
model_fit_deepar <- deep_ar(
id = "id",
freq = "D", # D
prediction_length = HORIZON,
lookback_length = 2*HORIZON,
epochs = 5#,
# learn_rate = 0.01
) %>%
set_engine("gluonts_deepar") %>%
fit(value ~ Datas + id, CORN_df )
model_fit_deepar
parsnip model object
DeepAR
--------
Model: <gluonts.mx.model.predictor.RepresentableBlockPredictor object at 0x0000013F5A4C5F60>
gluonts.model.deepar._network.DeepARPredictionNetwork(cardinality=[1], cell_type="lstm", context_length=48, default_scale=None, distr_output=gluonts.mx.distribution.student_t.StudentTOutput(), dropout_rate=0.1, dropoutcell_type="ZoneoutCell", dtype=numpy.float32, embedding_dimension=[1], history_length=1141, impute_missing_values=False, lags_seq=[1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 20, 21, 22, 27, 28, 29, 30, 31, 56, 84, 363, 364, 365, 727, 728, 729, 1091, 1092, 1093], minimum_scale=1e-10, num_cells=40, num_imputation_samples=1, num_layers=2, num_parallel_samples=100, prediction_length=24, scaling=True)
Podemos verificar graficamente
modeltime_forecast_tbl <- modeltime_table(
model_fit_deepar
) %>%
modeltime_forecast(
new_data = new_data,
actual_data = CORN_df,
keep_data = TRUE
) %>%
group_by(id)
modeltime_forecast_tbl %>%
plot_modeltime_forecast(
.conf_interval_show = FALSE,
.facet_ncol = 1,
.facet_scales = "free",
.interactive = TRUE
)
Reestima o modelo para o dataset full:
model_fit_nbeats_ensemble <- nbeats(
id = "id",
freq = "M",
prediction_length = HORIZON, # 30 dias x 24 meses
lookback_length = 2*HORIZON,
epochs = 5
# num_batches_per_epoch = 15,
# batch_size = 1# ,
# learn_rate = 0.01
) %>%
set_engine("gluonts_nbeats_ensemble") %>%
fit(value ~ Datas + id, CORN_df)
model_fit_nbeats_ensemble
parsnip model object
NBEATS ENSEMBLE
--------
Model: <gluonts.model.n_beats._ensemble.NBEATSEnsemblePredictor object at 0x0000013F5A7A01D0>
Graficamente temos:
modeltime_forecast_tbl <- modeltime_table(
model_fit_nbeats_ensemble
) %>%
modeltime_forecast(
new_data = new_data,
actual_data = CORN_df,
keep_data = TRUE
) %>%
group_by(id)
modeltime_forecast_tbl %>%
plot_modeltime_forecast(
.conf_interval_show = FALSE,
.facet_ncol = 1,
.facet_scales = "free",
.interactive = TRUE
)
Como visto as métricas de acurácia x as projeções pra fora da amostra se mostraram bem limitadas, o que nos conduz a atribuir maior relevância no critério de escolha puramente visual pelo sentido subjetivo de nossa expectativa em relação à coerência com o comportamento futuro.
Assim, escolhemos o modelo N-Beats como guia e geramos o dataframe com os valores projetados para o final de cada mês à frente:
modeltime_forecast_tbl
Em seguida, precisamos transformar esse dataframe com os nossos valores de interesse num modelo de forecast diário. Filtrando temos,
precos_projetados <- modeltime_forecast_tbl %>%
select(
.key,
.index,
Target,
.value,
) %>% as.data.frame() %>%
filter(
.key == "prediction" |
Target == "CORN.Close"
)
precos_projetados <- data.frame(
precos_projetados$.index,
precos_projetados$id,
precos_projetados$.key,
precos_projetados$.value
) %>% rename(
index = "precos_projetados..index",
id = "precos_projetados.id",
key = "precos_projetados..key",
value = "precos_projetados..value"
) %>%
filter(
key == "prediction",
id == "CORN.Close"
) %>%
mutate(
index = AsDate(index),
index = zoo::as.yearmon(index, "%b%y"),
value = round(value, 2)
) %>% select(
index,
id,
value
)
precos_projetados
Agora que obtivemos os valores projetados, partiremos para um processo conhecido como bootstraping para interpolar os dados projetados mês a mês para uma granularidade diária.
O primeiro passo consiste em criar um vetor das datas no formato
mês-ano
do tipo 01-2022
p. ex. e assim
sucessivamente até o 24º mês á frente
precos_projetados <- precos_projetados %>%
mutate(index = c(
"01-2022",
"02-2022",
"03-2022",
"04-2022",
"05-2022",
"06-2022",
"07-2022",
"08-2022",
"09-2022",
"10-2022",
"11-2022",
"12-2022",
"01-2023",
"02-2023",
"03-2023",
"04-2023",
"05-2023",
"06-2023",
"07-2023",
"08-2023",
"09-2023",
"10-2023",
"11-2023",
"12-2023")
)%>%
mutate(index = AsDate(index),
index = zoo::as.yearmon(index, "%b%y"))
glimpse(precos_projetados)
Rows: 24
Columns: 3
$ index <yearmon> jan 2022, fev 2022, mar 2022, abr 2022, mai 2022, jun 2022, …
$ id <chr> "CORN.Close", "CORN.Close", "CORN.Close", "CORN.Close", "CORN.Cl…
$ value <dbl> 23.66, 21.29, 22.25, 23.03, 21.14, 22.69, 22.50, 23.35, 21.69, 2…
write.csv(precos_projetados, "precos_projetados.csv", row.names = FALSE)
Agora criamos uma função interativa que transforma os dados mensais em diários:
mes_pra_dia <- function( variavel, mes_ref ){
set.seed(123)
for (i in 1:length(variavel)){
valores_no_mes <- abs(variavel[i] + arima.sim(model = list(order = c(1, 1, 1), ar = 0.5, ma = 0.5),
n = days_in_month(mes_ref[i])-1, mean = 0, sd = 5)) %>%
as.data.frame() %>%
mutate(
mes_ano = paste(month(mes_ref[i]), "-" , year(mes_ref[i]) )
) %>%
rename(variavel = "x")
print(valores_no_mes)
}
}
Em nosso dataframe de valores projetados teremos:
fcst_diario <- mes_pra_dia(precos_projetados$value,
precos_projetados$index)
Os modelos de redes neurais profundas (deep learning) apresentados se mostraram altamente capazes de gerar projeções futuras como direcionadores de cenários para auxiliar substancialmente os participantes (players) da principal bolsa de commodities do mundo (Chicago) com clareza no processo de tomada de decisão e formualações de estratégia de investimento. Ao considerar o volume de negociação como proxy dos movimentos de oferta e demanda (dia a dia de pregão) contra os retornos dos preços e volume somado aos movimentos de tendência identificáveis a olho nú fora dos períodos de "quebra" temos um modelo com um raciocínio econômico pré-estabelecido para evoluir numa combinmação interessante com modelos econométricos no futuro. Todavia, os resultados apresentados pelos modelos apresentam algumas limitações a saber: - As métricas de perfomance ao compararmos os dois modelos de deep learning para séries temporais se mostram evidentes, todavia ao observarmos os resultados dos forecastings para fora da amostra notamos uma razoabilidade nos valores previstos pelo N-Beats Ensemble Model. - Incapacidade de identificar os fatos geradores (inferência causal) dos movimentos que justificariam as quebras nas séries temporais e consequentemente os movimentos que deslocariam as curvas de volume e preço; (para uma possível alternativa, consulte o pacote desenvolvido pelo Google ``causalImpact``) - Limitação para medir o efeito de recuperação pós-crises eminentes ou aglomerações de volatilidade ou nervosismo de mercado, muito comuns nos dados investigados (para uma possível alternativa, vide modelos da família GARCH)
Bai, Jushan, and Pierre Perron. 2003. “Computation and Analysis of Multiple Structural Change Models.” Journal of Applied Econometrics 18 (1): 1–22.
Brodersen KH, Gallusser F, Koehler J, Remy N, Scott SL. Inferring causal impact using Bayesian structural time-series models. Annals of Applied Statistics, 2015, Vol. 9, No. 1, 247-274. http://research.google.com/pubs/pub41854.html
Brodersen, K. H. Inferring the effect of an event using CausalImpact by Kay Brodersen in YouTube
Chow, Gregory C. Econometric methods. Nova York: McGraw-Hill, 1983.
Chow, Gregory C. “Tests of equality between sets of coefficients in two linear regressions”. Econometrica, v. 28, n. 3, 1960. p. 591-605.
Gujarati, D., N. Econometria Básica, 3a. ed. São Paulo, 2020.
citation(package = "modeltime.gluonts")
To cite package 'modeltime.gluonts' in publications use:
Dancho M (2022). _modeltime.gluonts: 'GluonTS' Deep Learning_. R
package version 0.3.1,
<https://github.com/business-science/modeltime.gluonts>.
A BibTeX entry for LaTeX users is
@Manual{,
title = {modeltime.gluonts: 'GluonTS' Deep Learning},
author = {Matt Dancho},
year = {2022},
note = {R package version 0.3.1},
url = {https://github.com/business-science/modeltime.gluonts},
}
citation(package = "modeltime")
To cite package 'modeltime' in publications use:
Dancho M (2022). _modeltime: The Tidymodels Extension for Time Series
Modeling_. R package version 1.2.3,
<https://CRAN.R-project.org/package=modeltime>.
A BibTeX entry for LaTeX users is
@Manual{,
title = {modeltime: The Tidymodels Extension for Time Series Modeling},
author = {Matt Dancho},
year = {2022},
note = {R package version 1.2.3},
url = {https://CRAN.R-project.org/package=modeltime},
}
citation(package = "tidymodels")
To cite package 'tidymodels' in publications use:
Kuhn et al., (2020). Tidymodels: a collection of packages for
modeling and machine learning using tidyverse principles.
https://www.tidymodels.org
A BibTeX entry for LaTeX users is
@Manual{,
title = {Tidymodels: a collection of packages for modeling and machine learning using tidyverse principles.},
author = {Max Kuhn and Hadley Wickham},
url = {https://www.tidymodels.org},
year = {2020},
}
citation(package = "timetk")
To cite package 'timetk' in publications use:
Dancho M, Vaughan D (2022). _timetk: A Tool Kit for Working with Time
Series in R_. R package version 2.8.1,
<https://CRAN.R-project.org/package=timetk>.
A BibTeX entry for LaTeX users is
@Manual{,
title = {timetk: A Tool Kit for Working with Time Series in R},
author = {Matt Dancho and Davis Vaughan},
year = {2022},
note = {R package version 2.8.1},
url = {https://CRAN.R-project.org/package=timetk},
}
Contador do tempo total de execução.
end_time <- Sys.time()
end_time - start_time
Time difference of 9.676882 mins