title: Ineq and eq constraints with scipy.optimize.minimize()
body: <p>I am attempting to understand the behavior of the constraints in <code>scipy.optimize.minimize</code>:</p>
  
  <p>First, I create 4 assets and 100 scenarios of returns. The average returning funds are in order best to worse <code>D &gt; B &gt; A &gt; C</code></p>
  
  <pre><code>#seed first 
  np.random.seed(1)
  
  df_returns = pd.DataFrame(np.random.rand(100,4) - 0.25, columns =list('ABCD'))
  df_returns.head()
  
      A           B           C           D
  0   0.167022    0.470324    -0.249886   0.052333
  1   -0.103244   -0.157661   -0.063740   0.095561
  2   0.146767    0.288817    0.169195    0.435220
  3   -0.045548   0.628117    -0.222612   0.420468
  4   0.167305    0.308690    -0.109613   -0.051899
  </code></pre>
  
  <p>and a set of weights</p>
  
  <pre><code>weights = pd.Series([0.25, 0.25, 0.25, 0.25], index=list('ABCD'))
  
      0
  A   0.25
  B   0.25
  C   0.25
  D   0.25
  </code></pre>
  
  <p>we create an objective function:</p>
  
  <pre><code>def returns_objective_function(weights, df_returns):
      result = -1. * (df_returns * weights).mean().sum()
      return result
  </code></pre>
  
  <p>and constraints and bounds</p>
  
  <pre><code>cons = ({'type': 'eq', 'fun': lambda weights: np.sum(weights) -1  })
  bnds = ((0.01, .8), (0.01, .8), (0.01, .8), (0.01, .75))
  </code></pre>
  
  <p>Let's optimize</p>
  
  <pre><code>optimize.minimize(returns_objective_function, weights, (df_returns),
                                bounds=bnds, constraints=cons, method= 'SLSQP')
  
  And we get success.
    status: 0
   success: True
      njev: 8
      nfev: 48
       fun: -0.2885398923185326
         x: array([ 0.01,  0.23,  0.01,  0.75])
   message: 'Optimization terminated successfully.'
       jac: array([-0.24384782, -0.2789166 , -0.21977262, -0.29300382,  0.        ])
       nit: 8
  </code></pre>
  
  <p>Now I wish to add constraints starting with a basic inequality:</p>
  
  <p><code>scipy.optimize.minimize</code> documentation states</p>
  
  <blockquote>
    <p>Equality constraint means that the constraint function result is to be zero whereas inequality means that it is to be non-negative. </p>
  </blockquote>
  
  <pre><code>cons = ( 
          {'type': 'eq', 'fun': lambda weights: np.sum(weights) -1  }
          ,{'type': 'ineq', 'fun': lambda weights: np.sum(weights) + x}
  )
  </code></pre>
  
  <p>Depending on x, I get unexpected behavior.</p>
  
  <pre><code>x = -100
  </code></pre>
  
  <p>Based on the bounds, weights can be a maximum of 3.15 and, of course, must sum to 1 by the first equality constraint <code>np.sum(weights) - 1</code>, but, as a result, <code>np.sum(weights) + x</code> would always be negative. I believe no solution should be found, yet <code>scipy.optimize.minimize</code> returns success.</p>