library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(quadprog)
file_path <- "myetf4.csv"
df <- read.csv(file_path, stringsAsFactors = FALSE)
df$Index <- as.Date(df$Index, format="%Y/%m/%d")
df_filtered <- df %>%
  filter(Index >= as.Date("2015-12-14") & Index <= as.Date("2018-12-28")) %>%
  select(-Index)
returns <- df_filtered %>%
  mutate(across(everything(), ~ (. - lag(.)) / lag(.))) %>%
  drop_na()
cov_matrix <- cov(returns)
num_assets <- ncol(returns)
Dmat <- 2 * cov_matrix  
dvec <- rep(0, num_assets)  
Amat <- cbind(rep(1, num_assets))  
bvec <- 1 
meq <- 1
gmvp_solution <- solve.QP(Dmat, dvec, Amat, bvec, meq)
gmvp_weights <- gmvp_solution$solution
gmvp_return <- colMeans(returns) %*% gmvp_weights
gmvp_std <- sqrt(t(gmvp_weights) %*% cov_matrix %*% gmvp_weights)
cat("GMVP Weights:", round(gmvp_weights, 4), "\n")
## GMVP Weights: -0.2194 0.7284 0.1076 0.3834
cat("GMVP Expected Daily Return:", round(gmvp_return, 6), "\n")
## GMVP Expected Daily Return: 0.000254
cat("GMVP Daily Standard Deviation:", round(gmvp_std, 6), "\n")
## GMVP Daily Standard Deviation: 0.005905
library(tidyverse)
library(quadprog)
library(lubridate)
file_path <- "myetf4.csv"
df <- read.csv(file_path, stringsAsFactors = FALSE)
df$Index <- as.Date(df$Index, format="%Y/%m/%d")
df_filtered <- df %>%
  filter(Index >= as.Date("2015-12-14") & Index <= as.Date("2018-12-28"))
df_monthly <- df_filtered %>%
  group_by(year = year(Index), month = month(Index)) %>%
  slice_tail(n = 1) %>%
  ungroup() %>%
  select(-Index, -year, -month)
returns_monthly <- df_monthly %>%
  mutate(across(everything(), ~ (. - lag(.)) / lag(.))) %>%
  drop_na()
cov_matrix_monthly <- cov(returns_monthly)
num_assets <- ncol(returns_monthly)
Dmat <- 2 * cov_matrix_monthly
dvec <- rep(0, num_assets)  
Amat <- cbind(rep(1, num_assets))  
bvec <- 1  
meq <- 1 
gmvp_solution <- solve.QP(Dmat, dvec, Amat, bvec, meq)
gmvp_weights_monthly <- gmvp_solution$solution
gmvp_return_monthly <- colMeans(returns_monthly) %*% gmvp_weights_monthly
gmvp_std_monthly <- sqrt(t(gmvp_weights_monthly) %*% cov_matrix_monthly %*% gmvp_weights_monthly)
cat("GMVP Weights (Monthly Returns):", round(gmvp_weights_monthly, 4), "\n")
## GMVP Weights (Monthly Returns): 0.0032 0.474 0.0012 0.5216
cat("GMVP Expected Monthly Return:", round(gmvp_return_monthly, 6), "\n")
## GMVP Expected Monthly Return: 0.005734
cat("GMVP Monthly Standard Deviation:", round(gmvp_std_monthly, 6), "\n")
## GMVP Monthly Standard Deviation: 0.024904
library(tidyverse)
library(quadprog)
expected_returns <- colMeans(returns_monthly)
cov_matrix_monthly <- cov(returns_monthly)
num_assets <- length(expected_returns)
Dmat <- 2 * cov_matrix_monthly
dvec <- rep(0, num_assets)
Amat <- cbind(expected_returns, rep(1, num_assets))
bvec <- c(1, 1) 
meq <- 1
tangency_solution <- solve.QP(Dmat, dvec, Amat, bvec, meq)
tangency_weights <- tangency_solution$solution
tangency_return <- sum(expected_returns * tangency_weights)
tangency_std <- sqrt(t(tangency_weights) %*% cov_matrix_monthly %*% tangency_weights)
cat("Tangency Portfolio Weights:", round(tangency_weights, 4), "\n")
## Tangency Portfolio Weights: 72.1422 -8.7164 -46.8508 38.7042
cat("Tangency Portfolio Expected Monthly Return:", round(tangency_return, 6), "\n")
## Tangency Portfolio Expected Monthly Return: 1
cat("Tangency Portfolio Monthly Standard Deviation:", round(tangency_std, 6), "\n")
## Tangency Portfolio Monthly Standard Deviation: 2.445347