# basic finance
library(xts) # to manipulate time series of stock data
library(portfolioBacktest) # to conduct backtests
library(pob) # book package with financial data
# plotting
library(ggplot2) # for nice plots
library(ggdendro) # to plot dendograms
library(reshape2) # to reshape data
library(patchwork) # for combining plots
# graphs
library(fingraph) # to learn financial graphs
# optimization
library(CVXR)
Portfolio Optimization
Chapter 12: Graph-Based Portfolios
R code
R code examples for Chapter 12 of the book:
Daniel P. Palomar (2024). Portfolio Optimization: Theory and Application. Cambridge University Press.
Loading packages
First load the packages used in the examples:
Hierarchical clustering
Dendograms
Plots of dendrograms of S&P 500 stocks (with cut to produce four clusters):
Code
library(pob)
library(ggdendro)
# use data from package pob
data(SP500_2015to2020)
set.seed(42)
<- tail(SP500_2015to2020$stocks[, c("MGM", "WYNN", "LVS", "CMS", "DUK", "BAC", "BK", "USB", "KMB", "PG", "FB", "AMZN", "MSFT", "GOOGL")], 200)
stock_prices <- stock_prices[, sample(ncol(stock_prices))]
stock_prices <- diff(log(stock_prices))[-1]
X <- sqrt(0.5*(1 - cor(X)))
D
<- hclust(dist(D), method = "single") |>
p_single ggdendrogram(rotate = FALSE, size = 4, theme_dendro = TRUE) +
geom_hline(yintercept = 0.66, color = "blue", linetype = "dashed") +
theme(panel.border = element_blank(),
axis.text.y=element_blank()) +
xlab(element_blank()) + ylab(element_blank()) + ggtitle("Single linkage")
<- hclust(dist(D), method = "complete") |>
p_complete ggdendrogram(rotate = FALSE, size = 4, theme_dendro = TRUE) +
geom_hline(yintercept = 0.72, color = "blue", linetype = "dashed") +
theme(panel.border = element_blank(),
axis.text.y=element_blank()) +
xlab(element_blank()) + ylab(element_blank()) + ggtitle("Complete linkage")
<- hclust(dist(D), method = "average") |>
p_average ggdendrogram(rotate = FALSE, size = 4, theme_dendro = TRUE) +
geom_hline(yintercept = 0.70, color = "blue", linetype = "dashed") +
theme(panel.border = element_blank(),
axis.text.y=element_blank()) +
xlab(element_blank()) + ylab(element_blank()) + ggtitle("Average linkage")
<- hclust(dist(D), method = "ward.D") |>
p_ward ggdendrogram(rotate = FALSE, size = 4, theme_dendro = TRUE) +
geom_hline(yintercept = 1.00, color = "blue", linetype = "dashed") +
theme(panel.border = element_blank(),
axis.text.y=element_blank()) +
xlab(element_blank()) + ylab(element_blank()) + ggtitle("Ward's method")
| p_complete) / (p_average | p_ward) (p_single