ro

Author

co

library(fpp3)
── Attaching packages ──────────────────────────────────────────── fpp3 1.0.3 ──
✔ tibble      3.3.1     ✔ tsibble     1.2.0
✔ dplyr       1.2.1     ✔ tsibbledata 0.4.1
✔ tidyr       1.3.2     ✔ ggtime      0.2.0
✔ lubridate   1.9.5     ✔ feasts      0.5.0
✔ ggplot2     4.0.3     ✔ fable       0.5.0
── 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()
library(tidyquant)
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
── Attaching core tidyquant packages ─────────────────────── tidyquant 1.0.12 ──
✔ PerformanceAnalytics 2.1.0      ✔ TTR                  0.24.4
✔ quantmod             0.4.29     ✔ xts                  0.14.2
── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
✖ zoo::as.Date()                 masks base::as.Date()
✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
✖ dplyr::filter()                masks stats::filter()
✖ xts::first()                   masks dplyr::first()
✖ zoo::index()                   masks tsibble::index()
✖ tsibble::interval()            masks lubridate::interval()
✖ dplyr::lag()                   masks stats::lag()
✖ xts::last()                    masks dplyr::last()
✖ PerformanceAnalytics::legend() masks graphics::legend()
✖ quantmod::summary()            masks base::summary()
✖ tidyquant::VAR()               masks fable::VAR()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Attaching package: 'tidyquant'


The following object is masked from 'package:fable':

    VAR
library(dplyr)

# Download Apple stock data
df_daily <- tq_get(
  "AAPL",
  get = "stock.prices",
  from = "2020-01-01"
)

# Convert daily data to monthly time series
stock_monthly <- df_daily %>%
  mutate(month = yearmonth(date)) %>%
  group_by(month) %>%
  summarise(price = mean(adjusted)) %>%
  as_tsibble(index = month)

# Split into training (80%) and testing (20%)
n <- nrow(stock_monthly)

train <- stock_monthly[1:floor(0.8 * n), ]
test <- stock_monthly[(floor(0.8 * n) + 1):n, ]

# Fit the three forecasting models
models <- train %>%
  model(
    Naive = NAIVE(price),
    SNaive = SNAIVE(price),
    Drift = RW(price ~ drift())
  )

# Forecast on the test data
forecast_stock <- models %>%
  forecast(h = nrow(test))

# Plot forecasts vs actual values
autoplot(forecast_stock, data = train) +
  autolayer(test, price) +
  labs(
    title = "Apple Stock Price Forecast",
    x = "Date",
    y = "Adjusted Closing Price"
  )

# Compare forecasting accuracy
accuracy(forecast_stock, test)
# A tibble: 3 × 10
  .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Drift  Test   11.2  28.5  24.4  3.01  9.46   NaN   NaN 0.681
2 Naive  Test   31.3  47.8  40.4 10.5  15.0    NaN   NaN 0.730
3 SNaive Test   40.6  55.2  42.7 14.7  15.7    NaN   NaN 0.769
# Rank models by RMSE
accuracy(forecast_stock, test) %>%
  arrange(RMSE)
# A tibble: 3 × 10
  .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Drift  Test   11.2  28.5  24.4  3.01  9.46   NaN   NaN 0.681
2 Naive  Test   31.3  47.8  40.4 10.5  15.0    NaN   NaN 0.730
3 SNaive Test   40.6  55.2  42.7 14.7  15.7    NaN   NaN 0.769
cat("\nRecommendation:\n")

Recommendation:
cat("Choose the model with the lowest RMSE.\n")
Choose the model with the lowest RMSE.
cat("If the Drift model has the lowest RMSE and predicts an upward trend, Buy/Hold the stock.\n")
If the Drift model has the lowest RMSE and predicts an upward trend, Buy/Hold the stock.
cat("If the forecast trends downward, Sell or Avoid buying.\n")
If the forecast trends downward, Sell or Avoid buying.