title: Optimal Portfolio with multiple constraints on weights allocation - Mixed-integer quadratic program using Python CVXPY
body: <p>I'm trying to solve the classical Markowitz optimal portfolio problem, but adding multiple constraints on the weights allocation:</p>
  <ol>
  <li>Each asset should have a weight on the interval <code>[0,10%]</code> (long-only strategy);</li>
  <li>The vector of weights vector should sum <code>100%</code>;</li>
  <li>For the assets whose weight is greater than <code>5%</code>, the aggregate sum should not be greater than <code>40%</code>.</li>
  </ol>
  <p>This problem can be classified as a Mixed-Integer quadratic program. To solve it, I'm using CVXPY library from Python. The code that I have developed is structured as follows:</p>
  <ol>
  <li>Two continuous-variable vectors <code>w</code> and <code>w_5</code>, which represent the weights vector for assets whose weight is <code>w &lt;= 5%</code> and <code>w_5 &gt; 5%</code> respectively.</li>
  <li>Two boolean-variable vector <code>d</code> and <code>d_5</code>, to indicate if an asset is in the <code>w</code> vector or in the <code>w_5</code> vector.</li>
  <li>In addition, the corresponding variables to solve the classic mean-variance optimization problem (this works without problem if I do not introduce constraint #3)</li>
  </ol>
  <p>The code looks like this:</p>
  <pre><code># Expected annualized yield
  mu = np.mean(df_yield, axis = 0).values
      
  # Annualized covariance matrix
  sigma = df_yield.cov().values
      
  # Number of assets
  n = sigma.shape[0]
  
  # Efficient Frontier (Mean-Covariance Optimization) - Parameters
  w = cp.Variable(n)
  w_5 = cp.Variable(n)
  d = cp.Variable(n, boolean = True)
  d_5 = cp.Variable(n, boolean = True)
  gamma = cp.Parameter(nonneg = True)
  ret = mu.T @ w
  risk = cp.quad_form(w, sigma)
  
  # Markowitz Efficient Frontier (Mean-Covariance Optimization) - Constraints
  eps = 10e-10
  constraints = [
     # Assets with weight &lt;= 5%
     w &lt;= 0.05 * d,
     w &gt;= 0,
     # Assets with weight &gt; 5%
     w_5 &lt;= 0.10 * d_5,
     w_5 &gt;= (0.05 + eps) * d_5,
     # Total sum thresholds
     cp.sum(w) + cp.sum(w_5) == 1,
     cp.sum(d) + cp.sum(d_5) == n,
     cp.sum(w) &gt;= 0.4,
     cp.sum(w_5) &lt;= 0.4,]
  
  # Markowitz Efficient Frontier (Mean-Covariance Optimization) - Problem
  prob = cp.Problem(cp.Maximize(ret - gamma * risk), constraints)
      
  # Markowitz Efficient Frontier (Mean-Covariance Optimization) - Simulation
  risk_data = np.zeros(n_samples)
  ret_data = np.zeros(n_samples)
  gamma_vals = np.logspace(gamma_low, gamma_high, num = n_samples)
  portfolio_weights = []
  for i in range(n_samples):
      gamma.value = gamma_vals[i]
      prob.solve()
      risk_data[i] = np.sqrt(risk.value)
      ret_data[i] = ret.value
      portfolio_weights.append(w.value)
  
  # Maximum Sharpe Ratio
  sharpes = ret_data / risk_data
  </code></pre>
  <p>The resulting output is:</p>
  <p><em>SolverError: Either candidate conic solvers (['GLPK_MI']) do not support the cones output by the problem (SOC, NonNeg, Zero), or there are not enough constraints in the problem.</em></p>
  <p>From this I can infer that I'm missing some additional constraint, but not idea how to solve it. Any guess?</p>