def msr(riskfree_rate, er, cov):
    '\n    Returns the weights of the portfolio that gives you the maximum sharpe ratio\n    given the riskfree rate and expected returns and a covariance matrix\n    '
    n = er.shape[0]
    init_guess = np.repeat((1 / n), n)
    bounds = (((0.0, 1.0),) * n)
    weights_sum_to_1 = {'type': 'eq', 'fun': (lambda weights: (np.sum(weights) - 1))}

    def neg_sharpe(weights, riskfree_rate, er, cov):
        '\n        Returns the negative of the sharpe ratio\n        of the given portfolio\n        '
        r = portfolio_return(weights, er)
        vol = portfolio_vol(weights, cov)
        return ((- (r - riskfree_rate)) / vol)
    weights = minimize(neg_sharpe, init_guess, args=(riskfree_rate, er, cov), method='SLSQP', options={'disp': False}, constraints=(weights_sum_to_1,), bounds=bounds)
    return weights.x
Returns the weights of the portfolio that gives you the maximum sharpe ratio
given the riskfree rate and expected returns and a covariance matrix
def msr(riskfree_rate, er, cov):
    '\n    Returns the weights of the portfolio that gives you the maximum sharpe ratio\n    given the riskfree rate and expected returns and a covariance matrix\n    '
    n = er.shape[0]
    init_guess = np.repeat((1 / n), n)
    bounds = (((0.0, 1.0),) * n)
    weights_sum_to_1 = {'type': 'eq', 'fun': (lambda weights: (np.sum(weights) - 1))}

    def neg_sharpe(weights, riskfree_rate, er, cov):
        '\n        Returns the negative of the sharpe ratio\n        of the given portfolio\n        '
        r = portfolio_return(weights, er)
        vol = portfolio_vol(weights, cov)
        return ((- (r - riskfree_rate)) / vol)
    weights = minimize(neg_sharpe, init_guess, args=(riskfree_rate, er, cov), method='SLSQP', options={'disp': False}, constraints=(weights_sum_to_1,), bounds=bounds)
    return weights.x