Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XVIII): interatividade de objetos-conta e de outros objetos da biblioteca

17 dezembro 2019, 11:12
Artyom Trishkin
0
1 983

Sumário

Criaremos um objeto básico a partir do qual herdaremos todos os outros objetos de biblioteca que precisam de funcionalidade de evento. Agora é muito mais simples definir os parâmetros dos eventos monitorados e obtê-los dos objetos, uma vez que tudo é feito na classe base, além disso, para todos seus objetos herdeiros é necessário executar as mesmas ações para definir as propriedades e os valores monitorados que queremos rastrear nas propriedades do objeto.

Hoje vamos modificar levemente o objeto base e inserir nele o objeto-conta. Também vamos testar a possibilidade de definir as propriedades necessárias para rastrear vários objetos e seus valores usando um EA de teste como modelo.
No último artigo ao criar os métodos do objeto base CBaseObj e os métodos de seu herdeiro - objeto-símbolo -, fiquei um pouco empolgado e criei um conjunto de métodos em duas classes que na verdade se duplicam. Vamos corrigir esse equívoco, para isso, simplesmente removeremos os métodos de configuração e obtenção de propriedades da classe do objeto-herdeiro CSymbol e solicitaremos os métodos do objeto base CBaseObj.

Aprimorando o objeto base e o objeto-símbolo

Abrimos o arquivo \MQL5\Include\DoEasy\Objects\BaseObj.mqh e fazemos as alterações necessárias.

Transferimos o método CheckEvents() da classe CSymbol para a classe base CBaseObj, já que este método é absolutamente idêntico para quaisquer objetos herdeiros da classe base, o que significa que o seu local deve ser na classe base.
Escrevemo sua definição na seção protegida da classe 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:

Da seção pública removemos os métodos que definem os valores dos sinalizadores de eventos, uma vez que os eventos acontecem independentemente da nossa vontade e os sinalizadores são definidos sem a intervenção do usuário. Por esse motivo, parece-me completamente inadequado manter os métodos para definir à força os sinalizadores de eventos:

//--- Устанавливает Флаг изменения значения свойства больше, чем на величину (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);

Agora, os métodos que retornam valores controlados definidos pelo usuário para as propriedades dos objetos, o valor atual das propriedades dos objetos e os valores para as alterações nas propriedades dos objetos terão nomes mais legíveis e melhor pensados:

//--- Возвращает установленную величину контролируемого приращения (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];  }

Após o teste detalhado da funcionalidade de evento parar o objeto base CBaseObj, foram detectados erros na definição de eventos. Verificou-se que, no método para preencher as propriedades do objeto base e buscar eventos FillPropertySettings() aconteceu uma imprecisão, isto é, em qualquer caso, no final do método, o estado atual das propriedades era registrado no estado passado. Isso não permitia determinar a magnitude da alteração nas propriedades, uma vez que o valor recém-obtido da propriedade era imediatamente registrado no passado. Para valores pequenos da alteração controlada, esse erro não acontecia, pois a propriedade conseguia se alterar para um valor maior do que o especificado para a geração do evento.
Mas era impossível fazer isso quando era necessário rastrear uma alteração de magnitude consideravelmente grande acontecendo em vários ticks.
Agora foram feitas correções, assim, o evento atual é registrado no passado só quando o evento é registrado:

-*//*-+
-*//*-| Заполняет массив свойств объекта                                 |
-*//*-+
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;
  }
-*//*-+

Anteriormente, no método para inicialização das propriedades do objeto base, as propriedades eram inicializadas com valores LONG_MAX,
agora vamos inicializar os valores com zero:

-*//*-+
-*//*-| Сбрасывает переменные отслеживаемых данных объекта               |
-*//*-+
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;
  }
-*//*-+

Escrevemos a implementação do método CheckEvents(), transferido de 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;
     }
  }  
-*//*-+

Fazemos correções na classe do objeto-símbolo CSymbol.
Abrimos o arquivo \MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqh e fazemos as alterações necessárias.

Da seção privada da classe removemos dois métodos:

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);

O método de inicialização de dados controlados não é necessário, pois todas as propriedades e parâmetros necessários para o rastreamento de qualquer classe com base no objeto base devem ser feitos especificando explicitamente os valores dos parâmetros que estão sendo monitorados e, por padrão, nenhuma alteração nas propriedades dos objetos herdeiros é rastreada. Já transferimos o método CheckEvents() para a classe base CBaseObj.

Da seção pública da classe removemos os métodos que, de fato, duplicam os métodos do objeto base:

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);       }

