# Load libraries
library(xts)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(quantmod)
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(dplyr)
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:xts':
##
## first, last
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
# Set date range
begin_date <- "2013-01-01"
end_date <- "2015-12-31"
# Stock list (AEZS removed)
stock_namelist <- c("AAPL", "AMD", "ADI", "ABBV", "A", "APD", "AA", "CF")
# Initialize an empty list to store stock data
stock_list <- list()
# Download adjusted close prices and store them in the list
for (symbol in stock_namelist) {
tryCatch({
stock_data <- Ad(getSymbols(symbol, from = begin_date, to = end_date, auto.assign = FALSE))
colnames(stock_data) <- symbol
stock_list[[symbol]] <- stock_data
}, error = function(e) {
message(paste("Skipping:", symbol, "— not available."))
})
}
# Check if we have valid data
if (length(stock_list) == 0) {
stop("No stock data available. Check tickers or date range.")
}
# Merge all stock data into one xts object
data_set <- do.call(merge, stock_list)
# Check the merged data columns
print("✅ Data columns after merge:")
## [1] "✅ Data columns after merge:"
print(colnames(data_set))
## [1] "AAPL" "AMD" "ADI" "ABBV" "A" "APD" "AA" "CF"
# Calculate log returns
X <- diff(log(data_set), na.pad = FALSE)
# Display log returns
print("✅ First few rows of log returns (X):")
## [1] "✅ First few rows of log returns (X):"
print(head(X))
## AAPL AMD ADI ABBV A
## 2013-01-03 -0.012702479 -0.015936577 -0.016267645 -0.008291678 0.003575422
## 2013-01-04 -0.028249359 0.039375128 -0.017947173 -0.012713275 0.019555361
## 2013-01-07 -0.005899884 0.030420658 0.003053182 0.002033301 -0.007259161
## 2013-01-08 0.002687289 0.000000000 -0.010370959 -0.022004723 -0.008022627
## 2013-01-09 -0.015752325 -0.015094611 -0.002609039 0.005620620 0.026649245
## 2013-01-10 0.012320080 -0.003809616 0.012041307 0.002945649 0.007354887
## APD AA CF
## 2013-01-03 -0.0035001848 0.008859488 -0.004740209
## 2013-01-04 0.0133508004 0.020731800 0.022151682
## 2013-01-07 -0.0009223412 -0.017429398 -0.003753247
## 2013-01-08 0.0018453074 0.000000000 -0.014768444
## 2013-01-09 0.0133907530 -0.002200072 0.034375871
## 2013-01-10 -0.0009103671 -0.012188648 0.014917725
cat("\n✅ Dimensions of X: ", nrow(X), "rows ×", ncol(X), "columns\n")
##
## ✅ Dimensions of X: 754 rows × 8 columns
# Load Fama-French 5-Factor data (adjust your file path)
ff_data <- read_csv("/cloud/project/F-F_Research_Data_5_Factors_2x3 (1).CSV", skip = 4)
## Rows: 82 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (5): 0.0862, 0.0204, 0.0247, 0.0018, -0.0191
## date (1): 2018-04-30
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ff_data <- ff_data[!is.na(as.numeric(ff_data[[1]])), ]
# Rename columns (5 factors only)
colnames(ff_data)[1:6] <- c("Date", "Mkt_RF", "SMB", "HML", "RMW", "CMA")
# Convert types
ff_data <- ff_data %>%
mutate(
Date = ymd(as.character(Date)),
Mkt_RF = as.numeric(Mkt_RF) / 100,
SMB = as.numeric(SMB) / 100,
HML = as.numeric(HML) / 100,
RMW = as.numeric(RMW) / 100,
CMA = as.numeric(CMA) / 100
)
# Create xts object for Fama-French factors
fama_lib <- xts(ff_data[, c("Mkt_RF", "SMB", "HML", "RMW", "CMA")], order.by = ff_data$Date)
# Align Fama-French factors with stock returns
F_FamaFrench <- fama_lib[index(X)]
# Check Fama-French data