Библиотека для простого и быстрого создания программ для MetaTrader (Часть XVIII): Интерактивность объекта-аккаунт и любых других объектов библиотеки

12 августа 2019, 11:42
Artyom Trishkin
0
1 013

Содержание

Мы создали базовый объект, от которого будем наследовать все остальные объекты библиотеки, которым необходим событийный функционал. Теперь задавать параметры отслеживаемых событий и получать их от объектов стало очень просто — всё делается в базовом классе и для всех его объектов-наследников необходимо провести одинаковые действия по установке отслеживаемых свойств и значений, которые хотим отслеживать в свойствах объекта.

Сегодня немного доработаем базовый объект и подключим к нему объект-аккаунт. Также мы протестируем возможность задания нужных для отслеживания свойств разных объектов и их значений на примере тестового советника.
В прошлой статье при создании методов базового объекта CBaseObj и методов его наследника — объекта-символа — я, скажем так, немного увлёкся и сделал набор методов в двух классах, которые фактически дублируют друг друга. Исправим данное недоразумение — просто удалим методы установки и получения свойств из класса объекта-наследника CSymbol, и упорядочим методы базового объекта CBaseObj.

Доработка базового объекта и объекта-символа

Откроем файл \MQL5\Include\DoEasy\Objects\BaseObj.mqh и внесём в него некоторые правки.

Метод CheckEvents() из класса CSymbol перенесём в базовый класс CBaseObj, так как этот метод абсолютно идентичен для любых объектов-наследников базового класса, а значит — ему самое место в базовом классе.
Впишем его определение в защищённую секцию класса CBaseObj:

protected:
   CArrayObj         m_list_events_base;                       // Список базовых событий объекта
   CArrayObj         m_list_events;                            // Список событий объекта
   MqlTick           m_tick;                                   // Структура тика для получения котировочных данных
   double            m_hash_sum;                               // Хэш-сумма данных объекта
   double            m_hash_sum_prev;                          // Хэш-сумма данных объекта на прошлой проверке
   int               m_digits_currency;                        // Число знаков после запятой валюты счёта
   int               m_global_error;                           // Код глобальной ошибки
   long              m_chart_id;                               // Идентификатор графика управляющей программы
   bool              m_is_event;                               // Флаг события объекта
   int               m_event_code;                             // Код события объекта
   int               m_event_id;                               // Идентификатор события (равен значению свойства объекта)
   string            m_name;                                   // Наименование объекта
   string            m_folder_name;                            // Имя папки хранения объектов-наследников CBaseObj
   bool              m_first_start;                            // Флаг первого запуска
   int               m_type;                                   // Тип объекта (соответствует идентификаторам коллекций)

//--- Данные для хранения, контроля и возврата отслеживаемых свойств:
//--- [Индекс свойства][0] Контролируемая величина прироста значения свойства
//--- [Индекс свойства][1] Контролируемая величина уменьшения значения свойства
//--- [Индекс свойства][2] Контрольный уровень значения свойства
//--- [Индекс свойства][3] Значение свойства
//--- [Индекс свойства][4] Величина изменения значения свойства
//--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста
//--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения
//--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня
//--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня
//--- [Индекс свойства][9] Флаг равенства значения свойства контрольному уровню
   long              m_long_prop_event[][CONTROLS_TOTAL];         // Массив для хранения величин целочисленных свойств объекта и контролируемых значений изменения свойств
   double            m_double_prop_event[][CONTROLS_TOTAL];       // Массив для хранения величин вещественных свойств объекта и контролируемых значений изменения свойств
   long              m_long_prop_event_prev[][CONTROLS_TOTAL];    // Массив для хранения величин контролируемых целочисленных свойств объекта на прошлой проверке
   double            m_double_prop_event_prev[][CONTROLS_TOTAL];  // Массив для хранения величин контролируемых вещественных свойств объекта на прошлой проверке

//--- Возвращает (1) время в милисекундах, (2) милисекунды из значения времени из MqlTick
   long              TickTime(void)                            const { return #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ;  }
   ushort            MSCfromTime(const long time_msc)          const { return #ifdef __MQL5__ ushort(this.TickTime()%1000) #else 0 #endif ;              }
//--- возвращает факт наличия кода события в событии объекта
   bool              IsPresentEventFlag(const int change_code) const { return (this.m_event_code & change_code)==change_code; }
//--- Возвращает число знаков после запятой валюты счёта
   int               DigitsCurrency(void)                      const { return this.m_digits_currency; }
//--- Возвращает количество знаков после запятой в double-значении
   int               GetDigits(const double value)             const;

//--- Устанавливает размер массива (1) целочисленных, (2) вещественных контролируемых свойств объекта
   bool              SetControlDataArraySizeLong(const int size);
   bool              SetControlDataArraySizeDouble(const int size);
//--- Проверяет размер массива свойств объекта
   bool              CheckControlDataArraySize(bool check_long=true);
   
//--- Проверяет список изменений свойств символа и создаёт событие
   void              CheckEvents(void);
   
//--- (1) Упаковывает ushort-число в переданное long-число
//--- (2) преобразует ushort-значение в заданный байт long-числа
   long              UshortToLong(const ushort ushort_value,const uchar to_byte,long &long_value);
   
protected:
   long              UshortToByte(const ushort value,const uchar index) const;
   
public:

Из публичной секции удалим методы, устанавливающие значения флагам событий — события происходят независимо от нашего желания, и флаги устанавливаются без участия пользователя. Поэтому держать методы для принудительной установки флагов событий мне кажется совершенно нецелосообразным:

//--- Устанавливает Флаг изменения значения свойства больше, чем на величину (1) прироста, (2) уменьшения
   template<typename T> void  SetControlledFlagINC(const int property,const T value); 
   template<typename T> void  SetControlledFlagDEC(const int property,const T value); 
//--- Устанавливает Флаг изменения значения свойства (1) больше, (2) меньше контрольного уровня, (3) равенства уровню
   template<typename T> void  SetControlledFlagMORE(const int property,const T value);
   template<typename T> void  SetControlledFlagLESS(const int property,const T value);
   template<typename T> void  SetControlledFlagEQUAL(const int property,const T value);

Методы, возвращающие установленные пользователем контролируемые величины свойств объектов, текущее значение свойств объектов, и величин изменений свойств объектов, теперь будут носить более удобочитаемые и осмысленные наименования:

//--- Возвращает установленную величину контролируемого приращения (1) целочисленных, (2) вещественных свойств объекта
   long              GetControlledLongValueINC(const int property)         const { return this.m_long_prop_event[property][0];                           }
   double            GetControlledDoubleValueINC(const int property)       const { return this.m_double_prop_event[property-this.m_long_prop_total][0];  }
//--- Возвращает установленную величину контролируемого уменьшения (1) целочисленных, (2) вещественных свойств объекта
   long              GetControlledLongValueDEC(const int property)         const { return this.m_long_prop_event[property][1];                           }
   double            GetControlledDoubleValueDEC(const int property)       const { return this.m_double_prop_event[property-this.m_long_prop_total][1];  }
//--- Возвращает установленный контрольный уровень (1) целочисленных, (2) вещественных свойств объекта
   long              GetControlledLongValueLEVEL(const int property)       const { return this.m_long_prop_event[property][2];                           }
   double            GetControlledDoubleValueLEVEL(const int property)     const { return this.m_double_prop_event[property-this.m_long_prop_total][2];  }

//--- Возвращает текущее значение (1) целочисленного, (2) вещественного свойства объекта
   long              GetPropLongValue(const int property)            const { return this.m_long_prop_event[property][3];                           }
   double            GetPropDoubleValue(const int property)          const { return this.m_double_prop_event[property-this.m_long_prop_total][3];  }
//--- Возвращает величину изменения контролируемого (1) целочисленного, (2) вещественного свойства объекта
   long              GetPropLongChangedValue(const int property)     const { return this.m_long_prop_event[property][4];                           }
   double            GetPropDoubleChangedValue(const int property)   const { return this.m_double_prop_event[property-this.m_long_prop_total][4];  }

//--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства больше, чем на величину прироста
   long              GetPropLongFlagINC(const int property)          const { return this.m_long_prop_event[property][5];                           }
   double            GetPropDoubleFlagINC(const int property)        const { return this.m_double_prop_event[property-this.m_long_prop_total][5];  }
//--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства больше, чем на величину уменьшения
   long              GetPropLongFlagDEC(const int property)          const { return this.m_long_prop_event[property][6];                           }
   double            GetPropDoubleFlagDEC(const int property)        const { return this.m_double_prop_event[property-this.m_long_prop_total][6];  }
//--- Возвращает Флаг увеличения значения (1) целочисленного, (2) вещественного свойства больше контрольного уровня
   long              GetPropLongFlagMORE(const int property)         const { return this.m_long_prop_event[property][7];                           }
   double            GetPropDoubleFlagMORE(const int property)       const { return this.m_double_prop_event[property-this.m_long_prop_total][7];  }
//--- Возвращает Флаг уменьшения значения (1) целочисленного, (2) вещественного свойства меньше контрольного уровня
   long              GetPropLongFlagLESS(const int property)         const { return this.m_long_prop_event[property][8];                           }
   double            GetPropDoubleFlagLESS(const int property)       const { return this.m_double_prop_event[property-this.m_long_prop_total][8];  }
//--- Возвращает Флаг равенства значений (1) целочисленного, (2) вещественного свойства и контрольного уровня
   long              GetPropLongFlagEQUAL(const int property)        const { return this.m_long_prop_event[property][9];                           }
   double            GetPropDoubleFlagEQUAL(const int property)      const { return this.m_double_prop_event[property-this.m_long_prop_total][9];  }

При углубленном тестировании событийного функционала базового объекта CBaseObj были замечены ошибки при определении событий. Оказалось, что в методе заполнения свойств базового объекта и поиска событий FillPropertySettings() была допущена неточность — в любом случае в самом конце метода текущее состояние свойств записывалось в прошлое состояние. Это не давало определить величину изменения свойств, так как вновь полученное значение свойства сразу же записывалось в прошлое. При малых значениях контролируемого изменения эта ошибка не проявлялась, так как свойство успевало за один раз измениться на величину, больше, чем задано для генерации события.
Но когда необходимо было отследить изменение на достаточно большую величину, которое происходит не за один тик, то в данном случае этого сделать было невозможно.
Теперь внесены правки текущее состояние записывается в прошлое только при регистрации события:

//+------------------------------------------------------------------+
//| Заполняет массив свойств объекта                                 |
//+------------------------------------------------------------------+
template<typename T> bool CBaseObj::FillPropertySettings(const int index,T &array[][CONTROLS_TOTAL],T &array_prev[][CONTROLS_TOTAL],int &event_id)
  {
   //--- Данные в ячейках массива
   //--- [Индекс свойства][0] Контролируемая величина прироста значения свойства
   //--- [Индекс свойства][1] Контролируемая величина уменьшения значения свойства
   //--- [Индекс свойства][2] Контрольный уровень значения свойства
   //--- [Индекс свойства][3] Значение свойства
   //--- [Индекс свойства][4] Величина изменения значения свойства
   //--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста
   //--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения
   //--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня
   //--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня
   //--- [Индекс свойства][9] Флаг равенства значения свойства контрольному уровню
  
   //--- Устанавливаем смещение индекса double-свойства и задаём идентификатор события
   event_id=index+(typename(T)=="double" ? this.m_long_prop_total : 0);
   //--- Обнуляем все флаги событий
   for(int j=5;j<CONTROLS_TOTAL;j++)
      array[index][j]=false;
   //--- Величина изменения свойства
   T value=array[index][3]-array_prev[index][3];
   array[index][4]=value;
   //--- Если контролируемая величина прироста значения свойства установлена
   if(array[index][0]<LONG_MAX)
     {
      //--- Если величина изменения свойства больше контролируемой величины увеличения - есть событие,
      //--- добавляем событие в список, ставим флаг и сохраняем новый размер значения свойства
      if(value>0 && value>array[index][0])
        {
         if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_INC,value))
           {
            array[index][5]=true;
            array_prev[index][4]=value;
           }
         //--- Сохраняем текущее значение свойства как прошлое
         array_prev[index][3]=array[index][3];
        }
     }
   //--- Если контролируемая величина уменьшения значения свойства установлена
   if(array[index][1]<LONG_MAX)
     {
      //--- Если величина изменения свойства больше контролируемой величины уменьшения - есть событие,
      //--- добавляем событие в список, ставим флаг и сохраняем новый размер значения свойства
      if(value<0 && fabs(value)>array[index][1])
        {
         if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_DEC,value))
           {
            array[index][6]=true;
            array_prev[index][4]=value;
           }
         //--- Сохраняем текущее значение свойства как прошлое
         array_prev[index][3]=array[index][3];
        }
     }
   //--- Если значение контролируемого уровня установлено
   if(array[index][2]<LONG_MAX)
     {
      value=array[index][3]-array[index][2];
      //--- Если значение свойства стало больше контрольного уровня - есть событие,
      //--- добавляем событие в список и ставим флаг
      if(value>0 && array_prev[index][3]<=array[index][2])
        {
         if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_MORE_THEN,array[index][2]))
            array[index][7]=true;
         //--- Сохраняем текущее значение свойства как прошлое
         array_prev[index][3]=array[index][3];
        }
      //--- Если значение свойства стало меньше контрольного уровня - есть событие,
      //--- добавляем событие в список и ставим флаг
      else if(value<0 && array_prev[index][3]>=array[index][2])
        {
         if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_LESS_THEN,array[index][2]))
            array[index][8]=true;
         //--- Сохраняем текущее значение свойства как прошлое
         array_prev[index][3]=array[index][3];
        }
      //--- Если значение свойства стало равно контрольному уровню - есть событие,
      //--- добавляем событие в список и ставим флаг
      else if(value==0 && array_prev[index][3]!=array[index][2])
        {
         if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_EQUALS,array[index][2]))
            array[index][9]=true;
         //--- Сохраняем текущее значение свойства как прошлое
         array_prev[index][3]=array[index][3];
        }
     }
   return true;
  }
//+------------------------------------------------------------------+

В методе инициализации свойств базового объекта ранее свойства инициализировались значениями LONG_MAX,
теперь инициализировать значения будем нулём:

//+------------------------------------------------------------------+
//| Сбрасывает переменные отслеживаемых данных объекта               |
//+------------------------------------------------------------------+
void CBaseObj::ResetChangesParams(void)
  {
   if(!this.CheckControlDataArraySize(true) || !this.CheckControlDataArraySize(false))
      return;
   this.m_list_events.Clear();
   this.m_list_events.Sort();
   this.m_list_events_base.Clear();
   this.m_list_events_base.Sort();
//--- Данные в ячейках массива
//--- [Индекс свойства][3] Значение свойства
//--- [Индекс свойства][4] Величина изменения значения свойства
//--- [Индекс свойства][5] Флаг изменения значения свойства больше, чем на величину прироста
//--- [Индекс свойства][6] Флаг изменения значения свойства больше, чем на величину уменьшения
//--- [Индекс свойства][7] Флаг увеличения значения свойства больше контрольного уровня
//--- [Индекс свойства][8] Флаг уменьшения значения свойства меньше контрольного уровня
//--- [Индекс свойства][9] Флаг равенства значения свойства контролируемому значению
   for(int i=this.m_long_prop_total-1;i>WRONG_VALUE;i--)
      for(int j=3; j<CONTROLS_TOTAL; j++)
         this.m_long_prop_event[i][j]=0;
   for(int i=this.m_double_prop_total-1;i>WRONG_VALUE;i--)
      for(int j=3; j<CONTROLS_TOTAL; j++)
         this.m_double_prop_event[i][j]=0;
  }
//+------------------------------------------------------------------+

Впишем реализацию метода CheckEvents(), перенёсённого из CSymbol:

//+------------------------------------------------------------------+
//| Проверяет список изменений свойств объекта и создаёт событие     |
//+------------------------------------------------------------------+
void CBaseObj::CheckEvents(void)
  {
   int total=this.m_list_events_base.Total();
   if(total==0)
      return;
   
   for(int i=0;i<total;i++)
     {
      CBaseEvent *event=this.GetEventBase(i);
      if(event==NULL)
         continue;
      long lvalue=0;
      this.UshortToLong(this.MSCfromTime(this.TickTime()),0,lvalue);
      this.UshortToLong(event.Reason(),1,lvalue);
      this.UshortToLong((ushort)this.m_type,2,lvalue);
      if(this.EventAdd((ushort)event.ID(),lvalue,event.Value(),this.m_name))
         this.m_is_event=true;
     }
  }  
//+------------------------------------------------------------------+

Внесём исправления в класс объекта-символа CSymbol.
Откроем файл \MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqh и внесём изменения.

Из приватной секции класса удалим два метода:

private:
   struct MqlMarginRate
     {
      double         Initial;                                  // коэффициент взимания начальной маржи
      double         Maintenance;                              // коэффициент взимания поддерживающей маржи
     };
   struct MqlMarginRateMode
     {
      MqlMarginRate  Long;                                     // MarginRate длинных позиций
      MqlMarginRate  Short;                                    // MarginRate коротких позиций
      MqlMarginRate  BuyStop;                                  // MarginRate BuyStop-ордеров
      MqlMarginRate  BuyLimit;                                 // MarginRate BuyLimit-ордеров
      MqlMarginRate  BuyStopLimit;                             // MarginRate BuyStopLimit-ордеров
      MqlMarginRate  SellStop;                                 // MarginRate SellStop-ордеров
      MqlMarginRate  SellLimit;                                // MarginRate SellLimit-ордеров
      MqlMarginRate  SellStopLimit;                            // MarginRate SellStopLimit-ордеров
     };
   MqlMarginRateMode m_margin_rate;                            // Структура коэффициентов взимания маржи
   MqlBookInfo       m_book_info_array[];                      // Массив структур данных стакана

   long              m_long_prop[SYMBOL_PROP_INTEGER_TOTAL];   // Целочисленные свойства
   double            m_double_prop[SYMBOL_PROP_DOUBLE_TOTAL];  // Вещественные свойства
   string            m_string_prop[SYMBOL_PROP_STRING_TOTAL];  // Строковые свойства
   bool              m_is_change_trade_mode;                   // Флаг изменения режима торговли для символа

//--- Инициализирует переменные контролируемых данных символа
   virtual void      InitControlsParams(void);
//--- Проверяет список изменений свойств символа и создаёт событие
   void              CheckEvents(void);

Метод инициализации контролируемых данных не нужен, так как все необходимые для отслеживания свойства и параметры для любого класса на основе базового объекта нужно производить явным указанием значений отслеживаемых параметров, а по умолчанию никакие изменения свойств объектов-наследников не отслеживаются. Метод CheckEvents() мы уже перенесли отсюда в базовый класс CBaseObj.

Из публичной секции класса удалим методы, которые фактически дублировали методы базового объекта:

public:
//--- Устанавливает величину изменения контролируемого свойства символа
   template<typename T> void  SetControlChangedValue(const int property,const T value);
//--- Устанавливает величину контролируемого (1) приращения, (2) уменьшения свойства символа, (3) контрольного уровня
   template<typename T> void  SetControlPropertyINC(const int property,const T value);
   template<typename T> void  SetControlPropertyDEC(const int property,const T value);
   template<typename T> void  SetControlPropertyLEVEL(const int property,const T value);
//--- Устанавливает Флаг изменения значения свойства символа больше, чем на величину (1) прироста, (2) уменьшения
   template<typename T> void  SetControlFlagINC(const int property,const T value);
   template<typename T> void  SetControlFlagDEC(const int property,const T value);
   