Os métodos para obter e configurar os parâmetros das propriedades controladas do símbolo agora para retornarem valores usam diretamente métodos da classe base. Simplesmente vou mostrar a lista de métodos:

-*//*-+
-*//*-| Получение и установка параметров отслеживаемых изменений свойств |
-*//*-+
   //--- Исполнение
   //--- Флаг изменения режима торговли для символа
   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);                   }
//---

E os métodos cuja implementação é realizada fora do corpo da classe agora também usam diretamente métodos da classe base:

-*//*-+
-*//*-| Устанавливает контролируемую величину прироста цены 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));
  }
-*//*-+

Além disso, no construtor da classe, cometi um erro lógico: os dados do objeto base não eram preenchidos imediatamente após a criação do objeto-símbolo, isso fazia com que, na primeira inicialização, o evento não fosse monitorado até que não acontecesse algum evento de alteração no valor da propriedade do símbolo com magnitude entre dois ticks vizinhos insignificante; depois disso, eram preenchidos os dados do objeto base.

Vamos corrigir isso, logo após o preenchimento de propriedades do objeto-símbolo, escrevemos o preenchimento de propriedades do seu objeto base:

-*//*-+
-*//*-| Закрытый параметрический конструктор                             |
-*//*-+
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();
  }
-*//*-+

Na classe de coleção de símbolos no arquivo \MQL5\Include\DoEasy\Collections\SymbolsCollection.mqh, na seção pública da classe, também alteramos o nome do método de atualização de símbolos da coleção e da pesquisa de eventos SymbolsEventsControl().
Escolhemos um nome para o método em conformidade com sua tarefa— atualização de dados e pesquisa de eventos:

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

Essas eram todas as alterações que era necessário fazer nas classes do objeto base, do seu herdeiro — objeto-símbolo e classe de coleção de símbolos.

Agora, modifiquemos as classes do objeto-conta para que ele seja o herdeiro do objeto base CBaseObj e obtenha dele a funcionalidade de evento, para facilmente controlar o rastreamento nas alterações de propriedades do objeto-conta.

Renovando o objeto-conta

No último artigo, lembramos que, ao usar o objeto base como fonte de geração de eventos, não necessitávamos mais criar sinalizadores de eventos e criar identificadores de eventos a partir das combinações destes sinalizadores. Agora, a funcionalidade de evento do objeto base é mais flexível. Assim, do arquivo Defines.mqh da biblioteca podemos remover enumerações que já se tornaram desnecessárias:

-*//*-+
-*//*-| Данные для работы с аккаунтами                                   |
-*//*-+
-*//*-+
-*//*-| Список флагов событий аккаунта                                   |
-*//*-+
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,                     -*//*- Уменьшение текущей суммы заблокированных комиссий по счёту
  };

E tudo o que resta destas enumerações é a substituição de macro indicando o código para o próximo evento:

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

Abrimos o arquivo \MQL5\Include\DoEasy\Objects\Accounts\Account.mqh e fazemos as alterações necessárias.

Na seção pública da classe declaramos o método virtual 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);

Para atualizar os dados da conta atual, usaremos o método Refresh() da mesma maneira que na classe CSymbol e em todas as classes subsequentes baseadas no objeto base CBaseObj(). Anteriormente, atualizávamos os dados da conta atual vindos da classe de coleção de contas. Mas, para que todas as classes tenham a mesma estrutura, faremos tudo da mesma maneira que fizemos em CSymbol, também fá-lo-emos em outras classes futuras.

Para obter e definir parâmetros para as propriedades monitoradas do símbolo, já criamos métodos na classe CSymbol.
Criamos os mesmos métodos para a classe de objeto-conta:

-*//*-+
-*//*-| Получение и установка параметров отслеживаемых изменений свойств |
-*//*-+
   //--- установка контролируемой величины (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);             }

-*//*-+

No construtor da classe, primeiro, especificamos os tamanhos dos arrays de dados, em seguida, inicializamos todos os dados controlados no objeto base CBaseObj e, depois do preenchimento de todas as propriedades do objeto-conta, preenchemos as propriedades no objeto base. No final, atualizamos todas as informações da conta no objeto base 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();
  }
-*//*-+-------------------------------------------------------------------+

Fora do corpo da classe, escreveremos a implementação do método virtual para atualizar os dados da conta:

-*//*-+
-*//*-| Обновляет все данные аккаунта                                    |
-*//*-+
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();
  }
-*//*-+

