简体   繁体   中英

Choose weights that minimize portfolio variance

I am looking for a method that chooses the weights that minimize the portfolio variance.

For example:

I have 3 assets; their returns are given in an array below:

import numpy as np
x = np.array([[0.2,-0.1,0.5,-0.2],[0, -0.9, 0.8, 0.2],[0.4,0.5,-0.3,-.01]])

I can weight them how I want to as long as sum of their weights adds to 1. I am looking for such weights that minimize variance of the portfolio.

Here are two examples of randomly chosen weights:

weight_1 = [0.3,0.3,0.4]

weighted_x_1 = [ele_x*ele_w for ele_x,ele_w in zip (x,weight_1)]

var_1 = np.var(sum(weighted_x_1))


weight_2 = [-0.2,0.4,0.8]

weighted_x_2 = [ele_x*ele_w for ele_x,ele_w in zip (x,weight_2)]

var_2 = np.var(sum(weighted_x_2))

Output:

>>> var_1
0.02351675000000001
>>> var_2
0.012071999999999999

The second way is better.

Is there a Python (or a Python library) method that could do this for me? If not any suggestions on what method I should use to do the above are welcome.

Thank You in Advance

Please see the accepted answer to this question: Finance Lib with portfolio optimization method in python

Relevant bit is here:

Here's a quote from a post I found.

Some research says that "mean variance portfolio optimization" can give good results. I discussed this in a message

To implement this approach, a needed input is the covariance matrix of returns, which requires historical stock prices, which one can obtain using "Python quote grabber" http://www.openvest.org/Databases/ovpyq .

For expected returns -- hmmm. One of the papers I cited found that assuming equal expected returns of all stocks can give reasonable results.

Then one needs a "quadratic programming" solver, which appears to be handled by the CVXOPT Python package.

If someone implements the approach in Python, I'd be happy to hear about it.

There is a "backtest" package in R (open source stats package callable from Python) http://cran.r-project.org/web/packages/backtest/index.html "for exploring portfolio-based hypotheses about financial instruments (stocks, bonds, swaps, options, et cetera)."

My full solution can be viewed in PDF .

The trick is to put the vectors x_i as columns of a matrix X .
Then writing the problem becomes a Convex Problem with constrain of the solution to be on the Unit Simplex.

I solved it using Projected Sub Gradient Method .
I calculated the Gradient of the objective function and created a projection to the Unit Simplex .

Now all needed is to iterate them.
I validated my solution using CVX .

% StackOverflow 44984132
% How to calculate weight to minimize variance?
% Remarks:
%   1.  sa
% TODO:
%   1.  ds
% Release Notes
% - 1.0.000     08/07/2017
%   *   First release.


%% General Parameters

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = OFF;


%% Simulation Parameters

dimOrder    = 3;
numSamples = 4;

mX = randi([1, 10], [dimOrder, numSamples]);
vE = ones([dimOrder, 1]);


%% Solve Using CVX

cvx_begin('quiet')
    cvx_precision('best');
    variable vW(numSamples)
    minimize( (0.5 * sum_square_abs( mX * vW - (1 / numSamples) * (vE.' * mX * vW) * vE )) )
    subject to
        sum(vW) == 1;
        vW >= 0;
cvx_end

disp([' ']);
disp(['CVX Solution -                       [ ', num2str(vW.'), ' ]']);


%% Solve Using Projected Sub Gradient

numIterations   = 20000;
stepSize        = 0.001;
simplexRadius   = 1; %<! Unit Simplex Radius
stopThr         = 1e-6;

hKernelFun  = @(vW) ((mX * vW) - ((1 / numSamples) * ((vE.' * mX * vW) * vE)));
hObjFun     = @(vW) 0.5 * sum(hKernelFun(vW) .^ 2);
hGradFun    = @(vW) (mX.' * hKernelFun(vW)) - ((1 / numSamples) * vE.' * (hKernelFun(vW)) * mX.' * vE);

vW = rand([numSamples, 1]);
vW = vW(:) / sum(vW);

for ii = 1:numIterations
    vGradW = hGradFun(vW);
    vW = vW - (stepSize * vGradW);

    % Projecting onto the Unit Simplex
    % sum(vW) == 1, vW >= 0.
    vW = ProjectSimplex(vW, simplexRadius, stopThr);
end

disp([' ']);
disp(['Projected Sub Gradient Solution -    [ ', num2str(vW.'), ' ]']);


%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);

You can see the full code in StackOverflow Q44984132 Repository (PDF is available as well).

The solution was taken from StackOverflow Q44984132 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM