lequant40 / portfolio_allocation_js

A JavaScript library to allocate and optimize financial portfolios.
https://lequant40.github.io/portfolio_allocation_js/
MIT License
175 stars 31 forks source link

Mean Variance Optimization not working as expected #8

Closed lequant40 closed 4 years ago

lequant40 commented 4 years ago

X ref. from https://github.com/lequant40/portfolio_allocation_js/issues/7, to better separate issues.

Thanks Roman. That did the trick! Now I'm running into a different issue and would greatly appreciate any help:

I'm using the function below I created in Google Sheets, but am getting a #ERROR! that says "Error: unsupported problem detected (line 5838)". My goal is to calculate mean variance weights given an expected return stream, a covariance matrix, a target volatility, min weights, and max weights:

function computeWts(rets, cv, targetVol, minWts, maxWts) { return (PortfolioAllocation.meanVarianceOptimizationWeights(rets, cv, {constraints: {optimizationMethod: 'maximumTargetVolatility', maxVolatility: targetVol, minWeights: minWts, maxWeights: maxWts}})); }

The arguments I'm passing are below (and are all in cells in Google Sheets):

rets: 4.7% 5.0% 6.1% 4.0% 5.4% 2.0% 2.2% 2.4% 2.4% 3.6%

cv: 2.3% | 2.5% | 3.3% | 1.7% | 2.3% | -0.4% | -0.3% | -0.3% | 0.1% | 1.7% 2.5% | 2.9% | 3.8% | 1.9% | 2.5% | -0.4% | -0.3% | -0.3% | 0.2% | 1.9% 3.3% | 3.8% | 5.3% | 2.3% | 3.1% | -0.5% | -0.3% | -0.4% | 0.3% | 2.9% 1.7% | 1.9% | 2.3% | 1.4% | 1.8% | -0.3% | -0.3% | -0.3% | 0.0% | 1.1% 2.3% | 2.5% | 3.1% | 1.8% | 4.0% | -0.1% | 0.0% | 0.2% | 0.7% | 1.8% -0.4% | -0.4% | -0.5% | -0.3% | -0.1% | 0.2% | 0.2% | 0.2% | 0.2% | -0.1% -0.3% | -0.3% | -0.3% | -0.3% | 0.0% | 0.2% | 0.4% | 0.2% | 0.3% | 0.0% -0.3% | -0.3% | -0.4% | -0.3% | 0.2% | 0.2% | 0.2% | 0.3% | 0.2% | 0.0% 0.1% | 0.2% | 0.3% | 0.0% | 0.7% | 0.2% | 0.3% | 0.2% | 0.5% | 0.4% 1.7% | 1.9% | 2.9% | 1.1% | 1.8% | -0.1% | 0.0% | 0.0% | 0.4% | 2.0%

targetVol: 5.5%

minWts: 3% 3% 3% 0% 0% 0% 0% 3% 0% 0%

maxWts: 35% 35% 35% 35% 35% 35% 35% 35% 35% 35%

_Originally posted by @grantackerman1 in https://github.com/lequant40/portfolio_allocation_js/issues/7#issuecomment-676556595_

lequant40 commented 4 years ago

Hi !

Yeah, this problem is unsupported because there are 2 different assets with the same return (2.4%). This prevents the portfolio maximizing the return to be unique, and poses difficulties to the vanilla critical line algorithm of Markowitz.

In his book Portfolio Selection, Markowitz state that "one way to handle this is to alter the [returns] slightly". In your case, it would mean deciding for 2.41 % v.s. 2.40% for one of the two asset for example.

Cheers,

Roman

PS: Implementing a proper solution to allow for assets with identical returns is on the top of my to-do list, so, eventually, this error will not appear anymore, but I cannot commit on any timeline. Meanwhile, I will keep this Git issue opened as you are not the first one who notices this behaviour.

PPS: Now, speciafically for your example, I might have two remarks:

lequant40 commented 4 years ago

Solved locally.

Will be solved with release 0.0.10.

grantackerman1 commented 4 years ago

Ok thanks!

In response to your question, I found the optimizationMethod: 'maximumTargetVolatility' from a previous Issue that was posted. Should I instead be setting the "volatility" parameter under "constraints" to what I want? i.e. PortfolioAllocation.meanVarianceOptimizationWeights(rets, cv, {constraints: {volatility: targetVol, minWeights: minWts, maxWeights: maxWts}}) ?

In addition, is it possible to set additional allocation constraints besides just min and max values? For example, is there a way I could constrain the weight of Asset B to be less than or equal to half the weight of Asset A? This would be helpful to me because I don't want my allocations to stray too far from the relative sizes of the Assets (e.g., If my assets are US stocks and Emerging stocks, I don't want to have my Emerging allocation get larger than my US allocation because the US market is bigger than the Emerging market).

lequant40 commented 4 years ago

Thanks for the answer.

Yep, you should definitely update to the way above, as this is the one now supported: PortfolioAllocation.meanVarianceOptimizationWeights(rets, cv, {constraints: {volatility: targetVol, minWeights: minWts, maxWeights: maxWts}})

Note that in case the portfolio volatility requested is not reacheable (because either too low or too high w.r.t. the possible combination of assets), an error will be generated. There are two ways to solve this:

Re your other question:

lequant40 commented 4 years ago

Equal returns managed with mean variance optimization starting from v0.0.10

lequant40 commented 3 years ago

@grantackerman1, if you are still interested by this one, I have some news about the management of general linear inequalities.

For reasons related to the performances of CPU-intensive scripts run into Google Sheets, I am straying away from a library to be included in Google Sheets, but I am now releasing the capabilities of the Portfolio Allocation library as a Web API.

I delivered the management of general linear inequalities for mean-variance optimization a couple of days ago.

If you are interested -> https://portfoliooptimizer.io/, and for your particular use-case -> https://docs.portfoliooptimizer.io/#mean-variance-efficient-portfolio

An example of integration in Google Sheets of this API is available here ->https://portfoliooptimizer.io/blog/integration-in-google-sheets/.

In case you would need some help to call this API, feel free to contact me at contact@portfoliooptimizer.io.