R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(data.table)
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:xts':
## 
##     first, last
# Define the ETF tickers
tickers <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")

# Download data from Yahoo Finance
getSymbols(tickers, from = "2010-01-01", to = Sys.Date(), src = "yahoo", adjust = TRUE)
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT" "IYR" "GLD"
# Combine adjusted prices into a single data frame
etf_data <- na.omit(merge(Ad(SPY), Ad(QQQ), Ad(EEM), Ad(IWM), Ad(EFA), Ad(TLT), Ad(IYR), Ad(GLD)))

# Rename columns
colnames(etf_data) <- tickers

# Calculate monthly returns using discrete returns
monthly_returns <- to.monthly(etf_data)$returns

# Extract year from the index
monthly_returns$Year <- as.integer(format(as.Date(index(monthly_returns)), "%Y"))

# Download Fama French 3 factors data
download.file("http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/F-F_Research_Data_Factors_CSV.zip",
              destfile = "F-F_Research_Data_Factors_CSV.zip")

# Unzip the downloaded file
unzip("F-F_Research_Data_Factors_CSV.zip")

# Read the CSV file
ff_data <- fread("F-F_Research_Data_Factors.CSV", skip = 3)
## Warning in fread("F-F_Research_Data_Factors.CSV", skip = 3): Stopped early on
## line 1177. Expected 5 fields but found 0. Consider fill=TRUE and comment.char=.
## First discarded non-empty line: <<Annual Factors: January-December >>
# Rename columns
colnames(ff_data) <- c("Year", "Mkt-RF", "SMB", "HML", "RF")

# Convert Fama French data to digit numbers (not in percentage) for Mkt-RF, SMB, HML, and RF columns
ff_data[, c("Mkt-RF", "SMB", "HML", "RF") := .(as.numeric(`Mkt-RF`) / 100, as.numeric(SMB) / 100, as.numeric(HML) / 100, as.numeric(RF) / 100)]

# Merge monthly return data from questions 2 and 3 based on the 'Year' column
merged_data <- merge(monthly_returns, ff_data, by = "Year")

# Remove the 'Year' column to avoid redundancy
merged_data$Year <- NULL

# Now, continue with the rest of the analysis...
# Check the structure of the merged data
str(merged_data)
## 'data.frame':    0 obs. of  4 variables:
##  $ Mkt-RF: num 
##  $ SMB   : num 
##  $ HML   : num 
##  $ RF    : num
# Compute MVP monthly returns based on CAPM model
start_date <- as.Date("2019-03-01")
end_date <- as.Date("2024-02-29")
past_returns <- merged_data[merged_data$Year >= start_date & merged_data$Year <= end_date, -1]

# Check if past_returns contains the expected data

# Calculate covariance matrix
cov_mat <- cov(past_returns)

# Check if cov_mat is calculated correctly

# Check if "Mkt-RF" column exists in past_returns
colnames(past_returns)
## [1] "SMB" "HML" "RF"
# If "Mkt-RF" doesn't exist, it could be due to incorrect column names or some other issue

# Now, continue with the rest of the analysis...
# Check the structure of monthly_returns and ff_data
str(monthly_returns)
## List of 1
##  $ Year: int(0)
str(ff_data)
## Classes 'data.table' and 'data.frame':   1172 obs. of  5 variables:
##  $ Year  : int  192607 192608 192609 192610 192611 192612 192701 192702 192703 192704 ...
##  $ Mkt-RF: num  0.0296 0.0264 0.0036 -0.0324 0.0253 0.0262 -0.0006 0.0418 0.0013 0.0046 ...
##  $ SMB   : num  -0.0256 -0.0117 -0.014 -0.0009 -0.001 -0.0003 -0.0037 0.0004 -0.0165 0.003 ...
##  $ HML   : num  -0.0243 0.0382 0.0013 0.007 -0.0051 -0.0005 0.0454 0.0294 -0.0261 0.0081 ...
##  $ RF    : num  0.0022 0.0025 0.0023 0.0032 0.0031 0.0028 0.0025 0.0026 0.003 0.0025 ...
##  - attr(*, ".internal.selfref")=<externalptr>
# Ensure that both datasets have the 'Year' column with the same name and data type

# Check the 'Year' column in both datasets
head(monthly_returns$Year)
## integer(0)
head(ff_data$Year)
## [1] 192607 192608 192609 192610 192611 192612
# If there's any discrepancy in the 'Year' column between the datasets, correct it

# Retry the merging process
merged_data <- merge(monthly_returns, ff_data, by = "Year")

# Check the structure and content of merged_data
str(merged_data)
## 'data.frame':    0 obs. of  5 variables:
##  $ Year  : int 
##  $ Mkt-RF: num 
##  $ SMB   : num 
##  $ HML   : num 
##  $ RF    : num
head(merged_data)
## [1] Year   Mkt-RF SMB    HML    RF    
## <0 rows> (or 0-length row.names)
# If the merging is successful, continue with the subsequent calculations

# Compute MVP monthly returns based on CAPM model
start_date <- as.Date("2019-03-01")
end_date <- as.Date("2024-02-29")
past_returns <- merged_data[merged_data$Year >= start_date & merged_data$Year <= end_date, -1]

# Check if past_returns contains the expected data

# Calculate covariance matrix
cov_mat <- cov(past_returns)

# Check if cov_mat is calculated correctly

# Check if "Mkt-RF" column exists in past_returns
colnames(past_returns)
## [1] "Mkt-RF" "SMB"    "HML"    "RF"
# If "Mkt-RF" doesn't exist, it could be due to incorrect column names or some other issue

# Continue with the rest of the analysis...

# Now, if the merging is successful, continue with the subsequent calculations

Including Plots

You can also embed plots, for example:

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.