################################################################################
## -------------------------------------------------------------------------- ##
##                                Bocconi University                          ##
##                                 MAFINRISK 2020/21                          ##
##                                                                            ##
##                    Topics in Financial Econometrics with R                 ##
##                                                                            ##
##                        Group1 Exam Solutions - Question 3                  ##
##                                                                            ##
## Authors:                                                                   ##
##          VASILEIOS OURANOS - vasileios.ouranos@master.unibocconi.it        ##                                   
##          EMILIO SCHIAVO - emilio.schiavo@master.unibocconi.it              ##
##          XAVIER SELLAM - xavier.sellam@master.unibocconi.it                ##
##          THIBAUD RAVENEAU - thibaud.raveneau@master.unibocconi.it          ##
## -------------------------------------------------------------------------- ##
################################################################################

# load required packages
library(fEcofin) 
library(ggplot2)
library(reshape2)

# create data frame with dates as rownames
berndt.df = berndtInvest[, -1]
rownames(berndt.df) = as.character(as.Date(berndtInvest[, 1]))


################################################################################
# Derive the optimal portfolio weights (i.e. the weights in the tangency portfolio)
# using the CER for (i) the Minimun Variance Portfolio , (ii) the tangency portfolio. 
###############################################################################
returns.mat = as.matrix(berndt.df[, c(1:9,11:16)])
#returns.mat = as.matrix(berndt.df[, c(-10, -17)])
n.obs = nrow(returns.mat)
cov.sample=var(returns.mat)
rf = mean(berndt.df$RKFREE)
#
# compute global min variance portfolio
#
# use CER model: estimate the relevant unknown parameters with the sample covariances
w.gmin.sample = solve(var(returns.mat))%*%rep(1,nrow(cov.sample))
w.gmin.sample = w.gmin.sample/sum(w.gmin.sample)
colnames(w.gmin.sample) = "sample"
barplot(t(w.gmin.sample), horiz=F, main="Weights", col="blue", cex.names = 0.75, las=2)
#
# compute tangency portfolio
#

mu = matrix(colMeans(returns.mat), nrow = ncol(returns.mat), ncol = 1)
e = matrix(1, nrow = nrow(cov.sample), ncol = 1) # unitary column vector e

#
# Constant expected returns
#
# compute the column vector with weights of the CER tangency portfolio
w.tan.sample = (solve(cov.sample)%*%(mu-rf*e))/as.numeric(t(e)%*%(solve(cov.sample)%*%(mu-rf*e)))


# visualize the differences
par(mfrow=c(1,2))
barplot(t(w.tan.sample), horiz=T, main="Tangency Port CER", col="blue", cex.names = 0.75, las=1)
barplot(t(w.gmin.sample), horiz=T, main="Min Var Port CER", col="red", cex.names = 0.75, las=1)
par(mfrow=c(1,1))


################################################################################
# Graphs the value over-time of 1 dollar invested in 1978:1 until the end of the 
# available sample in the two alternative tangency portfolios and in the market 
###############################################################################

# here we compute buy and hold portfolio return in a vectorized way

bh.CER.tan = berndt.df[, c(1:9,11:16)] + 1 # add 1 to returns
bh.CER.tan[1,] = t(w.tan.sample)            # substitute weights in the first row
bh.CER.tan = cumprod(bh.CER.tan)           # cumproduct along the columns
bh.CER.tan = rowSums(bh.CER.tan)           # sum along rows
# notice that by construction the first element is 1

# same procedure for the minimum variance
bh.CER.gmin = berndt.df[, c(1:9,11:16)] + 1 
bh.CER.gmin[1,] = t(w.gmin.sample)              
bh.CER.gmin = cumprod(bh.CER.gmin)           
bh.CER.gmin = rowSums(bh.CER.gmin)           
   

# market buy and hold return
bh.market = berndt.df$MARKET + 1
bh.market[1] = 1
bh.market = cumprod(bh.market)

# time history Plot
dates = as.Date(berndtInvest[, 1])
th.df = data.frame(bh.CER.tan,bh.CER.gmin,bh.market, dates)
colnames(th.df) = c("CER tangency", "CER Global Min Var", "Market", "date")
th.df = melt(th.df, id.vars = "date")
colnames(th.df) = c("date", "Portfolio", "Value")
ggplot(th.df) + geom_line(aes(x = date, y = Value, colour = Portfolio)) +
  ggtitle("Time Series of buy and hold portfolios")


# compare means and sd values on global min variance portfolios
mu.vals = colMeans(returns.mat)
mu.gmin.sample = as.numeric(crossprod(w.gmin.sample, mu.vals))
sd.gmin.sample = as.numeric(sqrt(t(w.gmin.sample)%*%var(returns.mat)%*%w.gmin.sample))
mu.tan.sample = as.numeric(crossprod(w.tan.sample, mu.vals))
sd.tansample = as.numeric(sqrt(t(w.tan.sample)%*%var(returns.mat)%*%w.tan.sample))
cbind(mu.tan.sample,mu.gmin.sample, sd.tan.sample, sd.gmin.sample)



