# Tutorial Week 7
# Davide Benedetti
# 27/02/2021
library(tidyverse)
library(tidyquant)
tickers <- read.csv("AMS Yahoo Ticker Symbols 2017.csv")
# load the list of tickers from Yahoo finance
stocks <- tq_get(tickers$Ticker, from = "2018-01-01")
## alternatively you can run
# load("stocks.RData")
ret <- stocks %>%
# remove stocks “GROHA.AS” and “HUNDP.AS”
filter(symbol != “GROHA.AS” & symbol != “HUNDP.AS”) %>%
# caluclate log annualized returns
group_by(symbol) %>%
mutate(return = log(adjusted/lag(adjusted)) * 252 ) %>%
# select only columns ‘symbol’, ‘date’ and ‘return’
select(symbol, date, return) %>%
# remove rows with NaN’s
na.omit() %>%
# unstack the stocks as column variables
spread(symbol, return) %>%
# remove columns with too many NaN’s
select(where(~ sum(!is.na(.x)) > 700 )) %>%
# remove rows with even one NaN’s
na.omit()
# check the data
library(stargazer)
ret %>% as.data.frame() %>%
stargazer(type = “text”)
# There are a lot of stocks which are not very liquid,
# and their returns are zero for long periods as they are
# not often traded, so their price does not change
# We are going to remove stocks which are not traded at least 50% of the times
X <- data.frame(ret[,-1])
X <- X[, colSums(X == 0) < 300] %>%
as.matrix()
# now we can apply PCA on X
eigenPort <- prcomp(X, center = T, scale = F)
eigenvalues <- as.matrix(eigenPort$sdev^2)
eigenvectors <- as.matrix(eigenPort$rotation)
princomp <- eigenPort$x
mu <- eigenPort$center
# the first 5 components explain 50% of Sigma
cumsum(eigenvalues) / sum(eigenvalues) * 100
# eigenvectors can be interpreted as portfolio weights
# applying them to the stocks will generate new portfolios
# that are incorrelated with one another
# These portfolios can also be intepreted as latent (unobservable) risk factors
# and we can plot their weights (eigenvectors) to interpret them
for(ii in 1:5){
barplot(eigenvectors[,ii],
ylab = "", xlab = "",
main = paste0("PC", ii))
}
# PC1 can be intepreted as the market portfolio
# PC2 is a portfolio that goes long on stock "ESP.AS"
# we can find similar interpretation for the others
# and we can use more components
# we can also plot the PC portfolios (latent risk factors)
for(ii in 1:5){
pc_port <- X %*% eigenvectors[,ii]/sum(eigenvectors[,ii])
plot(ret$date, pc_port,
ylab = "", xlab = "", main = paste0("PC", ii),
type = "l")
}
# after we interpreted the components we are interested on as risk factors,
# we can calculate the exposure to each one of them
# for any given a portfolio allocation we want to invest into
# Es.1: equally weighted portfolio
w_eq <- rep(1/ncol(X), ncol(X))
# Es.2: min-Var portfolio with target return
library(PortfolioAnalytics)
portf <- portfolio.spec(colnames(X))
portf <- add.constraint(portf, type="weight_sum",
min_sum=0.99, max_sum=1.01)
portf <- add.constraint(portf, type="long_only")
portf <- add.constraint(portf, type="return",
return_target = 0.1)
portf <- add.objective(portf, type="risk", name = "var")
portf_res <- optimize.portfolio(zoo(X, ret$date), portf,
optimize_method = "ROI",
trace = F, message = F,
verbose = F)
w_minvar <- portf_res$weights
barplot(w_eq, ylab = "", xlab = "", main = "Weights Equally-Weighted Portfolio")
barplot(w_minvar, ylab = "", xlab = "", main = "Weights Min-Var Portfolio")
# exposure to PCA risk factors for the two portfolios
t(eigenvectors) %*% cbind(w_eq, w_minvar)