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