254 lines
11 KiB
MQL5
254 lines
11 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| sugenovariable.mqh |
| |||
//| Copyright 2000-2025, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
//| Implementation of Fuzzy library in MetaQuotes Language 5 |
| |||
//| |
| |||
//| The features of the library include: |
| |||
//| - Create Mamdani fuzzy model |
| |||
//| - Create Sugeno fuzzy model |
| |||
//| - Normal membership function |
| |||
//| - Triangular membership function |
| |||
//| - Trapezoidal membership function |
| |||
//| - Constant membership function |
| |||
//| - Defuzzification method of center of gravity (COG) |
| |||
//| - Defuzzification method of bisector of area (BOA) |
| |||
//| - Defuzzification method of mean of maxima (MeOM) |
| |||
//| |
| |||
//| This file is free software; you can redistribute it and/or |
| |||
//| modify it under the terms of the GNU General Public License as |
| |||
//| published by the Free Software Foundation (www.fsf.org); either |
| |||
//| version 2 of the License, or (at your option) any later version. |
| |||
//| |
| |||
//| This program is distributed in the hope that it will be useful, |
| |||
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |||
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |||
//| GNU General Public License for more details. |
| |||
//+------------------------------------------------------------------+
| |||
#include <Arrays\List.mqh>
| |||
#include "FuzzyVariable.mqh"
| |||
#include "Dictionary.mqh"
| |||
//+------------------------------------------------------------------+
| |||
//| Purpose: creating Sugeno variable. |
| |||
//+------------------------------------------------------------------+
| |||
//+------------------------------------------------------------------+
| |||
//| The base class for Linear Sugeno Function |
| |||
//+------------------------------------------------------------------+
| |||
class ISugenoFunction : public CNamedValueImpl
| |||
{
| |||
public:
| |||
//--- method to check type
| |||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_ISugenoFunction); }
| |||
};
| |||
//+------------------------------------------------------------------+
| |||
//| Lenear function for Sugeno Fuzzy System |
| |||
//+------------------------------------------------------------------+
| |||
class CLinearSugenoFunction : public ISugenoFunction
| |||
{
| |||
private:
| |||
CList *m_input; // List of input variables
| |||
CList *m_coeffs; // The dictionary which stores variables and their coefficients
| |||
double m_const_value; // The constant term of the linear equation
| |||
| |||
public:
| |||
CLinearSugenoFunction(const string name,CList *in);
| |||
CLinearSugenoFunction(const string name,CList *in,CList *coeffs,const double constValue);
| |||
CLinearSugenoFunction(const string name,CList *in,const double &coeffs[]);
| |||
~CLinearSugenoFunction(void);
| |||
//--- method to check type
| |||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_LinearSugenoFunction); }
| |||
//--- methods gets or sets constant coefficient
| |||
double ConstValue() { return(m_const_value); }
| |||
void ConstValue(const double value) { m_const_value=value; }
| |||
//--- methods gets or sets coefficient by fuzzy variable
| |||
double GetCoefficient(CFuzzyVariable *var);
| |||
void SetCoefficient(CFuzzyVariable *var,const double coeff);
| |||
//--- calculate
| |||
double Evaluate(CList *inputValues);
| |||
};
| |||
//+------------------------------------------------------------------+
| |||
//| First constructor with parameters |
| |||
//+------------------------------------------------------------------+
| |||
CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in)
| |||
{
| |||
m_coeffs=new CList;
| |||
CNamedValueImpl::Name(name);
| |||
m_input=in;
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Second constructor with parameters |
| |||
//+------------------------------------------------------------------+
| |||
CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in,CList *coeffs,const double constValue)
| |||
{
| |||
CNamedValueImpl::Name(name);
| |||
m_input=in;
| |||
//--- Check that all coeffecients are related to the variable from input
| |||
for(int i=0; i<coeffs.Total(); i++)
| |||
{
| |||
CDictionary_Obj_Double *p_vd=coeffs.GetNodeAtIndex(i);
| |||
if((m_input.IndexOf(p_vd.Key())==-1) && (in.Total()==coeffs.Total()))
| |||
{
| |||
Print("Input of the fuzzy system does not contain all variable.");
| |||
}
| |||
}
| |||
m_coeffs=coeffs;
| |||
m_const_value=constValue;
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Third constructor with parameters |
| |||
//+------------------------------------------------------------------+
| |||
CLinearSugenoFunction::CLinearSugenoFunction(const string name,CList *in,const double &coeffs[])
| |||
{
| |||
m_coeffs=new CList;
| |||
m_input=in;
| |||
CNamedValueImpl::Name(name);
| |||
//--- Check input values
| |||
if(ArraySize(coeffs)!=in.Total() && ArraySize(coeffs)!=(in.Total()+1))
| |||
{
| |||
Print("Wrong lenght of coefficients array");
| |||
}
| |||
//--- Fill list of coefficients
| |||
for(int i=0; i<in.Total(); i++)
| |||
{
| |||
CDictionary_Obj_Double *p_vd=new CDictionary_Obj_Double;
| |||
CFuzzyVariable *var=in.GetNodeAtIndex(i);
| |||
p_vd.SetAll(var,coeffs[i]);
| |||
m_coeffs.Add(p_vd);
| |||
}
| |||
if(ArraySize(coeffs)==(in.Total()+1))
| |||
{
| |||
m_const_value=coeffs[ArraySize(coeffs)-1];
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Destructor |
| |||
//+------------------------------------------------------------------+
| |||
CLinearSugenoFunction::~CLinearSugenoFunction(void)
| |||
{
| |||
if(CheckPointer(m_input)==POINTER_DYNAMIC)
| |||
delete m_input;
| |||
if(CheckPointer(m_coeffs)==POINTER_DYNAMIC)
| |||
delete m_coeffs;
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Get coefficient by fuzzy variable |
| |||
//+------------------------------------------------------------------+
| |||
double CLinearSugenoFunction::GetCoefficient(CFuzzyVariable *var)
| |||
{
| |||
if(var==NULL)
| |||
{
| |||
//--- return const coefficient
| |||
return (m_const_value);
| |||
}
| |||
else
| |||
{
| |||
for(int i=0; i<m_coeffs.Total(); i++)
| |||
{
| |||
CDictionary_Obj_Double *p_vd=m_coeffs.GetNodeAtIndex(i);
| |||
if(p_vd.Key()==var)
| |||
{
| |||
//--- return coefficient
| |||
return (p_vd.Value());
| |||
}
| |||
}
| |||
}
| |||
//--- return NULL
| |||
return (NULL);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Set coefficient by fuzzy variable |
| |||
//+------------------------------------------------------------------+
| |||
void CLinearSugenoFunction::SetCoefficient(CFuzzyVariable *var,const double coeff)
| |||
{
| |||
if(var==NULL)
| |||
{
| |||
m_const_value=coeff;
| |||
}
| |||
else
| |||
{
| |||
for(int i=0; i<m_coeffs.Total(); i++)
| |||
{
| |||
CDictionary_Obj_Double *p_vd=m_coeffs.GetNodeAtIndex(i);
| |||
if(p_vd.Key()==var)
| |||
{
| |||
p_vd.Value(coeff);
| |||
}
| |||
m_coeffs.Delete(i);
| |||
m_coeffs.Insert(p_vd,i);
| |||
}
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Calculate result of linear function |
| |||
//+------------------------------------------------------------------+
| |||
double CLinearSugenoFunction::Evaluate(CList *inputValues)
| |||
{
| |||
double result=0.0;
| |||
for(int i=0; i<m_coeffs.Total(); i++)
| |||
{
| |||
CDictionary_Obj_Double *p_vd1=m_coeffs.GetNodeAtIndex(i);
| |||
CDictionary_Obj_Double *p_vd2=inputValues.GetNodeAtIndex(i);
| |||
result+=(p_vd1.Value())*(p_vd2.Value());
| |||
}
| |||
result+=m_const_value;
| |||
//--- return result
| |||
return (result);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Used as an output variable in Sugeno fuzzy inference system |
| |||
//+------------------------------------------------------------------+
| |||
class CSugenoVariable : public CNamedVariableImpl
| |||
{
| |||
private:
| |||
CList *m_functions; // List of Sugeno functions
| |||
| |||
public:
| |||
CSugenoVariable(const string name);
| |||
~CSugenoVariable(void);
| |||
//--- method to check type
| |||
virtual bool IsTypeOf(EnType type) { return(type==TYPE_CLASS_SugenoVariable); }
| |||
//--- method gets the list of functions that belongs to the variable
| |||
CList *Functions() { return(m_functions); }
| |||
//--- overload gets the list of functions that belongs to the variable
| |||
CList *Values() { return(m_functions); }
| |||
//--- find function by name
| |||
ISugenoFunction *GetFuncByName(const string name);
| |||
};
| |||
//+------------------------------------------------------------------+
| |||
//| Constructor with parameters |
| |||
//+------------------------------------------------------------------+
| |||
CSugenoVariable::CSugenoVariable(const string name)
| |||
{
| |||
m_functions=new CList;
| |||
CNamedVariableImpl::Name(name);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Destructor |
| |||
//+------------------------------------------------------------------+
| |||
CSugenoVariable::~CSugenoVariable(void)
| |||
{
| |||
delete m_functions;
| |||
}
| |||
//+--------------------------------------------------------------------------------------+
| |||
//| Find function by its name |
| |||
//+--------------------------------------------------------------------------------------+
| |||
ISugenoFunction *CSugenoVariable::GetFuncByName(const string name)
| |||
{
| |||
CList *values=CSugenoVariable::Values();
| |||
values.Total();
| |||
for(int i=0; i<values.Total(); i++)
| |||
{
| |||
CNamedValueImpl *func=values.GetNodeAtIndex(i);
| |||
if(func.Name()==name)
| |||
{
| |||
ISugenoFunction *result=m_functions.GetNodeAtIndex(i);
| |||
//--- return result
| |||
return (result);
| |||
}
| |||
}
| |||
Print("The function of the same name is not found");
| |||
//--- return
| |||
return (NULL);
| |||
}
| |||
//+------------------------------------------------------------------+
|