2025/12/01This report analyzes stock price trends for 9 technology stocks from 2016 to 2024. The analysis includes:
library(ggplot2)
library(dplyr)
library(tidyr)
library(knitr)
We generate simulated stock price data for the following stocks: AAPL, AMD, MU, NIO, NVDA, PRPL, SNAP, TSLA, and TWTR.
# Set seed for reproducibility
set.seed(123)
# Function to generate stock price data
generate_stock_data <- function() {
stocks <- c('AAPL', 'AMD', 'MU', 'NIO', 'NVDA', 'PRPL', 'SNAP', 'TSLA', 'TWTR')
dates <- seq(as.Date("2016-01-01"), as.Date("2024-01-01"), by = "week")
# Stock configurations
configs <- list(
AAPL = list(start = 25, trend = 0.0015, volatility = 0.02),
AMD = list(start = 10, trend = 0.002, volatility = 0.04),
MU = list(start = 15, trend = 0.0012, volatility = 0.035),
NIO = list(start = 5, trend = 0.001, volatility = 0.06),
NVDA = list(start = 20, trend = 0.0025, volatility = 0.045),
PRPL = list(start = 10, trend = 0.0005, volatility = 0.05),
SNAP = list(start = 15, trend = 0.0008, volatility = 0.055),
TSLA = list(start = 20, trend = 0.002, volatility = 0.05),
TWTR = list(start = 20, trend = 0.0008, volatility = 0.04)
)
# Generate data for all stocks
all_data <- data.frame()
for (stock in stocks) {
config <- configs[[stock]]
price <- config$start
prices <- numeric(length(dates))
for (i in 1:length(dates)) {
change <- (runif(1) - 0.5) * config$volatility * price + config$trend * price
price <- max(1, price + change)
prices[i] <- price
}
stock_df <- data.frame(
Date = dates,
Stock = stock,
Price = round(prices, 2)
)
all_data <- rbind(all_data, stock_df)
}
return(all_data)
}
# Generate the data
stock_data <- generate_stock_data()
# Display first few rows
kable(head(stock_data, 10), caption = "First 10 rows of stock data")
| Date | Stock | Price |
|---|---|---|
| 2016-01-01 | AAPL | 24.93 |
| 2016-01-08 | AAPL | 25.11 |
| 2016-01-15 | AAPL | 25.10 |
| 2016-01-22 | AAPL | 25.33 |
| 2016-01-29 | AAPL | 25.60 |
| 2016-02-05 | AAPL | 25.40 |
| 2016-02-12 | AAPL | 25.45 |
| 2016-02-19 | AAPL | 25.69 |
| 2016-02-26 | AAPL | 25.76 |
| 2016-03-04 | AAPL | 25.77 |
# Data structure
str(stock_data)
## 'data.frame': 3762 obs. of 3 variables:
## $ Date : Date, format: "2016-01-01" "2016-01-08" ...
## $ Stock: chr "AAPL" "AAPL" "AAPL" "AAPL" ...
## $ Price: num 24.9 25.1 25.1 25.3 25.6 ...
This faceted plot shows the closing prices for each stock over time, allowing us to see individual trends and volatility patterns.
ggplot(stock_data, aes(x = Date, y = Price)) +
geom_line(color = "#2c3e50", size = 0.7) +
facet_wrap(~ Stock, scales = "free_y", ncol = 3) +
labs(
x = "Date",
y = "Closing prices",
title = ""
) +
theme_minimal() +
theme(
strip.background = element_rect(fill = "gray90", color = NA),
strip.text = element_text(face = "bold", size = 11),
panel.grid.minor = element_blank(),
panel.spacing = unit(0.5, "lines"),
axis.text = element_text(size = 8),
axis.title = element_text(size = 10)
)
This plot normalizes all stock prices to a base value of $1 at the start date, making it easier to compare relative performance across stocks with different price levels.
# Calculate normalized prices
normalized_data <- stock_data %>%
group_by(Stock) %>%
mutate(Normalized_Price = Price / first(Price)) %>%
ungroup()
# Define colors for each stock
stock_colors <- c(
"AAPL" = "#e74c3c",
"AMD" = "#3498db",
"MU" = "#2ecc71",
"NIO" = "#9b59b6",
"NVDA" = "#f39c12",
"PRPL" = "#e8d21d",
"SNAP" = "#1abc9c",
"TSLA" = "#e91e63",
"TWTR" = "#95a5a6"
)
ggplot(normalized_data, aes(x = Date, y = Normalized_Price, color = Stock)) +
geom_line(size = 1) +
scale_color_manual(values = stock_colors) +
labs(
x = "Date",
y = "Normalized price (Base = $1)",
title = "Normalized Stock Prices (2016-2024)",
color = "Stock"
) +
theme_minimal() +
theme(
legend.position = "right",
panel.grid.minor = element_blank(),
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
axis.title = element_text(size = 11),
axis.text = element_text(size = 9)
)
# Calculate summary statistics by stock
summary_stats <- stock_data %>%
group_by(Stock) %>%
summarise(
Start_Price = round(first(Price), 2),
End_Price = round(last(Price), 2),
Min_Price = round(min(Price), 2),
Max_Price = round(max(Price), 2),
Avg_Price = round(mean(Price), 2),
Total_Return_Pct = round(((last(Price) - first(Price)) / first(Price)) * 100, 2)
) %>%
arrange(desc(Total_Return_Pct))
kable(summary_stats,
caption = "Summary Statistics by Stock (Sorted by Total Return)",
col.names = c("Stock", "Start Price", "End Price", "Min Price",
"Max Price", "Avg Price", "Total Return (%)"))
| Stock | Start Price | End Price | Min Price | Max Price | Avg Price | Total Return (%) |
|---|---|---|---|---|---|---|
| NVDA | 19.64 | 64.91 | 19.64 | 65.29 | 42.04 | 230.50 |
| AMD | 10.01 | 21.18 | 9.84 | 21.28 | 15.43 | 111.59 |
| TSLA | 20.28 | 40.16 | 18.62 | 40.25 | 28.61 | 98.03 |
| AAPL | 24.93 | 45.51 | 24.93 | 45.61 | 34.95 | 82.55 |
| SNAP | 15.34 | 26.35 | 14.36 | 27.00 | 18.43 | 71.77 |
| TWTR | 20.00 | 29.61 | 19.93 | 32.07 | 24.92 | 48.05 |
| MU | 15.13 | 21.05 | 14.63 | 22.47 | 18.54 | 39.13 |
| NIO | 4.90 | 6.65 | 4.10 | 7.19 | 5.59 | 35.71 |
| PRPL | 9.83 | 9.65 | 8.49 | 10.98 | 9.84 | -1.83 |
# Best performer
best_stock <- summary_stats$Stock[1]
best_return <- summary_stats$Total_Return_Pct[1]
# Worst performer
worst_stock <- summary_stats$Stock[nrow(summary_stats)]
worst_return <- summary_stats$Total_Return_Pct[nrow(summary_stats)]
# Most volatile
volatility <- stock_data %>%
group_by(Stock) %>%
summarise(volatility = sd(Price)) %>%
arrange(desc(volatility))
most_volatile <- volatility$Stock[1]
Based on the analysis:
# Save to CSV
write.csv(stock_data, "stock_prices.csv", row.names = FALSE)
cat("Data exported to: stock_prices.csv\n")
## Data exported to: stock_prices.csv
This analysis demonstrates the varying performance of technology stocks from 2016 to 2024. The normalized view clearly shows which stocks outperformed others in terms of relative returns, while the faceted plots reveal individual price trends and volatility patterns.
Session Info
sessionInfo()
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=English_United States.utf8
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## time zone: Asia/Taipei
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] knitr_1.50 tidyr_1.3.1 dplyr_1.1.4 ggplot2_4.0.0
##
## loaded via a namespace (and not attached):
## [1] vctrs_0.6.5 cli_3.6.5 rlang_1.1.6 xfun_0.52
## [5] purrr_1.1.0 generics_0.1.4 S7_0.2.0 jsonlite_2.0.0
## [9] labeling_0.4.3 glue_1.8.0 htmltools_0.5.8.1 sass_0.4.10
## [13] scales_1.4.0 rmarkdown_2.29 grid_4.5.1 tibble_3.3.0
## [17] evaluate_1.0.5 jquerylib_0.1.4 fastmap_1.2.0 yaml_2.3.10
## [21] lifecycle_1.0.4 compiler_4.5.1 RColorBrewer_1.1-3 pkgconfig_2.0.3
## [25] rstudioapi_0.17.1 farver_2.1.2 digest_0.6.37 R6_2.6.1
## [29] tidyselect_1.2.1 pillar_1.11.1 magrittr_2.0.4 bslib_0.9.0
## [33] withr_3.0.2 tools_4.5.1 gtable_0.3.6 cachem_1.1.0