Portfolio Management Assignment

Quarto

## Portfolio Management Assignment

1. Introduction

This project focuses on constructing a Minimum Variance Portfolio (MVP) using 8 ETFs and comparing CAPM and Fama-French 3-factor models.

2. R Implementation and Results

```{r} #| echo: true #| message: false #| warning: false

library(quantmod) library(PerformanceAnalytics) library(frenchdata)

Define tickers

tickers <- c(“SPY”, “QQQ”, “EEM”, “IWM”, “EFA”, “TLT”, “IYR”, “GLD”)

Download ETF data

getSymbols(tickers, src = “yahoo”, from = “2010-01-01”, to = “2025-05-01”)

Extract Adjusted Prices and calculate monthly returns

prices <- do.call(merge, lapply(tickers, function(x) Ad(get(x)))) monthly_prices <- to.monthly(prices, indexAt = “lastof”, OHLC = FALSE) monthly_returns <- na.omit(Return.calculate(monthly_prices, method = “discrete”))

Prepare ETF return dataframe

etf_ret_df <- data.frame(date = index(monthly_returns), coredata(monthly_returns)) etf_ret_df$month_yr <- format(etf_ret_df$date, “%Y-%m”)

Download and process Fama-French factors

ff_download <- download_french_data(“Fama/French 3 Factors”) ff_raw <- ff_download$subsets$data[[1]] ff_raw$date <- as.Date(paste0(ff_raw$date, “01”), format = “%Y%m%d”) ff_factors <- ff_raw ff_factors[, c(“Mkt-RF”, “SMB”, “HML”, “RF”)] <- ff_raw[, c(“Mkt-RF”, “SMB”, “HML”, “RF”)] / 100 ff_factors$month_yr <- format(ff_factors$date, “%Y-%m”)

Merge ETF returns with FF factors

final_data <- merge(etf_ret_df, ff_factors, by = “month_yr”) head(final_data)

2. Portfolio Optimization and Realized Returns

March 2025 Analysis (Question 7)

We calculate weights using both CAPM and Fama-French covariance matrices for the period ending February 2025.

Training data for March 2025 prediction (2020-03 to 2025-02)

train_data <- final_data[final_data\(month_yr >= "2020-03" & final_data\)month_yr <= “2025-02”, ] returns_matrix <- as.matrix(train_data[, 3:10]) ones <- rep(1, 8)

1. CAPM Weights (MVP)

cov_matrix_capm <- cov(returns_matrix) inv_cov <- solve(cov_matrix_capm) weights_capm <- (inv_cov %% ones) / as.numeric(t(ones) %% inv_cov %*% ones)

2. Fama-French Weights

betas <- matrix(NA, nrow = 8, ncol = 3) for(i in 1:8) { excess_ret <- returns_matrix[,i] - train_data\(RF model <- lm(excess_ret ~ train_data\)Mkt-RF + train_data\(SMB + train_data\)HML) betas[i,] <- coef(model)[2:4] } factor_cov <- cov(train_data[, c(“Mkt-RF”, “SMB”, “HML”)]) resid_var <- diag(apply(returns_matrix, 2, var)) cov_matrix_ff <- betas %% factor_cov %% t(betas) + resid_var inv_cov_ff <- solve(cov_matrix_ff) weights_ff <- (inv_cov_ff %% ones) / as.numeric(t(ones) %% inv_cov_ff %*% ones)

Realized Returns for March 2025

march_2025_rets <- as.numeric(final_data[final_data$month_yr == “2025-03”, 3:10]) realized_ret_capm_mar <- sum(march_2025_rets * weights_capm) realized_ret_ff_mar <- sum(march_2025_rets * weights_ff)

cat(“Realized Return (CAPM) March 2025:”, realized_ret_capm_mar, “”) cat(“Realized Return (FF) March 2025:”, realized_ret_ff_mar, “”)

April 2025 Analysis (Question 8)

We roll the window forward by one month to calculate the realized return for April 2025.

Training data for April 2025 prediction (2020-04 to 2025-03)

train_apr <- final_data[final_data\(month_yr >= "2020-04" & final_data\)month_yr <= “2025-03”, ] ret_matrix_apr <- as.matrix(train_apr[, 3:10])

Re-calculate MVP Weights for April

cov_apr <- cov(ret_matrix_apr) inv_cov_apr <- solve(cov_apr) w_apr <- (inv_cov_apr %% ones) / sum(inv_cov_apr %% ones)

Actual April 2025 Returns

actual_apr_rets <- as.numeric(final_data[final_data$month_yr == “2025-04”, 3:10]) realized_ret_apr <- sum(actual_apr_rets * w_apr)

cat(“Realized Return April 2025:”, realized_ret_apr, “”)

3. Theoretical Background

Chapter 5: Risk and Return

We analyzed historical ETF performance, focusing on the trade-off between risk (standard deviation) and expected return.

Chapter 6 & 7: Portfolio Allocation and MVP

By minimizing the portfolio variance using the covariance matrix \(\Sigma\), we identify the Minimum Variance Portfolio (MVP) weights:

$$w = \frac{\Sigma^{-1} \mathbf{1}}{\mathbf{1}’ \Sigma^{-1} \mathbf{1}}$$

Chapter 8: Index Models

The Fama-French 3-factor model expands upon CAPM by considering Market, Size (SMB), and Value (HML) factors to better estimate the risk structure of the portfolio.