### Environment
# Clear the workspace
rm(list = ls()) # Clear environment
gc() # Clear unused memory
## used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
## Ncells 522848 28.0 1159205 62 NA 669291 35.8
## Vcells 970910 7.5 8388608 64 16384 1840004 14.1
cat("\f") # Clear the console
dev.off # Clear the charts
## function (which = dev.cur())
## {
## if (which == 1)
## stop("cannot shut down device 1 (the null device)")
## .External(C_devoff, as.integer(which))
## dev.cur()
## }
## <bytecode: 0x7fef54a43830>
## <environment: namespace:grDevices>
#make vector containing the packages
packages <- c("ggplot2",
"knitr",
"fpp3",
"forecast",
"dplyr",
"lubridate",
"grid",
"gridExtra")
#Install packages
for (i in 1:length(packages)) {# Iterate through each package in the 'packages' vector.
if (!packages[i] %in% rownames(installed.packages())) {#check if package is installed
install.packages(packages[i], #install package if it isn't already
repos = "http://cran.rstudio.com/",
dependencies = TRUE)}
library(packages[i], character.only = TRUE)} # Load the package into the R session.
## ── Attaching packages ────────────────────────────────────────────── fpp3 0.5 ──
## ✔ tibble 3.2.1 ✔ tsibbledata 0.4.1
## ✔ dplyr 1.1.1 ✔ feasts 0.3.2
## ✔ tidyr 1.3.0 ✔ fable 0.3.3
## ✔ lubridate 1.9.2 ✔ fabletools 0.4.1
## ✔ tsibble 1.1.4
## ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
## ✖ lubridate::date() masks base::date()
## ✖ dplyr::filter() masks stats::filter()
## ✖ tsibble::intersect() masks base::intersect()
## ✖ tsibble::interval() masks lubridate::interval()
## ✖ dplyr::lag() masks stats::lag()
## ✖ tsibble::setdiff() masks base::setdiff()
## ✖ tsibble::union() masks base::union()
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
# Remove unnecessary values from environment
rm(i,packages)
### Data
# Import datasets
# Energy
ET <- read.csv("/Users/cam/Desktop/PREDICTIVE ANALYTICS/Discussions/Data/ET_stock.csv")
XOM <- read.csv("/Users/cam/Desktop/PREDICTIVE ANALYTICS/Discussions/Data/XOM_stock.csv")
# Pharma
LLY <- read.csv("/Users/cam/Desktop/PREDICTIVE ANALYTICS/Discussions/Data/LLY_stock.csv")
NVO <- read.csv("/Users/cam/Desktop/PREDICTIVE ANALYTICS/Discussions/Data/NVO_stock.csv")
# Remove the dollar sign and convert to numeric
ET$Close.Last <- as.numeric(sub("\\$", "", ET$Close.Last))
XOM$Close.Last <- as.numeric(sub("\\$", "", XOM$Close.Last))
LLY$Close.Last <- as.numeric(sub("\\$", "", LLY$Close.Last))
NVO$Close.Last <- as.numeric(sub("\\$", "", NVO$Close.Last))
# Combine to be 1 dataset
stocks <-data.frame(
Date = ET$Date,
ET = ET$Close.Last,
XOM = XOM$Close.Last,
NVO = NVO$Close.Last,
LLY = LLY$Close.Last
)
# Convert values to proper format
stocks$Date <- as.Date(stocks$Date, format = "%m/%d/%y")
# Aggregate daily values to monthly average
stocks$Date <- format(stocks$Date, "%Y-%m") # Filters down to monthly
stocks <- aggregate(cbind(ET, LLY, NVO, XOM) ~ Date, data = stocks, FUN = mean)
# Remove unnecessary tables
rm(ET,LLY,NVO,XOM)
# Round all values
stocks$ET <- round(stocks$ET,2)
stocks$XOM <- round(stocks$XOM,2)
stocks$NVO <- round(stocks$NVO,2)
stocks$LLY <- round(stocks$LLY,2)
# Create Mutual Fund variable (Puts about $200 towards each stock)
stocks$Fund <- (13.01*stocks$ET) + (1.67*stocks$LLY) + (8.12*stocks$NVO) + (2.46*stocks$XOM)
# Break into testing and training
# Convert values to proper format... again
stocks$Date <- as.Date(paste(stocks$Date, "-01", sep=""), format="%Y-%m-%d")
# Make a porfolio table
portfolio <- data.frame(
Date = stocks$Date,
ET = 13.01*stocks$ET,
LLY = 1.67*stocks$LLY,
NVO = 8.12*stocks$NVO,
XOM = 2.46*stocks$XOM
)
# Round all values
portfolio$ET <- round(portfolio$ET,2)
portfolio$XOM <- round(portfolio$XOM,2)
portfolio$NVO <- round(portfolio$NVO,2)
portfolio$LLY <- round(portfolio$LLY,2)
# Add fund and sector performance to portfolio
portfolio$Fund <- portfolio$ET + portfolio$LLY + portfolio$NVO + portfolio$XOM
portfolio$Energy <- portfolio$ET + portfolio$XOM
portfolio$Pharma <- portfolio$LLY + portfolio$NVO
# Training data
train <- subset(portfolio, Date <= max(portfolio$Date) - years(1))
# Testing data
test <- subset(portfolio, Date > max(portfolio$Date) - years(1))
# Make time series for all
# Training ts
ET_train <- ts(train$ET,
start = c(2019,04),
frequency = 12
)
XOM_train <- ts(train$XOM,
start = c(2019,04),
frequency = 12
)
LLY_train <- ts(train$LLY,
start = c(2019,04),
frequency = 12
)
NVO_train <- ts(train$NVO,
start = c(2019,04),
frequency = 12
)
Fund_train <- ts(train$Fund,
start = c(2019,04),
frequency = 12
)
Energy_train <- ts(train$Energy,
start = c(2019,04),
frequency = 12
)
Pharma_train <- ts(train$Pharma,
start = c(2019,04),
frequency = 12
)
# Testing ts
ET_test <- ts(test$ET,
start = c(2023,05),
frequency = 12
)
XOM_test <- ts(test$XOM,
start = c(2023,05),
frequency = 12
)
LLY_test <- ts(test$LLY,
start = c(2023,05),
frequency = 12
)
NVO_test <- ts(test$NVO,
start = c(2023,05),
frequency = 12
)
Fund_test <- ts(test$Fund,
start = c(2023,05),
frequency = 12
)
Energy_test <- ts(test$Energy,
start = c(2023,05),
frequency = 12
)
Pharma_test <- ts(test$Pharma,
start = c(2023,05),
frequency = 12
)
# Full data
ET <- ts(stocks$ET,
start = c(2019,04),
frequency = 12
)
XOM <- ts(stocks$XOM,
start = c(2019,04),
frequency = 12
)
LLY <- ts(stocks$LLY,
start = c(2019,04),
frequency = 12
)
NVO <- ts(stocks$NVO,
start = c(2019,04),
frequency = 12
)
Fund <- ts(portfolio$Fund,
start = c(2019,04),
frequency = 12
)
Energy <- ts(portfolio$Energy,
start = c(2019,04),
frequency = 12
)
Pharma <- ts(portfolio$Pharma,
start = c(2019,04),
frequency = 12
)
The mock mutual fund for this segment invests about $200 dollars per stock into 4 stocks in April, 2019. This makes for 13.01 shares of Energy Transfer and 2.46 shares of Exxon Mobile in the Energy sector and 1.67 shares of Eli Lilly and Co and 8.12 shares of Novo Nordisk in the pharma sector.
Forecasts the total mutual fund performance
Forecasts sector performance
Forecasts individual stock performance
Based on this example, it appears that the top-down style is the most accurate predictor although I would not become overly reliant on it. It seems that the key reason for this is that the aggregated data has a much smoother upward trend than some individual stocks. This appears to mainly be influenced by the high performance pharma stocks. After that, the bottom-up and middle-out performed similarly with the bottom-up performing marginally better. The key reason for this is likely that the middle-out significantly underestimated the pharma sector.