Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
optimization using quadratic return

Here's an algo for comment/criticism. It allocates the portfolio by minimizing the variance using the square of the return, times its sign:

prices = history(252,'1d','price').as_matrix(context.stocks)  
ret = np.diff(prices,axis=0) # daily returns  
ret = np.multiply(np.sign(ret),np.square(ret))  

It seems to do pretty good job, given that the securities are:

    context.stocks = [ sid(19662),  # XLY Consumer Discrectionary SPDR Fund  
                       sid(19656),  # XLF Financial SPDR Fund  
                       sid(19658),  # XLK Technology SPDR Fund  
                       sid(19655),  # XLE Energy SPDR Fund  
                       sid(19661),  # XLV Health Care SPRD Fund  
                       sid(19657),  # XLI Industrial SPDR Fund  
                       sid(19659),  # XLP Consumer Staples SPDR Fund  
                       sid(19654),  # XLB Materials SPDR Fund  
                       sid(19660)]  # XLU Utilities SPRD Fund  

There are a number of ways the algo could be improved, including comments, readability, use of the new function scheduler, use of Pandas (?), etc. No time now...feel free to re-factor as you see fit.

Grant

4 responses

Grant,

If you print the allocations (context.x0) then it seems to keep with XLP almost the whole time? Occasionally it divides between another ETF?

Thanks Jack,

Well, my first criticism...it was kinda seat of the pants. When I get the chance, I'll have a look. I suppose one wouldn't expect to do much better than SPY without reducing the diversification of an equal-weight portfolio of the securities, right?

Grant

Here's an incremental revision that fixes a bug. It should now re-balance every 21 trading days:

    # trading control  
    #################################  
    context.day_count += 1  
    # Limit trading frequency  
    if context.day_count % context.trading_period != 0.0:  
        return  
    #################################  

To get this to work (otherwise a build error results), I had to use:

from scipy import optimize  
res= optimize.minimize(variance, context.x0, args=ret,method='SLSQP',constraints=cons,bounds=bnds)  

Also, the variable chart is now:

allocation_avg = np.average(allocation,weights=allocation)  
record(allocation_avg = allocation_avg)  

Per James' observation, this shows that the algo has limited diversification. We are dealing with industry sector ETFs here, so holding just one or two ETFs maybe ain't so bad?

Grant

funny that this one doesnt work anymore.... it gives:

ValueError:
shapes (9,251,1) and (1,251,9) not aligned: 1 (dim 2) != 251 (dim 1)