531 lines
44 KiB
MQL5
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;
|
|
}
|
|
//+------------------------------------------------------------------+
|