Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Minimum Variance Portfolio

I used scipy's fmin to find the portfolio weights that minimized the variance. I used the returns on the volume weighted average prices for all the calculations. The portfolio sids were randomly generated.

8 responses

Hello David,

Your cash balance builds up. Is this intentional, or should it be reinvested? I see in your code that you have

context.cash_buffer = .2  

Are you meaning to hold 20% of your portfolio value in cash?

Grant

The cash buffer was intended to keep the algo from going too deep into the negative cash range since there's no constraints set up. If I start the algo at non-ideal period in time it goes pretty deep into the negative cash. This back test is a good example, I set context.cash_buffer = 0 and started it in 2007.

This is actually not a very good optimization technique. It's way too slow and doesn't scale well to larger portfolios. I didn't bother with a re-investment strategy because of this.

I would like a second opinion on the pvar() function at the bottom if you don't mind. It was an attempt to find the variance of a weighted portfolio but I am not 100% on it and don't if there's a better way to go about it.

David,

Do you have a reference for your pvar function? What is it supposed to do?

Grant

Hi David,

I don't have time right now, but my sense is that you might want to look into a matrix formulation of the problem. For example:

http://faculty.washington.edu/ezivot/econ424/portfolioTheoryMatrix.pdf

Python's scipy/numpy have vectorized matrix operations, which you should be able to apply here.

Grant

Thanks for getting back to me. if I pass it an evenly weighted vector, it seems to give the same value that pandas gets for the average of the covariances in the covariance matrix, so It might be working okay. Ill have to do the math again to be sure. Thanks for the reference, it looks like what im looking for.

David,

No problem...I may give a minimum variance portfolio a try myself. By the way, I don't think you should need to apply any minimization routine. Glancing through the paper, there appears to be a closed-form solution which results from solving a system of linear equations (see pg.8).

Grant

Problem solved.
here's a thrown together version of that solution. It takes a DataFrame of returns and solves the Lagrangian.
The weights are the first n-1 elements of the solution array so it returns those.

def min_var_weights(returns):  
    cov = 2*returns.cov()  
    cov['lambda'] = np.ones(len(cov))  
    z = np.ones(len(cov) + 1)  
    x = np.ones(len(cov) + 1)  
    z[-1] = 0.0  
    x[-1] = 1.0  
    m = [i for i in cov.as_matrix()]  
    m.append(z)  
    return np.linalg.solve(np.array(m), x)[:-1]  

Great...should speed things up. --Grant