library(quantmod)
## Warning: package 'quantmod' was built under R version 4.5.2
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.5.2
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.5.2
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.5.2
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.1 ✔ stringr 1.5.2
## ✔ ggplot2 4.0.0 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.1.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::first() masks xts::first()
## ✖ dplyr::lag() masks stats::lag()
## ✖ dplyr::last() masks xts::last()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.5.2
tickers <- c("AAPL","AMD","MU","NIO","NVDA","PRPL","SNAP","TSLA")
start_date <- "2016-01-01"
end_date <- "2024-12-01"
getSymbols(tickers, from = start_date, to = end_date, auto.assign = TRUE)
## [1] "AAPL" "AMD" "MU" "NIO" "NVDA" "PRPL" "SNAP" "TSLA"
prices <- map(tickers, ~ Ad(get(.x))) %>%
reduce(merge) %>%
`colnames<-`(tickers)
normalized <- prices / as.numeric(prices[1,])
df_norm <- data.frame(Date = index(normalized), coredata(normalized)) %>%
pivot_longer(-Date, names_to = "Stock", values_to = "Price")
p1 <- ggplot(df_norm, aes(Date, Price, color = Stock)) +
geom_line() +
labs(title = "Normalized Stock Prices (2016–2024)",
y = "Normalized Price (Base = 1)",
x = "Date") +
theme_minimal()
p1
## Warning: Removed 975 rows containing missing values or values outside the scale range
## (`geom_line()`).

df_raw <- data.frame(Date = index(prices), coredata(prices)) %>%
pivot_longer(-Date, names_to = "Stock", values_to = "Close")
p2 <- ggplot(df_raw, aes(Date, Close)) +
geom_line(color = "steelblue") +
facet_wrap(~ Stock, scales = "free_y", ncol = 3) +
labs(title = "Closing Prices of Sampled Stocks (2016–2024)",
y = "Closing Price",
x = "Date") +
theme_minimal()
p2
