1. Download Daily Prices (2024 to Present)

I download daily adjusted closing prices for AAPL, MSFT, GOOG, AMZN, TSM, and NVDA from Yahoo Finance, starting January 1, 2024, using the quantmod package.

tickers <- c("AAPL", "MSFT", "GOOG", "AMZN", "TSM", "NVDA")

start_date <- as.Date("2024-01-01")
end_date   <- Sys.Date()

# Download data for each ticker into the environment
getSymbols(tickers, src = "yahoo", from = start_date, to = end_date)
## [1] "AAPL" "MSFT" "GOOG" "AMZN" "TSM"  "NVDA"
# Combine adjusted closing prices into one xts object
prices <- do.call(merge, lapply(tickers, function(t) Ad(get(t))))
colnames(prices) <- tickers

# Preview the price data
head(prices)
##                AAPL     MSFT     GOOG   AMZN      TSM     NVDA
## 2024-01-02 183.4040 363.1179 138.2505 149.93 98.27406 48.02879
## 2024-01-03 182.0307 362.8536 139.0430 148.47 96.95767 47.43153
## 2024-01-04 179.7189 360.2491 136.7448 144.57 95.95103 47.85928
## 2024-01-05 178.9977 360.0632 136.1009 145.24 96.41563 48.95511
## 2024-01-08 183.3250 366.8581 139.2114 149.10 98.96128 52.10198
## 2024-01-09 182.9100 367.9351 141.2224 151.37 98.62251 52.98642

2. Compute Daily Returns

I calculate daily log returns for each stock and display the first few rows below.

returns <- do.call(merge, lapply(tickers, function(t) dailyReturn(get(t), type = "log")))
colnames(returns) <- tickers

# Remove the first row (NA, since there's no prior day return)
returns <- na.omit(returns)

# Show the first few returns for all stocks
kable(head(returns), digits = 5, caption = "First Few Daily Log Returns")
First Few Daily Log Returns
AAPL MSFT GOOG AMZN TSM NVDA
-0.008101091 -0.0080297729 -0.0002866352 -0.010681103 -0.007066486 -0.022092637
-0.007515780 -0.0007282534 0.0057159562 -0.009785544 -0.013485585 -0.012513591
-0.012781452 -0.0072034423 -0.0166671055 -0.026619056 -0.010436632 0.008978073
-0.004021108 -0.0005165286 -0.0047198571 0.004623714 0.004830475 0.022638569
0.023887295 0.0186956645 0.0225973879 0.026229678 0.026060402 0.062299338
-0.002265974 0.0029314755 0.0143419662 0.015109876 -0.003429176 0.016832655

Summary Statistics

kable(table.Stats(returns), digits = 5, caption = "Summary Statistics of Daily Returns")
Summary Statistics of Daily Returns
AAPL MSFT GOOG AMZN TSM NVDA
Observations 676.0000 676.0000 676.0000 676.0000 676.0000 676.0000
NAs 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
Minimum -0.0970 -0.1053 -0.0780 -0.0941 -0.1430 -0.1859
Quartile 1 -0.0071 -0.0073 -0.0092 -0.0103 -0.0123 -0.0142
Median 0.0012 0.0005 0.0021 0.0004 0.0026 0.0026
Arithmetic Mean 0.0008 0.0004 0.0013 0.0008 0.0021 0.0022
Geometric Mean 0.0007 0.0003 0.0011 0.0006 0.0018 0.0017
Quartile 3 0.0093 0.0088 0.0115 0.0125 0.0159 0.0196
Maximum 0.1426 0.1442 0.0950 0.1425 0.1160 0.1716
SE Mean 0.0007 0.0006 0.0007 0.0008 0.0010 0.0012
LCL Mean (0.95) -0.0005 -0.0008 -0.0001 -0.0008 0.0002 -0.0001
UCL Mean (0.95) 0.0022 0.0017 0.0027 0.0023 0.0041 0.0045
Variance 0.0003 0.0003 0.0004 0.0004 0.0007 0.0009
Stdev 0.0174 0.0167 0.0191 0.0204 0.0259 0.0303
Skewness 0.3067 0.7489 0.2309 0.5264 -0.1173 -0.0875
Kurtosis 9.4369 12.2955 3.9651 6.6589 2.4326 4.6400

Visualizing Cumulative Growth

Daily returns bounce around too much day-to-day to show a clear trend on their own. Instead, this chart shows how $1 invested in each stock on January 1, 2024 would have grown over time — making it much easier to compare overall performance across stocks.

growth <- exp(cumsum(returns))  # convert log returns into cumulative growth of $1
colnames(growth) <- tickers

stock_colors <- c(AAPL = "black", MSFT = "orange", GOOG = "forestgreen",
                   AMZN = "blue", TSM = "purple", NVDA = "red")

plot.zoo(growth, main = "Growth of $1 Invested (Jan 2024 - Present)",
          xlab = "Date", ylab = "Value of $1 Invested",
          col = stock_colors[tickers], screens = 1)
legend("topleft", legend = tickers, col = stock_colors[tickers], lty = 1, cex = 0.7)