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(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.86005 40.73326 31.82712 52.51540 37.52378 61.13187 28.10298
## 2010-01-05 87.09001 40.73326 32.05812 52.33483 37.55686 61.52662 28.17046
## 2010-01-06 87.15131 40.48758 32.12519 52.28556 37.71561 60.70306 28.15819
## 2010-01-07 87.51919 40.51389 31.93889 52.67135 37.57008 60.80511 28.40972
## 2010-01-08 87.81041 40.84735 32.19226 52.95863 37.86774 60.77789 28.21954
## 2010-01-11 87.93307 40.68063 32.12519 52.74524 38.17862 60.44437 28.35451
##               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.010941227      0.002800811       0.01147276      0.008439994
## 2010-01-15   -0.008117044     -0.015037794      -0.02893498     -0.013018927
## 2010-01-22   -0.038982966     -0.036859108      -0.05578081     -0.030621989
## 2010-01-29   -0.016664614     -0.031023568      -0.03357743     -0.026243322
## 2010-02-05   -0.006797796      0.004440527      -0.02821327     -0.013974528
## 2010-02-12    0.012937911      0.018148048       0.03333330      0.029526288
##            weekly.returns.4 weekly.returns.5 weekly.returns.6 weekly.returns.7
## 2010-01-08      0.009166449    -5.790512e-03      0.004147466      0.014298722
## 2010-01-15     -0.003493371     2.004681e-02     -0.006303951     -0.004579349
## 2010-01-22     -0.055740916     1.010057e-02     -0.041785424     -0.033285246
## 2010-01-29     -0.025802595     3.370531e-03     -0.008447730     -0.011290465
## 2010-02-05     -0.019054889    -5.464003e-05      0.003223882     -0.012080019
## 2010-02-12      0.005244716    -1.946087e-02     -0.007574358      0.022544905
head(monthly_returns_df)
##            monthly.returns monthly.returns.1 monthly.returns.2
## 2010-01-29     -0.05241301       -0.07819878      -0.103722723
## 2010-02-26      0.03119482        0.04603882       0.017763479
## 2010-03-31      0.06087918        0.07710933       0.081109013
## 2010-04-30      0.01547008        0.02242548      -0.001661941
## 2010-05-28     -0.07945475       -0.07392386      -0.093935411
## 2010-06-30     -0.05174083       -0.05975654      -0.013986721
##            monthly.returns.3 monthly.returns.4 monthly.returns.5
## 2010-01-29       -0.06048764      -0.074916074       0.027836329
## 2010-02-26        0.04475104       0.002667447      -0.003425384
## 2010-03-31        0.08230735       0.063854336      -0.020572623
## 2010-04-30        0.05678396      -0.028045789       0.033217727
## 2010-05-28       -0.07536615      -0.111928289       0.051084345
## 2010-06-30       -0.07743390      -0.020618818       0.057978395
##            monthly.returns.6 monthly.returns.7
## 2010-01-29       -0.05195392      -0.034972713
## 2010-02-26        0.05457053       0.032748219
## 2010-03-31        0.09748530      -0.004386396
## 2010-04-30        0.06388111       0.058834363
## 2010-05-28       -0.05683557       0.030513147
## 2010-06-30       -0.04670103       0.023553189
#Q3
library(readxl)

# Read factor data from Excel file
factor_data <- read_xlsx("C:/Users/daavka/Desktop/New folder/F-F_Research_Data_Factors.xlsx")
# 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")
## Warning: The `value` argument of `names<-` must have the same length as `x` as of tibble
## 3.0.0.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Display the first few rows of factor_data
head(factor_data)
## # A tibble: 6 × 1
##   Date                                                          
##   <chr>                                                         
## 1 The 1-month TBill return is from Ibbotson and Associates, Inc.
## 2 <NA>                                                          
## 3 ,Mkt-RF,SMB,HML,RF                                            
## 4 192607,    2.96,   -2.56,   -2.43,    0.22                    
## 5 192608,    2.64,   -1.17,    3.82,    0.25                    
## 6 192609,    0.36,   -1.40,    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
## <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)

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.