European stocks rise sharply after Trump postpones the 50% tariff on the EU. According to the ML model, this may boost prices to the $18,000 band for the MSCI Europe Index.
library(tidymodels) library(tidyverse) library(tidyquant) library(modeltime) library(timetk) #MSCI Europe Index #download:https://www.msci.com/indexes/index/990500 df_msci_eur <- read_csv("data/msci_eur.csv") %>% janitor::clean_names() %>% rename(close = value) # Split Data splits <- time_series_split(df_msci_eur, assess = "3 months", cumulative = TRUE) df_train <- training(splits) df_test <- testing(splits) #Model 1: Auto ARIMA model_fit_arima_no_boost <- arima_reg() %>% set_engine(engine = "auto_arima") %>% fit(close ~ date, data = df_train) #Model 2: Boosted Auto ARIMA model_fit_arima_boosted <- arima_boost( min_n = 2, learn_rate = 0.015 ) %>% set_engine(engine = "auto_arima_xgboost") %>% fit(close ~ date + as.numeric(date) + factor(lubridate::month(date, label = TRUE), ordered = F), data = df_train) #Model 3: Exponential Smoothing model_fit_ets <- exp_smoothing() %>% set_engine(engine = "ets") %>% fit(close ~ date, data = df_train) #Model 4: Prophet model_fit_prophet <- prophet_reg() %>% set_engine(engine = "prophet") %>% fit(close ~ date, data = df_train) #Model 5: Linear Regression model_fit_lm <- linear_reg() %>% set_engine("lm") %>% fit(close ~ as.numeric(date) + factor(lubridate::month(date, label = TRUE), ordered = FALSE), data = df_train) #Model 6: MARS library(earth) model_spec_mars <- mars(mode = "regression") %>% set_engine("earth") recipe_spec <- recipe(close ~ date, data = df_train) %>% step_date(date, features = "month", ordinal = FALSE) %>% step_mutate(date_num = as.numeric(date)) %>% step_normalize(date_num) %>% step_rm(date) wflw_fit_mars <- workflow() %>% add_recipe(recipe_spec) %>% add_model(model_spec_mars) %>% fit(df_train) #Radial basis function support vector machines model_spec_svm <- svm_rbf(cost = 1, margin = 0.1) %>% set_mode("regression") %>% set_engine("kernlab") wflw_fit_svm <- workflow() %>% add_recipe(recipe_spec) %>% add_model(model_spec_svm) %>% fit(df_train) #Model Tables models_tbl <- modeltime_table( model_fit_arima_no_boost, model_fit_arima_boosted, model_fit_ets, model_fit_prophet, model_fit_lm, wflw_fit_mars, wflw_fit_svm ) #Calibration calibration_tbl <- models_tbl %>% modeltime_calibrate(new_data = df_test) #Accuracy calibration_tbl %>% modeltime_accuracy() %>% table_modeltime_accuracy( .interactive = TRUE ) #Calibrate the Linear Regression model to a testing set calibration_lm <- model_fit_lm %>% modeltime_calibrate(new_data = df_test) #Predictive intervals (95% Confidence Interval) calibration_lm %>% modeltime_forecast(actual_data = df_msci_eur %>% filter(date >= last(date) - months(3)), new_data = testing(splits)) %>% plot_modeltime_forecast(.interactive = FALSE, .legend_show = FALSE, .line_size = 1.5, .color_lab = "", .title = "MSCI Europe Index") + ggrepel::geom_text_repel( data = df_msci_eur %>% slice_tail(n = 1), aes(label = paste0("$",format(round(close , 2), big.mark = ",")), x= date, y = close), hjust = 1, vjust = .5, nudge_x = 0.5, fontface = "bold", family = "Roboto Slab", size = 6, color = "black", segment.color = NA ) + ggrepel::geom_text_repel( data = . %>% slice_tail(n = 1), aes(label = paste0("$",format(round(.conf_hi,2), big.mark = ",")), x= .index, y = .conf_hi), hjust = 1, vjust = 1, nudge_x = .5, fontface = "bold", family = "Roboto Slab", size = 6, color = "dimgray", segment.color = NA ) + labs(subtitle = "<span style = 'color:dimgrey;'>Predictive Intervals</span><br><span style = 'color:red;'>ML Model</span>") + scale_x_date(expand = expansion(mult = c(.1, .25)), labels = scales::label_date(format = "%b'%y")) + scale_y_continuous(labels = scales::label_currency()) + theme_minimal(base_family = "Roboto Slab", base_size = 20) + theme(legend.position = "none", plot.background = element_rect(fill = "azure", color = "azure"), plot.title = element_text(face = "bold"), axis.text = element_text(face = "bold"), plot.subtitle = ggtext::element_markdown(face = "bold")) ################################################################################