title: Equal Risk Contribution portfolio scipy optimization not working
body: <p>I'm trying to create a tool for an equal risk contribution portfolio,essentially following this article (<a href="https://quantdare.com/risk-parity-in-python/" rel="nofollow noreferrer">https://quantdare.com/risk-parity-in-python/</a>) but it is failing at the last step (def risk_parity_weights) as the scipy optimizer isn't working. It keeps giving me the initial weights as the optimized weights, and I know they aren't the optimized weights because even Excel Solver has been able to optimize this. All the others functions have been checked and are correct. Not sure what I'm doing wrong - please help!</p>
  
  <pre><code>#Calculate portfolio st.dev
      portfolio_stdev = np.sqrt(weights*covariances*weights.T)[0,0]
  
      #Calculate Marginal Risk Contribution of each asset
      MRC = covariances*weights.T/portfolio_stdev
  
      #Calculate Risk Contribution of each asset
      RC = np.multiply(MRC,weights.T)
      return RC
  
  def risk_budget_objective_error(weights,*args):
  
      #Covariance table occupies the first position in args variable
      covariances = args[0]
  
      #State risk budgets
      assets_risk_budget = args[1]
  
      #Convert weights array to numpy matrix
      weights = np.matrix(weights)
  
      #Calculate portfolio st_dev
      portfolio_stdev = calculate_portfolio_stdev(ca_begweights,ca_cov)
  
      #Calculate risk contributions
      assets_risk_contribution = calculate_risk_contribution(ca_begweights,ca_cov)
  
      #Calculate desired risk contribution of each asset
      assets_risk_target = np.asmatrix(np.multiply(portfolio_stdev,assets_risk_budget))
  
      #Calculate error between desired contribution and calculated distribution of each asset
      error = sum(np.square(assets_risk_contribution - assets_risk_target.T))[0,0]
  
      return error
  
  def risk_parity_weights(covariances,assets_risk_budget, initial_weights):
  
      #Constraints to optimization
      #sum equals 100%
      cons = ({'type':'eq','fun':lambda x: np.sum(x) - 1.0},
                {'type':'ineq','fun':lambda x: x})
  
      #Optimization in scipy
      optimize_result = minimize(risk_budget_objective_error,
                             x0 = initial_weights,
                             args = (covariances, assets_risk_budget),
                             method = 'SLSQP',
                             constraints = cons,
                             tol = Tolerance,
                             options = {'disp':True})
  
      #Get optimized weights
      weights = optimize_result.x
  
      return weights
  </code></pre>
  
  <p><code>risk_parity_weights(ca_cov,risk_budget_all, ca_begweights)</code> gives me </p>
  
  <pre><code>Optimization terminated successfully.    (Exit mode 0)
              Current function value: 9.54000328523598e-07
              Iterations: 1
              Function evaluations: 5
              Gradient evaluations: 1
  </code></pre>
  
  <p>See variables data below</p>
  
  <pre><code>ca_cov = array([[ 5.28024463e-06, 3.29734889e-07, -7.04781216e-08], [ 3.29734889e-07, 1.32373854e-05, 3.71807979e-08], [-7.04781216e-08, 3.71807979e-08, 3.50845569e-05]]) 
  
  risk_budget_all = Unnamed: 1 0.333333 Unnamed: 2 0.333333 Unnamed: 3 0.333333 Name: Risk Budget, dtype: object 
  
  ca_begweights = array([0.33333333, 0.33333333, 0.33333333]) 
  </code></pre>