Q1
# Load required libraries
library(readr)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(quadprog)
library(readr)
library(xts)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
# Read the CSV file with appropriate column types
myetf4 <- read_csv("myetf4.csv",
col_types = cols(Index = col_date(format = "%Y/%m/%d")))
# Convert to xts object
myetf4_xts <- xts(myetf4[, -1], order.by = myetf4$Index)
# Display the first few rows of the xts object
head(myetf4_xts)
## tw0050 tw0056 tw006205 tw00646
## 2015-12-14 53.29 18.25 31.06 19.61
## 2015-12-15 53.33 18.38 31.59 19.63
## 2015-12-16 54.14 18.56 31.60 19.89
## 2015-12-17 54.77 18.81 32.23 20.05
## 2015-12-18 54.50 18.95 32.18 19.85
## 2015-12-21 54.41 19.02 33.00 19.64
start_date <- as.Date("2015-12-14")
end_date <- as.Date("2018-12-28")
myetf4 <- filter(myetf4, Index >= start_date & Index <= end_date)
# Calculate daily returns
returns <- myetf4 %>%
mutate(`tw0050` = log(`tw0050` / lag(`tw0050`)),
`tw0056` = log(`tw0056` / lag(`tw0056`)),
`tw006205` = log(`tw006205` / lag(`tw006205`)),
`tw00646` = log(`tw00646` / lag(`tw00646`))) %>%
select(-Index) %>%
na.omit()
cov_matrix <- cov(returns)
objective_function <- function(w, cov_matrix) {
return(t(w) %*% cov_matrix %*% w)
}
constraints <- matrix(1, nrow = 1, ncol = ncol(returns))
bounds <- matrix(c(0, 1), nrow = 2, ncol = ncol(returns))
init_guess <- rep(1/ncol(returns), ncol(returns))
optimal_weights <- solve.QP(Dmat = cov_matrix, dvec = rep(0, ncol(returns)),
Amat = t(constraints), bvec = c(1),
meq = 1)$solution
portfolio_return <- sum(colMeans(returns) * optimal_weights) * 252 # 252 trading days in a year
portfolio_std_dev <- sqrt(t(optimal_weights) %*% cov_matrix %*% optimal_weights) * sqrt(252)
# Print results
print("Optimal Weights:")
## [1] "Optimal Weights:"
print(optimal_weights)
## [1] -0.2241314 0.7298726 0.1080760 0.3861827
print("Portfolio Return:")
## [1] "Portfolio Return:"
print(portfolio_return)
## [1] 0.05704909
print("Portfolio Standard Deviation:")
## [1] "Portfolio Standard Deviation:"
print(portfolio_std_dev)
## [,1]
## [1,] 0.09400267
#Q2
# Load required libraries
library(readr)
library(dplyr)
library(quadprog)
library(zoo)
library(readr)
library(xts)
# Read the CSV file with appropriate column types
myetf4 <- read_csv("myetf4.csv",
col_types = cols(Index = col_date(format = "%Y/%m/%d")))
# Convert to xts object
myetf4_xts <- xts(myetf4[, -1], order.by = myetf4$Index)
# Display the first few rows of the xts object
head(myetf4_xts)
## tw0050 tw0056 tw006205 tw00646
## 2015-12-14 53.29 18.25 31.06 19.61
## 2015-12-15 53.33 18.38 31.59 19.63
## 2015-12-16 54.14 18.56 31.60 19.89
## 2015-12-17 54.77 18.81 32.23 20.05
## 2015-12-18 54.50 18.95 32.18 19.85
## 2015-12-21 54.41 19.02 33.00 19.64
start_date <- as.Date("2015-12-14")
end_date <- as.Date("2018-12-28")
myetf4 <- filter(myetf4, Index >= start_date & Index <= end_date)
zoo_data <- zoo(myetf4[,-1], order.by = myetf4$Index)
monthly_returns <- aggregate(zoo_data, as.yearmon, function(x) log(x[length(x)] / x[1]))
cov_matrix <- cov(monthly_returns)
objective_function <- function(w, cov_matrix) {
return(t(w) %*% cov_matrix %*% w)
}
constraints <- matrix(1, nrow = 1, ncol = ncol(monthly_returns))
bounds <- matrix(c(0, 1), nrow = 2, ncol = ncol(monthly_returns))
init_guess <- rep(1/ncol(monthly_returns), ncol(monthly_returns))
optimal_weights <- solve.QP(Dmat = cov_matrix, dvec = rep(0, ncol(monthly_returns)),
Amat = t(constraints), bvec = c(1),
meq = 1)$solution
portfolio_return <- sum(colMeans(monthly_returns) * optimal_weights) * 12 # 12 trading months in a year
portfolio_std_dev <- sqrt(t(optimal_weights) %*% cov_matrix %*% optimal_weights) * sqrt(12)
# Print results
print("Optimal Weights:")
## [1] "Optimal Weights:"
print(optimal_weights)
## [1] -0.20712438 0.70666783 0.05229222 0.44816432
print("Portfolio Return:")
## [1] "Portfolio Return:"
print(portfolio_return)
## [1] 0.05834204
print("Portfolio Standard Deviation:")
## [1] "Portfolio Standard Deviation:"
print(portfolio_std_dev)
## [,1]
## [1,] 0.08896461
#Q3
portfolio_sharpe <- colMeans(monthly_returns) / apply(monthly_returns, 2, sd)
tangency_portfolio <- optimal_weights
# Print results
print("Tangency Portfolio (Weights):")
## [1] "Tangency Portfolio (Weights):"
print(tangency_portfolio)
## [1] -0.20712438 0.70666783 0.05229222 0.44816432