Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
braverock
GitHub Repository: braverock/portfolioanalytics
Path: blob/master/R/charts.multiple.R
1433 views
1
# compare optimal weights of multiple portfolios
2
3
#' @rdname chart.Weights
4
#' @method chart.Weights opt.list
5
#' @export
6
chart.Weights.opt.list <- function(object, neighbors=NULL, ..., main="Weights", las=3, xlab=NULL, cex.lab=1, element.color="darkgray", cex.axis=0.8, colorset=NULL, legend.loc="topright", cex.legend=0.8, plot.type="line"){
7
if(!inherits(object, "opt.list")) stop("object must be of class 'opt.list'")
8
9
if(plot.type %in% c("bar", "barplot")){
10
barplotOptWeights(object=object, main=main, las=las, xlab=xlab, cex.lab=cex.lab, element.color=element.color, cex.axis=cex.axis, colorset=colorset, legend.loc=legend.loc, cex.legend=cex.legend, ...)
11
} else if(plot.type == "line"){
12
13
# get the optimal weights in a matrix
14
weights_mat <- extractWeights.opt.list(object)
15
opt_names <- rownames(weights_mat)
16
17
columnnames <- colnames(weights_mat)
18
numassets <- length(columnnames)
19
20
if(is.null(xlab))
21
minmargin = 3
22
else
23
minmargin = 5
24
if(main=="") topmargin=1 else topmargin=4
25
if(las > 1) {# set the bottom border to accommodate labels
26
bottommargin = max(c(minmargin, (strwidth(columnnames,units="in"))/par("cin")[1])) * cex.lab
27
if(bottommargin > 10 ) {
28
bottommargin<-10
29
columnnames<-substr(columnnames,1,19)
30
# par(srt=45) #TODO figure out how to use text() and srt to rotate long labels
31
}
32
}
33
else {
34
bottommargin = minmargin
35
}
36
par(mar = c(bottommargin, 4, topmargin, 2) +.1)
37
38
if(is.null(colorset)) colorset=1:nrow(weights_mat)
39
if(length(colorset) != nrow(weights_mat)) colorset <- rep(colorset[1], nrow(weights_mat))
40
plot(weights_mat[1,], type="n", axes=FALSE, xlab='', ylab="Weights", main=main, ...)
41
for(i in 1:nrow(weights_mat)){
42
points(weights_mat[i,], type="b", col=colorset[i], lty=1)
43
}
44
if(!is.null(legend.loc)) legend(legend.loc, legend=opt_names, col=colorset, bty="n", lty=1, cex=cex.legend)
45
axis(2, cex.axis=cex.axis, col=element.color)
46
axis(1, labels=columnnames, at=1:numassets, las=las, cex.axis=cex.axis, col=element.color)
47
box(col=element.color)
48
}
49
}
50
51
barplotOptWeights <- function(object, ..., main="Weights", las=3, xlab=NULL, cex.lab=1, element.color="darkgray", cex.axis=0.8, colorset=NULL, legend.loc="topright", cex.legend=0.8){
52
if(!inherits(object, "opt.list")) stop("object must be of class 'opt.list'")
53
54
# get the optimal weights in a matrix
55
weights_mat <- extractWeights.opt.list(object)
56
opt_names <- rownames(weights_mat)
57
58
if(is.null(colorset)) colorset <- 1:nrow(weights_mat)
59
60
barplot(weights_mat, beside=TRUE, main=main, cex.axis=cex.axis, cex.names=cex.lab, las=las, col=colorset, ...)
61
if(!is.null(legend.loc)){
62
legend(legend.loc, legend=opt_names, fill=colorset, bty="n", cex=cex.legend)
63
}
64
box(col=element.color)
65
}
66
67
#' @rdname chart.RiskReward
68
#' @method chart.RiskReward opt.list
69
#' @export
70
chart.RiskReward.opt.list <- function(object, ..., risk.col="ES", return.col="mean", main="", ylim=NULL, xlim=NULL, labels.assets=TRUE, chart.assets=FALSE, pch.assets=1, cex.assets=0.8, cex.axis=0.8, cex.lab=0.8, colorset=NULL, element.color="darkgray"){
71
if(!inherits(object, "opt.list")) stop("object must be of class 'opt.list'")
72
# Get the objective measures
73
obj <- extractObjectiveMeasures(object)
74
75
# check if risk.col and return.col are valid objective measures
76
columnnames <- colnames(obj)
77
if(!(risk.col %in% columnnames)) stop(paste(risk.col, "not in column names"))
78
if(!(return.col %in% columnnames)) stop(paste(return.col, "not in column names"))
79
80
if(chart.assets){
81
# Get the returns from the firts opt.list object
82
R <- object[[1]]$R
83
if(is.null(R)) stop("Returns object not detected, must run optimize.portfolio with trace=TRUE")
84
if(!all(sapply(X=object, FUN=function(x) identical(x=R, y=x$R)))){
85
message("Not all returns objects are identical, using returns object from first optimize.portfolio object")
86
}
87
# Get the arguments from the optimize.portfolio objects
88
# to calculate the risk and return metrics for the scatter plot.
89
# (e.g. arguments=list(p=0.925, clean="boudt")
90
arguments <- NULL # maybe an option to let the user pass in an arguments list?
91
if(is.null(arguments)){
92
# get all the arguments from the portfolio in each optimize.portfolio object
93
tmp <- lapply(X=object, function(x) {
94
lapply(x$portfolio$objectives, function(u) u$arguments)
95
})
96
# Flatten the nested lists
97
tmp.args <- do.call(c, unlist(tmp, recursive=FALSE))
98
# Remove the name that gets added with unlist
99
names(tmp.args) <- gsub("^.*\\.", replacement="", names(tmp.args))
100
# Remove any duplicate arguments
101
# if(any(duplicated(names(tmp.args)))) message("Multiple duplicate arguments, using first valid argument")
102
tmp.args <- tmp.args[!duplicated(names(tmp.args))]
103
if(!is.null(tmp.args$portfolio_method)) tmp.args$portfolio_method <- "single"
104
arguments <- tmp.args
105
}
106
asset_ret <- scatterFUN(R=R, FUN=return.col, arguments)
107
asset_risk <- scatterFUN(R=R, FUN=risk.col, arguments)
108
} else {
109
asset_ret <- NULL
110
asset_risk <- NULL
111
}
112
113
# data to plot
114
dat <- na.omit(obj[, c(risk.col, return.col)])
115
if(ncol(dat) < 1) stop("No data to plot after na.omit")
116
dat_names <- rownames(dat)
117
118
# colors to plot
119
if(is.null(colorset)){
120
colorset <- 1:nrow(dat)
121
}
122
123
# set xlim and ylim
124
if(is.null(xlim)){
125
xlim <- range(c(dat[, risk.col], asset_risk))
126
xlim[1] <- 0
127
xlim[2] <- xlim[2] * 1.25
128
}
129
130
if(is.null(ylim)){
131
ylim <- range(c(dat[, return.col], asset_ret))
132
ylim[1] <- 0
133
ylim[2] <- ylim[2] * 1.15
134
}
135
136
# plot the points
137
plot(x=dat[, risk.col], y=dat[, return.col], cex.lab=cex.lab, main=main, ylab=return.col, xlab=risk.col, xlim=xlim, ylim=ylim, pch=pch.assets, col=colorset, ..., axes=FALSE)
138
if(labels.assets) text(x=dat[, risk.col], y=dat[, return.col], labels=dat_names, pos=4, cex=cex.assets, col=colorset)
139
140
# plot the risk-reward scatter of the assets
141
if(chart.assets){
142
points(x=asset_risk, y=asset_ret)
143
text(x=asset_risk, y=asset_ret, labels=colnames(R), pos=4, cex=0.8)
144
}
145
146
# add the axis
147
axis(2, cex.axis=cex.axis, col=element.color)
148
axis(1, cex.axis=cex.axis, col=element.color)
149
box(col=element.color)
150
}
151
152
153
###############################################################################
154
# R (https://r-project.org/) Numeric Methods for Optimization of Portfolios
155
#
156
# Copyright (c) 2004-2021 Brian G. Peterson, Peter Carl, Ross Bennett, Kris Boudt
157
#
158
# This library is distributed under the terms of the GNU Public License (GPL)
159
# for full details see the file COPYING
160
#
161
# $Id$
162
#
163
###############################################################################
164
165