required_pkgs <- c("quantmod", "lubridate", "httr", "jsonlite")
new_pkgs <- required_pkgs[!(required_pkgs %in% installed.packages()[, "Package"])]
if(length(new_pkgs)) install.packages(new_pkgs, repos = "https://cloud.r-project.org")
lapply(required_pkgs, require, character.only = TRUE)
## Loading required package: quantmod
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Loading required package: lubridate
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
## Loading required package: httr
## Loading required package: jsonlite
## [[1]]
## [1] TRUE
## 
## [[2]]
## [1] TRUE
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] TRUE
ticker <- "MSFT"                       
from   <- as.Date("2024-10-01")
to     <- as.Date("2025-01-31")
msft_xts <- getSymbols(ticker, src = "yahoo", from = from, to = to, auto.assign = FALSE)
print("First rows:")
## [1] "First rows:"
print(head(msft_xts))
##            MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted
## 2024-10-01    428.45    428.48   418.81     420.69    19092900      417.5552
## 2024-10-02    422.58    422.82   416.71     417.13    16582300      414.0218
## 2024-10-03    417.63    419.55   414.29     416.54    13686400      413.4361
## 2024-10-04    418.24    419.75   414.97     416.06    19169700      412.9597
## 2024-10-07    416.00    417.11   409.00     409.54    20919800      406.4883
## 2024-10-08    410.90    415.66   408.17     414.71    19229300      411.6198
print("Last rows:")
## [1] "Last rows:"
print(tail(msft_xts))
##            MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted
## 2025-01-23    442.00    446.75   441.50     446.71    18389300      444.2688
## 2025-01-24    445.16    446.65   441.40     444.06    15549500      441.6333
## 2025-01-27    424.01    435.20   423.50     434.56    35647800      432.1852
## 2025-01-28    434.60    448.38   431.38     447.20    23491700      444.7561
## 2025-01-29    446.69    446.88   440.40     442.33    23581400      439.9127
## 2025-01-30    418.77    422.86   413.16     414.99    54586300      412.7221
## Question 6 / 7 
n_rows <- NROW(msft_xts)
cat("Number of rows (trading days) returned by getSymbols():", n_rows, "\n")
## Number of rows (trading days) returned by getSymbols(): 83
##Question 8
opens <- Op(msft_xts)                  
max_open_idx <- which.max(as.numeric(opens))
max_open_date <- index(opens)[max_open_idx]
max_open_value <- as.numeric(opens[max_open_idx])
cat("Max Open value =", max_open_value, "on", as.character(max_open_date), "\n")
## Max Open value = 451.32 on 2024-12-18
map_period <- function(d) {
  d <- as.Date(d)
  if(d >= as.Date("2024-10-21") & d <= as.Date("2024-10-29")) return("Option A: Oct21-Oct29")
  if(d >= as.Date("2025-01-11") & d <= as.Date("2025-01-21")) return("Option B: Jan11-Jan21")
  if(d >= as.Date("2024-12-09") & d <= as.Date("2024-12-18")) return("Option C: Dec9-Dec18")
  if(d >  as.Date("2025-01-21"))                           return("Option D: After Jan21")
  return("None of the above")
}
cat("That date falls into:", map_period(max_open_date), "\n")
## That date falls into: Option C: Dec9-Dec18
all_dates <- seq(from, to, by = "day")
monfri <- all_dates[!weekdays(all_dates) %in% c("Saturday", "Sunday")]
# common US market holidays in this interval (typical NYSE closures)
us_holidays <- as.Date(c("2024-11-28", "2024-12-25", "2025-01-01"))
bizdays_minus_holidays <- setdiff(monfri, us_holidays)
cat("Mon-Fri days in interval:", length(monfri), "\n")
## Mon-Fri days in interval: 89
cat("Mon-Fri minus listed US market holidays:", length(bizdays_minus_holidays), "\n")
## Mon-Fri minus listed US market holidays: 86