docs: def efficient_return(self, target_return, market_neutral=False):
          """
          Calculate the 'Markowitz portfolio', minimising volatility for a given target return.
  
          :param target_return: the desired return of the resulting portfolio.
          :type target_return: float
          :param market_neutral: whether the portfolio should be market neutral (weights sum to zero),
                                 defaults to False. Requires negative lower weight bound.
          :type market_neutral: bool, optional
          :raises ValueError: if ``target_return`` is not a positive float
          :return: asset weights for the Markowitz portfolio
          :rtype: dict
          """
          if not isinstance(target_return, float) or target_return < 0:
              raise ValueError("target_return should be a positive float")
  
          args = (self.cov_matrix, self.gamma)
          target_constraint = {
              "type": "eq",
              "fun": lambda w: w.dot(self.expected_returns) - target_return,
          }
          # The equality constraint is either "weights sum to 1" (default), or
          # "weights sum to 0" (market neutral).
          if market_neutral:
              if self.bounds[0][0] is not None and self.bounds[0][0] >= 0:
                  warnings.warn(
                      "Market neutrality requires shorting - bounds have been amended",
                      RuntimeWarning,
                  )
                  self.bounds = self._make_valid_bounds((-1, 1))
              constraints = [
                  {"type": "eq", "fun": lambda x: np.sum(x)},
                  target_constraint,
              ]
          else:
              constraints = self.constraints + [target_constraint]
  
          result = sco.minimize(
              objective_functions.volatility,
              x0=self.initial_guess,
              args=args,
              method="SLSQP",
              bounds=self.bounds,
              constraints=constraints,
          )
          self.weights = result["x"]
          return dict(zip(self.tickers, self.weights))