//--- Возвращает установленную величину контролируемого приращения (1) целочисленного, (2) вещественного свойства символа
   long              GetControlParameterINC(const ENUM_SYMBOL_PROP_INTEGER property)   const { return this.GetControlledValueLongINC(property);             }
   double            GetControlParameterINC(const ENUM_SYMBOL_PROP_DOUBLE property)    const { return this.GetControlledValueDoubleINC(property);           }
//--- Возвращает установленную величину контролируемого уменьшения (1) целочисленного, (2) вещественного свойства символа
   long              GetControlParameterDEC(const ENUM_SYMBOL_PROP_INTEGER property)   const { return this.GetControlledValueLongDEC(property);             }
   double            GetControlParameterDEC(const ENUM_SYMBOL_PROP_DOUBLE property)    const { return this.GetControlledValueDoubleDEC(property);           }
//--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства символа больше, чем на величину прироста
   long              GetControlFlagINC(const ENUM_SYMBOL_PROP_INTEGER property)        const { return this.GetControlledFlagLongINC(property);              }
   double            GetControlFlagINC(const ENUM_SYMBOL_PROP_DOUBLE property)         const { return this.GetControlledFlagDoubleINC(property);            }
//--- Возвращает Флаг изменения значения (1) целочисленного, (2) вещественного свойства символа больше, чем на величину уменьшения
   bool              GetControlFlagDEC(const ENUM_SYMBOL_PROP_INTEGER property)        const { return (bool)this.GetControlledFlagLongDEC(property);        }
   bool              GetControlFlagDEC(const ENUM_SYMBOL_PROP_DOUBLE property)         const { return (bool)this.GetControlledFlagDoubleDEC(property);      }
//--- Возвращает величину изменения контролируемого (1) целочисленного, (2) вещественного свойства объекта
   long              GetControlChangedValue(const ENUM_SYMBOL_PROP_INTEGER property)   const { return this.GetControlledChangedValueLong(property);         }
   double            GetControlChangedValue(const ENUM_SYMBOL_PROP_DOUBLE property)    const { return this.GetControlledChangedValueDouble(property);       }

Методы получения и установки параметров отслеживаемых свойств символа теперь для возврата значений напрямую используют методы базового класса. Просто приведу список методов:

//+------------------------------------------------------------------+
//| Получение и установка параметров отслеживаемых изменений свойств |
//+------------------------------------------------------------------+
   //--- Исполнение
   //--- Флаг изменения режима торговли для символа
   bool              IsChangedTradeMode(void)                              const { return this.m_is_change_trade_mode;                                      } 
   //--- Сделки текущей сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества сделок в текущую сессию
   //--- получение (3) величины изменения количества сделок в текущую сессию,
   //--- получение флага изменения количества сделок в текущую сессию больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlSessionDealsInc(const long value)                 { this.SetControlledValueINC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value));        }
   void              SetControlSessionDealsDec(const long value)                 { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value));        }
   void              SetControlSessionDealsLevel(const long value)               { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value));      }
   long              GetValueChangedSessionDeals(void)                     const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_DEALS);                   }
   bool              IsIncreasedSessionDeals(void)                         const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_DEALS);                  }
   bool              IsDecreasedSessionDeals(void)                         const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_DEALS);                  }
   //--- Ордера Buy текущей сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества Buy-ордеров в текущий момент
   //--- получение (4) величины изменения количества Buy-ордеров в текущий момент,
   //--- получение флага изменения количества Buy-ордеров в текущий момент больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionBuyOrdInc(const long value)                { this.SetControlledValueINC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value));   }
   void              SetControlSessionBuyOrdDec(const long value)                { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value));   }
   void              SetControlSessionBuyOrdLevel(const long value)              { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); }
   long              GetValueChangedSessionBuyOrders(void)                 const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS);              }
   bool              IsIncreasedSessionBuyOrders(void)                     const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS);             }
   bool              IsDecreasedSessionBuyOrders(void)                     const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS);             }
   //--- Ордера Sell текущей сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества Sell-ордеров в текущий момент
   //--- получение (4) величины изменения количества Sell-ордеров в текущий момент,
   //--- получение флага изменения количества Sell-ордеров в текущий момент больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionSellOrdInc(const long value)               { this.SetControlledValueINC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value));  }
   void              SetControlSessionSellOrdDec(const long value)               { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value));  }
   void              SetControlSessionSellOrdLevel(const long value)             { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value));}
   long              GetValueChangedSessionSellOrders(void)                const { return this.GetPropLongChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS);             }
   bool              IsIncreasedSessionSellOrders(void)                    const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS);            }
   bool              IsDecreasedSessionSellOrders(void)                    const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS);            }
   //--- Объем в последней сделке
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня объема в последней сделке
   //--- получение (4) величины изменения объема в последней сделке,
   //--- получение флага изменения объема в последней сделке больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeInc(const long value)                       { this.SetControlledValueINC(SYMBOL_PROP_VOLUME,(long)::fabs(value));               }
   void              SetControlVolumeDec(const long value)                       { this.SetControlledValueDEC(SYMBOL_PROP_VOLUME,(long)::fabs(value));               }
   void              SetControlVolumeLevel(const long value)                     { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME,(long)::fabs(value));             }
   long              GetValueChangedVolume(void)                           const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUME);                          }
   bool              IsIncreasedVolume(void)                               const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUME);                         }
   bool              IsDecreasedVolume(void)                               const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUME);                         }
   //--- Максимальный Volume за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального объема за день
   //--- получение (4) величины изменения максимального объема за день,
   //--- получение флага изменения максимального объема за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeHighInc(const long value)                   { this.SetControlledValueINC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value));           }
   void              SetControlVolumeHighDec(const long value)                   { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value));           }
   void              SetControlVolumeHighLevel(const long value)                 { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value));         }
   long              GetValueChangedVolumeHigh(void)                       const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUMEHIGH);                      }
   bool              IsIncreasedVolumeHigh(void)                           const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUMEHIGH);                     }
   bool              IsDecreasedVolumeHigh(void)                           const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUMEHIGH);                     }
   //--- Минимальный Volume за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального объема за день
   //--- получение (4) величины изменения минимального объема за день,
   //--- получение флага изменения минимального объема за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeLowInc(const long value)                    { this.SetControlledValueINC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value));            }
   void              SetControlVolumeLowDec(const long value)                    { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value));            }
   void              SetControlVolumeLowLevel(const long value)                  { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value));          }
   long              GetValueChangedVolumeLow(void)                        const { return this.GetPropLongChangedValue(SYMBOL_PROP_VOLUMELOW);                       }
   bool              IsIncreasedVolumeLow(void)                            const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_VOLUMELOW);                      }
   bool              IsDecreasedVolumeLow(void)                            const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_VOLUMELOW);                      }
   //--- Спред
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня спреда в пунктах
   //--- получение (4) величины изменения спреда в пунктах,
   //--- получение флага изменения спреда в пунктах больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSpreadInc(const int value)                        { this.SetControlledValueINC(SYMBOL_PROP_SPREAD,(long)::fabs(value));               }
   void              SetControlSpreadDec(const int value)                        { this.SetControlledValueDEC(SYMBOL_PROP_SPREAD,(long)::fabs(value));               }
   void              SetControlSpreadLevel(const int value)                      { this.SetControlledValueLEVEL(SYMBOL_PROP_SPREAD,(long)::fabs(value));             }
   int               GetValueChangedSpread(void)                           const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_SPREAD);                     }
   bool              IsIncreasedSpread(void)                               const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_SPREAD);                         }
   bool              IsDecreasedSpread(void)                               const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_SPREAD);                         }
   //--- StopLevel
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня StopLevel в пунктах
   //--- получение (4) величины изменения StopLevel в пунктах,
   //--- получение флага изменения StopLevel в пунктах больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlStopLevelInc(const int value)                     { this.SetControlledValueINC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value));    }
   void              SetControlStopLevelDec(const int value)                     { this.SetControlledValueDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value));    }
   void              SetControlStopLevelLevel(const int value)                   { this.SetControlledValueLEVEL(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value));  }
   int               GetValueChangedStopLevel(void)                        const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_TRADE_STOPS_LEVEL);          }
   bool              IsIncreasedStopLevel(void)                            const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_TRADE_STOPS_LEVEL);              }
   bool              IsDecreasedStopLevel(void)                            const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL);              }
   //--- Дистанция заморозки
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня FreezeLevel в пунктах
   //--- получение (4) величины изменения FreezeLevel в пунктах,
   //--- получение флага изменения FreezeLevel в пунктах больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlFreezeLevelInc(const int value)                   { this.SetControlledValueINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value));   }
   void              SetControlFreezeLevelDec(const int value)                   { this.SetControlledValueDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value));   }
   void              SetControlFreezeLevelLevel(const int value)                 { this.SetControlledValueLEVEL(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); }
   int               GetValueChangedFreezeLevel(void)                      const { return (int)this.GetPropLongChangedValue(SYMBOL_PROP_TRADE_FREEZE_LEVEL);         }
   bool              IsIncreasedFreezeLevel(void)                          const { return (bool)this.GetPropLongFlagINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL);             }
   bool              IsDecreasedFreezeLevel(void)                          const { return (bool)this.GetPropLongFlagDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL);             }
   
   //--- Bid
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Bid
   //--- получение (4) величины изменения цены Bid или Last,
   //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidInc(const double value)                        { this.SetControlledValueINC(SYMBOL_PROP_BID,::fabs(value));                        }
   void              SetControlBidDec(const double value)                        { this.SetControlledValueDEC(SYMBOL_PROP_BID,::fabs(value));                        }
   void              SetControlBidLevel(const double value)                      { this.SetControlledValueLEVEL(SYMBOL_PROP_BID,::fabs(value));                      }
   double            GetValueChangedBid(void)                              const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BID);                           }
   bool              IsIncreasedBid(void)                                  const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BID);                          }
   bool              IsDecreasedBid(void)                                  const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BID);                          }
   //--- Максимальный Bid за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Bid
   //--- получение (4) величины изменения максимального Bid или Last,
   //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidHighInc(const double value)                    { this.SetControlledValueINC(SYMBOL_PROP_BIDHIGH,::fabs(value));                    }
   void              SetControlBidHighDec(const double value)                    { this.SetControlledValueDEC(SYMBOL_PROP_BIDHIGH,::fabs(value));                    }
   void              SetControlBidHighLevel(const double value)                  { this.SetControlledValueLEVEL(SYMBOL_PROP_BIDHIGH,::fabs(value));                  }
   double            GetValueChangedBidHigh(void)                          const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDHIGH);                       }
   bool              IsIncreasedBidHigh(void)                              const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDHIGH);                      }
   bool              IsDecreasedBidHigh(void)                              const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDHIGH);                      }
   //--- Минимальный Bid за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Bid
   //--- получение (4) величины изменения минимального Bid или Last,
   //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidLowInc(const double value)                     { this.SetControlledValueINC(SYMBOL_PROP_BIDLOW,::fabs(value));                     }
   void              SetControlBidLowDec(const double value)                     { this.SetControlledValueDEC(SYMBOL_PROP_BIDLOW,::fabs(value));                     }
   void              SetControlBidLowLevel(const double value)                   { this.SetControlledValueLEVEL(SYMBOL_PROP_BIDLOW,::fabs(value));                   }
   double            GetValueChangedBidLow(void)                           const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDLOW);                        }
   bool              IsIncreasedBidLow(void)                               const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDLOW);                       }
   bool              IsDecreasedBidLow(void)                               const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDLOW);                       }
   
   //--- Last
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Last
   //--- получение (4) величины изменения цены Bid или Last,
   //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlLastInc(const double value)                       { this.SetControlledValueINC(SYMBOL_PROP_LAST,::fabs(value));                       }
   void              SetControlLastDec(const double value)                       { this.SetControlledValueDEC(SYMBOL_PROP_LAST,::fabs(value));                       }
   void              SetControlLastLevel(const double value)                     { this.SetControlledValueLEVEL(SYMBOL_PROP_LAST,::fabs(value));                     }
   double            GetValueChangedLast(void)                             const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LAST);                          }
   bool              IsIncreasedLast(void)                                 const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LAST);                         }
   bool              IsDecreasedLast(void)                                 const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LAST);                         }
   //--- Максимальный Last за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Last
   //--- получение (4) величины изменения максимального Bid или Last,
   //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlLastHighInc(const double value)                   { this.SetControlledValueINC(SYMBOL_PROP_LASTHIGH,::fabs(value));                   }
   void              SetControlLastHighDec(const double value)                   { this.SetControlledValueDEC(SYMBOL_PROP_LASTHIGH,::fabs(value));                   }
   void              SetControlLastHighLevel(const double value)                 { this.SetControlledValueLEVEL(SYMBOL_PROP_LASTHIGH,::fabs(value));                 }
   double            GetValueChangedLastHigh(void)                         const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTHIGH);                      }
   bool              IsIncreasedLastHigh(void)                             const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTHIGH);                     }
   bool              IsDecreasedLastHigh(void)                             const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTHIGH);                     }
   //--- Минимальный Last за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Last
   //--- получение (4) величины изменения минимального Bid или Last,
   //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlLastLowInc(const double value)                    { this.SetControlledValueINC(SYMBOL_PROP_LASTLOW,::fabs(value));                    }
   void              SetControlLastLowDec(const double value)                    { this.SetControlledValueDEC(SYMBOL_PROP_LASTLOW,::fabs(value));                    }
   void              SetControlLastLowLevel(const double value)                  { this.SetControlledValueLEVEL(SYMBOL_PROP_LASTLOW,::fabs(value));                  }
   double            GetValueChangedLastLow(void)                          const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTLOW);                       }
   bool              IsIncreasedLastLow(void)                              const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTLOW);                      }
   bool              IsDecreasedLastLow(void)                              const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTLOW);                      }
   
   //--- Bid/Last
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Bid или Last
   //--- получение (4) величины изменения цены Bid или Last,
   //--- получение флага изменения цены Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidLastInc(const double value);
   void              SetControlBidLastDec(const double value);
   void              SetControlBidLastLevel(const double value);
   double            GetValueChangedBidLast(void)                          const;
   bool              IsIncreasedBidLast(void)                              const;
   bool              IsDecreasedBidLast(void)                              const;
   //--- Максимальный Bid/Last за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Bid или Last
   //--- получение (4) величины изменения максимального Bid или Last,
   //--- получение флага изменения максимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidLastHighInc(const double value);
   void              SetControlBidLastHighDec(const double value);
   void              SetControlBidLastHighLevel(const double value);
   double            GetValueChangedBidLastHigh(void)                      const;
   bool              IsIncreasedBidLastHigh(void)                          const;
   bool              IsDecreasedBidLastHigh(void)                          const;
   //--- Минимальный Bid/Last за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Bid или Last
   //--- получение (4) величины изменения минимального Bid или Last,
   //--- получение флага изменения минимального Bid или Last больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlBidLastLowInc(const double value);
   void              SetControlBidLastLowDec(const double value);
   void              SetControlBidLastLowLevev(const double value);
   double            GetValueChangedBidLastLow(void)                       const;
   bool              IsIncreasedBidLastLow(void)                           const;
   bool              IsDecreasedBidLastLow(void)                           const;
   
   //--- Ask
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены Ask
   //--- получение (4) величины изменения цены Ask,
   //--- получение флага изменения цены Ask больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlAskInc(const double value)                        { this.SetControlledValueINC(SYMBOL_PROP_ASK,::fabs(value));                        }
   void              SetControlAskDec(const double value)                        { this.SetControlledValueDEC(SYMBOL_PROP_ASK,::fabs(value));                        }
   void              SetControlAskLevel(const double value)                      { this.SetControlledValueLEVEL(SYMBOL_PROP_ASK,::fabs(value));                      }
   double            GetValueChangedAsk(void)                              const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASK);                           }
   bool              IsIncreasedAsk(void)                                  const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASK);                          }
   bool              IsDecreasedAsk(void)                                  const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASK);                          }
   //--- Максимальный Ask за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального Ask за день
   //--- получение (4) величины изменения максимального Ask за день,
   //--- получение флага изменения максимального Ask за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlAskHighInc(const double value)                    { this.SetControlledValueINC(SYMBOL_PROP_ASKHIGH,::fabs(value));                    }
   void              SetControlAskHighDec(const double value)                    { this.SetControlledValueDEC(SYMBOL_PROP_ASKHIGH,::fabs(value));                    }
   void              SetControlAskHighLevel(const double value)                  { this.SetControlledValueLEVEL(SYMBOL_PROP_ASKHIGH,::fabs(value));                  }
   double            GetValueChangedAskHigh(void)                          const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASKHIGH);                       }
   bool              IsIncreasedAskHigh(void)                              const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASKHIGH);                      }
   bool              IsDecreasedAskHigh(void)                              const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASKHIGH);                      }
   //--- Минимальный Ask за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального Ask за день
   //--- получение (4) величины изменения минимального Ask за день,
   //--- получение флага изменения минимального Ask за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlAskLowInc(const double value)                     { this.SetControlledValueINC(SYMBOL_PROP_ASKLOW,::fabs(value));                     }
   void              SetControlAskLowDec(const double value)                     { this.SetControlledValueDEC(SYMBOL_PROP_ASKLOW,::fabs(value));                     }
   void              SetControlAskLowLevel(const double value)                   { this.SetControlledValueLEVEL(SYMBOL_PROP_ASKLOW,::fabs(value));                   }
   double            GetValueChangedAskLow(void)                           const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_ASKLOW);                        }
   bool              IsIncreasedAskLow(void)                               const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_ASKLOW);                       }
   bool              IsDecreasedAskLow(void)                               const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_ASKLOW);                       }
   //--- Реальный Volume за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня реального Volume за день
   //--- получение (4) величины изменения реального Volume за день,
   //--- получение флага изменения реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeRealInc(const double value)                 { this.SetControlledValueINC(SYMBOL_PROP_VOLUME_REAL,::fabs(value));                }
   void              SetControlVolumeRealDec(const double value)                 { this.SetControlledValueDEC(SYMBOL_PROP_VOLUME_REAL,::fabs(value));                }
   void              SetControlVolumeRealLevel(const double value)               { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME_REAL,::fabs(value));              }
   double            GetValueChangedVolumeReal(void)                       const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUME_REAL);                   }
   bool              IsIncreasedVolumeReal(void)                           const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUME_REAL);                  }
   bool              IsDecreasedVolumeReal(void)                           const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUME_REAL);                  }
   //--- Максимальный реальный Volume за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня максимального реального Volume за день
   //--- получение (4) величины изменения максимального реального Volume за день,
   //--- получение флага изменения максимального реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeHighRealInc(const double value)             { this.SetControlledValueINC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value));            }
   void              SetControlVolumeHighRealDec(const double value)             { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value));            }
   void              SetControlVolumeHighRealLevel(const double value)           { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value));          }
   double            GetValueChangedVolumeHighReal(void)                   const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUMEHIGH_REAL);               }
   bool              IsIncreasedVolumeHighReal(void)                       const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUMEHIGH_REAL);              }
   bool              IsDecreasedVolumeHighReal(void)                       const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUMEHIGH_REAL);              }
   //--- Минимальный реальный Volume за день
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня минимального реального Volume за день
   //--- получение (4) величины изменения минимального реального Volume за день,
   //--- получение флага изменения минимального реального Volume за день больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlVolumeLowRealInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value));             }
   void              SetControlVolumeLowRealDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value));             }
   void              SetControlVolumeLowRealLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value));           }
   double            GetValueChangedVolumeLowReal(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUMELOW_REAL);                }
   bool              IsIncreasedVolumeLowReal(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUMELOW_REAL);               }
   bool              IsDecreasedVolumeLowReal(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUMELOW_REAL);               }
   //--- Цена исполнения опциона
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены исполнения опциона
   //--- получение (4) величины изменения цены исполнения опциона,
   //--- получение флага изменения цены исполнения опциона больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlOptionStrikeInc(const double value)               { this.SetControlledValueINC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value));              }
   void              SetControlOptionStrikeDec(const double value)               { this.SetControlledValueDEC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value));              }
   void              SetControlOptionStrikeLevel(const double value)             { this.SetControlledValueLEVEL(SYMBOL_PROP_OPTION_STRIKE,::fabs(value));            }
   double            GetValueChangedOptionStrike(void)                     const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_OPTION_STRIKE);                 } 
   bool              IsIncreasedOptionStrike(void)                         const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_OPTION_STRIKE);                }
   bool              IsDecreasedOptionStrike(void)                         const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_OPTION_STRIKE);                }
   //--- Максимально-допустимый совокупный объём позиций и ордеров в одном направлении
   //--- (1) Установка контрольного уровня
   //--- (2) получение величины изменения максимально-допустимого совокупного объёма позиций и ордеров в одном направлении,
   //--- получение флага (3) увеличения, (4) уменьшения максимально-допустимого совокупного объёма позиций и ордеров в одном направлении
   void              SetControlVolumeLimitLevel(const double value)              { this.SetControlledValueLEVEL(SYMBOL_PROP_VOLUME_LIMIT,::fabs(value));             }
   double            GetValueChangedVolumeLimit(void)                      const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_VOLUME_LIMIT);                  }
   bool              IsIncreasedVolumeLimit(void)                          const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_VOLUME_LIMIT);                 }
   bool              IsDecreasedVolumeLimit(void)                          const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_VOLUME_LIMIT);                 }
   //---  Своп на покупку
   //--- (1) Установка контрольного уровня
   //--- (2) получение величины изменения свопа на покупку,
   //--- получение флага (3) увеличения, (4) уменьшения свопа на покупку
   void              SetControlSwapLongLevel(const double value)                 { this.SetControlledValueLEVEL(SYMBOL_PROP_SWAP_LONG,::fabs(value));                }
   double            GetValueChangedSwapLong(void)                         const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SWAP_LONG);                     }
   bool              IsIncreasedSwapLong(void)                             const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SWAP_LONG);                    }
   bool              IsDecreasedSwapLong(void)                             const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SWAP_LONG);                    }
   //---  Своп на продажу
   //--- (1) Установка контрольного уровня
   //--- (2) получение величины изменения свопа на продажу,
   //--- получение флага (3) увеличения, (4) уменьшения свопа на продажу
   void              SetControlSwapShortLevel(const double value)                { this.SetControlledValueLEVEL(SYMBOL_PROP_SWAP_SHORT,::fabs(value));               }
   double            GetValueChangedSwapShort(void)                        const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SWAP_SHORT);                    }
   bool              IsIncreasedSwapShort(void)                            const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SWAP_SHORT);                   }
   bool              IsDecreasedSwapShort(void)                            const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SWAP_SHORT);                   }
   //--- Cуммарный объём сделок в текущую сессию
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного объёма сделок в текущую сессию
   //--- получение (4) величины изменения суммарного объёма сделок в текущую сессию,
   //--- получение флага изменения суммарного объёма сделок в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionVolumeInc(const double value)              { this.SetControlledValueINC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value));             }
   void              SetControlSessionVolumeDec(const double value)              { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value));             }
   void              SetControlSessionVolumeLevel(const double value)            { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_VOLUME,::fabs(value));           }
   double            GetValueChangedSessionVolume(void)                    const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_VOLUME);                }
   bool              IsIncreasedSessionVolume(void)                        const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_VOLUME);               }
   bool              IsDecreasedSessionVolume(void)                        const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_VOLUME);               }
   //--- Cуммарный оборот в текущую сессию
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного оборота в текущую сессию
   //--- получение (4) величины изменения суммарного оборота в текущую сессию,
   //--- получение флага изменения суммарного оборота в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionTurnoverInc(const double value)            { this.SetControlledValueINC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value));           }
   void              SetControlSessionTurnoverDec(const double value)            { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value));           }
   void              SetControlSessionTurnoverLevel(const double value)          { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value));         }
   double            GetValueChangedSessionTurnover(void)                  const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_TURNOVER);              }
   bool              IsIncreasedSessionTurnover(void)                      const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_TURNOVER);             }
   bool              IsDecreasedSessionTurnover(void)                      const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_TURNOVER);             }
   //--- Cуммарный объём открытых позиций
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня суммарного объёма открытых позиций в текущую сессию
   //--- получение (4) величины изменения суммарного объёма открытых позиций в текущую сессию,
   //--- получение флага изменения суммарного объёма открытых позиций в текущую сессию больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionInterestInc(const double value)            { this.SetControlledValueINC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value));           }
   void              SetControlSessionInterestDec(const double value)            { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value));           }
   void              SetControlSessionInterestLevel(const double value)          { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_INTEREST,::fabs(value));         }
   double            GetValueChangedSessionInterest(void)                  const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_INTEREST);              }
   bool              IsIncreasedSessionInterest(void)                      const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_INTEREST);             }
   bool              IsDecreasedSessionInterest(void)                      const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_INTEREST);             }
   //--- Общий объём ордеров на покупку в текущий момент
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня общего объёма ордеров на покупку в текущий момент
   //--- получение (4) величины изменения общего объёма ордеров на покупку в текущий момент,
   //--- получение флага изменения общего объёма ордеров на покупку в текущий момент больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionBuyOrdVolumeInc(const double value)        { this.SetControlledValueINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value));  }
   void              SetControlSessionBuyOrdVolumeDec(const double value)        { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value));  }
   void              SetControlSessionBuyOrdVolumeLevel(const double value)      { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value));}
   double            GetValueChangedSessionBuyOrdVolume(void)              const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME);     }
   bool              IsIncreasedSessionBuyOrdVolume(void)                  const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME);    }
   bool              IsDecreasedSessionBuyOrdVolume(void)                  const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME);    }
   //--- Общий объём ордеров на продажу в текущий момент
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня общего объёма ордеров на продажу в текущий момент
   //--- получение (4) величины изменения общего объёма ордеров на продажу в текущий момент,
   //--- получение флага изменения общего объёма ордеров на продажу в текущий момент больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionSellOrdVolumeInc(const double value)       { this.SetControlledValueINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); }
   void              SetControlSessionSellOrdVolumeDec(const double value)       { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); }
   void              SetControlSessionSellOrdVolumeLevel(const double value)     { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value));}
   double            GetValueChangedSessionSellOrdVolume(void)             const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME);    }
   bool              IsIncreasedSessionSellOrdVolume(void)                 const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME);   }
   bool              IsDecreasedSessionSellOrdVolume(void)                 const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME);   }
   //--- Цена открытия сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены открытия сессии
   //--- получение (4) величины изменения цены открытия сессии,
   //--- получение флага изменения цены открытия сессии больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionPriceOpenInc(const double value)           { this.SetControlledValueINC(SYMBOL_PROP_SESSION_OPEN,::fabs(value));               }
   void              SetControlSessionPriceOpenDec(const double value)           { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_OPEN,::fabs(value));               }
   void              SetControlSessionPriceOpenLevel(const double value)         { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_OPEN,::fabs(value));             }
   double            GetValueChangedSessionPriceOpen(void)                 const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_OPEN);                  }
   bool              IsIncreasedSessionPriceOpen(void)                     const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_OPEN);                 }
   bool              IsDecreasedSessionPriceOpen(void)                     const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_OPEN);                 }
   //--- Цена закрытия сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня цены закрытия сессии
   //--- получение (4) величины изменения цены закрытия сессии,
   //--- получение флага изменения цены закрытия сессии больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionPriceCloseInc(const double value)          { this.SetControlledValueINC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value));              }
   void              SetControlSessionPriceCloseDec(const double value)          { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value));              }
   void              SetControlSessionPriceCloseLevel(const double value)        { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_CLOSE,::fabs(value));            }
   double            GetValueChangedSessionPriceClose(void)                const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_CLOSE);                 }
   bool              IsIncreasedSessionPriceClose(void)                    const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_CLOSE);                }
   bool              IsDecreasedSessionPriceClose(void)                    const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_CLOSE);                }
   //--- Средневзвешенная цена сессии
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня средневзвешенной цены сессии
   //--- получение (4) величины изменения средневзвешенной цены сессии,
   //--- получение флага изменения средневзвешенной цены сессии больше, чем на величину (5) прироста, (6) уменьшения
   void              SetControlSessionPriceAWInc(const double value)             { this.SetControlledValueINC(SYMBOL_PROP_SESSION_AW,::fabs(value));                 }
   void              SetControlSessionPriceAWDec(const double value)             { this.SetControlledValueDEC(SYMBOL_PROP_SESSION_AW,::fabs(value));                 }
   void              SetControlSessionPriceAWLevel(const double value)           { this.SetControlledValueLEVEL(SYMBOL_PROP_SESSION_AW,::fabs(value));               }
   double            GetValueChangedSessionPriceAW(void)                   const { return this.GetPropDoubleChangedValue(SYMBOL_PROP_SESSION_AW);                    }
   bool              IsIncreasedSessionPriceAW(void)                       const { return (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_SESSION_AW);                   }
   bool              IsDecreasedSessionPriceAW(void)                       const { return (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_SESSION_AW);                   }
