code: def custom_objective(self, objective_function, *args):
          
          result = sco.minimize(
              objective_function,
              x0=self.initial_guess,
              args=args,
              method="SLSQP",
              bounds=self.bounds,
              constraints=self.constraints,
          )
          self.weights = result["x"]
          return dict(zip(self.tickers, self.weights))
docs: Optimise some objective function. While an implicit requirement is that the function
          can be optimised via a quadratic optimiser, this is not enforced. Thus there is a
          decent chance of silent failure.
  
          :param objective_function: function which maps (weight, args) -> cost
          :type objective_function: function with signature (np.ndarray, args) -> float
          :return: asset weights that optimise the custom objective
          :rtype: dict