Discussion 5

Author

Sam Kuhn

Read data

library(tidyverse)
library(fpp3)
library(ggthemes)
library(tidyquant)
theme_set(theme_calc())
theme_update(axis.title = element_blank())

Retrieve ticker data

stocks <- tidyquant::tq_get(
  x = c("TSLA", "AMZN", "AMD", "AAPL", "NVDA"),
  get = "stock.prices"
)
stocks <- stocks |> 
  mutate(industry = case_when(
    symbol %in% c("TSLA", "AMZN") ~ "Retail",
    symbol %in% c("AMD", "AAPL", "NVDA") ~ "Tech"
  ))

Plot

stocks |> 
  ggplot(aes(date, close)) +
  geom_line(color = "#00AFBB") +
  labs(
    title = "Daily close price for major tech stocks"
  ) +
  facet_wrap(~symbol, scales = "free_y")

Create aggregate tsibble

stocks_ts <- stocks |> 
  group_by(week = yearmonth(date), symbol, industry) |> 
  summarise(
    weekly_close = mean(close)
  ) |> 
  as_tsibble(index = week, key = c(symbol, industry)) |> 
  aggregate_key(symbol / industry, close = mean(weekly_close))

Train/test splits

train <- stocks_ts |> 
  filter_index("2013 Jan" ~ "2019 Feb")
test <- stocks_ts |> 
  filter_index("2019 Mar" ~ .)

Fit models

stocks_fit <- train |> 
  model(
    additive_ets = ETS(close ~ error("A") + trend("A") + season("A")),
    stochastic = ARIMA(close ~ pdq(d = 1))
  )
stocks_fit |> glance()
# A tibble: 22 × 13
   symbol industry     .model       sigma2 log_lik   AIC  AICc   BIC   MSE  AMSE
   <chr*> <chr*>       <chr>         <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 AAPL   Tech         additive_ets   5.59   -214.  462.  473.  501.  4.38 11.6 
 2 AAPL   Tech         stochastic     4.13   -155.  314.  314.  318. NA    NA   
 3 AAPL   <aggregated> additive_ets   5.59   -214.  462.  473.  501.  4.38 11.6 
 4 AAPL   <aggregated> stochastic     4.13   -155.  314.  314.  318. NA    NA   
 5 AMD    Tech         additive_ets   3.81   -200.  433.  444.  473.  2.98  6.48
 6 AMD    Tech         stochastic     3.28   -146.  298.  298.  305. NA    NA   
 7 AMD    <aggregated> additive_ets   3.81   -200.  433.  444.  473.  2.98  6.48
 8 AMD    <aggregated> stochastic     3.28   -146.  298.  298.  305. NA    NA   
 9 AMZN   Retail       additive_ets  10.4    -237.  508.  519.  547.  8.14 23.9 
10 AMZN   Retail       stochastic     7.04   -174.  355.  356.  365. NA    NA   
# ℹ 12 more rows
# ℹ 3 more variables: MAE <dbl>, ar_roots <list>, ma_roots <list>

Generate forecasts

stocks_fc <- stocks_fit |> 
  reconcile(
    bottoms_up = bottom_up(stochastic),
    middle_out = middle_out(stochastic),
    top_down = top_down(stochastic)
  ) |> 
  forecast(h = 12)

Accuracy metrics

stocks_fc |>
  filter(is_aggregated(industry), is_aggregated(symbol)) |>
  accuracy(
    data = stocks_ts,
    measures = list(rmse = RMSE, mase = MASE)
  ) |>
  group_by(.model) |>
  summarise(rmse = mean(rmse), mase = mean(mase))
# A tibble: 5 × 3
  .model         rmse   mase
  <chr>         <dbl>  <dbl>
1 additive_ets  12.5   1.35 
2 bottoms_up   162.   23.2  
3 middle_out   162.   23.2  
4 stochastic     9.39  0.920
5 top_down       9.39  0.920

Plot

stocks_fc |> 
  autoplot(stocks_ts |> 
             filter_index(.~ "2020 Feb")) +
  facet_wrap(vars(symbol, industry))