library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.0     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.1     ✔ tibble    3.1.8
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(lubridate)
library(ggplot2)

# Load the data
sector_returns <- read_csv("C:\\Users\\emman\\Downloads\\10_Industry_Portfolios.csv")
## Rows: 1173 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (11): date, NoDur, Durbl, Manuf, Enrgy, HiTec, Telcm, Shops, Hlth, Utils...
## 
## ℹ 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.
# Convert the date column to Date type
sector_returns <- sector_returns %>%
  mutate(date = ymd(paste0(date, "01")))

# Filter data starting from 1964 (to have 5 years of data by 1969)
sector_returns <- sector_returns %>%
  filter(date >= as.Date("1969-01-01"))

# Function to calculate MVP weights
mvp_weights <- function(cov_matrix) {
  inv_cov <- solve(cov_matrix)
  ones <- rep(1, nrow(inv_cov))
  weights <- inv_cov %*% ones / sum(inv_cov %*% ones)
  return(weights)
}

# Initialize vectors to store results
dates <- sector_returns$date
num_sectors <- ncol(sector_returns) - 1
mvp_returns <- numeric(length(dates) - 60 + 1)

# Calculate rolling 5-year covariance matrices and MVP returns
for (i in 60:length(dates)) {
  ret_window <- sector_returns[(i-59):i, -1]
  cov_matrix <- cov(ret_window)
  weights <- mvp_weights(cov_matrix)
  current_returns <- as.numeric(sector_returns[i, -1])
  mvp_returns[i-59] <- sum(weights * current_returns)
}

# Create a data frame for the results
mvp_data <- data.frame(
  date = dates[60:length(dates)],
  mvp_return = mvp_returns
)

# Calculate cumulative returns
mvp_data <- mvp_data %>%
  mutate(cumulative_return = cumprod(1 + mvp_return / 100))

# Plot cumulative returns
ggplot(mvp_data, aes(x = date, y = cumulative_return)) +
  geom_line(color = "blue") +
  labs(title = "Cumulative Returns of Minimum Variance Portfolio (MVP)",
       x = "Date",
       y = "Cumulative Return") +
  theme_minimal()

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:

summary(cars)
##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00

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.