Article-22714-Volatility-Mo.../Scripts/slsqp_article/slsqp_optimization_with_numerical_gradients.mq5
2026-06-03 20:14:05 +02:00

120 行
4.1 KiB
MQL5

//+------------------------------------------------------------------+
//| 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<slsqp_article\slsqp.mqh>
//+------------------------------------------------------------------+
//| 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;
}
};
//+------------------------------------------------------------------+