//---

И методы, реализация которых выполнена за пределами тела класса, так же теперь используют напрямую методы базового класса:

//+------------------------------------------------------------------+
//| Устанавливает контролируемую величину прироста цены Bid или Last |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastInc(const double value)
  {
   this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value));
  }
//+------------------------------------------------------------------+
//|Устанавливает контролируемую величину уменьшения цены Bid или Last|
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastDec(const double value)
  {
   this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Устанавливает контрольный уровень цены Bid или Last              |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastLevel(const double value)
  {
   this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Возвращает величину изменения цены Bid или Last                  |
//+------------------------------------------------------------------+
double CSymbol::GetValueChangedBidLast(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BID) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LAST));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения цены Bid или Last больше,              |
//| чем на величину прироста                                         |
//+------------------------------------------------------------------+
bool CSymbol::IsIncreasedBidLast(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BID) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LAST));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения цены Bid или Last больше,              |
//| чем на величину уменьшения                                       |
//+------------------------------------------------------------------+
bool CSymbol::IsDecreasedBidLast(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BID) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LAST));
  }
//+------------------------------------------------------------------+
//| Устанавливает контролируемую величину прироста                   |
//| максимальной цены Bid или Last                                   |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastHighInc(const double value)
  {
   this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Устанавливает контролируемую величину уменьшения                 |
//| максимальной цены Bid или Last                                   |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastHighDec(const double value)
  {
   this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Устанавливает контрольный уровень максимальной цены Bid или Last |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastHighLevel(const double value)
  {
   this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Возвращает величину изменения максимальной цены Bid или Last     |
//+------------------------------------------------------------------+
double CSymbol::GetValueChangedBidLastHigh(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDHIGH) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTHIGH));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения максимальной цены                      |
//| Bid или Last больше, чем на величину прироста                    |
//+------------------------------------------------------------------+
bool CSymbol::IsIncreasedBidLastHigh(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTHIGH));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения максимальной цены                      |
//| Bid или Last больше, чем на величину уменьшения                  |
//+------------------------------------------------------------------+
bool CSymbol::IsDecreasedBidLastHigh(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTHIGH));
  }
//+------------------------------------------------------------------+
//| Устанавливает контролируемую величину прироста                   |
//| минимальной цены Bid или Last                                    |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastLowInc(const double value)
  {
   this.SetControlledValueINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Устанавливает контролируемую величину уменьшения                 |
//| минимальной цены Bid или Last                                    |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastLowDec(const double value)
  {
   this.SetControlledValueDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Устанавливает контрольный уровень минимальной цены Bid или Last  |
//+------------------------------------------------------------------+
void CSymbol::SetControlBidLastLowLevev(const double value)
  {
   this.SetControlledValueLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value));
  }
//+------------------------------------------------------------------+
//| Возвращает величину изменения минимальной цены Bid или Last      |
//+------------------------------------------------------------------+
double CSymbol::GetValueChangedBidLastLow(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetPropDoubleChangedValue(SYMBOL_PROP_BIDLOW) : this.GetPropDoubleChangedValue(SYMBOL_PROP_LASTLOW));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения минимальной цены                       |
//| Bid или Last больше, чем на величину прироста                    |
//+------------------------------------------------------------------+
bool CSymbol::IsIncreasedBidLastLow(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_BIDLOW) : (bool)this.GetPropDoubleFlagINC(SYMBOL_PROP_LASTLOW));
  }
//+------------------------------------------------------------------+
//| Возвращает флаг изменения минимальной цены                       |
//| Bid или Last больше, чем на величину уменьшения                  |
//+------------------------------------------------------------------+
bool CSymbol::IsDecreasedBidLastLow(void) const
  {
   return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_BIDLOW) : (bool)this.GetPropDoubleFlagDEC(SYMBOL_PROP_LASTLOW));
  }
//+------------------------------------------------------------------+

Также, в конструкторе класса мною была допущена логическая ошибка — данные базового объекта не заполнялись сразу после создания объекта-символа, что приводило к тому, что при первом запуске события не отслеживались до тех пор, пока не произойдёт какое-либо событие изменения значения свойства символа, величина изменения которого между двумя соседними тиками была незначительна, и после этого данные базового объекта заполнялись.

Исправим эту ошибку — впишем сразу же после заполнения свойств объекта-символа заполнение свойств его базового объекта:

//+------------------------------------------------------------------+
//| Закрытый параметрический конструктор                             |
//+------------------------------------------------------------------+
CSymbol::CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name,const int index)
  {
   this.m_name=name;
   this.m_type=COLLECTION_SYMBOLS_ID;
   if(!this.Exist())
     {
      ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\"",": ",TextByLanguage("Ошибка. Такого символа нет на сервере","Error. There is no such symbol on the server"));
      this.m_global_error=ERR_MARKET_UNKNOWN_SYMBOL;
     }
   bool select=::SymbolInfoInteger(this.m_name,SYMBOL_SELECT);
   ::ResetLastError();
   if(!select)
     {
      if(!this.SetToMarketWatch())
        {
         this.m_global_error=::GetLastError();
         ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось поместить в обзор рынка. Ошибка: ","Failed to put in the market watch. Error: "),this.m_global_error);
        }
     }
   ::ResetLastError();
   if(!::SymbolInfoTick(this.m_name,this.m_tick))
     {
      this.m_global_error=::GetLastError();
      ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error);
     }
//--- Инициализация массивов данных базового объекта
   this.SetControlDataArraySizeLong(SYMBOL_PROP_INTEGER_TOTAL);
   this.SetControlDataArraySizeDouble(SYMBOL_PROP_DOUBLE_TOTAL);
   this.ResetChangesParams();
   this.ResetControlsParams();
   
//--- Инициализация данных символа
   this.Reset();
   this.InitMarginRates();
#ifdef __MQL5__
   ::ResetLastError();
   if(!this.MarginRates())
     {
      this.m_global_error=::GetLastError();
      ::Print(DFUN_ERR_LINE,this.Name(),": ",TextByLanguage("Не удалось получить коэффициенты взимания маржи. Ошибка: ","Failed to get margin rates. Error: "),this.m_global_error);
      return;
     }
#endif 
   
//--- Сохранение целочисленных свойств
   this.m_long_prop[SYMBOL_PROP_STATUS]                                             = symbol_status;
   this.m_long_prop[SYMBOL_PROP_INDEX_MW]                                           = index;
   this.m_long_prop[SYMBOL_PROP_VOLUME]                                             = (long)this.m_tick.volume;
   this.m_long_prop[SYMBOL_PROP_SELECT]                                             = ::SymbolInfoInteger(this.m_name,SYMBOL_SELECT);
   this.m_long_prop[SYMBOL_PROP_VISIBLE]                                            = ::SymbolInfoInteger(this.m_name,SYMBOL_VISIBLE);
   this.m_long_prop[SYMBOL_PROP_SESSION_DEALS]                                      = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_DEALS);
   this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS]                                 = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_BUY_ORDERS);
   this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS]                                = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_SELL_ORDERS);
   this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH]                                         = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMEHIGH);
   this.m_long_prop[SYMBOL_PROP_VOLUMELOW]                                          = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMELOW);
   this.m_long_prop[SYMBOL_PROP_DIGITS]                                             = ::SymbolInfoInteger(this.m_name,SYMBOL_DIGITS);
   this.m_long_prop[SYMBOL_PROP_SPREAD]                                             = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD);
   this.m_long_prop[SYMBOL_PROP_SPREAD_FLOAT]                                       = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD_FLOAT);
   this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH]                                    = ::SymbolInfoInteger(this.m_name,SYMBOL_TICKS_BOOKDEPTH);
   this.m_long_prop[SYMBOL_PROP_TRADE_MODE]                                         = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_MODE);
   this.m_long_prop[SYMBOL_PROP_START_TIME]                                         = ::SymbolInfoInteger(this.m_name,SYMBOL_START_TIME);
   this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME]                                    = ::SymbolInfoInteger(this.m_name,SYMBOL_EXPIRATION_TIME);
   this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL]                                  = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_STOPS_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL]                                 = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_FREEZE_LEVEL);
   this.m_long_prop[SYMBOL_PROP_TRADE_EXEMODE]                                      = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_EXEMODE);
   this.m_long_prop[SYMBOL_PROP_SWAP_ROLLOVER3DAYS]                                 = ::SymbolInfoInteger(this.m_name,SYMBOL_SWAP_ROLLOVER3DAYS);
   this.m_long_prop[SYMBOL_PROP_TIME]                                               = this.TickTime();
   this.m_long_prop[SYMBOL_PROP_EXIST]                                              = this.SymbolExists();
   this.m_long_prop[SYMBOL_PROP_CUSTOM]                                             = this.SymbolCustom();
   this.m_long_prop[SYMBOL_PROP_MARGIN_HEDGED_USE_LEG]                              = this.SymbolMarginHedgedUseLEG();
   this.m_long_prop[SYMBOL_PROP_ORDER_MODE]                                         = this.SymbolOrderMode();
   this.m_long_prop[SYMBOL_PROP_FILLING_MODE]                                       = this.SymbolOrderFillingMode();
   this.m_long_prop[SYMBOL_PROP_EXPIRATION_MODE]                                    = this.SymbolExpirationMode();
   this.m_long_prop[SYMBOL_PROP_ORDER_GTC_MODE]                                     = this.SymbolOrderGTCMode();
   this.m_long_prop[SYMBOL_PROP_OPTION_MODE]                                        = this.SymbolOptionMode();
   this.m_long_prop[SYMBOL_PROP_OPTION_RIGHT]                                       = this.SymbolOptionRight();
   this.m_long_prop[SYMBOL_PROP_BACKGROUND_COLOR]                                   = this.SymbolBackgroundColor();
   this.m_long_prop[SYMBOL_PROP_CHART_MODE]                                         = this.SymbolChartMode();
   this.m_long_prop[SYMBOL_PROP_TRADE_CALC_MODE]                                    = this.SymbolCalcMode();
   this.m_long_prop[SYMBOL_PROP_SWAP_MODE]                                          = this.SymbolSwapMode();