Neste caso, primeiro, é zerado o sinalizador do evento de conta e é redefinida a soma de hash (provavelmente também nos livraremos da soma de hash se ela não for necessária para outros objetos baseados em CBaseObj).
Em seguida, são preenchidas todas as propriedades do objeto-conta e, como no construtor da classe, os dados da conta são preenchidos no objeto base, é chamado o método de atualização do objeto base no qual acontece, além da atualização de dados atuais, a pesquisa de alterações nos valores das propriedades do objeto; adicionalmente, se for excedido o tamanho da alteração nos valores definidos para pesquisa de eventos, serão gerados os eventos base do objeto.
Depois, com ajuda do método CheckEvents() da classe pai verificamos se existem eventos básicos na lista de eventos básicos do objeto CBaseObj, e, se houver, o método criará uma lista de eventos de seu herdeiro, neste caso, uma lista de eventos da conta.

A classe CAccount foi modificada.

Agora vamos editar a classe de coleção de contas.
Abrimos o arquivo \MQL5\Include\DoEasy\Collections\AccountsCollection.mqh e fazemos as alterações necessárias.

Excluímos tudo o que se tornou desnecessário:

-*//*-+
-*//*-| Коллекция аккаунтов                                              |
-*//*-+
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;         }
  };
-*//*-+

Alteramos os tipos de método e adicionamos as declarações de algumas variáveis e métodos necessários:

-*//*-+
-*//*-| Коллекция аккаунтов                                              |
-*//*-+
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);
  };

Do construtor da classe removemos a chamada de dois métodos, agora excluídos, e a limpeza da estrutura excluída:

-*//*-+
-*//*-| Конструктор                                                      |
-*//*-+
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();
  }
-*//*-+

Todas estas variáveis, estruturas e métodos agora são substituídos pela funcionalidade pronta do objeto base; além disso, para as classes herdeiras, eles não precisam ser executados novamente. Como no método de atualização dos dados da conta, é necessário remover a funcionalidade de evento:

-*//*-+
-*//*-| Обновляет данные текущего аккаунта                               |
-*//*-+
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;
     }
  }
-*//*-+

Substituímos tudo o que foi excluído pela chmada do método de atualização da classe base:

-*//*-+
-*//*-| Обновляет данные текущего аккаунта                               |
-*//*-+
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();
  }
-*//*-+

Método que atualiza dados do objeto e que procura alterações de propriedades para gerar eventos:

-*//*-+
-*//*-| Работа с событиями списка символов коллекции                     |
-*//*-+
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());
        }
     }
  }
-*//*-+

Neste caso, obtemos a tick do símbolo atual e, em caso de erro, salvamos o código de erro e saímos do método. Se na lista de coleção de contas não for encontrada a conta atual e seu índice for negativo, saímos do método.
Redefinimos o sinalizador de evento da conta
, limpamos a lista de eventos da conta e para ela definimos o sinalizador da lista classificada.
Da lista de coleção de contas obtemos o objeto da conta atual e atualizamos dados da conta.
Se, no momento, não houver evento de conta,
saímos do método.
Caso contrário, do objeto base obtemos a lista de eventos básicos de conta, definimos o sinalizador do evento da conta, obtemos o código do último evento (muito provavelmente, removeremos esses "remanescentes do passado") e num ciclo para a lista de eventos básicos obtemos o próximo evento da lista, salvamos o último evento da conta, adicionamo-lo à lista de eventos da conta e enviamos o evento para o gráfico do programa de controle.

Da listagem da classe removemos as implementações dos métodos SetAccountsParams(), SetEventCode(), EventDescription(), InitChangesParams() e InitControlsParams().

O método, que retorna o evento da conta por seu número na lista, anteriormente retornava o valor da enumeração. Agora a enumeração é removida e o método retorna int-значение. Logo, se não for encontrado o método, retornamos -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();
  }
-*//*-+

Estas são todas as alterações necessárias na classe de coleção de contas.

Resta fazer pequenas alterações na classe do objeto principal da biblioteca CEngine.
Abrimos o arquivo \MQL5\Include\DoEasy\ Engine.mqh e fazemos as alterações necessárias.

Anteriormente, a variável que armazenava o último evento da conta m_last_account_event e os métodos que retornavam seu GetAccountEventByIndex() e LastAccountEvent() tinham o tipo de enumeração ENUM_ACCOUNT_EVENT, do qual nos livramos. Vamos fazê-los com o tipo 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;                    }

