This analysis examines the stock price performance of eight major technology stocks from 2016 to 2024:
library(tidyverse)
library(tidyquant)
library(lubridate)
# Define stock symbols
stock_symbols <- c("AAPL", "AMD", "MU", "NIO", "NVDA", "PRPL", "SNAP", "TSLA")
# Download stock data from 2016 to 2024
stock_prices <- tq_get(stock_symbols,
from = "2016-01-01",
to = "2024-12-31",
get = "stock.prices")
# Display summary
cat("Total observations:", nrow(stock_prices), "\n")
## Total observations: 17134
cat("Date range:", min(stock_prices$date), "to", max(stock_prices$date), "\n")
## Date range: 16804 to 20087
# View first few rows
head(stock_prices, 10)
## # A tibble: 10 × 8
## symbol date open high low close volume adjusted
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 AAPL 2016-01-04 25.7 26.3 25.5 26.3 270597600 23.8
## 2 AAPL 2016-01-05 26.4 26.5 25.6 25.7 223164000 23.2
## 3 AAPL 2016-01-06 25.1 25.6 25.0 25.2 273829600 22.7
## 4 AAPL 2016-01-07 24.7 25.0 24.1 24.1 324377600 21.7
## 5 AAPL 2016-01-08 24.6 24.8 24.2 24.2 283192000 21.9
## 6 AAPL 2016-01-11 24.7 24.8 24.3 24.6 198957600 22.2
## 7 AAPL 2016-01-12 25.1 25.2 24.7 25.0 196616800 22.5
## 8 AAPL 2016-01-13 25.1 25.3 24.3 24.3 249758400 22.0
## 9 AAPL 2016-01-14 24.5 25.1 23.9 24.9 252680400 22.4
## 10 AAPL 2016-01-15 24.0 24.4 23.8 24.3 319335600 21.9
# Summary statistics
summary(stock_prices %>% select(symbol, close, volume))
## symbol close volume
## Length:17134 Min. : 0.564 Min. :0.000e+00
## Class :character 1st Qu.: 10.050 1st Qu.:1.993e+07
## Mode :character Median : 24.017 Median :5.210e+07
## Mean : 54.663 Mean :1.144e+08
## 3rd Qu.: 71.667 3rd Qu.:1.121e+08
## Max. :479.860 Max. :3.693e+09
Normalized prices allow us to compare relative performance across stocks with different price levels. We set the base price to $1 at the start date for each stock.
stock_normalized <- stock_prices %>%
group_by(symbol) %>%
mutate(normalized_price = adjusted / first(adjusted)) %>%
ungroup()
# Show normalized price summary
stock_normalized %>%
group_by(symbol) %>%
summarise(
start_price = first(adjusted),
end_price = last(adjusted),
normalized_end = last(normalized_price),
return_pct = (normalized_end - 1) * 100
) %>%
arrange(desc(return_pct))
## # A tibble: 8 × 5
## symbol start_price end_price normalized_end return_pct
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 NVDA 0.790 137. 174. 17308.
## 2 AMD 2.77 122. 44.2 4320.
## 3 TSLA 14.9 417. 28.0 2703.
## 4 AAPL 23.8 251. 10.6 957.
## 5 MU 14.0 85.1 6.08 508.
## 6 NIO 6.60 4.38 0.664 -33.6
## 7 SNAP 24.5 10.9 0.444 -55.6
## 8 PRPL 9.66 0.835 0.0865 -91.4
This plot shows the relative performance of all stocks on a single chart with normalized prices.
plot1 <- stock_normalized %>%
ggplot(aes(x = date, y = normalized_price, color = symbol)) +
geom_line(linewidth = 0.8) +
labs(
title = "Normalized Stock Prices (2016-2024)",
x = "Date",
y = "Normalized price (Base = $1)",
color = "Stock"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
legend.position = "right",
panel.grid.minor = element_blank()
) +
scale_y_continuous(breaks = seq(0, 200, 50))
print(plot1)
This plot shows actual closing prices for each stock in separate panels.
# Download stock data for plot 2 (8 currently trading stocks)
stocks_plot2 <- c("AAPL", "AMD", "MU", "NIO", "NVDA", "PRPL", "SNAP", "TSLA")
stock_prices_plot2 <- tq_get(stocks_plot2,
from = "2016-01-01",
to = "2023-12-31",
get = "stock.prices")
# Try to load TWTR data from CSV file (delisted in Oct 2022)
twtr_file <- "twtr_historical_data.csv" # Adjust path if needed
if (file.exists(twtr_file)) {
twtr_data <- read_csv(twtr_file, show_col_types = FALSE)
# Ensure date column is in proper format
if ("date" %in% names(twtr_data)) {
twtr_data <- twtr_data %>%
mutate(date = ymd(date))
}
# Add symbol column if missing
if (!"symbol" %in% names(twtr_data)) {
twtr_data <- twtr_data %>%
mutate(symbol = "TWTR")
}
# Filter date range to match other stocks
twtr_data <- twtr_data %>%
filter(date >= as.Date("2016-01-01"), date <= as.Date("2023-12-31"))
# Combine with other stock data
stock_prices_plot2 <- bind_rows(stock_prices_plot2, twtr_data)
message("TWTR data successfully loaded from CSV file")
} else {
message("Note: TWTR CSV file not found. Continuing with 8 stocks.")
message("To include TWTR, save the file as: ", twtr_file)
}
plot2 <- stock_prices_plot2 %>%
ggplot(aes(x = date, y = close)) +
geom_line(color = "navy", linewidth = 0.6) +
facet_wrap(~ symbol, scales = "free_y", ncol = 3) +
labs(
x = "Date",
y = "Closing prices"
) +
theme_minimal() +
theme(
strip.background = element_rect(fill = "gray85", color = NA),
strip.text = element_text(face = "bold", size = 11),
panel.grid.minor = element_blank(),
axis.text = element_text(size = 9)
)
print(plot2)
Each stock shows distinct price patterns:
performance_summary <- stock_normalized %>%
group_by(symbol) %>%
summarise(
start_date = min(date),
end_date = max(date),
start_price = first(adjusted),
end_price = last(adjusted),
total_return = ((end_price / start_price) - 1) * 100,
max_price = max(adjusted),
min_price = min(adjusted),
volatility = sd(adjusted / lag(adjusted) - 1, na.rm = TRUE) * 100
) %>%
arrange(desc(total_return))
knitr::kable(performance_summary,
digits = 2,
caption = "Stock Performance Summary (2016-2024)")
| symbol | start_date | end_date | start_price | end_price | total_return | max_price | min_price | volatility |
|---|---|---|---|---|---|---|---|---|
| NVDA | 2016-01-04 | 2024-12-30 | 0.79 | 137.46 | 17308.12 | 148.84 | 0.62 | 3.15 |
| AMD | 2016-01-04 | 2024-12-30 | 2.77 | 122.44 | 4320.22 | 211.38 | 1.80 | 3.72 |
| TSLA | 2016-01-04 | 2024-12-30 | 14.89 | 417.41 | 2702.54 | 479.86 | 9.58 | 3.70 |
| AAPL | 2016-01-04 | 2024-12-30 | 23.75 | 251.06 | 956.97 | 257.85 | 20.60 | 1.81 |
| MU | 2016-01-04 | 2024-12-30 | 13.99 | 85.07 | 508.16 | 152.51 | 9.33 | 2.92 |
| NIO | 2018-09-12 | 2024-12-30 | 6.60 | 4.38 | -33.64 | 62.84 | 1.32 | 5.75 |
| SNAP | 2017-03-02 | 2024-12-30 | 24.48 | 10.86 | -55.64 | 83.11 | 4.99 | 4.65 |
| PRPL | 2016-01-04 | 2024-12-30 | 9.66 | 0.83 | -91.35 | 40.04 | 0.56 | 4.87 |
# Save plots as high-resolution PNG files
ggsave("normalized_stock_prices.png", plot1, width = 10, height = 6, dpi = 300)
ggsave("faceted_stock_prices.png", plot2, width = 10, height = 8, dpi = 300)
This analysis demonstrates the varying performance of technology stocks over the 2016-2024 period:
The normalized price comparison highlights how different stocks can start at similar points but diverge dramatically based on company performance, market conditions, and sector trends.