//--- Сохранение вещественных свойств
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)]                          = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)]                           = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)]                         = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTHIGH);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)]                          = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTLOW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_POINT)]                            = ::SymbolInfoDouble(this.m_name,SYMBOL_POINT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)]                 = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)]          = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_PROFIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)]            = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_LOSS);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)]                  = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)]              = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_CONTRACT_SIZE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)]                       = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)]                       = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)]                      = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_STEP);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)]                     = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_LIMIT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)]                        = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_LONG);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)]                       = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_SHORT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)]                   = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)]               = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)]                   = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)]                 = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_TURNOVER);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)]                 = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_INTEREST);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)]        = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)]       = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)]                     = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_OPEN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)]                    = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_CLOSE);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)]                       = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_AW);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)]         = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_SETTLEMENT);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)]          = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MIN);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)]          = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MAX);
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)]                              = this.m_tick.bid;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)]                              = this.m_tick.ask;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_LAST)]                             = this.m_tick.last;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDHIGH)]                          = this.SymbolBidHigh();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDLOW)]                           = this.SymbolBidLow();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_REAL)]                      = this.SymbolVolumeReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMEHIGH_REAL)]                  = this.SymbolVolumeHighReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMELOW_REAL)]                   = this.SymbolVolumeLowReal();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_OPTION_STRIKE)]                    = this.SymbolOptionStrike();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_ACCRUED_INTEREST)]           = this.SymbolTradeAccruedInterest();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_FACE_VALUE)]                 = this.SymbolTradeFaceValue();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_LIQUIDITY_RATE)]             = this.SymbolTradeLiquidityRate();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_HEDGED)]                    = this.SymbolMarginHedged();
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_INITIAL)]              = this.m_margin_rate.Long.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL)]          = this.m_margin_rate.BuyStop.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL)]         = this.m_margin_rate.BuyLimit.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL)]     = this.m_margin_rate.BuyStopLimit.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE)]          = this.m_margin_rate.Long.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE)]      = this.m_margin_rate.BuyStop.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE)]     = this.m_margin_rate.BuyLimit.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE)] = this.m_margin_rate.BuyStopLimit.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_INITIAL)]             = this.m_margin_rate.Short.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL)]         = this.m_margin_rate.SellStop.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL)]        = this.m_margin_rate.SellLimit.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL)]    = this.m_margin_rate.SellStopLimit.Initial;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE)]         = this.m_margin_rate.Short.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE)]     = this.m_margin_rate.SellStop.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE)]    = this.m_margin_rate.SellLimit.Maintenance;
   this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE)]= this.m_margin_rate.SellStopLimit.Maintenance;
//--- Сохранение строковых свойств
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_NAME)]                             = this.m_name;
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_BASE)]                    = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_BASE);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_PROFIT)]                  = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_PROFIT);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_MARGIN)]                  = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_MARGIN);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_DESCRIPTION)]                      = ::SymbolInfoString(this.m_name,SYMBOL_DESCRIPTION);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_PATH)]                             = ::SymbolInfoString(this.m_name,SYMBOL_PATH);
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_BASIS)]                            = this.SymbolBasis();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_BANK)]                             = this.SymbolBank();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_ISIN)]                             = this.SymbolISIN();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_FORMULA)]                          = this.SymbolFormula();
   this.m_string_prop[this.IndexProp(SYMBOL_PROP_PAGE)]                             = this.SymbolPage();
//--- Сохранение дополнительных целочисленных свойств
   this.m_long_prop[SYMBOL_PROP_DIGITS_LOTS]                                        = this.SymbolDigitsLot();
   
//--- Заполнение текущих данных символа
   for(int i=0;i<SYMBOL_PROP_INTEGER_TOTAL;i++)
      this.m_long_prop_event[i][3]=this.m_long_prop[i];
   for(int i=0;i<SYMBOL_PROP_DOUBLE_TOTAL;i++)
      this.m_double_prop_event[i][3]=this.m_double_prop[i];
   
//--- Обновление данных в базовом объекте и поиск изменений
   CBaseObj::Refresh();
//---
   if(!select)
      this.RemoveFromMarketWatch();
  }
//+------------------------------------------------------------------+

В классе коллекции символов в файле \MQL5\Include\DoEasy\Collections\SymbolsCollection.mqh, в публичной секции класса, так же поменяем название метода обновления символов коллекции и поиска событий SymbolsEventsControl().
Сделаем название метода более подходящим под его задачи — обновление данных и поиск событий:

//--- Работа с событиями (1) списка символов коллекции, (2) окна обзора рынка
   void              RefreshAndEventsControl(void);
   void              MarketWatchEventsControl(const bool send_events=true);

Это все изменения, которые необходимо было сделать в классах базового объекта, его наследника — объекта-символа и классе коллекции символов.

Теперь приступим к доработке классов объекта-аккаунта так, чтобы и он был наследником базового объекта CBaseObj и получил от него событийный функционал для лёгкого управления отслеживанием изменений свойств объекта-аккаунта.

Ставим объект-аккаунт на новые рельсы

По прошлой статье мы помним, что при использовании базового объекта в качестве источника генерации событий мы больше не связаны необходимостью создавать флаги событий, и из комбинаций этих флагов создавать идентификаторы событий. Теперь событийный функционал базового объекта устроен гибче. А значит — нам можно удалить уже ставшие ненужными перечисления из файла Defines.mqh библиотеки:

//+------------------------------------------------------------------+
//| Данные для работы с аккаунтами                                   |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Список флагов событий аккаунта                                   |
//+------------------------------------------------------------------+
enum ENUM_ACCOUNT_EVENT_FLAGS
  {
   ACCOUNT_EVENT_FLAG_NO_EVENT            =  0,             // Нет события
   ACCOUNT_EVENT_FLAG_LEVERAGE            =  1,             // Изменение предоставленного плеча
   ACCOUNT_EVENT_FLAG_LIMIT_ORDERS        =  2,             // Изменение максимально допустимого количества действующих отложенных ордеров
   ACCOUNT_EVENT_FLAG_TRADE_ALLOWED       =  4,             // Изменение разрешения торговли на счёте
   ACCOUNT_EVENT_FLAG_TRADE_EXPERT        =  8,             // Изменение разрешения автоторговли на счёте
   ACCOUNT_EVENT_FLAG_BALANCE             =  16,            // Изменение баланса больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_EQUITY              =  32,            // Изменение собственных средств больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_PROFIT              =  64,            // Изменение профита больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_CREDIT              =  128,           // Изменение размера предоставленного кредита в валюте депозита
   ACCOUNT_EVENT_FLAG_MARGIN              =  256,           // Изменение размера зарезервированных залоговых средств на счете в валюте депозита больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_MARGIN_FREE         =  512,           // Изменение размера средств на счете в валюте депозита, доступных для открытия позиции больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_MARGIN_LEVEL        =  1024,          // Изменение уровня залоговых средств на счете в процентах больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_MARGIN_INITIAL      =  2048,          // Изменение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_MARGIN_MAINTENANCE  =  4096,          // Изменение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_MARGIN_SO_CALL      =  8192,          // Изменение уровня залоговых средств, при котором происходит MarginCall
   ACCOUNT_EVENT_FLAG_MARGIN_SO_SO        =  16384,         // Изменение уровня залоговых средств, при достижении которого происходит StopOut
   ACCOUNT_EVENT_FLAG_ASSETS              =  32768,         // Изменение текущего размера активов на счёте больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_LIABILITIES         =  65536,         // Изменение текущего размера обязательств на счёте больше заданной величины в +/-
   ACCOUNT_EVENT_FLAG_COMISSION_BLOCKED   =  131072,        // Изменение текущей суммы заблокированных комиссий по счёту больше заданной величины в +/-
  };
//+------------------------------------------------------------------+
//| Список возможных событий аккаунта                                |
//+------------------------------------------------------------------+
enum ENUM_ACCOUNT_EVENT
  {
   ACCOUNT_EVENT_NO_EVENT = TRADE_EVENTS_NEXT_CODE,         // Нет события
   ACCOUNT_EVENT_LEVERAGE_INC,                              // Увеличение предоставленного плеча
   ACCOUNT_EVENT_LEVERAGE_DEC,                              // Уменьшение предоставленного плеча
   ACCOUNT_EVENT_LIMIT_ORDERS_INC,                          // Увеличение максимально допустимого количества действующих отложенных ордеров
   ACCOUNT_EVENT_LIMIT_ORDERS_DEC,                          // Уменьшение максимально допустимого количества действующих отложенных ордеров
   ACCOUNT_EVENT_TRADE_ALLOWED_ON,                          // Разрешение торговли на счёте
   ACCOUNT_EVENT_TRADE_ALLOWED_OFF,                         // Запрет торговли на счёте
   ACCOUNT_EVENT_TRADE_EXPERT_ON,                           // Разрешение автоторговли на счёте
   ACCOUNT_EVENT_TRADE_EXPERT_OFF,                          // Запрет автоторговли на счёте
   ACCOUNT_EVENT_BALANCE_INC,                               // Увеличение баланса больше заданной величины
   ACCOUNT_EVENT_BALANCE_DEC,                               // Уменьшение баланса больше заданной величины
   ACCOUNT_EVENT_EQUITY_INC,                                // Увеличение собственных средств больше заданной величины
   ACCOUNT_EVENT_EQUITY_DEC,                                // Уменьшение собственных средств больше заданной величины
   ACCOUNT_EVENT_PROFIT_INC,                                // Увеличение профита больше заданной величины
   ACCOUNT_EVENT_PROFIT_DEC,                                // Уменьшение профита больше заданной величины
   ACCOUNT_EVENT_CREDIT_INC,                                // Увеличение размера предоставленного кредита в валюте депозита
   ACCOUNT_EVENT_CREDIT_DEC,                                // Уменьшение размера предоставленного кредита в валюте депозита
   ACCOUNT_EVENT_MARGIN_INC,                                // Увеличение размера зарезервированных залоговых средств на счете  в валюте депозита
   ACCOUNT_EVENT_MARGIN_DEC,                                // Уменьшение размера зарезервированных залоговых средств на счете  в валюте депозита
   ACCOUNT_EVENT_MARGIN_FREE_INC,                           // Увеличение размера средств на счете в валюте депозита, доступных для открытия позиции
   ACCOUNT_EVENT_MARGIN_FREE_DEC,                           // Уменьшение размера средств на счете в валюте депозита, доступных для открытия позиции
   ACCOUNT_EVENT_MARGIN_LEVEL_INC,                          // Увеличение уровня залоговых средств на счете в процентах
   ACCOUNT_EVENT_MARGIN_LEVEL_DEC,                          // Уменьшение уровня залоговых средств на счете в процентах
   ACCOUNT_EVENT_MARGIN_INITIAL_INC,                        // Увеличение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам
   ACCOUNT_EVENT_MARGIN_INITIAL_DEC,                        // Уменьшение размера средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам
   ACCOUNT_EVENT_MARGIN_MAINTENANCE_INC,                    // Увеличение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям
   ACCOUNT_EVENT_MARGIN_MAINTENANCE_DEC,                    // Уменьшение размера средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям
   ACCOUNT_EVENT_MARGIN_SO_CALL_INC,                        // Увеличение уровня залоговых средств, при котором происходит MarginCall
   ACCOUNT_EVENT_MARGIN_SO_CALL_DEC,                        // Уменьшение уровня залоговых средств, при котором происходит MarginCall
   ACCOUNT_EVENT_MARGIN_SO_SO_INC,                          // Увеличение уровня залоговых средств, при достижении которого происходит StopOut
   ACCOUNT_EVENT_MARGIN_SO_SO_DEC,                          // Уменьшение уровня залоговых средств, при достижении которого происходит StopOut
   ACCOUNT_EVENT_ASSETS_INC,                                // Увеличение текущего размера активов на счёте
   ACCOUNT_EVENT_ASSETS_DEC,                                // Уменьшение текущего размера активов на счёте
   ACCOUNT_EVENT_LIABILITIES_INC,                           // Увеличение текущего размера обязательств на счёте
   ACCOUNT_EVENT_LIABILITIES_DEC,                           // Уменьшение текущего размера обязательств на счёте
   ACCOUNT_EVENT_COMISSION_BLOCKED_INC,                     // Увеличение текущей суммы заблокированных комиссий по счёту
   ACCOUNT_EVENT_COMISSION_BLOCKED_DEC,                     // Уменьшение текущей суммы заблокированных комиссий по счёту
  };

И всё, что останется от данных перечислений, это макроподстановка, указывающая на код следующего события:

//+------------------------------------------------------------------+
//| Данные для работы с аккаунтами                                   |
//+------------------------------------------------------------------+
#define ACCOUNT_EVENTS_NEXT_CODE       (TRADE_EVENTS_NEXT_CODE)   // Код следующего событя после последнего кода события аккаунта
//+------------------------------------------------------------------+
//| Целочисленные свойства аккаунта                                  |
//+------------------------------------------------------------------+

Откроем файл \MQL5\Include\DoEasy\Objects\Accounts\Account.mqh и внесём в него необходимые изменения.

В публичной секции класса объявим виртуальный метод Refresh():

public:
//--- Конструктор
                     CAccount(void);
//--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство аккаунта
   void              SetProperty(ENUM_ACCOUNT_PROP_INTEGER property,long value)        { this.m_long_prop[property]=value;                                  }
   void              SetProperty(ENUM_ACCOUNT_PROP_DOUBLE property,double value)       { this.m_double_prop[this.IndexProp(property)]=value;                }
   void              SetProperty(ENUM_ACCOUNT_PROP_STRING property,string value)       { this.m_string_prop[this.IndexProp(property)]=value;                }
//--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство аккаунта
   long              GetProperty(ENUM_ACCOUNT_PROP_INTEGER property)             const { return this.m_long_prop[property];                                 }
   double            GetProperty(ENUM_ACCOUNT_PROP_DOUBLE property)              const { return this.m_double_prop[this.IndexProp(property)];               }
   string            GetProperty(ENUM_ACCOUNT_PROP_STRING property)              const { return this.m_string_prop[this.IndexProp(property)];               }

//--- Возвращает флаг расчёта уровне MarginCall и StopOut в процентах
   bool              IsPercentsForSOLevels(void)                                 const { return this.MarginSOMode()==ACCOUNT_STOPOUT_MODE_PERCENT;          }
//--- Возвращает флаг поддержания объектом-аккаунтом данного свойства
   virtual bool      SupportProperty(ENUM_ACCOUNT_PROP_INTEGER property)               { return true; }
   virtual bool      SupportProperty(ENUM_ACCOUNT_PROP_DOUBLE property)                { return true; }
   virtual bool      SupportProperty(ENUM_ACCOUNT_PROP_STRING property)                { return true; }

//--- Сравнивает объекты CAccount между собой по всем возможным свойствам (для сортировки списков по указанному свойству объекта-аккаунта)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Сравнивает объекты CAccount между собой по свойствам счёта (для поиска равных объектов-аккаунтов)
   bool              IsEqual(CAccount* compared_account) const;
//--- Обновляет все данные аккаунта
   virtual void      Refresh(void);
//--- (1) Сохраняет объект-аккаунт в файл, (2), загружает объект-аккаунт из файла
   virtual bool      Save(const int file_handle);
   virtual bool      Load(const int file_handle);

Для обновления данных текущего аккаунта будем использовать метод Refresh() точно так же, как и в классе CSymbol, и во всех последующих классах на основе базового объекта CBaseObj). Ранее мы обновляли данные текущего аккаунта из класса коллекции аккаунтов. Но для того чтобы все классы имели одинаковую структуру, сделаем всё так же, как сделали в CSymbol, и будем делать в остальных будущих классах.

Для получения и установки параметров отслеживаемых свойств символа мы в классе CSymbol уже создали методы.
Создадим такие же методы и для класса объекта-аккаунта:

