Q1

# Load necessary libraries
library(quantmod)
## Warning: package 'quantmod' was built under R version 4.3.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.3.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.3.3
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Warning: package 'TTR' was built under R version 4.3.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(xts)
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3
## Warning: package 'tibble' was built under R version 4.3.3
## Warning: package 'tidyr' was built under R version 4.3.3
## Warning: package 'readr' was built under R version 4.3.3
## Warning: package 'purrr' was built under R version 4.3.3
## Warning: package 'dplyr' was built under R version 4.3.3
## Warning: package 'stringr' was built under R version 4.3.3
## Warning: package 'forcats' was built under R version 4.3.3
## Warning: package 'lubridate' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::first()  masks xts::first()
## ✖ dplyr::lag()    masks stats::lag()
## ✖ dplyr::last()   masks xts::last()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readr)
library(magrittr)
## Warning: package 'magrittr' was built under R version 4.3.3
## 
## Attaching package: 'magrittr'
## 
## The following object is masked from 'package:purrr':
## 
##     set_names
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
library(PerformanceAnalytics)
## Warning: package 'PerformanceAnalytics' was built under R version 4.3.3
## 
## Attaching package: 'PerformanceAnalytics'
## 
## The following object is masked from 'package:graphics':
## 
##     legend
# Load the data
setwd("D:/School Folder/HW/Investment")
etf4 <- read.csv("myetf4.csv")
etf4$Index <- as.Date(etf4$Index)

# Create xts object
etf4.xts <- xts(etf4[, -1], order.by = etf4$Index)
etf4.ret <- etf4.xts %>% Return.calculate() %>% na.omit()
Mean.arithmetic (etf4.ret)
##                       tw0050       tw0056      tw006205      tw00646
## Arithmetic Mean 0.0004632227 0.0003846366 -0.0002118311 0.0002554122
cov(etf4.ret)
##                tw0050       tw0056     tw006205      tw00646
## tw0050   7.837060e-05 4.559164e-05 4.467258e-05 3.663388e-05
## tw0056   4.559164e-05 4.526413e-05 2.673674e-05 2.353543e-05
## tw006205 4.467258e-05 2.673674e-05 1.304184e-04 2.910367e-05
## tw00646  3.663388e-05 2.353543e-05 2.910367e-05 5.902892e-05
# optimal weights for 4 ETFs based on daily return
ETF.names <- c("0050", "0056", "006205", "00646")
mu.vec = c(0.00046322227, 0.0003846366, -0.0002118311, 0.0002554122)
names(mu.vec) = ETF.names 
sigma.mat= matrix(c(7.837060e-05, 4.559164e-05, 4.467258e-05, 3.663388e-05,
                    4.559164e-05, 4.526413e-05, 2.673674e-05, 2.353543e-05,
                    4.467258e-05, 2.673674e-05, 1.304184e-05, 2.910367e-05,
                    3.663388e-05, 2.353583e-05, 2.910367e-05, 5.902892e-05) ,
                  nrow=4, ncol=4)
dimnames(sigma.mat) = list(ETF.names, ETF.names)
mu.vec
##          0050          0056        006205         00646 
##  0.0004632223  0.0003846366 -0.0002118311  0.0002554122
sigma.mat
##                0050         0056       006205        00646
## 0050   7.837060e-05 4.559164e-05 4.467258e-05 3.663388e-05
## 0056   4.559164e-05 4.526413e-05 2.673674e-05 2.353583e-05
## 006205 4.467258e-05 2.673674e-05 1.304184e-05 2.910367e-05
## 00646  3.663388e-05 2.353543e-05 2.910367e-05 5.902892e-05
x.vec = rep(1,4)/4
names(x.vec) = ETF.names
mu.p.x = crossprod (x.vec,mu.vec)
sig2.p.x = t(x.vec) %*% sigma.mat %*%x.vec
sig.p.x = sqrt ( sig2.p.x)
mu.p.x
##            [,1]
## [1,] 0.00022286
sig.p.x
##           [,1]
## [1,] 0.0061657
# compute minimum variance portfolio
top.mat = cbind(2*sigma.mat, rep(1, 4))
bot.vec = c(rep(1, 4), 0)
Am.mat = rbind(top.mat, bot.vec)
b.vec = c(rep(0, 4), 1)
z.m.mat = solve(Am.mat)%*%b.vec
m.vec = z.m.mat [1:4,1]
m.vec
##       0050       0056     006205      00646 
##  0.2841066  1.0426639 -1.1108678  0.7840973
# portfolio return and standard deviation
mu.gmin = as.numeric(crossprod(m.vec, mu.vec))
mu.gmin
## [1] 0.0009682356
sig2.gmin = as.numeric(t(m.vec)%*%sigma.mat%*%m.vec)
sig.min = sqrt(sig2.gmin)
sig.min
## [1] 0.006992965

Q2

##                 tw0050       tw0056     tw006205      tw00646
## 2016-01-31 -0.01981651 -0.013785790 -0.173070915 -0.038883350
## 2016-02-29  0.02864096  0.043548387 -0.027578391 -0.003630705
## 2016-03-31  0.05550500 -0.002575992  0.082750583  0.026028110
## 2016-04-30 -0.04724138 -0.037190083 -0.024757804  0.009639777
## 2016-05-31  0.02515382  0.016630901  0.004415011  0.022110553
## 2016-06-30  0.03636364  0.029551451 -0.025641026 -0.026057030
##                      tw0050      tw0056     tw006205    tw00646
## Arithmetic Mean 0.008819836 0.007086721 -0.005355481 0.00451063
##                tw0050       tw0056     tw006205      tw00646
## tw0050   0.0011751458 0.0008661004 0.0008472189 0.0003928466
## tw0056   0.0008661004 0.0009080806 0.0005553289 0.0003572509
## tw006205 0.0008472189 0.0005553289 0.0024412877 0.0006736296
## tw00646  0.0003928466 0.0003572509 0.0006736296 0.0008605161
##                0050         0056       006205        00646
## 0050   0.0011751458 0.0008661004 0.0008472189 0.0003928466
## 0056   0.0008661004 0.0009080806 0.0005553289 0.0003572509
## 006205 0.0008472189 0.0005553289 0.0024412877 0.0006736296
## 00646  0.0003928466 0.0003572509 0.0006736296 0.0008605161
##             [,1]
## [1,] 0.003765426
##            [,1]
## [1,] 0.02825086
##        0050        0056      006205       00646 
## 0.003183681 0.474049222 0.001203766 0.521563330

Q3

# portofolio return and standard deviation
mu.gmin = as.numeric(crossprod(m.vec, mu.vec))
mu.gmin
sig2.gmin = as.numeric(t(m.vec)%*%sigma.mat%*%m.vec)
sig.gmin = sqrt(sig2.gmin)
sig.gmin

mu_tangency <- t(m.vec) %*% mu.vec  # Expected return of tangency portfolio
sigma_tangency <- sqrt(t(m.vec) %*% sigma.mat %*% m.vec)  # Standard deviation of tangency portfolio

cat("Expected return of tangency portfolio:", mu_tangency, "\n")
cat("Standard deviation of tangency portfolio (daily):", sigma_tangency, "\n")