require(feasts)
## Loading required package: feasts
## Warning: package 'feasts' was built under R version 4.3.3
## Loading required package: fabletools
## Warning: package 'fabletools' was built under R version 4.3.3
require(fpp3)
## Loading required package: fpp3
## Warning: package 'fpp3' was built under R version 4.3.2
## ── Attaching packages ────────────────────────────────────────────── fpp3 0.5 ──
## ✔ tibble 3.2.1 ✔ ggplot2 3.5.1
## ✔ dplyr 1.1.4 ✔ tsibble 1.1.4
## ✔ tidyr 1.3.0 ✔ tsibbledata 0.4.1
## ✔ lubridate 1.9.3 ✔ fable 0.3.3
## Warning: package 'tibble' was built under R version 4.3.2
## Warning: package 'dplyr' was built under R version 4.3.2
## Warning: package 'tidyr' was built under R version 4.3.2
## Warning: package 'lubridate' was built under R version 4.3.2
## Warning: package 'ggplot2' was built under R version 4.3.3
## Warning: package 'tsibble' was built under R version 4.3.3
## Warning: package 'tsibbledata' was built under R version 4.3.2
## Warning: package 'fable' was built under R version 4.3.2
## ── 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()
require(ggplot2)
require(kableExtra)
## Loading required package: kableExtra
## Warning: package 'kableExtra' was built under R version 4.3.3
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
require(latex2exp)
## Loading required package: latex2exp
## Warning: package 'latex2exp' was built under R version 4.3.2
require(readxl)
## Loading required package: readxl
## Warning: package 'readxl' was built under R version 4.3.2
require(tidyverse)
## Loading required package: tidyverse
## Warning: package 'tidyverse' was built under R version 4.3.2
## Warning: package 'readr' was built under R version 4.3.2
## Warning: package 'purrr' was built under R version 4.3.2
## Warning: package 'stringr' was built under R version 4.3.2
## Warning: package 'forcats' was built under R version 4.3.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ readr 2.1.4
## ✔ purrr 1.0.2 ✔ stringr 1.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ kableExtra::group_rows() masks dplyr::group_rows()
## ✖ tsibble::interval() masks lubridate::interval()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
require(magrittr)
## Loading required package: magrittr
## Warning: package 'magrittr' was built under R version 4.3.2
##
## Attaching package: 'magrittr'
##
## The following object is masked from 'package:purrr':
##
## set_names
##
## The following object is masked from 'package:tidyr':
##
## extract
require(quantmod)
## Loading required package: quantmod
## Warning: package 'quantmod' was built under R version 4.3.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.3.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.3.2
##
## Attaching package: 'zoo'
##
## The following object is masked from 'package:tsibble':
##
## index
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'xts'
##
## The following objects are masked from 'package:dplyr':
##
## first, last
##
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.3.2
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
require(tidyverse)
require(xts)
FYI-In order to knit, you cannot rely on reading from external sources. I downloaded the symbols and saved them into a dataframe.
#getSymbols(c("MSFT", "CSCO", "BABA", "AMZN"), src = "yahoo", from = "2018-01-01", to = "2022-12-31",
# auto.assign = TRUE, periodicity = 'monthly')
#total=as.data.frame(cbind(SPY$SPY.Adjusted, QQQ$QQQ.Adjusted,GLD$GLD.Adjusted,EEM$EEM.Adjusted))
#write.csv(total,'hts_example.csv', row.names = FALSE)
total=read.csv('hts_example.csv')
str(total)
## 'data.frame': 60 obs. of 4 variables:
## $ SPY.Adjusted: num 170 170 181 182 185 ...
## $ QQQ.Adjusted: num 98.4 96.9 103.2 100.2 104.6 ...
## $ GLD.Adjusted: num 107 119 118 124 116 ...
## $ EEM.Adjusted: num 26.4 26.2 29.5 29.7 28.6 ...
initial=1000
#Accumulation Rate
total[2:60,]=1+(total[2:60,]-total[1:59,])/total[1:59,]
#Value by Month
for (i in 2:60) total[i,]=total[i-1, ]*total[i,]
#Date
total$Date=yearmonth(seq(as.Date("2018-01-01"), as.Date("2022/12/31"), by="months"))
colnames(total)=c("MSFT", "CSCO", "BABA", "AMZN", "Date")
#Train / Test
train=total[1:48,]
test=total[49:60,]
# Time Series
myts=total%>%as_tsibble(index=Date)
traints=train%>%as_tsibble(index=Date)
testts=test%>%as_tsibble(index=Date)
# Pivot Longer
temp=myts%>%pivot_longer(!c(Date), names_to='Stock', values_to='Value')
train=traints%>%pivot_longer(!c(Date), names_to='Stock', values_to='Value')
test=testts%>%pivot_longer(!c(Date), names_to='Stock', values_to='Value')
temp$Sector=rep('Tech', nrow(temp))
train$Sector=rep('Tech', nrow(train))
test$Sector=rep('Tech', nrow(test))
temp$Sector[temp$Stock=="BABA"|temp$Stock=="AMZN"]="Store"
train$Sector[train$Stock=="BABA"|train$Stock=="AMZN"]="Store"
test$Sector[test$Stock=="BABA"|test$Stock=="AMZN"]="Store"
temp%>%autoplot()
## Plot variable not specified, automatically selected `.vars = Value`
# Aggregate & Plot
#Aggregate TS For Plotting
myagg <- temp |>
aggregate_key(Stock/Sector,Value=sum(Value))
myagg
## # A tsibble: 540 x 4 [1M]
## # Key: Stock, Sector [9]
## Date Stock Sector Value
## <mth> <chr*> <chr*> <dbl>
## 1 2018 Jan <aggregated> <aggregated> 402.
## 2 2018 Feb <aggregated> <aggregated> 412.
## 3 2018 Mar <aggregated> <aggregated> 431.
## 4 2018 Apr <aggregated> <aggregated> 436.
## 5 2018 May <aggregated> <aggregated> 435.
## 6 2018 Jun <aggregated> <aggregated> 443.
## 7 2018 Jul <aggregated> <aggregated> 463.
## 8 2018 Aug <aggregated> <aggregated> 460.
## 9 2018 Sep <aggregated> <aggregated> 463.
## 10 2018 Oct <aggregated> <aggregated> 455.
## # ℹ 530 more rows
#Plot
myagg%>%filter(is_aggregated(Sector))%>%
autoplot(Value) +
labs(y = "Value",
title = "Value of Investment") +
facet_wrap(vars(Stock), scales = "free_y", ncol = 3) +
theme(legend.position = "none")
#Bottoms Up Forecast
myagg2 <- train |>aggregate_key(Stock,Value=mean(Value))
m1=myagg2|> model(ets = ETS(Value))|>reconcile(bu = bottom_up(ets))
aug1=m1%>%augment()
f1=m1%>%forecast(h=12)
f1%>%autoplot(temp)
acc1=f1%>%accuracy(test |>aggregate_key(Stock,Value=mean(Value)))
#Middle Out Forecast
myagg3 <-train |>aggregate_key(Sector/Stock,Value=mean(Value))
m2=myagg3|> model(ets2 = ETS(Value)) |> reconcile(md = middle_out(ets2))
f2=m2%>%forecast(h=12)
f2%>%autoplot(temp%>%aggregate_key(Sector/Stock,Value=mean(Value)))+facet_wrap(~Stock+Sector)
acc2=f2%>%accuracy(test|>aggregate_key(Sector/Stock,Value=mean(Value)))
#Top Down
myagg4 <-train |>aggregate_key(Sector/Stock,Value=mean(Value))
m3=myagg4|> model(ets3 = ETS(Value)) |> reconcile(td = top_down(ets3))
f3=m3%>%forecast(h=12)
f3%>%autoplot(temp%>%aggregate_key(Sector/Stock,Value=mean(Value)))+facet_wrap(~Stock+Sector)
acc3=f3%>%accuracy(test|>aggregate_key(Sector/Stock,Value=mean(Value)))
#MinT
myagg5 <-train |>aggregate_key(Sector/Stock,Value=mean(Value))
m5=myagg5|> model(ets5 = ETS(Value)) |> reconcile(mint = min_trace(ets5))
f5=m5%>%forecast(h=12)
f5%>%autoplot(temp%>%aggregate_key(Sector/Stock,Value=mean(Value)))+facet_wrap(~Stock+Sector)
acc5=f5%>%accuracy(test|>aggregate_key(Sector/Stock,Value=mean(Value)))
glance(m1)
## # A tibble: 10 × 10
## Stock .model sigma2 log_lik AIC AICc BIC MSE AMSE MAE
## <chr*> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 AMZN ets 2.81 -117. 239. 240. 245. 2.69 4.71 1.29
## 2 AMZN bu 2.81 -117. 239. 240. 245. 2.69 4.71 1.29
## 3 BABA ets 21.9 -166. 338. 338. 343. 21.0 39.4 3.51
## 4 BABA bu 21.9 -166. 338. 338. 343. 21.0 39.4 3.51
## 5 CSCO ets 0.00160 -175. 360. 361. 369. 39.2 61.9 0.0305
## 6 CSCO bu 0.00160 -175. 360. 361. 369. 39.2 61.9 0.0305
## 7 MSFT ets 0.000995 -186. 383. 384. 392. 59.0 88.4 0.0220
## 8 MSFT bu 0.000995 -186. 383. 384. 392. 59.0 88.4 0.0220
## 9 <aggregated> ets 0.000790 -155. 319. 320. 328. 14.6 22.6 0.0211
## 10 <aggregated> bu 0.000790 -155. 319. 320. 328. 14.6 22.6 0.0211
glance(m2)
## # A tibble: 14 × 11
## Sector Stock .model sigma2 log_lik AIC AICc BIC MSE AMSE
## <chr*> <chr*> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Store AMZN ets2 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 2 Store AMZN md 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 3 Store BABA ets2 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 4 Store BABA md 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 5 Store <aggregate… ets2 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 6 Store <aggregate… md 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 7 Tech CSCO ets2 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 8 Tech CSCO md 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 9 Tech MSFT ets2 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 10 Tech MSFT md 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 11 Tech <aggregate… ets2 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 12 Tech <aggregate… md 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 13 <aggregated> <aggregate… ets2 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## 14 <aggregated> <aggregate… md 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## # ℹ 1 more variable: MAE <dbl>
glance(m3)
## # A tibble: 14 × 11
## Sector Stock .model sigma2 log_lik AIC AICc BIC MSE AMSE
## <chr*> <chr*> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Store AMZN ets3 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 2 Store AMZN td 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 3 Store BABA ets3 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 4 Store BABA td 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 5 Store <aggregate… ets3 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 6 Store <aggregate… td 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 7 Tech CSCO ets3 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 8 Tech CSCO td 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 9 Tech MSFT ets3 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 10 Tech MSFT td 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 11 Tech <aggregate… ets3 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 12 Tech <aggregate… td 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 13 <aggregated> <aggregate… ets3 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## 14 <aggregated> <aggregate… td 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## # ℹ 1 more variable: MAE <dbl>
glance(m5)
## # A tibble: 14 × 11
## Sector Stock .model sigma2 log_lik AIC AICc BIC MSE AMSE
## <chr*> <chr*> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Store AMZN ets5 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 2 Store AMZN mint 2.81e+0 -117. 239. 240. 245. 2.69 4.71
## 3 Store BABA ets5 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 4 Store BABA mint 2.19e+1 -166. 338. 338. 343. 21.0 39.4
## 5 Store <aggregate… ets5 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 6 Store <aggregate… mint 7.39e+0 -140. 286. 286. 291. 7.08 13.7
## 7 Tech CSCO ets5 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 8 Tech CSCO mint 1.60e-3 -175. 360. 361. 369. 39.2 61.9
## 9 Tech MSFT ets5 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 10 Tech MSFT mint 9.95e-4 -186. 383. 384. 392. 59.0 88.4
## 11 Tech <aggregate… ets5 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 12 Tech <aggregate… mint 1.15e-3 -180. 370. 371. 379. 46.8 72.0
## 13 <aggregated> <aggregate… ets5 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## 14 <aggregated> <aggregate… mint 7.90e-4 -155. 319. 320. 328. 14.6 22.6
## # ℹ 1 more variable: MAE <dbl>