[GSoC-PortA] Some feedback...
Peter Carl
peter at braverock.com
Fri Oct 4 23:16:29 CEST 2013
At first glance, that all sounds correct to me (or at least eerily similar
to what I've been doing by hand this week.) I agree - this is unique.
Let me know what I can test for you...
pcc
--
Peter Carl
http://www.braverock.com/peter
> I think I have a good first step in combining objective measures for all
> portfolios in an opt.list object. My apologies in advance for the long
> email, but I wanted to put this out there as this could be a pretty unique
> feature in PortfolioAnalytics.
>
> Here is an outline of what I am doing.
>
> Step 1: Get the objectives from the portfolio$objectives slot from each
> optimize.portfolio object in the opt.list object and combine into a single
> list of objectives. I am careful with how I construct the list so that
> risk_budget objectives are added last.
>
> Step 2: Detect and remove duplicates by objective name and type. The last
> objective is the one that is kept. This is the comprehensive objectives
> list of all objectives from each optimize.portfolio object in opt.list.
>
> Step 3: Insert the comprehensive objectives list into the
> portfolio$objectives slot in each optimize.portfolio object in the
> opt.list
> object. Then call constrained_objective given the returns, weights, and
> portfolio of each optimize.portfolio object. This allows the use of
> different returns, assets, and constraints, but calculates the same
> objectives.
>
> The drawbacks of this approach is that the objective_measures are
> recalculated and handling multiple arguments with different values is
> tricky.
>
> For example, say we combine two optimize.portfolio objects and both have
> ES
> as the only objective. The first object uses arguments=list(p=0.95,
> clean="boudt") and the second object uses arguments=list(p=0.90,
> clean="none") for the ES objective. The steps described above will use
> p=0.90 and clean="none" to calculate the objective_measure.
>
> One solution I thought of was to add a ... argument to
> extractObjectiveMeasures() so the user can pass in arguments, otherwise
> default to the steps described above.
>
> This is obviously a simple case where the previous way of extracting the
> objective_measures from multiple optimize.portfolio objects worked better,
> but that way only worked if all portfolio objects had the exact same
> objectives and types.
>
> Typing this I just realized I should probably do the following:
> if( all objectives are identical) {
> extract objective_measures the previous way
> } else {
> extract objective_measures using steps above
> }
>
> Any comments or suggestions?
>
> Thanks,
> Ross
>
>
> On Tue, Sep 24, 2013 at 4:00 AM, Peter Carl <peter at braverock.com> wrote:
>
>> Now that I think about it a bit more, I think that returns and assets
>> CAN
>> differ, as long as the measures are calculable at the portfolio level.
>> I'm not sure which of the processes you outlined below are preferable,
>> but
>> they are definitely in the right direction.
>>
>> pcc
>> --
>> Peter Carl
>> http://www.braverock.com/peter
>>
>> > On Mon, Sep 23, 2013 at 1:19 PM, Peter Carl <peter at braverock.com>
>> wrote:
>> >
>> >> Here's your comment from below:
>> >>
>> >> "It is tough to tell with the formatting on the email, but I'll take
>> a
>> >> closer look at the script in the sandbox to see if I can tell what is
>> >> going on. The idea is that extractObjectiveMeasures will return a
>> matrix
>> >> of the objective measures for all optimize.portfolio objects in the
>> >> opt.list object. For example, the meanSD row should have NAs under
>> the
>> >> ETL
>> >> and ETL component contribution columns. I am only stitching together
>> the
>> >> objective measures, I do not re-calculate StdDev or component StdDev
>> for
>> >> the portfolios with ETL as an objective. Basically, I just take
>> whatever
>> >> objectives are in the $objective_measures slot of each
>> >> optimize.portfolio
>> >> object. Should I be doing something such that all cells in the matrix
>> >> have
>> >> values? "
>> >>
>> >> I think so, although I doubt this has been well spelled out before.
>> The
>> >> question is: can we anticipate how to fill in these values given the
>> >> information in each object?
>> >>
>> >
>> > I think we might be able to depending on how the objective measures
>> are
>> > calculated on the weights.
>> >
>> > One way would be to pick out the objective names, match the name to
>> the
>> > function, and then calculate the objectives on the weights. The
>> parameters
>> > could be pulled from the $arguments list in each objective. This might
>> be
>> > tricky if there are multiple arguments with different arguments. This
>> is
>> > likely the simplest solution. If "ES" is an objective name, we could
>> by
>> > default calculate it with portfolio_method="component" since the
>> > univariate
>> > ES also calculated.
>> >
>> > Another way is to combine all the objectives from each object, try to
>> > detect and remove duplicate objectives objects, then pass that
>> portfolio
>> > object to constrained_objective to calculate over the weights.
>> >
>> > Not sure which way is better, I'll have to give this some thought and
>> try
>> > out a few things.
>> >
>> >
>> >>
>> >> When I do this by hand, I'm just calculating for the list of optimal
>> >> weights of each objective for each measure. At that point, I can
>> make
>> >> comparisons I couldn't otherwise.
>> >>
>> >> Note that the objectives can be vastly different, as long as the
>> assets
>> >> are the same and the parameters for each of the metrics are the same.
>> >>
>> >
>> > I could add a check to make sure that the assets and returns are the
>> same
>> > in each optimize.portfolio object. I think this will only work if that
>> is
>> > the case. It would be nice to have the flexibility to have different
>> > assets
>> > and returns, but that may not be doable.
>> >
>> >
>> >>
>> >> Does that make sense?
>> >>
>> >
>> > It does make sense, thanks for the feedback.
>> >
>> >
>> >>
>> >> pcc
>> >> --
>> >> Peter Carl
>> >> http://www.braverock.com/peter
>> >>
>> >> > Peter,
>> >> >
>> >> > Thanks for the feedback, I really appreciate it.
>> >> >
>> >> > see comments in line.
>> >> >
>> >> >
>> >> > On Sun, Sep 22, 2013 at 4:41 PM, Peter Carl <peter at braverock.com>
>> >> wrote:
>> >> >
>> >> >> Ross,
>> >> >>
>> >> >> I've been working through your vignette to hopefully give you some
>> >> more
>> >> >> detailed feedback, including on your questions from a few days
>> ago.
>> >> >> Sorry
>> >> >> this has taken so long, but I wanted to spend some focused time on
>> >> the
>> >> >> package.
>> >> >>
>> >> >> I realize that you've got different plot methods for each type,
>> and I
>> >> >> appreciate what a hassle it is to keep such methods relatively
>> >> >> consistent.
>> >> >> In chart.RiskReturn.DE, when the function doesn't find anything
>> that
>> >> >> fits
>> >> >> its defaults:
>> >> >> > plot(RiskBudget.DE)
>> >> >> Error in plot.window(...) : need finite 'xlim' values
>> >> >> In addition: Warning messages:
>> >> >> 1: In chart.Scatter.DE(object = DE, risk.col = risk.col,
>> return.col
>> =
>> >> >> return.col, :
>> >> >> mean or ES do not match extractStats output of
>> $objective_measures
>> >> >> slot
>> >> >> 2: In min(x) : no non-missing arguments to min; returning Inf
>> >> >> 3: In max(x) : no non-missing arguments to max; returning -Inf
>> >> >>
>> >> >> It's a risk budget on ETL, so if I tell it that, it works:
>> >> >> > plot(RiskBudget.DE, risk.col="ETL", return.col="mean")
>> >> >>
>> >> >
>> >> > The default is risk.col="ES". Because your objective name is "ETL",
>> >> you
>> >> > need to explicitly do risk.col="ETL".
>> >> >
>> >> >
>> >> >>
>> >> >> ...but it doesn't recover well when I try to plot the results in
>> >> >> variance
>> >> >> space:
>> >> >> > plot(RiskBudget.DE, risk.col="StdDev", return.col="mean")
>> >> >> Error in plot.window(...) : need finite 'xlim' values
>> >> >> In addition: Warning messages:
>> >> >> 1: In chart.Scatter.DE(object = DE, risk.col = risk.col,
>> return.col
>> =
>> >> >> return.col, :
>> >> >> mean or StdDev do not match extractStats output of
>> >> >> $objective_measures
>> >> >> slot
>> >> >> 2: In min(x) : no non-missing arguments to min; returning Inf
>> >> >> 3: In max(x) : no non-missing arguments to max; returning -Inf
>> >> >>
>> >> >>
>> >> >> I'm not exactly sure what the issue is here, but maybe it's
>> related:
>> >> >> > chart.RiskBudget(RiskBudget.DE, risk.type="percentage",
>> >> neighbors=5)
>> >> >> Error in subsetx[i, riskcols] : incorrect number of dimensions
>> >> >> > traceback()
>> >> >> 3: points(subsetx[i, riskcols], type = "b", col = "lightblue")
>> >> >> 2: chart.RiskBudget.optimize.portfolio(RiskBudget.DE, risk.type =
>> >> >> "percentage",
>> >> >> neighbors = 5)
>> >> >> 1: chart.RiskBudget(RiskBudget.DE, risk.type = "percentage",
>> >> neighbors =
>> >> >> 5)
>> >> >>
>> >> >
>> >> > Not sure either what the issue is, but I'll take a look.
>> >> >
>> >> >
>> >> >> In chart.RiskReturnScatter.RP, it looks like 'rp' is being passed
>> >> into
>> >> >> plot through dots.
>> >> >> > plot(EqmETL.RND, risk.col="StdDev", return.col="mean", rp=1000,
>> >> >> chart.assets=TRUE)
>> >> >> There were 13 warnings (use warnings() to see them)
>> >> >> > warnings()
>> >> >> Warning messages:
>> >> >> 1: "rp" is not a graphical parameter
>> >> >> 2: "rp" is not a graphical parameter
>> >> >> 3: "rp" is not a graphical parameter
>> >> >>
>> >> >
>> >> > The 'rp' argument is meant for optimize.portfolio.ROI and
>> >> > optimize.portfolio.GenSA objects. Since ROI and GenSA do not return
>> >> trace
>> >> > information like DEoptim or random portfolios, I added this as an
>> >> option
>> >> > to
>> >> > generate random portfolios to plot the feasible space. If you are
>> >> already
>> >> > passing in an optimize.portfolio.random object, there is no need to
>> >> pass
>> >> > in
>> >> > rp as an argument.
>> >> >
>> >> >
>> >> >>
>> >> >>
>> >> >> > extractWeights(buoys)
>> >> >> Convertible Arbitrage Equity Market Neutral Fixed Income
>> >> >> Arbitrage Event Driven CTA Global Global Macro Long/Short Equity
>> >> >> MeanSD 0.05000000 0.050
>> >> >> 0.050 0.30000000 0.0500000 0.2000000 0.300
>> >> >> MeanmETL 0.05000000 0.300
>> >> >> 0.050 0.05000000 0.2000000 0.3000000 0.050
>> >> >> MinSD 0.06042904 0.300
>> >> >> 0.300 0.05234676 0.1735858 0.0636384 0.050
>> >> >> MinmETL 0.05000000 0.300
>> >> >> 0.050 0.05000000 0.2000000 0.3000000 0.050
>> >> >> EqSD 0.12500000 0.240
>> >> >> 0.200 0.08500000 0.1050000 0.1700000 0.075
>> >> >> EqmETL 0.06000000 0.265
>> >> >> 0.165 0.09000000 0.2050000 0.1300000 0.080
>> >> >> RB 0.05200000 0.410
>> >> >> 0.060 0.05200000 0.1438995 0.2220000 0.058
>> >> >>
>> >> >> ...but this doesn't:
>> >> >> > extractObjectiveMeasures(buoys)
>> >> >> mean StdDev ES StdDev.contribution1
>> >> >> StdDev.contribution2 StdDev.contribution3
>> >> >> StdDev.contribution4
>> >> >> MeanSD 0.006782814 0.01546759 NA NA
>> >> >> NA NA NA
>> >> >> MeanmETL 0.005897789 NA 0.01505626 NA
>> >> >> NA NA NA
>> >> >> MinSD NA 0.01009001 NA NA
>> >> >> NA NA NA
>> >> >> MinmETL NA NA 0.01505626 NA
>> >> >> NA NA NA
>> >> >> EqSD NA 0.01113716 NA 0.001763096
>> >> >> 0.001565752 0.001886988 0.001258567
>> >> >> EqmETL NA NA 0.01646509 NA
>> >> >> NA NA NA
>> >> >> RB 0.005812997 NA NA NA
>> >> >> NA NA NA
>> >> >> StdDev.contribution5 StdDev.contribution6
>> >> StdDev.contribution7
>> >> >> StdDev.pct_contrib_StdDev1 StdDev.pct_contrib_StdDev2
>> >> >> MeanSD NA NA
>> >> NA
>> >> >> NA NA
>> >> >> MeanmETL NA NA
>> >> NA
>> >> >> NA NA
>> >> >> MinSD NA NA
>> >> NA
>> >> >> NA NA
>> >> >> MinmETL NA NA
>> >> NA
>> >> >> NA NA
>> >> >> EqSD 0.001039908 0.002296903
>> >> 0.001325947
>> >> >> 0.1583075 0.1405881
>> >> >> EqmETL NA NA
>> >> NA
>> >> >> NA NA
>> >> >> RB NA NA
>> >> NA
>> >> >> NA NA
>> >> >> ...snip...
>> >> >>
>> >> >>
>> >> > It is tough to tell with the formatting on the email, but I'll take
>> a
>> >> > closer look at the script in the sandbox to see if I can tell what
>> is
>> >> > going
>> >> > on. The idea is that extractObjectiveMeasures will return a matrix
>> of
>> >> the
>> >> > objective measures for all optimize.portfolio objects in the
>> opt.list
>> >> > object. For example, the meanSD row should have NAs under the ETL
>> and
>> >> ETL
>> >> > component contribution columns. I am only stitching together the
>> >> objective
>> >> > measures, I do not re-calculate StdDev or component StdDev for the
>> >> > portfolios with ETL as an objective. Basically, I just take
>> whatever
>> >> > objectives are in the $objective_measures slot of each
>> >> optimize.portfolio
>> >> > object. Should I be doing something such that all cells in the
>> matrix
>> >> have
>> >> > values?
>> >> >
>> >> >
>> >> >> As a consequence, only one portfolio appears in the following plot
>> >> >> (MeanSD):
>> >> >> > chart.RiskReward(buoys)
>> >> >>
>> >> >
>> >> > This relates to my comment above about how I am not recalculating
>> >> > anything.
>> >> > Before the portfolios are plotted in risk-return space, I omit rows
>> >> that
>> >> > have NA values. For example, if you wanted to plot all the
>> portfolios
>> >> in
>> >> > mean-ETL space, all portfolios should have mean and ETL as an
>> >> objective.
>> >> > You could set the multiplier to 0 so it does not affect the
>> >> optimization,
>> >> > but is returned in the $objective_measures slot.
>> >> >
>> >> >
>> >> >>
>> >> >> All in all, this is all looking good. I've got some scripts
>> checked
>> >> in
>> >> >> under sandbox/symposium2013 if you want to follow along.
>> >> >>
>> >> >
>> >> > I'll take a closer look and follow along, thanks!
>> >> >
>> >> >
>> >> >>
>> >> >> pcc
>> >> >> --
>> >> >> Peter Carl
>> >> >> http://www.braverock.com/peter
>> >> >>
>> >> >>
>> >> >> _______________________________________________
>> >> >> GSoC-PortA mailing list
>> >> >> GSoC-PortA at lists.r-forge.r-project.org
>> >> >>
>> http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta
>> >> >>
>> >> >
>> >>
>> >> _______________________________________________
>> >> GSoC-PortA mailing list
>> >> GSoC-PortA at lists.r-forge.r-project.org
>> >> http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta
>> >>
>> > _______________________________________________
>> > GSoC-PortA mailing list
>> > GSoC-PortA at lists.r-forge.r-project.org
>> > http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta
>> >
>>
>>
>> _______________________________________________
>> GSoC-PortA mailing list
>> GSoC-PortA at lists.r-forge.r-project.org
>> http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta
>>
> _______________________________________________
> GSoC-PortA mailing list
> GSoC-PortA at lists.r-forge.r-project.org
> http://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/gsoc-porta
>
More information about the GSoC-PortA
mailing list