No construtor da classe, na sua lista de inicialização, inicializamos a variável m_last_account_event com o valor -1. Anteriormente, nós a inicializávamos com a constante ACCOUNT_EVENT_NO_EVENT da enumeração excluída 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))
        {
         a::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   //---__MQL4__
   #else 
      if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         a::Print(DFUN_ERR_LINE,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   #endif 
  }
-*//*-+

Como alteramos o nome do método Refresh() da classe de coleção de símbolos para RefreshAndEventsControl() e criamos exatamente o mesmo método na classe de coleção de contas,
nos métodos para trabalhar com eventos de símbolos e de contas substituímos o nome do método a ser chamado:

-*//*-+
-*//*-| Работа с событиями коллекции символов                            |
-*//*-+
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();
     }
  }
-*//*-+

Todas essas são alterações na classe CEngine.

Agora, para qualquer uma das classes com base no objeto base CBaseObj, podemos definir programaticamente as propriedades que queremos rastrear, bem como os valores das alterações nas propriedades que excedidas gerarão eventos dos herdeiros da classe base.
Vamos ver como tudo isso pode ser feito.

Testando a definição de parâmetros de rastreamento e a obtenção de eventos de objeto

Para fazer um teste, pegamos no EA de teste do artigo anterior e o salvamos numa nova pasta com um novo nome
\MQL5\Experts\TestDoEasy\Part18\TestDoEasyPart18.mq5.

Precisamos testar a configuração dos parâmetros cujas alterações queremos rastrear, segundo os valores que definimos, em duas classes diferentes. Agora é possível fazer isso da mesma maneira.

Vamos rastrear a classe CSymbol

  • Aumento de 10 pontos para o preço Bid de todos os símbolos usados
  • Diminuição de 10 pontos para o preço Bid de todos os símbolos usados
  • Aumento de 4 pontos para o preço Bid de todos os símbolos usados
  • Diminuição de 4 pontos para o preço Bid de todos os símbolos usados
  • Controlamos o cruzamento através de um spread de 15 pontos para todos os símbolos usados
  • Controlamos o cruzamento de 1.10300 do preço Bid para o símbolo atual
Para a classe CAccount, rastrearemos
  • Aumento de 10 unidades no lucro atual para a moeda da conta
  • Aumento de 15 unidades no lucro atual para a moeda da conta
  • Controlamos o aumento acima do nível de 20 no lucro atual para a moeda da conta

Se os fundos aumentarem em mais de 15 unidades, fechamos a posição mais lucrativa, se existir e desde que seu lucro seja maior que zero.

Para teste, definimos todos os valores no manipulador 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(". Número de símbolos usados: ",". 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);
  }
-*//*-+

Na listagem, tudo está comentado. Espero que seja claro para estudar individualmente. Note apenas que, após definir o valor rastreado para a propriedade, exibimos esse valor no log (como um exemplo de obtenção de valor de propriedade rastreado definido).

Do manipulador Ontick() excluímos a variável para armazenar o último evento da conta last_account_event . Antes ela era necessária para determinar o novo evento.
Agora, o manipulador fica assim:

-*//*-+
-*//*-| 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();
     }
  }
-*//*-+

Agora todos os sinalizadores sobre novos eventos podem ser obtidos no objeto principal da biblioteca CEngine e, mais importante, pode-se até obter dois eventos idênticos de símbolos diferentes (diz respeito à definição de eventos de símbolos, enquanto a conta é sempre a mesma - a atual). Mas ao usar variáveis, isso era impossível, já que os eventos atuais e passados eram supostamente os mesmos, o que significa que não havia evento. Isso não estava certo.

No manipulador de eventos da biblioteca foram feitas melhorias para determinar eventos da conta o reagir a um aumento específico nos fundos:

-*//*-+
-*//*-| Обработка событий библиотеки 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);
     }
  }
-*//*-+

Todas as ações para identificar eventos são comentadas no código e, espero, sejam claras. Também foram trocados de lugar os blocos de processamento de eventos de diferentes classes (simplesmente para manter a ordem) e separados por condições if - else. Isso é importante porque temos vários tipos de eventos: os eventos de símbolo e de contas são tratados da mesma maneira (usando IDs de coleção), enquanto os eventos de negociação e da janela Observação do Mercado são tratados pelo valor das enumerações dos eventos. Para evitar conflitos entre diferentes métodos de definição de eventos, os blocos foram divididos por instruções condicionais.

A listagem completa do EA pode ser obtida nos arquivos anexados abaixo.

