Article-15346-MQL5-Trade-Mo.../Select.mqh
2026-03-23 13:19:06 +07:00

531 lines
44 KiB
MQL5

//+------------------------------------------------------------------+
//| Select.mqh |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link "https://mql5.com/ru/users/artmedia70"
#property version "1.00"
enum ENUM_COMPARER_TYPE // Режимы сравнения
{
EQUAL, // Равно
MORE, // Больше
LESS, // Меньше
NO_EQUAL, // Не равно
EQUAL_OR_MORE, // Больше или равно
EQUAL_OR_LESS // Меньше или равно
};
//+------------------------------------------------------------------+
//| Включаемые файлы |
//+------------------------------------------------------------------+
#include "Deal.mqh"
#include "Position.mqh"
//+------------------------------------------------------------------+
//| Список-хранилище |
//+------------------------------------------------------------------+
CArrayObj ListStorage; // Объект-хранилище для хранения сортированных списков коллекций
//+------------------------------------------------------------------+
//| Класс для выборки объектов, удовлетворяющих критерию |
//+------------------------------------------------------------------+
class CSelect
{
private:
//--- Метод сравнения двух величин
template<typename T>
static bool CompareValues(T value1,T value2,ENUM_COMPARER_TYPE mode);
public:
//+------------------------------------------------------------------+
//| Методы работы со сделками |
//+------------------------------------------------------------------+
//--- Возвращает список сделок, у которых одно из (1) целочисленных, (2) вещественных и (3) строковых свойств удовлетворяет заданному критерию
static CArrayObj *ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_INT property,long value,ENUM_COMPARER_TYPE mode);
static CArrayObj *ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_DBL property,double value,ENUM_COMPARER_TYPE mode);
static CArrayObj *ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_STR property,string value,ENUM_COMPARER_TYPE mode);
//--- Возвращает индекс сделки в списке с максимальным значением (1) целочисленного, (2) вещественного и (3) строкового свойства
static int FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_INT property);
static int FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_DBL property);
static int FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_STR property);
//--- Возвращает индекс сделки в списке с минимальным значением (1) целочисленного, (2) вещественного и (3) строкового свойства
static int FindDealMin(CArrayObj *list_source,ENUM_DEAL_PROPERTY_INT property);
static int FindDealMin(CArrayObj *list_source,ENUM_DEAL_PROPERTY_DBL property);
static int FindDealMin(CArrayObj *list_source,ENUM_DEAL_PROPERTY_STR property);
//+------------------------------------------------------------------+
//| Методы работы с позициями |
//+------------------------------------------------------------------+
//--- Возвращает список позиций, у которых одно из (1) целочисленных, (2) вещественных и (3) строковых свойств удовлетворяет заданному критерию
static CArrayObj *ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_INT property,long value,ENUM_COMPARER_TYPE mode);
static CArrayObj *ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_DBL property,double value,ENUM_COMPARER_TYPE mode);
static CArrayObj *ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_STR property,string value,ENUM_COMPARER_TYPE mode);
//--- Возвращает индекс позиции в списке с максимальным значением (1) целочисленного, (2) вещественного и (3) строкового свойства
static int FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_INT property);
static int FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_DBL property);
static int FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_STR property);
//--- Возвращает индекс позиции в списке с минимальным значением (1) целочисленного, (2) вещественного и (3) строкового свойства
static int FindPositionMin(CArrayObj *list_source,ENUM_POSITION_PROPERTY_INT property);
static int FindPositionMin(CArrayObj *list_source,ENUM_POSITION_PROPERTY_DBL property);
static int FindPositionMin(CArrayObj *list_source,ENUM_POSITION_PROPERTY_STR property);
};
//+------------------------------------------------------------------+
//| Метод сравнения двух величин |
//+------------------------------------------------------------------+
template<typename T>
bool CSelect::CompareValues(T value1,T value2,ENUM_COMPARER_TYPE mode)
{
switch(mode)
{
case EQUAL : return(value1==value2 ? true : false);
case NO_EQUAL : return(value1!=value2 ? true : false);
case MORE : return(value1>value2 ? true : false);
case LESS : return(value1<value2 ? true : false);
case EQUAL_OR_MORE : return(value1>=value2 ? true : false);
case EQUAL_OR_LESS : return(value1<=value2 ? true : false);
default : return false;
}
}
//+------------------------------------------------------------------+
//| Методы работы со списками сделок |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Возвращает список сделок, у которых одно из целочисленных |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_INT property,long value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
int total=list_source.Total();
for(int i=0; i<total; i++)
{
CDeal *obj=list_source.At(i);
long obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop, value, mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает список сделок, у которых одно из вещественных |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_DBL property,double value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
for(int i=0; i<list_source.Total(); i++)
{
CDeal *obj=list_source.At(i);
double obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop,value,mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает список сделок, у которых одно из строковых |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByDealProperty(CArrayObj *list_source,ENUM_DEAL_PROPERTY_STR property,string value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
for(int i=0; i<list_source.Total(); i++)
{
CDeal *obj=list_source.At(i);
string obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop,value,mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с максимальным значением целочисленного свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_INT property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CDeal *max_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
long obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
long obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с максимальным значением вещественного свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_DBL property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CDeal *max_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
double obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
double obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с максимальным значением строкового свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMax(CArrayObj *list_source,ENUM_DEAL_PROPERTY_STR property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CDeal *max_obj=NULL;
int total=list_source.Total();
if(total==0) return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
string obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
string obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с минимальным значением целочисленного свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMin(CArrayObj* list_source,ENUM_DEAL_PROPERTY_INT property)
{
int index=0;
CDeal *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
long obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
long obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с минимальным значением вещественного свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMin(CArrayObj* list_source,ENUM_DEAL_PROPERTY_DBL property)
{
int index=0;
CDeal *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
double obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
double obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс сделки в списке |
//| с минимальным значением строкового свойства |
//+------------------------------------------------------------------+
int CSelect::FindDealMin(CArrayObj* list_source,ENUM_DEAL_PROPERTY_STR property)
{
int index=0;
CDeal *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CDeal *obj=list_source.At(i);
string obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
string obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Методы работы со списками позиций |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Возвращает список позиций, у которых одно из целочисленных |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_INT property,long value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
int total=list_source.Total();
for(int i=0; i<total; i++)
{
CPosition *obj=list_source.At(i);
long obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop, value, mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает список позиций, у которых одно из вещественных |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_DBL property,double value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
for(int i=0; i<list_source.Total(); i++)
{
CPosition *obj=list_source.At(i);
double obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop,value,mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает список позиций, у которых одно из строковых |
//| свойств удовлетворяет заданному критерию |
//+------------------------------------------------------------------+
CArrayObj *CSelect::ByPositionProperty(CArrayObj *list_source,ENUM_POSITION_PROPERTY_STR property,string value,ENUM_COMPARER_TYPE mode)
{
if(list_source==NULL)
return NULL;
CArrayObj *list=new CArrayObj();
if(list==NULL)
return NULL;
list.FreeMode(false);
if(!ListStorage.Add(list))
{
delete list;
return NULL;
}
for(int i=0; i<list_source.Total(); i++)
{
CPosition *obj=list_source.At(i);
string obj_prop=obj.GetProperty(property);
if(CompareValues(obj_prop,value,mode))
list.Add(obj);
}
return list;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с максимальным значением целочисленного свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_INT property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CPosition *max_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
long obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
long obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с максимальным значением вещественного свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_DBL property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CPosition *max_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
double obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
double obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с максимальным значением строкового свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMax(CArrayObj *list_source,ENUM_POSITION_PROPERTY_STR property)
{
if(list_source==NULL)
return WRONG_VALUE;
int index=0;
CPosition *max_obj=NULL;
int total=list_source.Total();
if(total==0) return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
string obj1_prop=obj.GetProperty(property);
max_obj=list_source.At(index);
string obj2_prop=max_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,MORE))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с минимальным значением целочисленного свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMin(CArrayObj* list_source,ENUM_POSITION_PROPERTY_INT property)
{
int index=0;
CPosition *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
long obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
long obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с минимальным значением вещественного свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMin(CArrayObj* list_source,ENUM_POSITION_PROPERTY_DBL property)
{
int index=0;
CPosition *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
double obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
double obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+
//| Возвращает индекс позиции в списке |
//| с минимальным значением строкового свойства |
//+------------------------------------------------------------------+
int CSelect::FindPositionMin(CArrayObj* list_source,ENUM_POSITION_PROPERTY_STR property)
{
int index=0;
CPosition *min_obj=NULL;
int total=list_source.Total();
if(total==0)
return WRONG_VALUE;
for(int i=1; i<total; i++)
{
CPosition *obj=list_source.At(i);
string obj1_prop=obj.GetProperty(property);
min_obj=list_source.At(index);
string obj2_prop=min_obj.GetProperty(property);
if(CompareValues(obj1_prop,obj2_prop,LESS))
index=i;
}
return index;
}
//+------------------------------------------------------------------+