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