On Thu, Jul 11, 2013 at 3:28 PM, Brian G. Peterson <span dir="ltr"><<a href="mailto:brian@braverock.com" target="_blank">brian@braverock.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>On 07/11/2013 02:27 PM, Ross Bennett wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks for the insight and thoughts into making fn_map work with<br>
constrained_objective.<br>
<br>
Just to clarify a few points and make sure my understanding is<br>
correct. I am mainly thinking in terms of how this will apply to<br>
DEoptim and random for optimize methods.<br>
</blockquote>
<br></div>
For random portfolios and DEoptim, if you call fn_map inside<br>
constrained_objective, you'll either do nothing, or you'll try to<br>
re-adjust for any constraints which you had to relaxe the first time<br>
through.<br>
<br>
That bears expanding on...<br>
<br>
In the random portfolios code, you're using fn_map when *generating* the<br>
random portfolios.  So the weights vector is already 'as good as we<br>
could manage'.  In this case, I'd assume that we'd then force<br>
normalize=FALSE when calling constrained_objective().<div><br></div></blockquote><div>Got it. The only change I made to random_portfolios_v2() and randomize_portfolio_v2() was to accept a portfolio object. I will add fn_map() to randomize_portfolio_v2().</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
constrained_objective is the "fn" argument to DEoptim. The function<br>
"fn" needs to return a single argument, which in our case is the<br>
return value from constrained_objective, out.<br>
</blockquote>
<br></div>
For the DEoptim solver, we should be passing fnMap=fn_map in optimize.portfolio.  This will let DEoptim apply fn_map to the population of weight vectors in each generation.  (we may need a wrapper around fn_map that takes a multi-row matrix)  DEoptim will then use these pre-transformed vectors when calling constrained_objective(), so again, normalize=FALSE should be what we use from optimize.portfolio.</blockquote>

<div><br></div><div>Currently fn_map() returns a list containing the transformed weights as well as constraints that may have been relaxed. For this to work with fnMap in DEoptim, should fn_map() just return the transformed weights vector? Do we care what the constraints have been relaxed to and need to store the relaxed constraints or is this not important?</div>
<div><br></div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The store_output object is useful for us to track the weights vector<br>
before and after it is transformed at each iteration, but does not<br>
affect the optimization.<br>
</blockquote>
<br></div>
Correct.<br>
<br>
If we use normalize=TRUE, the *solver* will not know that we've internally transformed the weights vector to map to our allowed constraints.  In some cases, penalizing the weights vector for how much it fails to meet the constriants when normalize=FALSE will help guide the solver to make better decisions, without having to transform/map the weights vector (especially when the feasible space is large).  In other cases, penalizing the original weights vector won't help at all, typically when the feasible space is very irregular, there are lots of assets, or the optimizer has a limited knowledge of what's going on inside the objective function.<br>


<br>
So, for all the other solvers, I think we need to preserve the option for the user to either use the mapping function fn_map with normalize=TRUE, or to not use them, and to then penalizethe weights vector.<br>
<br>
I guess this suggests that the normalize=FALSE section of constrained_objective() needs to change as well to penalize based on the degree that the weights vector violates the constraints.  It already does this for leverage constraints, but not for the other constraint types. I think that there may be an argument to be made to *always* penalize, because the constraints may have been relaxed somewhat.  In that case, the 'else' clause of the normalise=TRUE/FALSE if/else block may come out of the else and just always be execute the penalty for weights that violate each constraint.</blockquote>

<div> </div><div>Thanks for the detailed explanation. That makes perfect sense, I'll add code to constrained objective so we have the ability to *always* penalize for the other constraints.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The transformed weights from the output of fn_map will be used to<br>
calculate the objective measures and the return value, out. Does the<br>
optimizer, e.g. DEoptim, keep track of the adjusted weights or the<br>
original weights?<br>
</blockquote>
<br></div>
The optimizer will only keep track of the weights it sends in, and the singular value of 'out'.</blockquote><div> </div><div>Thanks for clarifying.</div><div> </div><div>Thanks for all the guidance, I really appreciate it!</div>

<div><br></div><div>Regards,</div><div>Ross</div></div><br>