简体   繁体   中英

Scipy function minimization

with the x1 and x2 dataframes being: alloc 0.400000 mean 0.000732 stdev 0.015961 rfr 0.000000

alloc 0.200000 mean 0.000957 stdev 0.016520 rfr 0.000000

def create_function_duo(x1df, x2df):
    def funct(xi):
        y=0
        
        y+=xi*(x1df.iat[1]-x1df.iat[3])/(x1df.iat[2]-x1df.iat[3])
        y+=(1-xi)*(x2df.iat[1]-x2df.iat[3])/(x2df.iat[2]-x2df.iat[3])
        #only includes minimization, answer is flipped to negative
        return -y
    xi=x1df.iat[0].item()
    bi = (0,None)
    be = (1,None)
    bnds = (bi, be)
    
    min_result = spo.minimize(funct, xi, method = 'SLSQP',  bounds = bnds, options = {'disp':True}) #, 
    print('minima found at')
    print(min_result.x, min_result.fun)
    
    return min_result.x

Explanation: I'm trying to maximize the sharpe ratio of two funds. I realize this is expected to just spit back 1, but I can't get the minimize function to turn back anything with the bounds. If I declare bounds=(1,0) I get 'int is not iterable'

If I use the above, it spits back 'ValueError: Objective function must return a scalar'

I've even tried to return -y.item() to convert it to a float instead, and that gives an error: 'ValueError: can only convert an array of size 1 to a Python scalar'

I have no idea what's wrong here. the function returns a value (tested), the function declaration is inside the outer function and all x1df and x2dfs should be 'constant' when minimize is called. I need to set the bounds so xi is only between 0 and 1, but y should be free to change. I've tried bi=(0,1), be=(None, None), as well as bi=(None, 0), be=(None, 1), even bi=(0,), be=(1,) ('ValueError: not enough values to unpack (expected 2, got 1)'). I looked at a bounds question here, but I don't believe I have a Xi variable instead of xi. I don't understand something with bounds, please let me know what I'm doing wrong.

Bounds should be a sequence of (min,max) for each dimension. I understand you have 1 dimension, still it needs to be a sequence. So the following works (note bounds argument specifying min=0.0, max=1.0 bounds for the first, and only, argument xi)

    min_result = spo.minimize(funct, xi, method = 'SLSQP',  bounds = ((0,1),), options = {'disp':True}) #, 

and produces (the rest of your code intact)

Optimization terminated successfully    (Exit mode 0)
            Current function value: [-0.05792978]
            Iterations: 5
            Function evaluations: 10
            Gradient evaluations: 5
minima found at
[0.] [-0.05792978]
array([0.])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM