Constraints in scipy.optimize throwing x0 error

603 Views Asked by At

Looking to take a list of stocks and adjust their weight in a portfolio until the overall portfolio beta is 1.0 the output of "stonkBetas" is static and is:

[3.19292010501853,
 0.7472001935364129,
 1.0889157697158605,
 0.8944059912707691,
 0.04192080860817828,
 1.0011520737327186,
 0.9155119223385676]

I then create two functions. One to define how the betas are weighted. The second just as con that will make the constraint that the sum of the minimized weighted portfolio will have an overall summed beta of 1.0.

def betaOpp(weights):
    a,b,c,d,e,f,g=weights
    f=a*stonkBetas[0]+b*stonkBetas[1]+c*stonkBetas[2]+d*stonkBetas[3]+e*stonkBetas[4]+f*stonkBetas[5]+g*stonkBetas[6]
    return f

initial_guess = [.1,.1,.1,.1,.2,.2,.2]
print('hi')
print(sum(initial_guess))
print('bye')

def con(t):
    print('this should be zero:')
    print(sum(t)-1)
    return sum(t) - 1.0

cons = {'type':'eq', 'fun': con}
bnds = ((.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8))
res = optimize.minimize(betaOpp,initial_guess, bounds=bnds, constraints=cons)
print(res)

This gives me this output

hi
1.0
bye
this should be zero:
0.0
this should be zero:
0.0
this should be zero:
0.0
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
1.4901161193847656e-08
this should be zero:
6.661338147750939e-16
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-30-6567109e94a4> in <module>
     16 cons = {'type':'eq', 'fun': con}
     17 bnds = ((.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8),(.02,.8))
---> 18 res = optimize.minimize(betaOpp,x0=initial_guess, bounds=bnds, constraints=cons)
     19 print(res)

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    624     elif meth == 'slsqp':
    625         return _minimize_slsqp(fun, x0, args, jac, bounds,
--> 626                                constraints, callback=callback, **options)
    627     elif meth == 'trust-constr':
    628         return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, finite_diff_rel_step, **unknown_options)
    424 
    425         if mode == -1:  # gradient evaluation required
--> 426             g = append(sf.grad(x), 0.0)
    427             a = _eval_con_normals(x, cons, la, n, m, meq, mieq)
    428 

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/_differentiable_functions.py in grad(self, x)
    186         if not np.array_equal(x, self.x):
    187             self._update_x_impl(x)
--> 188         self._update_grad()
    189         return self.g
    190 

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/_differentiable_functions.py in _update_grad(self)
    169     def _update_grad(self):
    170         if not self.g_updated:
--> 171             self._update_grad_impl()
    172             self.g_updated = True
    173 

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/_differentiable_functions.py in update_grad()
     90                 self.ngev += 1
     91                 self.g = approx_derivative(fun_wrapped, self.x, f0=self.f,
---> 92                                            **finite_diff_options)
     93 
     94         self._update_grad_impl = update_grad

/opt/miniconda3/lib/python3.6/site-packages/scipy/optimize/_numdiff.py in approx_derivative(fun, x0, method, rel_step, abs_step, f0, bounds, sparsity, as_linear_operator, args, kwargs)
    389 
    390     if np.any((x0 < lb) | (x0 > ub)):
--> 391         raise ValueError("`x0` violates bound constraints.")
    392 
    393     if as_linear_operator:

ValueError: `x0` violates bound constraints.

And I just don't understand where I'm going wrong. The x0 is perfectly 1.0 - I can see it! Hopefully I'm just doing something stupid here. Please help!

0

There are 0 best solutions below