//+------------------------------------------------------------------+
//| Получение и установка параметров отслеживаемых изменений свойств |
//+------------------------------------------------------------------+
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня плеча
   //--- получение (3) величины изменения плеча,
   //--- получение флага изменения плеча больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlLeverageInc(const long value)               { this.SetControlledValueINC(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value));               }
   void              SetControlLeverageDec(const long value)               { this.SetControlledValueDEC(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value));               }
   void              SetControlLeverageLevel(const long value)             { this.SetControlledValueLEVEL(ACCOUNT_PROP_LEVERAGE,(long)::fabs(value));             }
   long              GetValueChangedLeverage(void)                   const { return this.GetPropLongChangedValue(ACCOUNT_PROP_LEVERAGE);                          }
   bool              IsIncreasedLeverage(void)                       const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_LEVERAGE);                         }
   bool              IsDecreasedLeverage(void)                       const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_LEVERAGE);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня количества действующих отложенных ордеров
   //--- получение (3) величины изменения количества действующих отложенных ордеров,
   //--- получение флага изменения количества действующих отложенных ордеров больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlLimitOrdersInc(const long value)            { this.SetControlledValueINC(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value));           }
   void              SetControlLimitOrdersDec(const long value)            { this.SetControlledValueDEC(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value));           }
   void              SetControlLimitOrdersLevel(const long value)          { this.SetControlledValueLEVEL(ACCOUNT_PROP_LIMIT_ORDERS,(long)::fabs(value));         }
   long              GetValueChangedLimitOrders(void)                const { return this.GetPropLongChangedValue(ACCOUNT_PROP_LIMIT_ORDERS);                      }
   bool              IsIncreasedLimitOrders(void)                    const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_LIMIT_ORDERS);                     }
   bool              IsDecreasedLimitOrders(void)                    const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_LIMIT_ORDERS);                     }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня разрешения торговли для текущего счета со стороны сервера
   //--- получение (3) величины изменения разрешения торговли для текущего счета со стороны сервера,
   //--- получение флага изменения разрешения торговли для текущего счета со стороны сервера больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlTradeAllowedInc(const long value)           { this.SetControlledValueINC(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value));          }
   void              SetControlTradeAllowedDec(const long value)           { this.SetControlledValueDEC(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value));          }
   void              SetControlTradeAllowedLevel(const long value)         { this.SetControlledValueLEVEL(ACCOUNT_PROP_TRADE_ALLOWED,(long)::fabs(value));        }
   long              GetValueChangedTradeAllowed(void)               const { return this.GetPropLongChangedValue(ACCOUNT_PROP_TRADE_ALLOWED);                     }
   bool              IsIncreasedTradeAllowed(void)                   const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_TRADE_ALLOWED);                    }
   bool              IsDecreasedTradeAllowed(void)                   const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_TRADE_ALLOWED);                    }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня разрешения торговли для эксперта со стороны сервера
   //--- получение (3) величины изменения разрешения торговли для эксперта со стороны сервера,
   //--- получение флага изменения разрешения торговли для эксперта со стороны сервера больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlTradeExpertInc(const long value)            { this.SetControlledValueINC(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value));           }
   void              SetControlTradeExpertDec(const long value)            { this.SetControlledValueDEC(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value));           }
   void              SetControlTradeExpertLevel(const long value)          { this.SetControlledValueLEVEL(ACCOUNT_PROP_TRADE_EXPERT,(long)::fabs(value));         }
   long              GetValueChangedTradeExpert(void)                const { return this.GetPropLongChangedValue(ACCOUNT_PROP_TRADE_EXPERT);                      }
   bool              IsIncreasedTradeExpert(void)                    const { return (bool)this.GetPropLongFlagINC(ACCOUNT_PROP_TRADE_EXPERT);                     }
   bool              IsDecreasedTradeExpert(void)                    const { return (bool)this.GetPropLongFlagDEC(ACCOUNT_PROP_TRADE_EXPERT);                     }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня баланса
   //--- получение (3) величины изменения баланса,
   //--- получение флага изменения баланса больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlBalanceInc(const long value)                { this.SetControlledValueINC(ACCOUNT_PROP_BALANCE,(double)::fabs(value));              }
   void              SetControlBalanceDec(const long value)                { this.SetControlledValueDEC(ACCOUNT_PROP_BALANCE,(double)::fabs(value));              }
   void              SetControlBalanceLevel(const long value)              { this.SetControlledValueLEVEL(ACCOUNT_PROP_BALANCE,(double)::fabs(value));            }
   double            GetValueChangedBalance(void)                    const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_BALANCE);                         }
   bool              IsIncreasedBalance(void)                        const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_BALANCE);                        }
   bool              IsDecreasedBalance(void)                        const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_BALANCE);                        }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня кредита
   //--- получение (3) величины изменения кредита,
   //--- получение флага изменения кредита больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlCreditInc(const long value)                 { this.SetControlledValueINC(ACCOUNT_PROP_CREDIT,(double)::fabs(value));               }
   void              SetControlCreditDec(const long value)                 { this.SetControlledValueDEC(ACCOUNT_PROP_CREDIT,(double)::fabs(value));               }
   void              SetControlCreditLevel(const long value)               { this.SetControlledValueLEVEL(ACCOUNT_PROP_CREDIT,(double)::fabs(value));             }
   double            GetValueChangedCredit(void)                     const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_CREDIT);                          }
   bool              IsIncreasedCredit(void)                         const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_CREDIT);                         }
   bool              IsDecreasedCredit(void)                         const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_CREDIT);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня прибыли
   //--- получение (3) величины изменения прибыли,
   //--- получение флага изменения прибыли больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlProfitInc(const long value)                 { this.SetControlledValueINC(ACCOUNT_PROP_PROFIT,(double)::fabs(value));               }
   void              SetControlProfitDec(const long value)                 { this.SetControlledValueDEC(ACCOUNT_PROP_PROFIT,(double)::fabs(value));               }
   void              SetControlProfitLevel(const long value)               { this.SetControlledValueLEVEL(ACCOUNT_PROP_PROFIT,(double)::fabs(value));             }
   double            GetValueChangedProfit(void)                     const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_PROFIT);                          }
   bool              IsIncreasedProfit(void)                         const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_PROFIT);                         }
   bool              IsDecreasedProfit(void)                         const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_PROFIT);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня средств
   //--- получение (3) величины изменения средств,
   //--- получение флага изменения средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlEquityInc(const long value)                 { this.SetControlledValueINC(ACCOUNT_PROP_EQUITY,(double)::fabs(value));               }
   void              SetControlEquityDec(const long value)                 { this.SetControlledValueDEC(ACCOUNT_PROP_EQUITY,(double)::fabs(value));               }
   void              SetControlEquityLevel(const long value)               { this.SetControlledValueLEVEL(ACCOUNT_PROP_EQUITY,(double)::fabs(value));             }
   double            GetValueChangedEquity(void)                     const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_EQUITY);                          }
   bool              IsIncreasedEquity(void)                         const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_EQUITY);                         }
   bool              IsDecreasedEquity(void)                         const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_EQUITY);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня залоговых средств
   //--- получение (3) величины изменения залоговых средств,
   //--- получение флага изменения залоговых средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginInc(const long value)                 { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN,(double)::fabs(value));               }
   void              SetControlMarginDec(const long value)                 { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN,(double)::fabs(value));               }
   void              SetControlMarginLevel(const long value)               { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN,(double)::fabs(value));             }
   double            GetValueChangedMargin(void)                     const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN);                          }
   bool              IsIncreasedMargin(void)                         const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN);                         }
   bool              IsDecreasedMargin(void)                         const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня свободных средств
   //--- получение (3) величины изменения свободных средств,
   //--- получение флага изменения свободных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginFreeInc(const long value)             { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value));          }
   void              SetControlMarginFreeDec(const long value)             { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value));          }
   void              SetControlMarginFreeLevel(const long value)           { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_FREE,(double)::fabs(value));        }
   double            GetValueChangedMarginFree(void)                 const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_FREE);                     }
   bool              IsIncreasedMarginFree(void)                     const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_FREE);                    }
   bool              IsDecreasedMarginFree(void)                     const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_FREE);                    }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня уровня свободных средств
   //--- получение (3) величины изменения уровня свободных средств,
   //--- получение флага изменения уровня свободных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginLevelInc(const long value)            { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value));         }
   void              SetControlMarginLevelDec(const long value)            { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value));         }
   void              SetControlMarginLevelLevel(const long value)          { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_LEVEL,(double)::fabs(value));       }
   double            GetValueChangedMarginLevel(void)                const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_LEVEL);                    }
   bool              IsIncreasedMarginLevel(void)                    const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_LEVEL);                   }
   bool              IsDecreasedMarginLevel(void)                    const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_LEVEL);                   }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня Margin Call
   //--- получение (3) величины изменения уровня Margin Call,
   //--- получение флага изменения уровня Margin Call больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginCallInc(const long value)             { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value));       }
   void              SetControlMarginCallDec(const long value)             { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value));       }
   void              SetControlMarginCallLevel(const long value)           { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_SO_CALL,(double)::fabs(value));     }
   double            GetValueChangedMarginCall(void)                 const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_SO_CALL);                  }
   bool              IsIncreasedMarginCall(void)                     const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_SO_CALL);                 }
   bool              IsDecreasedMarginCall(void)                     const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_SO_CALL);                 }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня Margin StopOut
   //--- получение (3) величины изменения уровня Margin StopOut,
   //--- получение флага изменения уровня Margin StopOut больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginStopOutInc(const long value)          { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value));         }
   void              SetControlMarginStopOutDec(const long value)          { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value));         }
   void              SetControlMarginStopOutLevel(const long value)        { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_SO_SO,(double)::fabs(value));       }
   double            GetValueChangedMarginStopOut(void)              const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_SO_SO);                    }
   bool              IsIncreasedMarginStopOut(void)                  const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_SO_SO);                   }
   bool              IsDecreasedMarginStopOut(void)                  const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_SO_SO);                   }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам
   //--- получение (3) величины изменения величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам,
   //--- получение флага изменения величины прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginInitialInc(const long value)          { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value));       }
   void              SetControlMarginInitialDec(const long value)          { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value));       }
   void              SetControlMarginInitialLevel(const long value)        { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_INITIAL,(double)::fabs(value));     }
   double            GetValueChangedMarginInitial(void)              const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_INITIAL);                  }
   bool              IsIncreasedMarginInitial(void)                  const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_INITIAL);                 }
   bool              IsDecreasedMarginInitial(void)                  const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_INITIAL);                 }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   //--- получение (3) величины изменения величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям,
   //--- получение флага изменения величины прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginMaintenanceInc(const long value)      { this.SetControlledValueINC(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value));   }
   void              SetControlMarginMaintenanceDec(const long value)      { this.SetControlledValueDEC(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value));   }
   void              SetControlMarginMaintenanceLevel(const long value)    { this.SetControlledValueLEVEL(ACCOUNT_PROP_MARGIN_MAINTENANCE,(double)::fabs(value)); }
   double            GetValueChangedMarginMaintenance(void)          const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_MARGIN_MAINTENANCE);              }
   bool              IsIncreasedMarginMaintenance(void)              const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_MARGIN_MAINTENANCE);             }

   bool              IsDecreasedMarginMaintenance(void)              const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_MARGIN_MAINTENANCE);             }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня активов
   //--- получение (3) величины изменения активов,
   //--- получение флага изменения активов больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlAssetsInc(const long value)                 { this.SetControlledValueINC(ACCOUNT_PROP_ASSETS,(double)::fabs(value));               }
   void              SetControlAssetsDec(const long value)                 { this.SetControlledValueDEC(ACCOUNT_PROP_ASSETS,(double)::fabs(value));               }
   void              SetControlAssetsLevel(const long value)               { this.SetControlledValueLEVEL(ACCOUNT_PROP_ASSETS,(double)::fabs(value));             }
   double            GetValueChangedAssets(void)                     const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_ASSETS);                          }
   bool              IsIncreasedAssets(void)                         const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_ASSETS);                         }
   bool              IsDecreasedAssets(void)                         const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_ASSETS);                         }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня обязательств
   //--- получение (3) величины изменения обязательств,
   //--- получение флага изменения обязательств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlLiabilitiesInc(const long value)            { this.SetControlledValueINC(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value));          }
   void              SetControlLiabilitiesDec(const long value)            { this.SetControlledValueDEC(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value));          }
   void              SetControlLiabilitiesLevel(const long value)          { this.SetControlledValueLEVEL(ACCOUNT_PROP_LIABILITIES,(double)::fabs(value));        }
   double            GetValueChangedLiabilities(void)                const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_LIABILITIES);                     }
   bool              IsIncreasedLiabilities(void)                    const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_LIABILITIES);                    }
   bool              IsDecreasedLiabilities(void)                    const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_LIABILITIES);                    }
   
   //--- установка контролируемой величины (1) прироста, (2) уменьшения, (3) контрольного уровня заблокированных комиссий
   //--- получение (3) величины изменения заблокированных комиссий,
   //--- получение флага изменения заблокированных комиссий больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlComissionBlockedInc(const long value)       { this.SetControlledValueINC(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value));   }
   void              SetControlComissionBlockedDec(const long value)       { this.SetControlledValueDEC(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value));   }
   void              SetControlComissionBlockedLevel(const long value)     { this.SetControlledValueLEVEL(ACCOUNT_PROP_COMMISSION_BLOCKED,(double)::fabs(value)); }
   double            GetValueChangedComissionBlocked(void)           const { return this.GetPropDoubleChangedValue(ACCOUNT_PROP_COMMISSION_BLOCKED);              }
   bool              IsIncreasedComissionBlocked(void)               const { return (bool)this.GetPropDoubleFlagINC(ACCOUNT_PROP_COMMISSION_BLOCKED);             }
   bool              IsDecreasedComissionBlocked(void)               const { return (bool)this.GetPropDoubleFlagDEC(ACCOUNT_PROP_COMMISSION_BLOCKED);             }

//+------------------------------------------------------------------+

В конструкторе класса сначала укажем размеры массивов данных, а затем инициализируем все контролируемые данные в базовом объекте CBaseObj, и далее — после заполнения всех свойств объекта-аккаунта, заполним свойства и в базовом объекте. Напоследок обновим все данные аккаунта в базовом объекте CBaseObj:

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CAccount::CAccount(void)
  {
//--- Инициализация контролируемых данных
   this.SetControlDataArraySizeLong(ACCOUNT_PROP_INTEGER_TOTAL);
   this.SetControlDataArraySizeDouble(ACCOUNT_PROP_DOUBLE_TOTAL);
   this.ResetChangesParams();
   this.ResetControlsParams();
  
//--- Сохранение целочисленных свойств
   this.m_long_prop[ACCOUNT_PROP_LOGIN]                              = ::AccountInfoInteger(ACCOUNT_LOGIN);
   this.m_long_prop[ACCOUNT_PROP_TRADE_MODE]                         = ::AccountInfoInteger(ACCOUNT_TRADE_MODE);
   this.m_long_prop[ACCOUNT_PROP_LEVERAGE]                           = ::AccountInfoInteger(ACCOUNT_LEVERAGE);
   this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS]                       = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE]                     = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED]                      = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED);
   this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT]                       = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE]                        = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ;
   this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS]                    = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ;
   this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE]                        = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4);
   
//--- Сохранение вещественных свойств
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)]          = ::AccountInfoDouble(ACCOUNT_BALANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)]           = ::AccountInfoDouble(ACCOUNT_CREDIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)]           = ::AccountInfoDouble(ACCOUNT_PROFIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)]           = ::AccountInfoDouble(ACCOUNT_EQUITY);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)]           = ::AccountInfoDouble(ACCOUNT_MARGIN);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)]      = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)]     = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)]   = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)]     = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)]   = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)]=::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)]           = ::AccountInfoDouble(ACCOUNT_ASSETS);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)]      = ::AccountInfoDouble(ACCOUNT_LIABILITIES);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)]=::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED);
   
//--- Сохранение строковых свойств
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_NAME)]             = ::AccountInfoString(ACCOUNT_NAME);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_SERVER)]           = ::AccountInfoString(ACCOUNT_SERVER);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_CURRENCY)]         = ::AccountInfoString(ACCOUNT_CURRENCY);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_COMPANY)]          = ::AccountInfoString(ACCOUNT_COMPANY);

//--- Имя объекта-аккаунта
   this.m_name=TextByLanguage("Счёт ","Account ")+(string)this.Login()+": "+this.Name()+" ("+this.Company()+")";
   this.m_type=COLLECTION_ACCOUNT_ID;

//--- Заполнение текущих данных аккаунта
   for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++)
      this.m_long_prop_event[i][3]=this.m_long_prop[i];
   for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++)
      this.m_double_prop_event[i][3]=this.m_double_prop[i];

//--- Обновление данных в базовом объекте и поиск изменений
   CBaseObj::Refresh();
  }
//+-------------------------------------------------------------------+

За пределами тела класса напишем реализацию виртуального метода обновления данных аккаунта:

//+------------------------------------------------------------------+
//| Обновляет все данные аккаунта                                    |
//+------------------------------------------------------------------+
void CAccount::Refresh(void)
  {
//--- Инициализация событийных данных
   this.m_is_event=false;
   this.m_hash_sum=0;
//--- Обновление целочисленных свойств
   this.m_long_prop[ACCOUNT_PROP_LOGIN]                                 = ::AccountInfoInteger(ACCOUNT_LOGIN);
   this.m_long_prop[ACCOUNT_PROP_TRADE_MODE]                            = ::AccountInfoInteger(ACCOUNT_TRADE_MODE);
   this.m_long_prop[ACCOUNT_PROP_LEVERAGE]                              = ::AccountInfoInteger(ACCOUNT_LEVERAGE);
   this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS]                          = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE]                        = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED]                         = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED);
   this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT]                          = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE]                           = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ;
   this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS]                       = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ;
   this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE]                           = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4);
   
//--- Обновление вещественных свойств
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)]             = ::AccountInfoDouble(ACCOUNT_BALANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)]              = ::AccountInfoDouble(ACCOUNT_CREDIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)]              = ::AccountInfoDouble(ACCOUNT_PROFIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)]              = ::AccountInfoDouble(ACCOUNT_EQUITY);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)]              = ::AccountInfoDouble(ACCOUNT_MARGIN);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)]         = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)]        = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)]      = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)]        = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)]      = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)]  =::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)]              = ::AccountInfoDouble(ACCOUNT_ASSETS);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)]         = ::AccountInfoDouble(ACCOUNT_LIABILITIES);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)]  =::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED);

//--- Заполнение текущих данных аккаунта в базовом объекте
   for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++)
      this.m_long_prop_event[i][3]=this.m_long_prop[i];
   for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++)
      this.m_double_prop_event[i][3]=this.m_double_prop[i];
   
//--- Обновление данных в базовом объекте и поиск изменений
   CBaseObj::Refresh();
   this.CheckEvents();
  }
//+------------------------------------------------------------------+

Здесь сначала сбрасывается флаг события аккаунта и обнуляется хэш-сумма (скорее всего и от хэш-суммы далее избавимся, если окажется, что она не потребуется для других объектов на основе CBaseObj).
Далее заполняются все свойства объекта-аккаунта, а затем — как и в конструкторе класса — заполняются данные аккаунта в базовом объекте, вызывается метод обновления базового объекта, в котором происходит помимо обновления текущих данных ещё и поиск изменения значений свойств объекта, и при превышении величины изменения значений, заданных для поиска событий, генерируются базовые события объекта.
Затем при помощи метода CheckEvents() родительского класса проверяем наличие базовых событий в списке базовых событий объекта CBaseObj, и при их наличии метод создаёт список событий своего наследника: в данном случае — список событий аккаунта.

Класс CAccount доработан.

Теперь внесём правки в класс коллекции аккаунтов.
Откроем файл \MQL5\Include\DoEasy\Collections\AccountsCollection.mqh и внесём в него необходимые изменения.

Удалим всё ставшее ненужным:

