def OptPort( naData, fTarget, naLower=None, naUpper=None, naExpected=None, s_type = "long"):
    """
    @summary Returns the Markowitz optimum portfolio for a specific return.
    @param naData: Daily returns of the various stocks (using returnize1)
    @param fTarget: Target return, i.e. 0.04 = 4% per period
    @param lPeriod: Period to compress the returns to, e.g. 7 = weekly
    @param naLower: List of floats which corresponds to lower portfolio% for each stock
    @param naUpper: List of floats which corresponds to upper portfolio% for each stock 
    @return tuple: (weights of portfolio, min possible return, max possible return)
    """
    ''' Attempt to import library '''
    try:
        pass
        from cvxopt import matrix
        from cvxopt.blas import dot
        from cvxopt.solvers import qp, options

    except __HOLE__:
        print 'Could not import CVX library'
        raise
    
    ''' Get number of stocks '''
    length = naData.shape[1]
    b_error = False

    naLower = deepcopy(naLower)
    naUpper = deepcopy(naUpper)
    naExpected = deepcopy(naExpected)
    
    # Assuming AvgReturns as the expected returns if parameter is not specified
    if (naExpected==None):
        naExpected = np.average( naData, axis=0 )

    na_signs = np.sign(naExpected)
    indices,  = np.where(na_signs == 0)
    na_signs[indices] = 1
    if s_type == "long":
        na_signs = np.ones(len(na_signs))
    elif s_type == "short":
        na_signs = np.ones(len(na_signs))*(-1)
    
    naData = na_signs*naData
    naExpected = na_signs*naExpected

    # Covariance matrix of the Data Set
    naCov=np.cov(naData, rowvar=False)
    
    # If length is one, just return 100% single symbol
    if length == 1:
        return (list(na_signs), np.std(naData, axis=0)[0], False)
    if length == 0:
        return ([], [0], False)
    # If we have 0/1 "free" equity we can't optimize
    # We just use     limits since we are stuck with 0 degrees of freedom
    
    ''' Special case for None == fTarget, simply return average returns and cov '''
    if( fTarget is None ):
        return (naExpected, np.std(naData, axis=0), b_error)
    
    # Upper bound of the Weights of a equity, If not specified, assumed to be 1.
    if(naUpper is None):
        naUpper= np.ones(length)
    
    # Lower bound of the Weights of a equity, If not specified assumed to be 0 (No shorting case)
    if(naLower is None):
        naLower= np.zeros(length)

    if sum(naLower) == 1:
        fPortDev = np.std(np.dot(naData, naLower))
        return (naLower, fPortDev, False)

    if sum(naUpper) == 1:
        fPortDev = np.std(np.dot(naData, naUpper))
        return (naUpper, fPortDev, False)
    
    naFree = naUpper != naLower
    if naFree.sum() <= 1:
        lnaPortfolios = naUpper.copy()
        
        # If there is 1 free we need to modify it to make the total
        # Add up to 1
        if naFree.sum() == 1:
            f_rest = naUpper[~naFree].sum()
            lnaPortfolios[naFree] = 1.0 - f_rest
            
        lnaPortfolios = na_signs * lnaPortfolios
        fPortDev = np.std(np.dot(naData, lnaPortfolios))
        return (lnaPortfolios, fPortDev, False)

    # Double the covariance of the diagonal elements for calculating risk.
    for i in range(length):
        naCov[i][i]=2*naCov[i][i]

    # Note, returns are modified to all be long from here on out
    (fMin, fMax) = getRetRange(False, naLower, naUpper, naExpected, "long") 
    #print (fTarget, fMin, fMax)
    if fTarget<fMin or fTarget>fMax:
        print "Target not possible", fTarget, fMin, fMax
        b_error = True

    naLower = naLower*(-1)
 
    # Setting up the parameters for the CVXOPT Library, it takes inputs in Matrix format.
    '''
    The Risk minimization problem is a standard Quadratic Programming problem according to the Markowitz Theory.
    '''
    S=matrix(naCov)
    #pbar=matrix(naExpected)
    naLower.shape=(length,1)
    naUpper.shape=(length,1)
    naExpected.shape = (1,length)
    zeo=matrix(0.0,(length,1))
    I = np.eye(length)
    minusI=-1*I
    G=matrix(np.vstack((I, minusI)))
    h=matrix(np.vstack((naUpper, naLower)))
    ones=matrix(1.0,(1,length)) 
    A=matrix(np.vstack((naExpected, ones)))
    b=matrix([float(fTarget),1.0])

    # Optional Settings for CVXOPT
    options['show_progress'] = False
    options['abstol']=1e-25
    options['reltol']=1e-24
    options['feastol']=1e-25
    

    # Optimization Calls
    # Optimal Portfolio
    try:
            lnaPortfolios = qp(S, -zeo, G, h, A, b)['x']
    except:
        b_error = True

    if b_error == True:
        print "Optimization not Possible"
        na_port = naLower*-1
        if sum(na_port) < 1:
            if sum(naUpper) == 1:
                na_port = naUpper
            else:
                i=0
                while(sum(na_port)<1 and i<25):
                    naOrder = naUpper - na_port
                    i = i+1
                    indices = np.where(naOrder > 0)
                    na_port[indices]= na_port[indices] + (1-sum(na_port))/len(indices[0]) 
                    naOrder = naUpper - na_port
                    indices = np.where(naOrder < 0)
                    na_port[indices]= naUpper[indices]
            
        lnaPortfolios = matrix(na_port)

    lnaPortfolios = (na_signs.reshape(-1,1) * lnaPortfolios).reshape(-1)
    # Expected Return of the Portfolio
    # lfReturn = dot(pbar, lnaPortfolios)
    
    # Risk of the portfolio
    fPortDev = np.std(np.dot(naData, lnaPortfolios))
    return (lnaPortfolios, fPortDev, b_error)
dataset/ETHPy150Open QuantSoftware/QuantSoftwareToolkit/QSTK/qstkutil/tsutil.py/OptPort