Setting paths and loading packages

setwd('/Users/yeshimonipede/Desktop/BC_Spring2024/Discussion5')
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(hts)
library(ggplot2)

#consumer defense sector
walmart <- read.csv("WMT.csv") %>% select(Date, Close)
target <- read.csv("TGT.csv") %>% select(Date, Close)
#communication services
spotify <- read.csv("SPOT.csv") %>% select(Date, Close)
netflix <- read.csv("NFLX.csv") %>% select(Date, Close)


start_train <- c(2019,5)
end_train <- c(2023,4)
start_test <- c(2023,5)
end_test <- c(2024,4)

# Create time series objects
walmart_ts <- ts(walmart$Close, start = c(2019,5), frequency = 12)
target_ts <- ts(target$Close, start = c(2019,5), frequency = 12)
spotify_ts <- ts(spotify$Close, start = c(2019,5), frequency = 12)
netflix_ts <- ts(netflix$Close, start = c(2019,5), frequency = 12)

Creating the mutual fund

library(hts)

# Create individual time series for each stock or asset class
walmart_ts <- ts(walmart$Close, start = c(2019, 5), frequency = 12)
target_ts <- ts(target$Close, start = c(2019, 5), frequency = 12)
spotify_ts <- ts(spotify$Close, start = c(2019, 5), frequency = 12)
netflix_ts <- ts(netflix$Close, start = c(2019, 5), frequency = 12)

# Combine the individual time series into a multivariate time series
mutual_fund_ts <- cbind(CDFWMT = walmart_ts,
                        CDFTGT = target_ts,
                        CMSNFX=netflix_ts,
                        CMSSPT= netflix_ts)

#Creating train and test
mutual_fund_train<-window(mutual_fund_ts, start=start_train, end=end_train)
mutual_fund_test<-window(mutual_fund_ts, start=start_test, end=end_test)


# Create hierarchical time series object
mutual_fund_hts <- hts(mutual_fund_train, characters = c(3,3)) 
mutual_fund_hts %>% aggts(levels=0:2)%>% autoplot(facet=TRUE)+xlab("Year")

Bottom_up

bu<-forecast(mutual_fund_hts,method="bu",fmethod="arima",h=12)

# Calculate accuracy measures
accuracy(bu$bts, mutual_fund_test)
##                ME     RMSE      MAE       MPE     MAPE     ACF1 Theil's U
## Test set 75.56459 144.6493 127.1471 -16.52679 78.48563 0.854921  3.746589

Top-down

td<-forecast(mutual_fund_hts,method="tdfp",fmethod="arima",h=12)

accuracy(td$bts, mutual_fund_test)
##                ME     RMSE      MAE       MPE     MAPE      ACF1 Theil's U
## Test set 57.22532 128.9796 115.4743 -26.04679 80.96994 0.8550281  4.110294

Middle-out

mo<-forecast(mutual_fund_hts,method="mo",fmethod="arima",level=2)

accuracy(mo$bts, mutual_fund_test)
##                ME     RMSE      MAE       MPE     MAPE     ACF1 Theil's U
## Test set 75.56459 144.6493 127.1471 -16.52679 78.48563 0.854921  3.746589

Conclusion:

Based off of the lower ME, RMSE, and MPE, the top down model performed the best of the three models. The ACF1 measures the correlation between forecast errors at different lags. All models have similar ACF1 values which suggests similar levels of autocorrelation. The bottoms up and middle out models have lower Theil’s U values.

Something strange is that the middle out and top down models have the same forecasts and therefore the same accuracy metrics. They also forecast the same value for every upcoming month and I am not sure why.