//+------------------------------------------------------------------+
//| Коллекция аккаунтов                                              |
//+------------------------------------------------------------------+
class CAccountsCollection : public CBaseObj
  {
private:
   struct MqlDataAccount
     {
      //--- Целочисленные свойства счёта
      long           login;                  // ACCOUNT_LOGIN (Номер счёта)
      long           leverage;               // ACCOUNT_LEVERAGE (Размер предоставленного плеча)
      int            limit_orders;           // ACCOUNT_LIMIT_ORDERS (Максимально допустимое количество действующих отложенных ордеров)
      bool           trade_allowed;          // ACCOUNT_TRADE_ALLOWED (Разрешенность торговли для текущего счета со стороны сервера)
      bool           trade_expert;           // ACCOUNT_TRADE_EXPERT (Разрешенность торговли для эксперта со стороны сервера)
      //--- Вещественные свойства счёта
      double         balance;                // ACCOUNT_BALANCE (Баланс счета в валюте депозита)
      double         credit;                 // ACCOUNT_CREDIT (Размер предоставленного кредита в валюте депозита)
      double         profit;                 // ACCOUNT_PROFIT (Размер текущей прибыли на счете в валюте депозита)
      double         equity;                 // ACCOUNT_EQUITY (Значение собственных средств на счете в валюте депозита)
      double         margin;                 // ACCOUNT_MARGIN (Размер зарезервированных залоговых средств на счете  в валюте депозита)
      double         margin_free;            // ACCOUNT_MARGIN_FREE (Размер свободных средств на счете  в валюте депозита, доступных для открытия позиции)
      double         margin_level;           // ACCOUNT_MARGIN_LEVEL (Уровень залоговых средств на счете в процентах)
      double         margin_so_call;         // ACCOUNT_MARGIN_SO_CALL (Уровень залоговых средств, при котором происходит MarginCall)
      double         margin_so_so;           // ACCOUNT_MARGIN_SO_SO (Уровень залоговых средств, при достижении которого происходит StopOut)
      double         margin_initial;         // ACCOUNT_MARGIN_INITIAL (Размер средств, зарезервированных на счёте, для обеспечения гарантийной суммы по всем отложенным ордерам)
      double         margin_maintenance;     // ACCOUNT_MARGIN_MAINTENANCE (Размер средств, зарезервированных на счёте, для обеспечения минимальной суммы по всем открытым позициям)
      double         assets;                 // ACCOUNT_ASSETS (Текущий размер активов на счёте)
      double         liabilities;            // ACCOUNT_LIABILITIES (Текущий размер обязательств на счёте)
      double         comission_blocked;      // ACCOUNT_COMMISSION_BLOCKED (Текущая сумма заблокированных комиссий по счёту)
     };
   MqlDataAccount    m_struct_curr_account;              // Текущие данные счёта
   MqlDataAccount    m_struct_prev_account;              // Прошлые данные счёта
   
   string            m_symbol;                           // Текущий символ
   CListObj          m_list_accounts;                    // Список объектов-аккаунтов
   int               m_index_current;                    // Индекс объекта-аккаунта с данными текущего счёта
   //--- Плечо
   long              m_changed_leverage_value;           // Величина изменения плеча
   bool              m_is_change_leverage_inc;           // Флаг увеличения плеча
   bool              m_is_change_leverage_dec;           // Флаг уменьшения плеча
   //--- Количество действующих отложенных ордеров
   int               m_changed_limit_orders_value;       // Величина изменения максимально допустимого количества действующих отложенных ордеров
   bool              m_is_change_limit_orders_inc;       // Флаг увеличения максимально допустимого количества действующих отложенных ордеров
   bool              m_is_change_limit_orders_dec;       // Флаг уменьшения максимально допустимого количества действующих отложенных ордеров
   //--- Торговля на счёте
   bool              m_is_change_trade_allowed_on;       // Флаг разрешения торговли для текущего счета со стороны сервера
   bool              m_is_change_trade_allowed_off;      // Флаг запрета торговли для текущего счета со стороны сервера
   //--- Автоторговля на счёте
   bool              m_is_change_trade_expert_on;        // Флаг разрешения торговли для эксперта со стороны сервера
   bool              m_is_change_trade_expert_off;       // Флаг запрета торговли для эксперта со стороны сервера
   //--- Баланс
   double            m_control_balance_inc;              // Контролируемая величина прироста баланса
   double            m_control_balance_dec;              // Контролируемая величина уменьшения баланса
   double            m_changed_balance_value;            // Величина изменения баланса
   bool              m_is_change_balance_inc;            // Флаг изменения баланса больше, чем на величину прироста
   bool              m_is_change_balance_dec;            // Флаг изменения баланса больше, чем на величину уменьшения
   //--- Кредит
   double            m_changed_credit_value;             // Величина изменения кредита
   bool              m_is_change_credit_inc;             // Флаг увеличения кредита
   bool              m_is_change_credit_dec;             // Флаг уменьшения кредита
   //--- Профит
   double            m_control_profit_inc;               // Контролируемая величина прироста прибыли
   double            m_control_profit_dec;               // Контролируемая величина уменьшения прибыли
   double            m_changed_profit_value;             // Величина изменения прибыли
   bool              m_is_change_profit_inc;             // Флаг изменения прибыли больше, чем на величину прироста
   bool              m_is_change_profit_dec;             // Флаг изменения прибыли больше, чем на величину уменьшения
   //--- Средства
   double            m_control_equity_inc;               // Контролируемая величина прироста средств
   double            m_control_equity_dec;               // Контролируемая величина уменьшения средств
   double            m_changed_equity_value;             // Величина изменения средств
   bool              m_is_change_equity_inc;             // Флаг изменения средств больше, чем на величину прироста
   bool              m_is_change_equity_dec;             // Флаг изменения средств больше, чем на величину уменьшения
   //--- Маржа
   double            m_control_margin_inc;               // Контролируемая величина прироста залоговых средств
   double            m_control_margin_dec;               // Контролируемая величина уменьшения залоговых средств
   double            m_changed_margin_value;             // Величина изменения залоговых средств
   bool              m_is_change_margin_inc;             // Флаг изменения залоговых средств больше, чем на величину прироста
   bool              m_is_change_margin_dec;             // Флаг изменения залоговых средств больше, чем на величину уменьшения
   //--- Свободная маржа
   double            m_control_margin_free_inc;          // Контролируемая величина прироста свободных средств
   double            m_control_margin_free_dec;          // Контролируемая величина уменьшения свободных средств
   double            m_changed_margin_free_value;        // Величина изменения свободных средств
   bool              m_is_change_margin_free_inc;        // Флаг изменения свободных средств больше, чем на величину прироста
   bool              m_is_change_margin_free_dec;        // Флаг изменения свободных средств больше, чем на величину уменьшения
   //--- Уровень маржи
   double            m_control_margin_level_inc;         // Контролируемая величина прироста уровня свободных средств
   double            m_control_margin_level_dec;         // Контролируемая величина уменьшения уровня свободных средств
   double            m_changed_margin_level_value;       // Величина изменения уровня свободных средств
   bool              m_is_change_margin_level_inc;       // Флаг изменения уровня свободных средств больше, чем на величину прироста
   bool              m_is_change_margin_level_dec;       // Флаг изменения уровня свободных средств больше, чем на величину уменьшения
   //--- Margin Call
   double            m_changed_margin_so_call_value;     // Величина изменения уровня Margin Call
   bool              m_is_change_margin_so_call_inc;     // Флаг увеличения уровня Margin Call
   bool              m_is_change_margin_so_call_dec;     // Флаг уменьшения уровня Margin Call
   //--- MarginStopOut
   double            m_changed_margin_so_so_value;       // Величина изменения уровня Margin StopOut
   bool              m_is_change_margin_so_so_inc;       // Флаг увеличения уровня Margin StopOut
   bool              m_is_change_margin_so_so_dec;       // Флаг уменьшения уровня Margin StopOut
   //--- Гарантийная сумма по отложенным ордерам
   double            m_control_margin_initial_inc;       // Контролируемая величина прироста размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам
   double            m_control_margin_initial_dec;       // Контролируемая величина уменьшения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам
   double            m_changed_margin_initial_value;     // Величина изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам
   bool              m_is_change_margin_initial_inc;     // Флаг изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину прироста
   bool              m_is_change_margin_initial_dec;     // Флаг изменения размера зарезервированных средств для обеспечения гарантийной суммы по отложенным ордерам больше, чем на величину уменьшения
   //--- Гарантийная сумма по открытым позициям
   double            m_control_margin_maintenance_inc;   // Контролируемая величина прироста зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   double            m_control_margin_maintenance_dec;   // Контролируемая величина уменьшения зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   double            m_changed_margin_maintenance_value; // Величина изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   bool              m_is_change_margin_maintenance_inc; // Флаг изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   bool              m_is_change_margin_maintenance_dec; // Флаг изменения размера зарезервированных средств для обеспечения минимальной суммы по всем открытым позициям
   //--- Активы
   double            m_control_assets_inc;               // Контролируемая величина прироста активов
   double            m_control_assets_dec;               // Контролируемая величина уменьшения активов
   double            m_changed_assets_value;             // Величина изменения активов
   bool              m_is_change_assets_inc;             // Флаг изменения активов больше, чем на величину прироста
   bool              m_is_change_assets_dec;             // Флаг изменения активов больше, чем на величину уменьшения
   //--- Обязательства
   double            m_control_liabilities_inc;          // Контролируемая величина прироста обязательств
   double            m_control_liabilities_dec;          // Контролируемая величина уменьшения обязательств
   double            m_changed_liabilities_value;        // Величина изменения обязательств
   bool              m_is_change_liabilities_inc;        // Флаг изменения обязательств больше, чем на величину прироста
   bool              m_is_change_liabilities_dec;        // Флаг изменения обязательств больше, чем на величину уменьшения
   //--- Заблокированные комиссии
   double            m_control_comission_blocked_inc;    // Контролируемая величина прироста заблокированных комиссий
   double            m_control_comission_blocked_dec;    // Контролируемая величина уменьшения заблокированных комиссий
   double            m_changed_comission_blocked_value;  // Величина изменения заблокированных комиссий
   bool              m_is_change_comission_blocked_inc;  // Флаг изменения заблокированных комиссий больше, чем на величину прироста
   bool              m_is_change_comission_blocked_dec;  // Флаг изменения заблокированных комиссий больше, чем на величину уменьшения
   
//--- Инициализирует переменные (1) отслеживаемых, (2) контролируемых данных аккаунта
   void              InitChangesParams(void);
   void              InitControlsParams(void);
//--- Устанавливает тип события и заполняет список событий
   virtual void      SetTypeEvent(void);
//--- Записывает данные текущего счёта в свойства объекта-аккаунта
   void              SetAccountsParams(CAccount* account);
//--- Проверяет наличие объекта-аккаунта в списке-коллекции
   bool              IsPresent(CAccount* account);
//--- Находит и возвращает индекс объекта-аккаунта с данными текущего счёта
   int               Index(void);
public:
//--- Возвращает полный список-коллекцию аккаунтов "как есть"
   CArrayObj        *GetList(void)                                                                          { return &this.m_list_accounts;                                         }
//--- Возвращает список по выбранному (1) целочисленному, (2) вещественному и (3) строковому свойству, удовлетворяющему сравниваемому критерию
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL)   { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL)  { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL)  { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
//--- Возвращает (1) индекс текущего объекта-аккаунта, (2) идентификатор события по его номеру в списке
   int               IndexCurrentAccount(void)                                                        const { return this.m_index_current;                                          }
   ENUM_ACCOUNT_EVENT GetEventID(const int shift=WRONG_VALUE,const bool check_out=true);
//--- (1) Устанавливает, (2) возвращает текущий символ
   void              SetSymbol(const string symbol)                                                         { this.m_symbol=symbol;                                  }
   string            GetSymbol(void)                                                                  const { return this.m_symbol;                                  }

//--- Конструктор, деструктор
                     CAccountsCollection();
                    ~CAccountsCollection();
//--- Добавляет объект-аккаунт в список
   bool              AddToList(CAccount* account);
//--- (1) Сохраняет объекты-аккаунты из списка в файлы
//--- (2) Загружает объекты-аккаунты из файлов в список
   bool              SaveObjects(void);
   bool              LoadObjects(void);
//--- Возвращает описание события аккаунта
   string            EventDescription(const ENUM_ACCOUNT_EVENT event);
//--- Обновляет данные текущего аккаунта
   virtual void      Refresh(void);
   
//--- Получение и установка параметров отслеживаемых изменений
   //--- Плечо:
   //--- (1) Величина изменения плеча, (2) Флаг увеличения плеча, (3) Флаг уменьшения плеча
   long              GetValueChangedLeverage(void)                                                    const { return this.m_changed_leverage_value;                  }
   bool              IsIncreaseLeverage(void)                                                         const { return this.m_is_change_leverage_inc;                  }
   bool              IsDecreaseLeverage(void)                                                         const { return this.m_is_change_leverage_dec;                  }
   //--- Количество действующих отложенных ордеров:
   //--- (1) Величина изменения, (2) Флаг увеличения, (3) Флаг уменьшения
   int               GetValueChangedLimitOrders(void)                                                 const { return this.m_changed_limit_orders_value;              }
   bool              IsIncreaseLimitOrders(void)                                                      const { return this.m_is_change_limit_orders_inc;              }
   bool              IsDecreaseLimitOrders(void)                                                      const { return this.m_is_change_limit_orders_dec;              }
   //--- Торговля на счёте:
   //--- (1) Флаг разрешения торговли для текущего счета, (2) Флаг запрета торговли для текущего счета со стороны сервера
   bool              IsOnTradeAllowed(void)                                                           const { return this.m_is_change_trade_allowed_on;              }
   bool              IsOffTradeAllowed(void)                                                          const { return this.m_is_change_trade_allowed_off;             }
   //--- Автоторговля на счёте:
   //--- (1) Флаг разрешения торговли для эксперта, (2) Флаг запрета торговли для эксперта со стороны сервера
   bool              IsOnTradeExpert(void)                                                            const { return this.m_is_change_trade_expert_on;               }
   bool              IsOffTradeExpert(void)                                                           const { return this.m_is_change_trade_expert_off;              }
   //--- Баланс:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения баланса
   //--- получение (3) величины изменения баланса,
   //--- получение флага изменения баланса больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlBalanceInc(const double value)                                               { this.m_control_balance_inc=::fabs(value);              }
   void              SetControlBalanceDec(const double value)                                               { this.m_control_balance_dec=::fabs(value);              }
   double            GetValueChangedBalance(void)                                                     const { return this.m_changed_balance_value;                   }
   bool              IsIncreaseBalance(void)                                                          const { return this.m_is_change_balance_inc;                   }
   bool              IsDecreaseBalance(void)                                                          const { return this.m_is_change_balance_dec;                   }
   //--- Кредит:
   //--- получение (1) величины изменения кредита, (2) флага увеличения кредита, (3) флага уменьшения кредита
   double            GetValueChangedCredit(void)                                                      const { return this.m_changed_credit_value;                    }
   bool              IsIncreaseCredit(void)                                                           const { return this.m_is_change_credit_inc;                    }
   bool              IsDecreaseCredit(void)                                                           const { return this.m_is_change_credit_dec;                    }
   //--- Профит:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения прибыли
   //--- получение (3) величины изменения прибыли,
   //--- получение флага изменения прибыли больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlProfitInc(const double value)                                                { this.m_control_profit_inc=::fabs(value);               }
   void              SetControlProfitDec(const double value)                                                { this.m_control_profit_dec=::fabs(value);               }
   double            GetValueChangedProfit(void)                                                      const { return this.m_changed_profit_value;                    }
   bool              IsIncreaseProfit(void)                                                           const { return this.m_is_change_profit_inc;                    }
   bool              IsDecreaseProfit(void)                                                           const { return this.m_is_change_profit_dec;                    }
   //--- Средства:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения средств
   //--- получение (3) величины изменения средств,
   //--- получение флага изменения средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlEquityInc(const double value)                                                { this.m_control_equity_inc=::fabs(value);               }
   void              SetControlEquityDec(const double value)                                                { this.m_control_equity_dec=::fabs(value);               }
   double            GetValueChangedEquity(void)                                                      const { return this.m_changed_equity_value;                    }
   bool              IsIncreaseEquity(void)                                                           const { return this.m_is_change_equity_inc;                    }
   bool              IsDecreaseEquity(void)                                                           const { return this.m_is_change_equity_dec;                    }
   //--- Маржа:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения залоговых средств
   //--- получение (3) величины изменения залоговых средств,
   //--- получение флага изменения залоговых средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginInc(const double value)                                                { this.m_control_margin_inc=::fabs(value);               }
   void              SetControlMarginDec(const double value)                                                { this.m_control_margin_dec=::fabs(value);               }
   double            GetValueChangedMargin(void)                                                      const { return this.m_changed_margin_value;                    }
   bool              IsIncreaseMargin(void)                                                           const { return this.m_is_change_margin_inc;                    }
   bool              IsDecreaseMargin(void)                                                           const { return this.m_is_change_margin_dec;                    }
   //--- Свободная маржа:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения свободных средств
   //--- получение (3) величины изменения свободных средств,
   //--- получение флага изменения свободных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginFreeInc(const double value)                                            { this.m_control_margin_free_inc=::fabs(value);          }
   void              SetControlMarginFreeDec(const double value)                                            { this.m_control_margin_free_dec=::fabs(value);          }
   double            GetValueChangedMarginFree(void)                                                  const { return this.m_changed_margin_free_value;               }
   bool              IsIncreaseMarginFree(void)                                                       const { return this.m_is_change_margin_free_inc;               }
   bool              IsDecreaseMarginFree(void)                                                       const { return this.m_is_change_margin_free_dec;               }
   //--- Уровень маржи:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения уровня свободных средств
   //--- получение (3) величины изменения уровня свободных средств,
   //--- получение флага изменения уровня свободных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginLevelInc(const double value)                                           { this.m_control_margin_level_inc=::fabs(value);         }
   void              SetControlMarginLevelDec(const double value)                                           { this.m_control_margin_level_dec=::fabs(value);         }
   double            GetValueChangedMarginLevel(void)                                                 const { return this.m_changed_margin_level_value;              }
   bool              IsIncreaseMarginLevel(void)                                                      const { return this.m_is_change_margin_level_inc;              }
   bool              IsDecreaseMarginLevel(void)                                                      const { return this.m_is_change_margin_level_dec;              }
   //--- Margin Call:
   //--- получение (1) величины изменения Margin Call, (2) флага увеличения уровня Margin Call, (3) флага уменьшения уровня Margin Call
   double            GetValueChangedMarginCall(void)                                                  const { return this.m_changed_margin_so_call_value;            }
   bool              IsIncreaseMarginCall(void)                                                       const { return this.m_is_change_margin_so_call_inc;            }
   bool              IsDecreaseMarginCall(void)                                                       const { return this.m_is_change_margin_so_call_dec;            }
   //--- Margin StopOut:
   //--- получение (1) величины изменения Margin StopOut, (2) флага увеличения уровня Margin StopOut, (3) флага уменьшения уровня Margin StopOut
   double            GetValueChangedMarginStopOut(void)                                               const { return this.m_changed_margin_so_so_value;              }
   bool              IsIncreaseMarginStopOut(void)                                                    const { return this.m_is_change_margin_so_so_inc;              }
   bool              IsDecreasMarginStopOute(void)                                                    const { return this.m_is_change_margin_so_so_dec;              }
   //--- Гарантийная сумма по отложенным ордерам:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения размера зарезервированных средств гарантийной суммы по отложенным ордерам
   //--- получение (3) величины изменения уровня зарезервированных средств,
   //--- получение флага изменения уровня зарезервированных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginInitialInc(const double value)                                         { this.m_control_margin_initial_inc=::fabs(value);       }
   void              SetControlMarginInitialDec(const double value)                                         { this.m_control_margin_initial_dec=::fabs(value);       }
   double            GetValueChangedMarginInitial(void)                                               const { return this.m_changed_margin_initial_value;            }
   bool              IsIncreaseMarginInitial(void)                                                    const { return this.m_is_change_margin_initial_inc;            }
   bool              IsDecreaseMarginInitial(void)                                                    const { return this.m_is_change_margin_initial_dec;            }
   //--- Гарантийная сумма по открытым позициям:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения размера зарезервированных средств гарантийной суммы по открытым позициям
   //--- получение (3) величины изменения уровня зарезервированных средств,
   //--- получение флага изменения уровня зарезервированных средств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlMarginMaintenanceInc(const double value)                                     { this.m_control_margin_maintenance_inc=::fabs(value);   }
   void              SetControlMarginMaintenanceDec(const double value)                                     { this.m_control_margin_maintenance_dec=::fabs(value);   }
   double            GetValueChangedMarginMaintenance(void)                                           const { return this.m_changed_margin_maintenance_value;        }
   bool              IsIncreaseMarginMaintenance(void)                                                const { return this.m_is_change_margin_maintenance_inc;        }
   bool              IsDecreaseMarginMaintenance(void)                                                const { return this.m_is_change_margin_maintenance_dec;        }
   //--- Активы:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения активов
   //--- получение (3) величины изменения уровня активов,
   //--- получение флага изменения уровня активов больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlAssetsInc(const double value)                                                { this.m_control_assets_inc=::fabs(value);               }
   void              SetControlAssetsDec(const double value)                                                { this.m_control_assets_dec=::fabs(value);               }
   double            GetValueChangedAssets(void)                                                      const { return this.m_changed_assets_value;                    }
   bool              IsIncreaseAssets(void)                                                           const { return this.m_is_change_assets_inc;                    }
   bool              IsDecreaseAssets(void)                                                           const { return this.m_is_change_assets_dec;                    }
   //--- Обязательства:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения обязательств
   //--- получение (3) величины изменения уровня обязательств,
   //--- получение флага изменения уровня обязательств больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlLiabilitiesInc(const double value)                                           { this.m_control_liabilities_inc=::fabs(value);          }
   void              SetControlLiabilitiesDec(const double value)                                           { this.m_control_liabilities_dec=::fabs(value);          }
   double            GetValueChangedLiabilities(void)                                                 const { return this.m_changed_liabilities_value;               }
   bool              IsIncreaseLiabilities(void)                                                      const { return this.m_is_change_liabilities_inc;               }
   bool              IsDecreaseLiabilities(void)                                                      const { return this.m_is_change_liabilities_dec;               }
   //--- Заблокированные комиссии:
   //--- установка контролируемой величины (1) прироста, (2) уменьшения заблокированных комиссий
   //--- получение (3) величины изменения уровня заблокированных комиссий,
   //--- получение флага изменения уровня заблокированных комиссий больше, чем на величину (4) прироста, (5) уменьшения
   void              SetControlComissionBlockedInc(const double value)                                      { this.m_control_comission_blocked_inc=::fabs(value);    }
   void              SetControlComissionBlockedDec(const double value)                                      { this.m_control_comission_blocked_dec=::fabs(value);    }
   double            GetValueChangedComissionBlocked(void)                                            const { return this.m_changed_comission_blocked_value;         }
   bool              IsIncreaseComissionBlocked(void)                                                 const { return this.m_is_change_comission_blocked_inc;         }
   bool              IsDecreaseComissionBlocked(void)                                                 const { return this.m_is_change_comission_blocked_dec;         }
  };