Compilamos o EA, definimos nas configurações do testador valor zero para os parâmetros StopLoss in points e TakeProfit in points, selecionamos para o parâmetro Mode of used symbols list o valor "Trabalhar apenas com o símbolo atual" e iniciamos o teste visual do EA M15 Last month:


Antes de iniciar o teste, vemos que no log são impressos os valores definidos para as propriedades monitoradas do símbolo e da conta. Durante o teste visual, no log são recebidas mensagens sobre eventos recebidos das propriedades cuja alteração é rastreada. Se os fundos aumentarem acima do valor controlado, são fechadas as posições lucrativas.

Criamos um objeto básico para todos os objetos da biblioteca, que fornece aos seus herdeiros funcionalidade de evento e métodos para definir/obter parâmetros de rastreamento, para quaisquer propriedades de qualquer objeto, a qualquer momento.
No futuro, isso simplificará bastante o desenvolvimento de novas classes de novos objetos.

O que vem agora?

No próximo artigo, criaremos uma classe de mensagens da biblioteca — internas (mensagens dos métodos da biblioteca) e externas (mensagens de erro e outras mensagens do terminal).

Abaixo estão anexados todos os arquivos da versão atual da biblioteca e os arquivos do EA de teste. Você pode baixá-los e testar tudo sozinho.
Se você tiver perguntas, comentários e sugestões, poderá expressá-los nos comentários do artigo.

Complementos

Artigos desta série:

Parte 1. Conceito, gerenciamento de dados e primeiros resultados
Parte 2. Coleção do histórico de ordens e negócios
Parte 3. Coleção de ordens e posições de mercado, busca e ordenação
Parte 4. Eventos de Negociação. Conceito
Parte 5. Classes e coleções de eventos de negociação. Envio de eventos para o programa
Parte 6. Eventos da conta netting
Parte 7. Eventos de ativação da ordem stoplimit, preparação da funcionalidade para os eventos de modificação de ordens e posições
Parte 8. Eventos de modificação de ordens e posições
Parte 9. Compatibilidade com a MQL4 - preparação dos dados
Parte 10. Compatibilidade com a MQL4 - eventos de abertura de posição e ativação de ordens pendentes
Parte 11. Compatibilidade com a MQL4 - eventos de encerramento de posição
Parte 12. Implementação da classe de objeto "conta" e da coleção de objetos da conta
Parte 13. Eventos do objeto conta
Parte 14. O objeto símbolo
Parte 15. Coleção de objetos-símbolos
Parte 16. Eventos de coleção de símbolos
Parte 17. Interatividade de objetos de biblioteca


Traduzido do russo pela MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/7149

Arquivos anexados |
MQL5.zip (210.04 KB)
MQL4.zip (210.03 KB)
Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XVII): interatividade de objetos de biblioteca Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XVII): interatividade de objetos de biblioteca

Hoje, concluiremos a lógica da funcionalidade do objeto básico de todos os objetos de biblioteca, o que permitirá que qualquer objeto de biblioteca criado com base nela interaja com o usuário. Por exemplo, podemos definir o tamanho máximo aceitável de spread para abrir uma posição, bem como o nível de preço que intersetado causará que nosso programa receba um evento do objeto-símbolo sobre um sinal indicando o tamanho do spread e o preço que cruza o nível controlado.

Bova abordagem para interpretar a divergência clássica e oculta. Parte II Bova abordagem para interpretar a divergência clássica e oculta. Parte II

Neste artigo, examinaremos criticamente a divergência clássica e analisaremos a eficácia de vários indicadores. Também oferecemos variantes de filtragem para aumentar a precisão da análise e continuar a considerar soluções não padrão. Como resultado, criaremos uma ferramenta atípica para resolver a tarefa em questão.

Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XIX): classe de mensagens de biblioteca Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XIX): classe de mensagens de biblioteca

No artigo, veremos uma classe para exibir mensagens de texto. Agora, vamos supor que temos suficientes mensagens de texto e devemos pensar em comoarmazená-las, exibi-las, editá-las em outro idioma e adicionar novos idiomas à biblioteca e alterná-los rapidamente.

Analisador Sintático HTML com o curl Analisador Sintático HTML com o curl

O artigo fornece a descrição de uma biblioteca simples para análise sintática (parser) de código HTML usando componentes de terceiros. Em particular, ela abrange as possibilidades de acessar dados que não podem ser recuperados usando os métodos HTTP GET e POST. Nós selecionaremos um site com páginas não muito extensas e tentaremos obter alguns dados interessantes dele.