PortfolioAnalytics question re: showing results
Matt, I'm glad it was helpful. That is correct, the *.EfficientFrontier routines are not flexible in some cases. create.EfficientFrontier can create an efficient.frontier object with custom objective/moment functions by specifying type="random" or type="DEoptim". Under the hood, it is just running an optimization and handing back the data needed for the chart. In most cases, it is better to run the optimization with trace=TRUE so that you have all the data you need for creating charts and doing other analysis. Ross
On Fri, Mar 18, 2016 at 2:37 PM, <matt at considine.net> wrote:
Hi Ross,
Thanks - that helps alot. It looks like part of what was tripping me up
is that the guts of the create/chart EfficientFrontier functions expect
hard-coded column headings. I.e. that those routines as written aren't
flexible enough to deal with the custom optimizing functions. Is that
correct or is there a more flexible set of those that I have overlooked?
The presentation graphs the create are quite clean.
In any case, thank you for the example and feedback.
Matt
On 2016-03-18 10:54, Ross Bennett wrote:
Hi Matt,
You are very close in your script. Note that create.EfficientFrontier with
type="mean-StdDev" is a special case for an efficient frontier that can be
formulated and solved with a QP solver.
Also note that your second call to add.objective should add to the
SD.portf portfolio and not init.portf
# Add measure 2, annualized standard deviation
# note that you want to add this to the SD.portf portfolio, not init.portf
SD.portf <- add.objective(portfolio=SD.portf,
type="risk", # the kind of objective this is
name="pasd1", # to minimize from the sample
enabled=TRUE, # enable or disable the objective
multiplier=0 # calculate it but don't use it
in the objective
)
I recommend actually running an optimization using random portfolios so
you get the entire feasible space given the constraints and objectives in
your portfolio.
rp <- random_portfolios(SD.portf, 5000)
# make sure to run with trace=TRUE for the extract stats output
opt <- optimize.portfolio(R, SD.portf, optimize_method="random",
trace=TRUE)
chart.RiskReward(opt, risk.col="pasd1.pasd1", return.col="pamean1.pamean1")
# use the output of extractStats to find portfolio with max return at a
given
# risk level and portfolio with min risk at a given return level
ex <- extractStats(opt)
head(ex)
# This should get you started
# order by max pamean1
head(ex[order(ex[,"pamean1.pamean1"], decreasing=TRUE),])
# order by min pasd1
head(ex[order(ex[,"pasd1.pasd1"], decreasing=FALSE),])
Hope this helps, let me know if you need any other pointers.
Regards,
Ross
On Fri, Mar 18, 2016 at 8:13 AM, <matt at considine.net> wrote:
Hi Brian,
Thanks for the offer of some code. I had wanted to try to figure this
out for myself, but I'm not making the headway I thought. IF you have some
code or a worked example you can send, I'd be appreciative.
That said here is what I am working with. Perhaps someone can suggest
what I am doing wrong?
Goal : generate/plot an efficient frontier (with annualized axes) using
PortfolioAnalytics, using monthly return data. (Ideally, I'd also want to
isolate the tangency/max Sharpe portfolio, a portfolio with max return at a
specific risk level and a portfolio with a min risk at a specific return.
But I'll deal with that later.)
Code : I tried to use code from some of the presentations, demos (DEoptim
and random portfolios, specifically) and vignettes. Also, I'm using the
latest version of the code from R-forge.
#-----------------------------
library(PortfolioAnalytics)
# Define pamean function
pamean1 <- function(R, weights, n=60, geometric=FALSE){
as.vector(sum(Return.annualized(last(R,n),
geometric=geometric)*weights))
}
# Define pasd function
pasd1 <- function(R, weights=NULL){
as.numeric(StdDev(R=R, weights=weights)*sqrt(12)) # hardcoded for
monthly data
}
data(edhec)
# Use the first 4 columns in edhec for a returns object
R <- edhec[, 1:4]
colnames(R) <- c("CA", "CTAG", "DS", "EM")
head(R, 5)
# Get a character vector of the fund names
funds <- colnames(R)
# Construct initial portfolio with basic constraints.
init.portf <- portfolio.spec(assets=funds)
init.portf <- add.constraint(portfolio=init.portf, type="full_investment")
init.portf <- add.constraint(portfolio=init.portf, type="box", min=0.0,
max=1.0)
# Portfolio with standard deviation as an objective
#SD.portf <- add.objective(portfolio=init.portf, type="risk",
name="pasd1") #pasd1 doesn't work?
#SD.portf <- add.objective(portfolio=SD.portf, type="return",
name="mean") #pamean1 doesn't work?
#Ok, let's try this :
#Add measure 1, annualized return
SD.portf <- add.objective(portfolio=init.portf,
type="return", # the kind of objective this is
name="pamean1", # name of the function
enabled=TRUE, # enable or disable the
objective
multiplier=0 # calculate it but don't use it
in the objective
)
# Add measure 2, annualized standard deviation
SD.portf <- add.objective(portfolio=init.portf,
type="risk", # the kind of objective this is
name="pasd1", # to minimize from the sample
enabled=TRUE, # enable or disable the
objective
multiplier=0 # calculate it but don't use it
in the objective
)
#Create efficient frontier
init.portf.ef <- create.EfficientFrontier(R=R, portfolio=SD.portf,
type="mean-StdDev")
#This chart never seems to show annualized axes
chart.EfficientFrontier(init.portf.ef, match.col="StdDev")
sd.moments <- set.portfolio.moments(R, SD.portf)
names(sd.moments) #returning NULL with pasd1/pamean1
print(sd.moments) #returning NULL with pasd1/pamean1
#Just a reality check to see what the axes ranges should roughly look like
ra <- Return.annualized(R[, , drop = FALSE], scale = 12, geometric =
FALSE)
sda <- StdDev.annualized(R[, , drop = FALSE], scale = 12)
sra <- SharpeRatio.annualized(R[, , drop = FALSE], scale = 12, Rf = 0.00,
geometric = FALSE)
pamean1(R)
ra
pasd1(R)
sda
#----------------------------------
Regards,
Matt
_______________________________________________ R-SIG-Finance at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. If you want to post, subscribe first. -- Also note that this is not the r-help list where general R questions should go.