//+------------------------------------------------------------------+

Изменим типы методов и добавим объявления некоторых необходимых переменных и методов:

//+------------------------------------------------------------------+
//| Коллекция аккаунтов                                              |
//+------------------------------------------------------------------+
class CAccountsCollection : public CBaseObj
  {
private:
   string            m_symbol;                                    // Текущий символ
   CListObj          m_list_accounts;                             // Список объектов-аккаунтов
   int               m_index_current;                             // Индекс объекта-аккаунта с данными текущего счёта
   int               m_last_event;                                // Последнее событие

//--- Проверяет наличие объекта-аккаунта в списке-коллекции
   bool              IsPresent(CAccount* account);
//--- Находит и возвращает индекс объекта-аккаунта с данными текущего счёта
   int               Index(void);
public:
//--- Возвращает полный список-коллекцию аккаунтов "как есть"
   CArrayObj        *GetList(void)                                                                          { return &this.m_list_accounts;                                         }
//--- Возвращает список по выбранному (1) целочисленному, (2) вещественному и (3) строковому свойству, удовлетворяющему сравниваемому критерию
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL)   { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL)  { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
   CArrayObj        *GetList(ENUM_ACCOUNT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL)  { return CSelect::ByAccountProperty(this.GetList(),property,value,mode);}
//--- Возвращает (1) индекс текущего объекта-аккаунта, (2) идентификатор события по его номеру в списке
   int               IndexCurrentAccount(void)                                                        const { return this.m_index_current;                                          }
   int               GetEventID(const int shift=WRONG_VALUE,const bool check_out=true);
//--- (1) Устанавливает, (2) возвращает текущий символ
   void              SetSymbol(const string symbol)                                                         { this.m_symbol=symbol;                                  }
   string            GetSymbol(void)                                                                  const { return this.m_symbol;                                  }
//--- (1) Обновляет данные, (2) работа с событиями текущего аккаунта
   virtual void      Refresh(void);
   void              RefreshAndEventsControl(void);

//--- Конструктор, деструктор
                     CAccountsCollection();
                    ~CAccountsCollection();
//--- Добавляет объект-аккаунт в список
   bool              AddToList(CAccount* account);
//--- (1) Сохраняет объекты-аккаунты из списка в файлы
//--- (2) Загружает объекты-аккаунты из файлов в список
   bool              SaveObjects(void);
   bool              LoadObjects(void);
  };

Удалим из конструктора класса вызов двух, теперь удалённых методов, и очистку удалённой структуры:

//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CAccountsCollection::CAccountsCollection(void) : m_symbol(::Symbol())
  {
   this.m_list_accounts.Clear();
   this.m_list_accounts.Sort(SORT_BY_ACCOUNT_LOGIN);
   this.m_list_accounts.Type(COLLECTION_ACCOUNT_ID);
   ::ZeroMemory(this.m_struct_prev_account);
   ::ZeroMemory(this.m_tick);
   this.InitChangesParams();
   this.InitControlsParams();
//--- Создание папки хранения файлов аккаунтов
   this.SetSubFolderName("Accounts");
   ::ResetLastError();
   if(!::FolderCreate(this.m_folder_name,FILE_COMMON))
      ::Print(DFUN,TextByLanguage("Не удалось создать папку хранения файлов. Ошибка ","Could not create file storage folder. Error "),::GetLastError());
//--- Создание и добавление в список объекта-аккаунта текущего счёта
   CAccount* account=new CAccount();
   if(account!=NULL)
     {
      if(!this.AddToList(account))
        {
         ::Print(DFUN_ERR_LINE,TextByLanguage("Ошибка. Не удалось добавить текущий объект-аккаунт в список-коллекцию.","Error. Failed to add current account object to collection list."));
         delete account;
        }
      else
         account.PrintShort();
     }
   else
      ::Print(DFUN,TextByLanguage("Ошибка. Не удалось создать объект-аккаунт с данными текущего счёта.","Error. Failed to create an account object with current account data."));

//--- Загрузка объектов-аккаунтов из файлов в коллекцию
   this.LoadObjects();
//--- Сохранение индекса текущего аккаунта
   this.m_index_current=this.Index();
  }
//+------------------------------------------------------------------+

Все эти переменные, структуры и методы теперь заменены уже готовым функционалом базового объекта и для классов-наследников их заново делать не нужно. Равно как и в методе обновления данных аккаунта нужно удалить событийный функционал:

//+------------------------------------------------------------------+
//| Обновляет данные текущего аккаунта                               |
//+------------------------------------------------------------------+
void CAccountsCollection::Refresh(void)
  {
   ::ResetLastError();
   if(!::SymbolInfoTick(::Symbol(),this.m_tick))
     {
      this.m_global_error=::GetLastError();
      return;
     }
   if(this.m_index_current==WRONG_VALUE)
      return;
   CAccount* account=this.m_list_accounts.At(this.m_index_current);
   if(account==NULL)
      return;
//--- Подготовка событийных данных
   this.m_is_event=false;
   ::ZeroMemory(this.m_struct_curr_account);
   this.m_hash_sum=0;
   this.SetAccountsParams(account);
//--- Первый запуск
   if(!this.m_struct_prev_account.login)
     {
      this.m_struct_prev_account=this.m_struct_curr_account;
      this.m_hash_sum_prev=this.m_hash_sum;
      return;
     }
//--- Если хэш-сумма аккаунта изменилась
   if(this.m_hash_sum!=this.m_hash_sum_prev)
     {
      this.m_list_events.Clear();
      this.m_event_code=this.SetEventCode();
      this.SetTypeEvent();
      int total=this.m_list_events.Total();
      if(total>0)
        {
         this.m_is_event=true;
         for(int i=0;i<total;i++)
           {
            CEventBaseObj *event=this.GetEvent(i,false);
            if(event==NULL)
               continue;
            ENUM_ACCOUNT_EVENT event_id=(ENUM_ACCOUNT_EVENT)event.ID();
            if(event_id==ACCOUNT_EVENT_NO_EVENT)
               continue;
            long lparam=event.LParam();
            double dparam=event.DParam();
            string sparam=event.SParam();
            ::EventChartCustom(this.m_chart_id,(ushort)event_id,lparam,dparam,sparam);
           }
        }
      this.m_hash_sum_prev=this.m_hash_sum;
     }
  }
//+------------------------------------------------------------------+

Всё удалённое заменяем на вызов метода обновления базового класса:

//+------------------------------------------------------------------+
//| Обновляет данные текущего аккаунта                               |
//+------------------------------------------------------------------+
void CAccountsCollection::Refresh(void)
  {
   ::ResetLastError();
   if(!::SymbolInfoTick(::Symbol(),this.m_tick))
     {
      this.m_global_error=::GetLastError();
      return;
     }
   if(this.m_index_current==WRONG_VALUE)
      return;
   CAccount* account=this.m_list_accounts.At(this.m_index_current);
   if(account==NULL)
      return;
   account.Refresh();
  }
//+------------------------------------------------------------------+

Метод, обновляющий данные объекта и ищущий изменения свойств для генерации событий:

//+------------------------------------------------------------------+
//| Работа с событиями списка символов коллекции                     |
//+------------------------------------------------------------------+
void CAccountsCollection::RefreshAndEventsControl(void)
  {
   ::ResetLastError();
   if(!::SymbolInfoTick(::Symbol(),this.m_tick))
     {
      this.m_global_error=::GetLastError();
      return;
     }
   if(this.m_index_current==WRONG_VALUE)
      return;
   this.m_is_event=false;
   this.m_list_events.Clear();
   this.m_list_events.Sort();
   CAccount* account=this.m_list_accounts.At(this.m_index_current);
   if(account==NULL)
      return;
   account.Refresh();
   if(!account.IsEvent())
      return;
   CArrayObj *list=account.GetListEvents();
   if(list==NULL)
      return;
   this.m_is_event=true;
   this.m_event_code=account.GetEventCode();
   int n=list.Total();
   for(int j=0; j<n; j++)
     {
      CEventBaseObj *event=list.At(j);
      if(event==NULL)
         continue;
      this.m_last_event=event.ID();
      if(this.EventAdd((ushort)event.ID(),event.LParam(),event.DParam(),event.SParam()))
        {
         ::EventChartCustom(this.m_chart_id,(ushort)event.ID(),event.LParam(),event.DParam(),event.SParam());
        }
     }
  }
//+------------------------------------------------------------------+

Здесь: получаем тик текущего символа, и при ошибке его получения сохраняем код ошибки выходим из метода. Если текущий аккаунт в списке коллекции аккаунтов по какой-то причине не был найден, и его индекс отрицателен, то выходим из метода.
Сбрасываем флаг события аккаунта
, очищаем список событий аккаунта и устанавливаем ему флаг сортированного списка.
Получаем объект текущего аккаунта из списка коллекции аккаунтов и обновляем данные аккаунта.
Если в данный момент нет события аккаунта, то дальше делать нечего
— выходим из метода.
Иначе — получаем список базовых событий аккаунта из базового объекта, ставим флаг события аккаунта, получаем код последнего события (тоже скорее всего далее удалим эти "пережитки прошлого"), и в цикле по списку базовых событий получаем очередное событие из списка, сохраняем последнее событие аккаунта, добавляем его в список событий аккаунта и отправляем событие на график управляющей программы.

Удалим из листинга класса реализации методов SetAccountsParams(), SetEventCode(), EventDescription(), InitChangesParams() и InitControlsParams().

Метод, возвращающий событие аккаунта по его номеру в списке, ранее возвращал значение перечисления. Теперь перечисление удалено, и метод возвращает int-значение. Соответственно, если событие не найдено, то возвращаем -1:

//+------------------------------------------------------------------+
//| Возвращает событие аккаунта по его номеру в списке               |
//+------------------------------------------------------------------+
int CAccountsCollection::GetEventID(const int shift=WRONG_VALUE,const bool check_out=true)
  {
   CEventBaseObj *event=this.GetEvent(shift,check_out);
   if(event==NULL)
      return WRONG_VALUE;
   return (int)event.ID();
  }
//+------------------------------------------------------------------+

Это все необходимые изменения в классе коллекции аккаунтов.

Осталось внести небольшие изменения в класс основного объекта библиотеки CEngine.
Откроем файл \MQL5\Include\DoEasy\ Engine.mqh и внесём изменения.

Ранее переменная, хранящая последнее событие аккаунта m_last_account_event и методы, возвращающие её GetAccountEventByIndex() и LastAccountEvent(), имели тип перечисления ENUM_ACCOUNT_EVENT, от которого мы избавились. Сделаем их с типом int:

//+------------------------------------------------------------------+
//| Класс-основа библиотеки                                          |
//+------------------------------------------------------------------+
class CEngine : public CObject
  {
private:
   CHistoryCollection   m_history;                       // Коллекция исторических ордеров и сделок
   CMarketCollection    m_market;                        // Коллекция рыночных ордеров и сделок
   CEventsCollection    m_events;                        // Коллекция событий
   CAccountsCollection  m_accounts;                      // Коллекция аккаунтов
   CSymbolsCollection   m_symbols;                       // Коллекция символов
   CArrayObj            m_list_counters;                 // Список счётчиков таймера
   int                  m_global_error;                  // Код глобальной ошибки
   bool                 m_first_start;                   // Флаг первого запуска
   bool                 m_is_hedge;                      // Флаг хедж-счёта
   bool                 m_is_tester;                     // Флаг работы в тестере
   bool                 m_is_market_trade_event;         // Флаг торгового события на счёте
   bool                 m_is_history_trade_event;        // Флаг торгового события в истории счёта
   bool                 m_is_account_event;              // Флаг события изменения аккаунта
   bool                 m_is_symbol_event;               // Флаг события изменения свойств символа
   ENUM_TRADE_EVENT     m_last_trade_event;              // Последнее торговое событие на счёте
   int                  m_last_account_event;            // Последнее событие в свойствах счёта
//--- Возвращает список (1) аккаунтов, (2) событий аккаунтов, (3) событие изменения аккаунта по его индексу в списке
//--- (4) текущий аккаунт, (5) описание события
   CArrayObj           *GetListAllAccounts(void)                        { return this.m_accounts.GetList();                   }
   CArrayObj           *GetListAccountEvents(void)                      { return this.m_accounts.GetListEvents();             }
   int                  GetAccountEventByIndex(const int index=-1)      { return this.m_accounts.GetEventID(index);           }
   CAccount            *GetAccountCurrent(void);
//--- Возвращает (1) последнее торговое событие, (2) последнее событие в свойствах счёта, (3) флаг счёта-хедж, (4) флаг работы в тестере
   ENUM_TRADE_EVENT     LastTradeEvent(void)                      const { return this.m_last_trade_event;                     }
   int                  LastAccountEvent(void)                    const { return this.m_last_account_event;                   }
   int                  LastSymbolsEvent(void)                    const { return this.m_last_symbol_event;                    }

В конструкторе класса, в его списке инициализации инициализируем переменную m_last_account_event значением -1. Ранее мы её инициализировали константой ACCOUNT_EVENT_NO_EVENT удалённого перечисления ENUM_ACCOUNT_EVENT.

//+------------------------------------------------------------------+
//| CEngine конструктор                                              |
//+------------------------------------------------------------------+
CEngine::CEngine() : m_first_start(true),
                     m_last_trade_event(TRADE_EVENT_NO_EVENT),
                     m_last_account_event(WRONG_VALUE),
                     m_last_symbol_event(WRONG_VALUE),
                     m_global_error(ERR_SUCCESS)
  {
   this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
   this.m_is_tester=::MQLInfoInteger(MQL_TESTER);
   
   this.m_list_counters.Sort();
   this.m_list_counters.Clear();
   this.CreateCounter(COLLECTION_ORD_COUNTER_ID,COLLECTION_ORD_COUNTER_STEP,COLLECTION_ORD_PAUSE);
   this.CreateCounter(COLLECTION_ACC_COUNTER_ID,COLLECTION_ACC_COUNTER_STEP,COLLECTION_ACC_PAUSE);
   
   this.CreateCounter(COLLECTION_SYM_COUNTER_ID1,COLLECTION_SYM_COUNTER_STEP1,COLLECTION_SYM_PAUSE1);
   this.CreateCounter(COLLECTION_SYM_COUNTER_ID2,COLLECTION_SYM_COUNTER_STEP2,COLLECTION_SYM_PAUSE2);
   
   ::ResetLastError();
   #ifdef __MQL5__
      if(!::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   //---__MQL4__
   #else 
      if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   #endif 
  }
//+------------------------------------------------------------------+

Так как мы поменяли название метода Refresh() класса коллекции символов на RefreshAndEventsControl(), и точно такой же метод создали в классе коллекции аккаунтов, то
заменим в методах работы с событиями символов и аккаунтов имя вызываемого метода:

//+------------------------------------------------------------------+
//| Работа с событиями коллекции символов                            |
//+------------------------------------------------------------------+
void CEngine::SymbolEventsControl(void)
  {
   this.m_symbols.RefreshAndEventsControl();
   this.m_is_symbol_event=this.m_symbols.IsEvent();
//--- Если есть изменения свойств символа
   if(this.m_is_symbol_event)
     {
      //--- Получаем последнее событие изменения свойств символа
      this.m_last_symbol_event=this.m_symbols.GetLastEvent();
     }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Проверка событий аккаунта                                        |
//+------------------------------------------------------------------+
void CEngine::AccountEventsControl(void)
  {
//--- Проверка изменений свойств аккаунта и установка флага событий изменения аккаунта
   this.m_accounts.RefreshAndEventsControl();
   this.m_is_account_event=this.m_accounts.IsEvent();
//--- Если есть изменения свойств аккаунта
   if(this.m_is_account_event)
     {
      //--- Получаем последнее событие изменения свойств аккаунта
      this.m_last_account_event=this.m_accounts.GetEventID();
     }
  }
//+------------------------------------------------------------------+

Это все изменения в классе CEngine.

Теперь у нас есть возможность программно задавать для любого из классов, основанных на базовом объекте CBaseObj, те свойства, которые мы желаем отслеживать, а также величины изменения свойств, при превышении которых будут генерироваться события наследников базового класса.
Посмотрим как это всё можно делать.

Тестирование установки параметров отслеживания и получения событий объектов

Для тестирования возьмём тестовый советник из прошлой статьи и сохраним его в новой папке и с новым именем
\MQL5\Experts\TestDoEasy\Part18\TestDoEasyPart18.mq5.

Итак. Нам необходимо протестировать установку параметров, которые мы хотим отследить на предмет их изменения. На заданные нами величины. В двух разных классах. И сделать это теперь возможно одинаковыми спообами.

Будем отслеживать для класса CSymbol

  • Увеличение цены Bid всех используемых символов на 10 пунктов
  • Уменьшение цены Bid всех используемых символов на 10 пунктов
  • Увеличение спреда всех используемых символов на 4 пункта
  • Уменьшение спреда всех используемых символов на 4 пункта
  • Проконтролируем пересечение значением спреда всех используемых символов уровня в 15 пунктов
  • Проконтролируем пересечение ценой Bid текущего символа значения 1.10300
Для класса CAccount будем отслеживать
  • Увеличение текущей прибыли на 10 единиц валюты счёта
  • Увеличение размера средств на 15 единиц валюты счёта
  • Проконтролируем увеличение текущей прибыли выше уровня 20 единиц валюты счёта

При увеличении размера средств больше 15 единиц, закроем самую прибыльную позицию при её наличии, и при условии, что её прибыль больше нуля.

Для теста все необходимые значения установим в обработчике OnInit():

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Вызов данной функции выводит в журнал список констант перечисления, 
//--- заданного в файле DELib.mqh в строках 22 и 25, для проверки корректности констант
   //EnumNumbersTest();

//--- Установка глобальных переменных советника
   prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_";
   for(int i=0;i<TOTAL_BUTT;i++)
     {
      butt_data[i].name=prefix+EnumToString((ENUM_BUTTONS)i);
      butt_data[i].text=EnumToButtText((ENUM_BUTTONS)i);
     }
   lot=NormalizeLot(Symbol(),fmax(InpLots,MinimumLots(Symbol())*2.0));
   magic_number=InpMagic;
   stoploss=InpStopLoss;
   takeprofit=InpTakeProfit;
   distance_pending=InpDistance;
   distance_stoplimit=InpDistanceSL;
   slippage=InpSlippage;
   trailing_stop=InpTrailingStop*Point();
   trailing_step=InpTrailingStep*Point();
   trailing_start=InpTrailingStart;
   stoploss_to_modify=InpStopLossModify;
   takeprofit_to_modify=InpTakeProfitModify;
   
//--- Проверка на выбор работы с полным списком
   used_symbols_mode=InpModeUsedSymbols;
   if((ENUM_SYMBOLS_MODE)used_symbols_mode==SYMBOLS_MODE_ALL)
     {
      int total=SymbolsTotal(false);
      string ru_n="\nКоличество символов на сервере "+(string)total+".\nМаксимальное количество: "+(string)SYMBOLS_COMMON_TOTAL+" символов.";
      string en_n="\nThe number of symbols on server "+(string)total+".\nMaximal number: "+(string)SYMBOLS_COMMON_TOTAL+" symbols.";
      string caption=TextByLanguage("Внимание!","Attention!");
      string ru="Выбран режим работы с полным списком.\nВ этом режиме первичная подготовка списка коллекции символов может занять длительное время."+ru_n+"\nПродолжить?\n\"Нет\" - работа с текущим символом \""+Symbol()+"\"";
      string en="Full list mode selected.\nIn this mode, the initial preparation of the collection symbols list may take a long time."+en_n+"\nContinue?\n\"No\" - working with the current symbol \""+Symbol()+"\"";
      string message=TextByLanguage(ru,en);
      int flags=(MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2);
      int mb_res=MessageBox(message,caption,flags);
      switch(mb_res)
        {
         case IDNO : 
           used_symbols_mode=SYMBOLS_MODE_CURRENT; 
           break;
         default:
           break;
        }
     }
//--- Заполнение массива используемых символов
   used_symbols=InpUsedSymbols;
   CreateUsedSymbolsArray((ENUM_SYMBOLS_MODE)used_symbols_mode,used_symbols,array_used_symbols);

//--- Установка типа используемого списка символов в коллекции символов
   engine.SetUsedSymbols(array_used_symbols);
//--- Отображение выбранного режима работы с коллекцией объектов-символов
   Print(engine.ModeSymbolsListDescription(),TextByLanguage(". Количество используемых символов: ",". The number of symbols used: "),engine.GetSymbolsCollectionTotal());

//--- Установка контрольных значений для символов
   string ru1="",ru2="",ru3="",en1="",en2="",en3="";
   //--- Получаем список всех символов коллекции
   CArrayObj *list=engine.GetListAllUsedSymbols();
   if(list!=NULL && list.Total()!=0)
     {
      //--- В цикле по списку устанавливаем нужные значения для отслеживаемых свойств символов
      //--- По умолчанию всем свойствам установлены значения LONG_MAX, что означает "Не отслеживать данное свойство" 
      //--- Включить или выключить (задать величину меньше LONG_MAX или наоборот - установить значение LONG_MAX) можно в любое время в любом месте программы
      for(int i=0;i<list.Total();i++)
        {
         CSymbol* symbol=list.At(i);
         if(symbol==NULL)
            continue;
         //--- Установка контроля увеличения цены символа на 10 пунктов
         symbol.SetControlBidInc(10*symbol.Point());
         ru1="Контролируем увеличение цены Bid для символа ";
         ru2=" на ";
         ru3=" пунктов";
         en1="Bid price increase control for symbol ";
         en2=" by ";
         en3=" points";
         Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueINC(SYMBOL_PROP_BID),symbol.Digits()));
         
         //--- Установка контроля уменьшения цены символа на 10 пунктов
         symbol.SetControlBidDec(10*symbol.Point());
         ru1="Контролируем уменьшение цены Bid для символа ";
         ru2=" на ";
         ru3=" пунктов";
         en1="Bid price decrease control for symbol ";
         en2=" by ";
         en3=" points";
         Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueINC(SYMBOL_PROP_BID),symbol.Digits()));
         
         //--- Установка контроля увеличения спреда символа на 4 пункта
         symbol.SetControlSpreadInc(4);
         ru1="Контролируем увеличение спреда для символа ";
         ru2=" на ";
         ru3=" пунктов";
         en1="Spread value increase control for symbol ";
         en2=" by ";
         en3=" points";
         Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueINC(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3));
         
         //--- Установка контроля уменьшения спреда символа на 4 пункта
         symbol.SetControlSpreadDec(4);
         ru1="Контролируем уменьшение спреда для символа ";
         ru2=" на ";
         ru3=" пунктов";
         en1="Spread value decrease control for symbol ";
         en2=" by ";
         en3=" points";
         Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueDEC(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3));
         
         //--- Установка контроля размера спреда по значению 15 пунктов
         symbol.SetControlSpreadLevel(15);
         ru1="Контролируем значение спреда для символа ";
         ru2=" в ";
         ru3=" пунктов";
         en1="Control the spread value for the symbol ";
         en2=" at ";
         en3=" points";
         Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),(string)symbol.GetControlledLongValueLEVEL(SYMBOL_PROP_SPREAD),TextByLanguage(ru3,en3));
         Print("------");
         
         //--- Установка контроля пересечения ценой значения 1.10700 для текущего символа
         if(symbol.Name()==Symbol())
           {
            symbol.SetControlBidLevel(1.10300);
            ru1="Контролируемый уровень цены Bid для символа ";
            ru2=" установлен в значение ";
            en1="Controlled level of Bid price for the symbol ";
            en2=" is set to ";
            Print(TextByLanguage(ru1,en1),symbol.Name(),TextByLanguage(ru2,en2),DoubleToString(symbol.GetControlledDoubleValueLEVEL(SYMBOL_PROP_BID),symbol.Digits()));
           }
        }
     }
