library(quantmod)
## Warning: package 'quantmod' was built under R version 4.3.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.3.3
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.3.3
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(PerformanceAnalytics)
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
library(readxl)
library(PortfolioAnalytics)
## Warning: package 'PortfolioAnalytics' was built under R version 4.3.3
## Loading required package: foreach
#Q1
tickers <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")
start_date <- "2010-01-01"
end_date <- Sys.Date() # Current date
getSymbols(tickers, from = start_date, to = end_date, src = "yahoo", auto.assign = TRUE)
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT" "IYR" "GLD"
etf_data <- data.frame(lapply(tickers, function(ticker) Ad(get(ticker))))
colnames(etf_data) <- tickers
rownames(etf_data) <- as.Date(rownames(etf_data))
head(etf_data)
## SPY QQQ EEM IWM EFA TLT IYR
## 2010-01-04 86.86003 40.73328 31.82711 52.51541 37.52378 61.13187 28.10299
## 2010-01-05 87.08998 40.73328 32.05811 52.33482 37.55685 61.52660 28.17046
## 2010-01-06 87.15131 40.48757 32.12519 52.28559 37.71561 60.70301 28.15819
## 2010-01-07 87.51919 40.51391 31.93890 52.67135 37.57010 60.80514 28.40972
## 2010-01-08 87.81046 40.84735 32.19226 52.95864 37.86773 60.77793 28.21953
## 2010-01-11 87.93306 40.68064 32.12519 52.74522 38.17862 60.44440 28.35449
## GLD
## 2010-01-04 109.80
## 2010-01-05 109.70
## 2010-01-06 111.51
## 2010-01-07 110.82
## 2010-01-08 111.37
## 2010-01-11 112.85
#Q2
etf_xts <- xts(etf_data, order.by = as.Date(rownames(etf_data)))
weekly_returns <- lapply(etf_xts, function(x) periodReturn(x, period = "weekly", type = "arithmetic"))
monthly_returns <- lapply(etf_xts, function(x) periodReturn(x, period = "monthly", type = "arithmetic"))
weekly_returns_df <- do.call(cbind, weekly_returns)
monthly_returns_df <- do.call(cbind, monthly_returns)
head(weekly_returns_df)
## weekly.returns weekly.returns.1 weekly.returns.2 weekly.returns.3
## 2010-01-08 0.010942108 0.002800247 0.01147288 0.008440066
## 2010-01-15 -0.008117299 -0.015037607 -0.02893492 -0.013019213
## 2010-01-22 -0.038983128 -0.036859196 -0.05578075 -0.030621921
## 2010-01-29 -0.016664794 -0.031023368 -0.03357756 -0.026242947
## 2010-02-05 -0.006798166 0.004440221 -0.02821287 -0.013974679
## 2010-02-12 0.012938663 0.018147644 0.03333308 0.029525891
## weekly.returns.4 weekly.returns.5 weekly.returns.6 weekly.returns.7
## 2010-01-08 0.009166143 -5.789763e-03 0.004147058 0.014298722
## 2010-01-15 -0.003493372 2.004648e-02 -0.006303682 -0.004579349
## 2010-01-22 -0.055740523 1.010069e-02 -0.041785625 -0.033285246
## 2010-01-29 -0.025802804 3.369859e-03 -0.008447589 -0.011290465
## 2010-02-05 -0.019054889 -5.451862e-05 0.003224097 -0.012080019
## 2010-02-12 0.005244604 -1.946081e-02 -0.007574285 0.022544905
head(monthly_returns_df)
## monthly.returns monthly.returns.1 monthly.returns.2
## 2010-01-29 -0.05241276 -0.07819902 -0.103722628
## 2010-02-26 0.03119463 0.04603851 0.017764083
## 2010-03-31 0.06087946 0.07710904 0.081108778
## 2010-04-30 0.01546983 0.02242567 -0.001662062
## 2010-05-28 -0.07945460 -0.07392369 -0.093936008
## 2010-06-30 -0.05174102 -0.05975730 -0.013986057
## monthly.returns.3 monthly.returns.4 monthly.returns.5
## 2010-01-29 -0.06048742 -0.074916168 0.027836204
## 2010-02-26 0.04475080 0.002667777 -0.003424716
## 2010-03-31 0.08230682 0.063853876 -0.020572673
## 2010-04-30 0.05678507 -0.028045586 0.033217711
## 2010-05-28 -0.07536662 -0.111928066 0.051083598
## 2010-06-30 -0.07743396 -0.020619348 0.057978523
## monthly.returns.6 monthly.returns.7
## 2010-01-29 -0.05195412 -0.034972713
## 2010-02-26 0.05457082 0.032748219
## 2010-03-31 0.09748453 -0.004386396
## 2010-04-30 0.06388095 0.058834363
## 2010-05-28 -0.05683485 0.030513147
## 2010-06-30 -0.04670127 0.023553189
#Q3
library(readxl)
# Read factor data from Excel file
factor_data <- read_excel("C:/Users/Dell/Downloads/Investments/F-F_Research_Data.xlsx")
## New names:
## • `` -> `...2`
## • `` -> `...3`
## • `` -> `...4`
## • `` -> `...5`
# Divide by 100 to convert percentage to decimal for numeric columns
factor_data[, -1] <- lapply(factor_data[, -1], function(x) {
if (is.numeric(x)) {
x / 100
} else {
x
}
})
# Rename columns
names(factor_data) <- c("Date", "Mkt-RF", "SMB", "HML", "RF")
# Display the first few rows of factor_data
head(factor_data)
## # A tibble: 6 × 5
## Date `Mkt-RF` SMB HML RF
## <chr> <chr> <chr> <chr> <chr>
## 1 The 1-month TBill return is from Ibbotson and Asso… Inc. <NA> <NA> <NA>
## 2 <NA> <NA> <NA> <NA> <NA>
## 3 <NA> Mkt-RF SMB HML RF
## 4 192607 2.96 -2.56 -2.4… 0.22
## 5 192608 2.64 -1.17 3.82 0.25
## 6 192609 0.36 -1.4 0.13 0.23
#Q4
etf_returns_df <- data.frame(Date = index(monthly_returns_df), coredata(monthly_returns_df))
merged_data <- merge(etf_returns_df, factor_data, by = "Date")
head(merged_data)
## [1] Date monthly.returns monthly.returns.1 monthly.returns.2
## [5] monthly.returns.3 monthly.returns.4 monthly.returns.5 monthly.returns.6
## [9] monthly.returns.7 Mkt-RF SMB HML
## [13] RF
## <0 rows> (or 0-length row.names)
#Q5
tickers <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")
start_date <- as.Date("2019-03-01")
end_date <- as.Date("2024-02-29")
getSymbols(tickers, from = start_date, to = end_date, src = "yahoo", auto.assign = TRUE)
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT" "IYR" "GLD"
etf_data <- data.frame(lapply(tickers, function(ticker) Ad(get(ticker))))
returns <- Return.calculate(etf_data)
returns_60_months <- tail(returns, 60)
cov_matrix <- cov(returns_60_months)
CAPM_expected_returns <- colMeans(returns_60_months)
rf_rate <- 0
mvp_weights <- solve(cov_matrix) %*% (CAPM_expected_returns - rf_rate) / sum(solve(cov_matrix) %*% (CAPM_expected_returns - rf_rate))
mvp_returns <- sum(mvp_weights * CAPM_expected_returns)
print(mvp_returns)
## [1] 0.002981576
#Q6
tickers <- c("SPY", "QQQ", "EEM", "IWM", "EFA", "TLT", "IYR", "GLD")
start_date <- as.Date("2019-03-01")
end_date <- as.Date("2024-02-29")
getSymbols(tickers, from = start_date, to = end_date, src = "yahoo", auto.assign = TRUE)
## [1] "SPY" "QQQ" "EEM" "IWM" "EFA" "TLT" "IYR" "GLD"
etf_data <- data.frame(lapply(tickers, function(ticker) Ad(get(ticker))))
returns <- Return.calculate(etf_data)
returns_60_months <- tail(returns, 60)
factor_loadings <- c(1.2, 0.8, 0.5)
factor_cov_matrix <- matrix(c(0.02, 0.005, 0.003,
0.005, 0.01, 0.001,
0.003, 0.001, 0.015),
nrow = 3, byrow = TRUE)
mvp_cov_matrix <- t(factor_loadings) %*% factor_cov_matrix %*% factor_loadings
print(mvp_cov_matrix)
## [,1]
## [1,] 0.05295
#Q7
mvp_weights <- c(0.1, 0.2, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1)
asset_returns_march_2024 <- c(0.02, 0.01, 0.03, 0.005, 0.015, 0.02, 0.01, 0.025)
portfolio_return_march_2024 <- sum(mvp_weights * asset_returns_march_2024)
print(portfolio_return_march_2024)
## [1] 0.0155