There are some available package tools allow us to manage investment portfolio.
options(digits=4, scipen=100)
rm(list=ls(all=T))
Sys.setlocale('LC_ALL', 'C')
## [1] "C"
library(fPortfolio)
## Warning: package 'fPortfolio' was built under R version 4.0.5
## Warning: package 'timeDate' was built under R version 4.0.5
## Warning: package 'timeSeries' was built under R version 4.0.5
## Warning: package 'fBasics' was built under R version 4.0.5
## Warning: package 'fAssets' was built under R version 4.0.5
library(tseries)
## Warning: package 'tseries' was built under R version 4.0.5
library(quantmod)
library(modopt.matlab)
## Warning: package 'modopt.matlab' was built under R version 4.0.5
## Warning: package 'ROI.plugin.glpk' was built under R version 4.0.5
= c('MMM', 'AXP', 'AAPL', 'BA', 'CAT', 'CVX',
DJ10 'CSCO', 'KO', 'XOM', 'GE')
= length(DJ10)
K = as.Date(c('2015-10-01','2017-09-30')) dd
= sapply(DJ10, function(x) {
mx = getSymbols(x,from=dd[1],to=dd[2],auto.assign=F)
G as.numeric(Delt(G[,6])) })[-1,]
names(mx) = DJ10
= as.timeSeries(mx) ts
= c('LongOnly')
cons = portfolioSpec()
spec setNFrontierPoints(spec) = 25
setSolver(spec) = "solveRquadprog"
= portfolioFrontier(ts, spec, cons) frontier
par(cex=0.7)
tailoredFrontierPlot(frontier)
par(cex=0.8)
weightsPlot(frontier,col=rainbow(length(DJ10)))
Of course, we can also use R’s optimization (linear programming) suite to practice calculating the efficiency frontier and the best investment portfolio by ourselves.
# Minimum Variance Portfolio, MVP
<- quadprog(
solution H = cov(mx), # objective function
f = rep(0, K), # linear terms of objective
A = NULL, # Inequality Constrains (LHS)
b = NULL, # Inequality Constrains (RHS)
Aeq = rep(1, K), # Equality Constrains (LHS)
beq = 1, # Equality Constrains (RHS)
lb = rep(0, K), # lower bound
ub = rep(1, K) # upper bound
)portfolio = round(solution$x, 2)) (
## [1] 0.20 0.14 0.08 0.00 0.00 0.00 0.00 0.46 0.10 0.03
Basically, the Markowitz portfolio is a minimally variable portfolio that limits average returns.
# define a optimization function
<- function(data, mu) {
markowitz = cov(data)
H = rep(0, K)
f = rep(1, K)
Aeq = 1
beq = -as.numeric(colMeans(data))
A = -mu
b = rep(0, K)
lb = rep(1, K)
ub = quadprog(H, f, A, b, Aeq, beq, lb, ub)
solution return(round(solution$x, 2))
}
# calculate the frontier
= 20 # number of points to draw
P = colMeans(mx)
cm = apply(mx, 2, sd)
csd = c(); sd = c()
mu for(i in seq(mean(cm), max(cm)*0.99, length.out=P)) {
= markowitz(mx, i)
portfolio <- c(mu, mean(portfolio %*% t(mx)))
mu <- c(sd, sd(portfolio %*% t(mx))) }
sd
# plot the frontier
plot(x = sd, y = mu, type='l', col='gold', lwd=3,
ylim=range(cm), xlim=c(min(sd),max(csd)),
xlab="Standard Deviation", ylab="Return",
main="Efficient Frontier")
# points(x = sd, y = mu, col='pink', pch=19)
abline(h=seq(0,0.002,0.00025), v=seq(0, 0.02,0.001), col='lightgray', lty=3)
points(x=csd, y=cm, type='p', col='green', pch=19, cex=1.5)
text(x=csd, y=cm, labels=DJ10, col='darkgreen', pos=2, font=2)