//+------------------------------------------------------------------+ //| slsqp_optimization_with_numerical_gradients.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //---objective function object CObjectiveFunc obj_func; //---inequality constraints function object CIneqConstraints ineq_func; //---equality constraints function object CEqConstraints eq_func; //---the initial guess vector initp = {2, 0}; //---gradient configuration instance GradDiffOptions obj_options; //---configure upper and lower limits obj_options.bounds = matrix::Zeros(2,2); obj_options.bounds[0,1] = 10.; obj_options.bounds[1,1] = 10.; //---set gradient calculation method obj_options.method = GRAD_POINT_2; //---set gradient options for objective function and constraints obj_func.setParams(obj_options); ineq_func.setParams(1,2,obj_options); eq_func.setParams(1,2,obj_options); //---initialize and verify configuration of all function objects if(!obj_func.initialize(initp) || !ineq_func.initialize(initp) || !eq_func.initialize(initp)) return; //---the minimizer instance CSlsqp slsqp_minim; //---configure the minimizer slsqp_minim.SetInequalityConstraints(ineq_func); slsqp_minim.SetEqualityConstraints(eq_func); //---run the optimizer OptimizeResult ro = slsqp_minim.Minimize(obj_func); //---check return code Print("Minimization return code : ", ro.return_code); //---print results if(ro.return_code>0) { Print("Solution ", ro.solution); Print("Minimum value of function ", ro.objective_result); Print("Gradient at the minimum ", ro.objective_gradient); Print("Number of iterations ", ro.niter); Print("Number of function evaluations ", ro.nfeval); } } //+------------------------------------------------------------------+ //| objective function | //+------------------------------------------------------------------+ class CObjectiveFunc:public CFunctor { protected: vector obj_gradient; public: CObjectiveFunc(void) { m_clip = true; obj_gradient = vector::Zeros(2); } ~CObjectiveFunc(void) { } virtual double orig_fun(vector& x) override { return pow((x[0] - 1),2) + pow((x[1] - 2.5),2); } }; //+------------------------------------------------------------------+ //| inequality constraints | //+------------------------------------------------------------------+ class CIneqConstraints: public CConstraints { private: vector obj_result; public: CIneqConstraints(void) { obj_result = vector::Zeros(1); } ~CIneqConstraints(void) { } virtual vector orig_fun(vector& x) override { obj_result[0] = pow(x[0],2) - x[1]; return obj_result; } }; //+------------------------------------------------------------------+ //| equality constraints | //+------------------------------------------------------------------+ class CEqConstraints: public CConstraints { private: vector obj_result; public: CEqConstraints(void) { obj_result = vector::Zeros(1); } ~CEqConstraints(void) { } virtual vector orig_fun(vector& x) override { obj_result[0] = x[0] - x[1] + 2; return obj_result; } }; //+------------------------------------------------------------------+