//--- Установка контрольных значений для текущего аккаунта
   Print("------");
   CAccount* account=engine.GetAccountCurrent();
   if(account!=NULL)
     {
      //--- Установка контроля увеличения значения прибыли
      account.SetControlledValueINC(ACCOUNT_PROP_PROFIT,10.0);
      Print(TextByLanguage("Контролируем увеличение прибыли аккаунта на ","Controlling account profit increase by "),DoubleToString(account.GetControlledDoubleValueINC(ACCOUNT_PROP_PROFIT),(int)account.CurrencyDigits())," ",account.Currency());
      //--- Установка контроля увеличения значения средств
      account.SetControlledValueINC(ACCOUNT_PROP_EQUITY,15.0);
      Print(TextByLanguage("Контролируем увеличение средств аккаунта на ","Controlling account equity increase by "),DoubleToString(account.GetControlledDoubleValueINC(ACCOUNT_PROP_EQUITY),(int)account.CurrencyDigits())," ",account.Currency());
      //--- Установка контрольного уровня прибыли
      account.SetControlledValueLEVEL(ACCOUNT_PROP_PROFIT,20.0);
      Print(TextByLanguage("Контролируем уровень прибыли аккаунта в ","Controlling the account profit level of "),DoubleToString(account.GetControlledDoubleValueLEVEL(ACCOUNT_PROP_PROFIT),(int)account.CurrencyDigits())," ",account.Currency());
     }

//--- Проверка и удаление неудалённых графических объектов советника
   if(IsPresentObects(prefix))
      ObjectsDeleteAll(0,prefix);

//--- Создание панели кнопок
   if(!CreateButtons(InpButtShiftX,InpButtShiftY))
      return INIT_FAILED;
//--- Установка состояния кнопки активизации трейлингов
   ButtonState(butt_data[TOTAL_BUTT-1].name,trailing_on);

//--- Установка параметров торгового класса CTrade
#ifdef __MQL5__
   trade.SetDeviationInPoints(slippage);
   trade.SetExpertMagicNumber(magic_number);
   trade.SetTypeFillingBySymbol(Symbol());
   trade.SetMarginMode();
   trade.LogLevel(LOG_LEVEL_NO);
#endif 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

В листинге всё прокомментировано, и, надеюсь, понятно для самостоятельного изучения. Замечу лишь, что после установки отслеживаемого значения свойству, это установленное значение тут же распечатываем в журнал (как пример получения установленного отслеживаемого значения свойства).

Из обработчика OnTick() удалим переменную для хранения последнего события аккаунта last_account_event — она была нужна ранее для определения нового события.
Теперь обработчик выглядит так:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Инициализация последних событий
   static ENUM_TRADE_EVENT last_trade_event=WRONG_VALUE;
//--- Если работа в тестере
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();
      PressButtonsControl();
     }
//--- Если последнее торговое событие изменилось
   if(engine.LastTradeEvent()!=last_trade_event)
     {
      last_trade_event=engine.LastTradeEvent();
      Comment("\nLast trade event: ",engine.GetLastTradeEventDescription());
      engine.ResetLastTradeEvent();
     }
//--- Если есть событие аккаунта
   if(engine.IsAccountsEvent())
     {
      //--- Если это тестер
      if(MQLInfoInteger(MQL_TESTER))
        {
         //--- Получим список всех событий аккаунта, произошедших одновременно
         CArrayObj* list=engine.GetListAccountEvents();
         if(list!=NULL)
           {
            //--- В цикле получаем очередное событие
            int total=list.Total();
            for(int i=0;i<total;i++)
              {
               //--- берём событие из списка
               CEventBaseObj *event=list.At(i);
               if(event==NULL)
                  continue;
               //--- Отправляем событие в обработчик событий
               long lparam=event.LParam();
               double dparam=event.DParam();
               string sparam=event.SParam();
               OnDoEasyEvent(CHARTEVENT_CUSTOM+event.ID(),lparam,dparam,sparam);
              }
           }
        }
     }
//--- Если есть событие коллекции символов
   if(engine.IsSymbolsEvent())
     {
      //--- Если это тестер
      if(MQLInfoInteger(MQL_TESTER))
        {
         //--- Получим список всех событий символов, произошедших одновременно
         CArrayObj* list=engine.GetListSymbolsEvents();
         if(list!=NULL)
           {
            //--- В цикле получаем очередное событие
            int total=list.Total();
            for(int i=0;i<total;i++)
              {
               //--- берём событие из списка
               CEventBaseObj *event=list.At(i);
               if(event==NULL)
                  continue;
               //--- Отправляем событие в обработчик событий
               long lparam=event.LParam();
               double dparam=event.DParam();
               string sparam=event.SParam();
               OnDoEasyEvent(CHARTEVENT_CUSTOM+event.ID(),lparam,dparam,sparam);
              }
           }
        }
     }
//--- Если установлен флаг трейлинга
   if(trailing_on)
     {
      TrailingPositions();
      TrailingOrders();
     }
  }
//+------------------------------------------------------------------+

Теперь все флаги о новых событиях можно получить из главного объекта библиотеки CEngine, и что более важно — можно получить даже два одинаковых события с разных символов (касается определения событий символов, а аккаунт всегда один — текущий). А вот при использовании переменных это было невозможно — так как текущее и прошлое события якобы одинаковы, а, значит, нет события. Это было не правильно.

В обработчик событий библиотеки были внесены доработки для определения событий аккаунта и реакции на увеличение размера средств на заданную величину:

//+------------------------------------------------------------------+
//| Обработка событий библиотеки DoEasy                              |
//+------------------------------------------------------------------+
void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
   string event="::"+string(idx);
   
//--- Извлекаем из lparam (1) милисекунды времени события, (2) причину, (3) источник события и (4) устанавливаем точное время события
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Обработка событий символов
   if(source==COLLECTION_SYMBOLS_ID)
     {
      CSymbol *symbol=engine.GetSymbolObjByName(sparam);
      if(symbol==NULL)
         return;
      //--- Количество знаков после запятой в значении события - если long-событие, то 0, иначе - Digits() символа
      int digits=(idx<SYMBOL_PROP_INTEGER_TOTAL ? 0 : symbol.Digits());
      //--- Текстовое описание события
      string id_descr=(idx<SYMBOL_PROP_INTEGER_TOTAL ? symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_INTEGER)idx) : symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_DOUBLE)idx));
      //--- Текстовое значение величины изменения свойства
      string value=DoubleToString(dparam,digits);
      
      //--- Проверка причин события и просто вывод в журнал его описания
      if(reason==BASE_EVENT_REASON_INC)
        {
         Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_DEC)
        {
         Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_MORE_THEN)
        {
         Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_LESS_THEN)
        {
         Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_EQUALS)
        {
         Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
     }   
     
//--- Обработка событий аккаунта
   else if(source==COLLECTION_ACCOUNT_ID)
     {
      CAccount *account=engine.GetAccountCurrent();
      if(account==NULL)
         return;
      //--- Количество знаков после запятой в значении события - если long-событие, то 0, иначе - Digits() символа
      int digits=int(idx<ACCOUNT_PROP_INTEGER_TOTAL ? 0 : account.CurrencyDigits());
      //--- Текстовое описание события
      string id_descr=(idx<ACCOUNT_PROP_INTEGER_TOTAL ? account.GetPropertyDescription((ENUM_ACCOUNT_PROP_INTEGER)idx) : account.GetPropertyDescription((ENUM_ACCOUNT_PROP_DOUBLE)idx));
      //--- Текстовое значение величины изменения свойства
      string value=DoubleToString(dparam,digits);
      
      //--- Проверка причин события и обработка увеличения средств на заданную величину,
      //--- для остальных событий - просто вывод в журнал его описания
      
      //--- Если это увеличение значения свойства
      if(reason==BASE_EVENT_REASON_INC)
        {
         //--- Распечатаем событие в журнал
         Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
         //--- если это увеличение средств
         if(idx==ACCOUNT_PROP_EQUITY)
           {
            //--- Получаем список всех открытых позиций
            CArrayObj* list_positions=engine.GetListMarketPosition();
            //--- Выбираем позиции с прибылью болше нуля
            list_positions=CSelect::ByOrderProperty(list_positions,ORDER_PROP_PROFIT_FULL,0,MORE);
            if(list_positions!=NULL)
              {
               //--- Сортируем список по прибыли с учётом комиссии и свопа
               list_positions.Sort(SORT_BY_ORDER_PROFIT_FULL);
               //--- Получаем индекс позиции с наибольшей прибылью
               int index=CSelect::FindOrderMax(list_positions,ORDER_PROP_PROFIT_FULL);
               if(index>WRONG_VALUE)
                 {
                  COrder* position=list_positions.At(index);
                  if(position!=NULL)
                    {
                     //--- Получаем тикет позиции с наибольшей прибылью и закрываем позицию по тикету
                     #ifdef __MQL5__
                        trade.PositionClose(position.Ticket());
                     #else 
                        PositionClose(position.Ticket(),position.Volume());
                     #endif 
                    }
                 }
              }
           }
        }
      //--- Остальные события просто выводим в журнал
      if(reason==BASE_EVENT_REASON_DEC)
        {
         Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_MORE_THEN)
        {
         Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_LESS_THEN)
        {
         Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
      if(reason==BASE_EVENT_REASON_EQUALS)
        {
         Print(account.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits));
        }
     } 
     
//--- Обработка торговых событий
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      event=EnumToString((ENUM_TRADE_EVENT)ushort(idx));
      int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS);
     }
     
//--- Обработка событий окна обзор рынка
   else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE)
     {
      string name="";
      //--- Событие окна "Обзор рынка"
      string descr=engine.GetMWEventDescription((ENUM_MW_EVENT)idx);
      name=(idx==MARKET_WATCH_EVENT_SYMBOL_SORT ? "" : ": "+sparam);
      Print(TimeMSCtoString(lparam)," ",descr,name);
     }
  }
//+------------------------------------------------------------------+

Все действия по определению событий прокомментированы в коде, и, надеюсь, понятны. Также были поменяны местами блоки обработки событий от разных классов (непринципиально — просто для порядка) и разделены условиями if - else, что важно по причине того, что у нас есть несколько типов событий: события символов и аккаунта, которые обрабатываются одинаково — по идентификаторам коллекций, и есть торговые события и события окна "Обзор рынка", которые обрабатываются по значению перечислений этих событий. Вот чтобы не было конфликтов между разными методиками определения событий, и были разделены блоки условными операторами.

Полный листинг советника можно взять из прикреплённых ниже файлов.

Скомпилируем советник, установим в настройках тестера нулевые значения для параметров StopLoss in points и TakeProfit in points, выберем для параметра Mode of used symbols list значение "Работа только с текущим символом" и запустим визуальный тест советника M15 Last month:


Перед запуском теста видим, что в журнал распечатаны установленные значения для отслеживаемых свойств символа и аккаунта. Во время визуального тестирования в журнал выводятся сообщения о полученных событий от тех свойств, изменения значений которых мы отслеживаем. При увеличении средств больше контролируемой величины, прибыльные позиции закрываются.

Итак: мы создали базовый объект для всех объектов библиотеки, который наделяет своих наследников событийным функционалом и методами установки и получения параметров отслеживания для любых свойств любых объектов в любое время.
В дальнейшем это сильно упростит разработку новых классов новых объектов.

Что дальше

В следующей статье сделаем класс сообщений библиотеки — внутренних (сообщений от библиотечных методов) и внешних (сообщения об ошибках и прочие сообщения от терминала).

Ниже прикреплены все файлы текущей версии библиотеки и файлы тестового советника. Их можно скачать и протестировать всё самостоятельно.
При возникновении вопросов, замечаний и пожеланий, вы можете озвучить их в комментариях к статье.

К содержанию

Статьи этой серии:

Часть 1. Концепция, организация данных
Часть 2. Коллекция исторических ордеров и сделок
Часть 3. Коллекция рыночных ордеров и позиций, организация поиска
Часть 4. Торговые события. Концепция
Часть 5. Классы и коллекция торговых событий. Отправка событий в программу
Часть 6. События на счёте с типом неттинг
Часть 7. События срабатывания StopLimit-ордеров, подготовка функционала для регистрации событий модификации ордеров и позиций
Часть 8. События модификации ордеров и позиций
Часть 9. Совместимость с MQL4 - Подготовка данных
Часть 10. Совместимость с MQL4 - События открытия позиций и активации отложенных ордеров
Часть 11. Совместимость с MQL4 - События закрытия позиций
Часть 12. Класс объекта "аккаунт", коллекция объектов-аккаунтов
Часть 13. События объекта "аккаунт"
Часть 14. Объект "Символ"
Часть 15. Коллекция объектов-символов
Часть 16. События коллекции символов
Часть 17. Интерактивность объектов библиотеки


Прикрепленные файлы |
MQL5.zip (221.58 KB)
MQL4.zip (221.58 KB)
Новый подход к интерпретации классической и обратной дивергенции. Часть 2 Новый подход к интерпретации классической и обратной дивергенции. Часть 2

В этой статье мы критическом ключе рассмотрим классическую дивергенцию и проанализируем эффективность различных индикаторов. А также предложим варианты фильтрации для повышения точности анализа и продолжим рассматривать нестандартные решения. Как результат - создадим нетипичный инструмент для решения поставленной задачи.

Библиотека для простого и быстрого создания программ для MetaTrader (Часть XVII): Интерактивность объектов библиотеки Библиотека для простого и быстрого создания программ для MetaTrader (Часть XVII): Интерактивность объектов библиотеки

Сегодня доведём до логического завершения функционал базового объекта всех объектов библиотеки, который позволит любому объекту библиотеки, созданному на его основе, интерактивно взаимодействовать с пользователем. Например, можно установить максимально приемлемый размер спреда для открытия позиции и значение уровня цены, при пересечении которого нам будет послано событие от объекта-символа в программу о сигнале по размеру спреда и пересечению ценой контролируемого уровня.

Парсинг HTML с помощью curl Парсинг HTML с помощью curl

В статье описывается простейшая библиотека с использованием сторонних компонентов для парсинга HTML-кода. Из неё вы узнаете как добраться до данных, которые нальзя получить GET и POST запросами. Мы подберем какой-либо сайт с не слишком объемными страницами и попытаемся получить с него интересную информацию.

Автоматическое создание документации к программам на MQL5 Автоматическое создание документации к программам на MQL5

Большинство Java программистов знакомы с автоматическим созданием документации, которая может быть создана при помощи программы JavaDocs. В мире C++ также есть несколько автоматических генераторов документации, одними из лидеров являются программы Microsoft's SandCastle и Doxygen. В статье описано, как можно использовать программу Doxygen для создания структурированных файлов справки HTML для программ, написанных на MQL5. Результаты данной работы убедили меня использовать Doxygen (или похожие программы) в будущем для создания документации к любому моему коду на MQL5, это значительно облегчает его понимание и использование.