pythonoptimizationscipyscipy-optimizescipy-optimize-minimize

Where did the data enter in this optimization problem?


I wonder, how the following code works:

import scipy.optimize as sco

n_assets = 7

def min_func_sharpe(weights):                           # Function to be minimized. Minimize Negative Sharpe Ratio.
    return - port_ret(weights) / port_vol(weights)

cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1}) 
bnds = tuple((0, 1) for x in range(n_assets))          

eweights = np.array(n_assets * [1. / n_assets,])        # Start optimization with equal weights vector.


opts = sco.minimize(min_func_sharpe, eweights, method='SLSQP', bounds=bnds, constraints=cons)

opts now contains the optimized weights for the data (which was imported in Jupyter Notebook). But where exactly did the data enter in this optimization process?


Solution

  • The scipy.optimize.minimize example you showed is provided 5 arguments.

    1. min_func_sharpe: This is the function that you want scipy to minimize the return value.
    2. eweights: This is what you are providing to scipy as the starting point for the optimization. For the best chance of success, this should be close to the optimal value.
    3. method='SLSQP': This is telling scipy which minimization method it should use to solve the problem. In this case, you're telling it to use the Sequential Least Squares Programming method.
    4. bounds=bnds: Here you are providing the upper and lower bounds the solution variables can take. In this case, you told it that all the values must be between 0 and 1, inclusive.
    5. constraints=cons: This last argument tells scipy that you also want to constrain the variables using a function. In this case, you gave an equality constraint that says that all the variables should sum up to 1.

    As you can see, the only "data" provided to the scipy.optimize.minimize function is a starting guess for the variables. Behind the scenes, scipy will evaluate your objective function, min_func_sharpe, iterate the solution variables, and check that it is satisfying the bounds and constraints you gave. The results are saved into opts, which you can access. In the end, scipy will either successfully find an optimum and have a solution vector that it generated (accessed using opts.x), or it will fail (if it failed, you will have opts.success == False).