Skip to content

Instantly share code, notes, and snippets.

@titipata
Last active August 29, 2015 14:17
Show Gist options
  • Save titipata/57acbc30a1355a18df95 to your computer and use it in GitHub Desktop.
Save titipata/57acbc30a1355a18df95 to your computer and use it in GitHub Desktop.
Optimization problem for assigning portfolio weight for each stock price

Portfolio Optimization (Stock Market)

Basically, we want to assign weight to history stock price, higher weight means good stock. So the question is: I need to maximize cost D, where we define as,

D = w' * std / sqrt (w' * Sigma * w)

where

  • w is portfolio weight

  • w' is the transpose of w

  • w is N-by-1 vector (weight vector corresponded to each stocks)

  • w' is 1-by-N vector

  • std is N-by-1 vector (standard deviation of history stock prices)

  • sigma is N-by-N matrix (covariance matrix of historical stock data)

  • (w' * std) is inner product of weight and standard deviation of stocks, which is scalar

  • sqrt(w' * Sigma * w) is also a scalar (called risk... I think)

The maximization of D needs to keep std and Sigma constant, and it only needs to vary "w". After max D is obtained I need to be able to see the final w and use it for future calculations.

The constraints are:

  • sum of the w in the vector any time equals = 1 (sum(w) = 1)
  • bound of each individual w in the vector: -1 =< w <= 1

Note Minimization Function from Matlab

Solution

Here I tested on random matrix. Note that we use cost = -D instead since fmincon solve minimization problem so it's equivalent to solve maximization problem for cost = D

% initial condition
N = 10;
Sigma = randn(N,N)'*randn(N,N);
w0 = randn(N,1);
std = abs(randn(N,1));
Aeq = ones(N,1)';
beq = 1;
lb = -ones(N,1);
ub = +ones(N,1);
calculate_cost = @(w) -w'*std/ sqrt(w'*Sigma*w); % inline function

% using fmincon to solve
w_final = fmincon(calculate_cost, w0, [], [], Aeq, beq, lb, ub);

Here is the solution with actual problem

[N, M] = size(std);
Aeq = ones(N,1)';
beq = 1;
lb = -ones(N,1);
ub = +ones(N,1);
w0 = randn(N,1);
calculate_cost = @(w) -w'*std/abs(sqrt(w'*Sigma*w)); % assuming we know Sigma and std

w_final = fmincon(calculate_cost, w0, [], [], Aeq, beq, lb, ub);

So w_final is the final weight solution, fmincon can stuck at local minima you can either run multiple time or seed with different initial condition w0

To test, with eyeball, corresponded w should has low value if std is high. And also cost of final weight w_final should be lower than initial w0

calculate_cost(w0)
calculate_cost(w_final) % should have lower cost than line above

Another easy way to assign weight to each stock

w_i = (1/sigma_i)/sum(1/sigma_i)

where sigma_i is standard deviation of history of stock price. Suppose stock is matrix where each column contains stock price history

std_vec = std(stock, 1); % standard deviation over column
w = (1./std_vec)/sum(1./std_vec); % final weight

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment