//+------------------------------------------------------------------+
//|                                                        Event.mqh |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict    // Нужно для mql4
//+------------------------------------------------------------------+
//| Включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Object.mqh>
#include "\..\..\Services\DELib.mqh"
#include "..\..\Collections\HistoryCollection.mqh"
#include "..\..\Collections\MarketCollection.mqh"
//+------------------------------------------------------------------+
//| Класс абстрактного события                                       |
//+------------------------------------------------------------------+
class CEvent : public CObject
  {
private:
   int               m_event_code;                                   // Код события
//--- Возвращает индекс массива, по которому фактически расположено (1) double-свойство и (2) string-свойство события
   int               IndexProp(ENUM_EVENT_PROP_DOUBLE property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL;                         }
   int               IndexProp(ENUM_EVENT_PROP_STRING property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL-EVENT_PROP_DOUBLE_TOTAL; }
protected:
   ENUM_TRADE_EVENT  m_trade_event;                                  // Торговое событие
   bool              m_is_hedge;                                     // Флаг хедж-счёта
   long              m_chart_id;                                     // Идентификатор графика управляющей программы
   int               m_digits;                                       // Digits() символа
   int               m_digits_acc;                                   // Количество знаков после запятой для валюты счета
   long              m_long_prop[EVENT_PROP_INTEGER_TOTAL];          // Целочисленные свойства события
   double            m_double_prop[EVENT_PROP_DOUBLE_TOTAL];         // Вещественные свойства события
   string            m_string_prop[EVENT_PROP_STRING_TOTAL];         // Строковые свойства события
//--- возвращает факт наличия флага в торговом событии
   bool              IsPresentEventFlag(const int event_code)  const { return (this.m_event_code & event_code)==event_code;                  }
//--- Возвращает (1) заданный магический номер, идентификатор (2) первой группы, (3) второй группы, (4) отложенного запроса из значения магика
   ushort            GetMagicID(void)                          const { return ushort(this.Magic() & 0xFFFF);                                 }
   uchar             GetGroupID1(void)                         const { return uchar(this.Magic()>>16) & 0x0F;                                }
   uchar             GetGroupID2(void)                         const { return uchar((this.Magic()>>16) & 0xF0)>>4;                           }
   uchar             GetPendReqID(void)                        const { return uchar(this.Magic()>>24) & 0xFF;                                }
//--- Защищённый параметрический конструктор
                     CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket);
public:
//--- Конструктор по умолчанию
                     CEvent(void){;}
 
//--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство события
   void              SetProperty(ENUM_EVENT_PROP_INTEGER property,long value) { this.m_long_prop[property]=value;                            }
   void              SetProperty(ENUM_EVENT_PROP_DOUBLE property,double value){ this.m_double_prop[this.IndexProp(property)]=value;          }
   void              SetProperty(ENUM_EVENT_PROP_STRING property,string value){ this.m_string_prop[this.IndexProp(property)]=value;          }
//--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство события
   long              GetProperty(ENUM_EVENT_PROP_INTEGER property)      const { return this.m_long_prop[property];                           }
   double            GetProperty(ENUM_EVENT_PROP_DOUBLE property)       const { return this.m_double_prop[this.IndexProp(property)];         }
   string            GetProperty(ENUM_EVENT_PROP_STRING property)       const { return this.m_string_prop[this.IndexProp(property)];         }

//--- Возвращает флаг поддержания событием данного свойства
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property)        { return true; }
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property)         { return true; }
   virtual bool      SupportProperty(ENUM_EVENT_PROP_STRING property)         { return true; }

//--- Устанавливает идентификатор графика управляющей программы
   void              SetChartID(const long id)                                { this.m_chart_id=id;                                          }
//--- Расшифровывает код события и устанавливает торговое событие, (2) возвращает торговое событие
   void              SetTypeEvent(void);
   ENUM_TRADE_EVENT  TradeEvent(void)                                   const { return this.m_trade_event;                                   }
//--- Отправляет событие на график (реализация в потомках класса)
   virtual void      SendEvent(void) {;}

//--- Сравнивает объекты CEvent между собой по заданному свойству (для сортировки списков по указанному свойству объекта-события)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Сравнивает объекты CEvent между собой по всем свойствам (для поиска равных объектов-событий)
   bool              IsEqual(CEvent* compared_event);
//+------------------------------------------------------------------+
//| Методы упрощённого доступа к свойствам объекта-события           |
//+------------------------------------------------------------------+
//--- Возвращает (1) тип события, (2) время события в милисекундах, (3) статус события, (4) причину события, (5) тип сделки, (6) тикет сделки, 
//--- (7) тип ордера, на основании которого исполнена сделка, (8) тип открывающего ордера позиции, (9) тикет последнего ордера позиции, 
//--- (10) тикет первого ордера позиции, (11) идентификатор позиции, (12) идентификатор встречной позиции, (13) магик, (14) магик встречной, (15) время открытия позиции
   ENUM_TRADE_EVENT  TypeEvent(void)                                    const { return (ENUM_TRADE_EVENT)this.GetProperty(EVENT_PROP_TYPE_EVENT);           }
   long              TimeEvent(void)                                    const { return this.GetProperty(EVENT_PROP_TIME_EVENT);                             }
   ENUM_EVENT_STATUS Status(void)                                       const { return (ENUM_EVENT_STATUS)this.GetProperty(EVENT_PROP_STATUS_EVENT);        }
   ENUM_EVENT_REASON Reason(void)                                       const { return (ENUM_EVENT_REASON)this.GetProperty(EVENT_PROP_REASON_EVENT);        }
   ENUM_DEAL_TYPE    TypeDeal(void)                                     const { return (ENUM_DEAL_TYPE)this.GetProperty(EVENT_PROP_TYPE_DEAL_EVENT);        }
   long              TicketDeal(void)                                   const { return this.GetProperty(EVENT_PROP_TICKET_DEAL_EVENT);                      }
   ENUM_ORDER_TYPE   TypeOrderEvent(void)                               const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORDER_EVENT);      }
   ENUM_ORDER_TYPE   TypeFirstOrderPosition(void)                       const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORDER_POSITION);   }
   long              TicketOrderEvent(void)                             const { return this.GetProperty(EVENT_PROP_TICKET_ORDER_EVENT);                     }
   long              TicketFirstOrderPosition(void)                     const { return this.GetProperty(EVENT_PROP_TICKET_ORDER_POSITION);                  }
   long              PositionID(void)                                   const { return this.GetProperty(EVENT_PROP_POSITION_ID);                            }
   long              PositionByID(void)                                 const { return this.GetProperty(EVENT_PROP_POSITION_BY_ID);                         }
   long              Magic(void)                                        const { return this.GetProperty(EVENT_PROP_MAGIC_ORDER);                            }
   long              MagicCloseBy(void)                                 const { return this.GetProperty(EVENT_PROP_MAGIC_BY_ID);                            }
   long              TimePosition(void)                                 const { return this.GetProperty(EVENT_PROP_TIME_ORDER_POSITION);                    }

//--- При смене направления позиции возвращает (1) тип ордера предыдущей позиции, (2) тикет ордера предыдущей позиции
//--- (3) тип ордера текущей позиции, (4) тикет ордера текущей позиции
//--- (5) тип и (6) тикет позиции до смены направления, (7) тип и (8) тикет позиции после смены направления
   ENUM_ORDER_TYPE   TypeOrderPosPrevious(void)                         const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE);   }
   long              TicketOrderPosPrevious(void)                       const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE); }
   ENUM_ORDER_TYPE   TypeOrderPosCurrent(void)                          const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT);  }
   long              TicketOrderPosCurrent(void)                        const { return (ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT);}
   ENUM_POSITION_TYPE TypePositionPrevious(void)                        const { return PositionTypeByOrderType(this.TypeOrderPosPrevious());                }
   ulong             TicketPositionPrevious(void)                       const { return this.TicketOrderPosPrevious();                                       }
   ENUM_POSITION_TYPE TypePositionCurrent(void)                         const { return PositionTypeByOrderType(this.TypeOrderPosCurrent());                 }
   ulong             TicketPositionCurrent(void)                        const { return this.TicketOrderPosCurrent();                                        }
   
//--- Возвращает (1) цену, на которой произошло событие, (2) цену открытия, (3) цену закрытия,
//--- (4) цену StopLoss, (5) цену TakeProfit, (6) профит, (7) Запрашиваемый объём ордера, 
//--- 8) Исполненный объём ордера, (9) Оставшийся объём ордера, (10) исполненный объём позиции
   double            PriceEvent(void)                                   const { return this.GetProperty(EVENT_PROP_PRICE_EVENT);                            }
   double            PriceOpen(void)                                    const { return this.GetProperty(EVENT_PROP_PRICE_OPEN);                             }
   double            PriceClose(void)                                   const { return this.GetProperty(EVENT_PROP_PRICE_CLOSE);                            }
   double            PriceStopLoss(void)                                const { return this.GetProperty(EVENT_PROP_PRICE_SL);                               }
   double            PriceTakeProfit(void)                              const { return this.GetProperty(EVENT_PROP_PRICE_TP);                               }
   double            Profit(void)                                       const { return this.GetProperty(EVENT_PROP_PROFIT);                                 }
   double            VolumeOrderInitial(void)                           const { return this.GetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL);                   }
   double            VolumeOrderExecuted(void)                          const { return this.GetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED);                  }
   double            VolumeOrderCurrent(void)                           const { return this.GetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT);                   }
   double            VolumePositionExecuted(void)                       const { return this.GetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED);               }

//--- При модификации цен возвращает (1) цену установки ордера, (2) StopLoss, (3) TakeProfit до модификации
   double            PriceOpenBefore(void)                              const { return this.GetProperty(EVENT_PROP_PRICE_OPEN_BEFORE);                      }
   double            PriceStopLossBefore(void)                          const { return this.GetProperty(EVENT_PROP_PRICE_SL_BEFORE);                        }
   double            PriceTakeProfitBefore(void)                        const { return this.GetProperty(EVENT_PROP_PRICE_TP_BEFORE);                        }
   double            PriceEventAsk(void)                                const { return this.GetProperty(EVENT_PROP_PRICE_EVENT_ASK);                        }
   double            PriceEventBid(void)                                const { return this.GetProperty(EVENT_PROP_PRICE_EVENT_BID);                        }

//--- Возвращает (1) символ, (2) символ встречной позиции
   string            Symbol(void)                                       const { return this.GetProperty(EVENT_PROP_SYMBOL);                                 }
   string            SymbolCloseBy(void)                                const { return this.GetProperty(EVENT_PROP_SYMBOL_BY_ID);                           }
   
//+------------------------------------------------------------------+
//| Описания свойств объекта-ордера                                  |
//+------------------------------------------------------------------+
//--- Возвращает описание (1) целочисленного, (2) вещественного и (3) строкового свойства ордера
   string            GetPropertyDescription(ENUM_EVENT_PROP_INTEGER property);
   string            GetPropertyDescription(ENUM_EVENT_PROP_DOUBLE property);
   string            GetPropertyDescription(ENUM_EVENT_PROP_STRING property);
//--- Возвращает наименование (1) статуса, (2) типа события
   string            StatusDescription(void)                const;
   string            TypeEventDescription(void)             const;
//--- Возвращает наименование (1) ордера сделки события, (2) родительского ордера позиции, (3) ордера текущей позиции, (4) текущей позиции
//--- Возвращает наименование (5) ордера и (6) позиции до смены направления
   string            TypeOrderDealDescription(void)         const;
   string            TypeOrderFirstDescription(void)        const;
   string            TypeOrderEventDescription(void)        const;
   string            TypePositionCurrentDescription(void)   const;
   string            TypeOrderPreviousDescription(void)     const;
   string            TypePositionPreviousDescription(void)  const;
//--- Возвращает наименование причины сделки/ордера/позиции
   string            ReasonDescription(void)                const;

//--- Выводит в журнал (1) описание свойств ордера (full_prop=true - все свойства, false - только поддерживаемые),
//--- (2) краткое сообщение о событии (реализация в потомках класса)
   void              Print(const bool full_prop=false);
   virtual void      PrintShort(void) {;}
  };
//+------------------------------------------------------------------+
//| Конструктор                                                      |
//+------------------------------------------------------------------+
CEvent::CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket) : m_event_code(event_code),m_digits(0)
  {
   this.m_long_prop[EVENT_PROP_STATUS_EVENT]       =  event_status;
   this.m_long_prop[EVENT_PROP_TICKET_ORDER_EVENT] =  (long)ticket;
   this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
   this.m_digits_acc=#ifdef __MQL4__ 2 #else (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #endif;
   this.m_chart_id=::ChartID();
  }
//+------------------------------------------------------------------+
//| Сравнивает объекты CEvent между собой по заданному свойству      |
//+------------------------------------------------------------------+
int CEvent::Compare(const CObject *node,const int mode=0) const
  {
   const CEvent *event_compared=node;
//--- сравнение целочисленных свойств двух событий
   if(mode<EVENT_PROP_INTEGER_TOTAL)
     {
      long value_compared=event_compared.GetProperty((ENUM_EVENT_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_EVENT_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- сравнение вещественных свойств двух событий
   if(mode<EVENT_PROP_DOUBLE_TOTAL+EVENT_PROP_INTEGER_TOTAL)
     {
      double value_compared=event_compared.GetProperty((ENUM_EVENT_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_EVENT_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- сравнение строковых свойств двух событий
   else if(mode<EVENT_PROP_DOUBLE_TOTAL+EVENT_PROP_INTEGER_TOTAL+EVENT_PROP_STRING_TOTAL)
     {
      string value_compared=event_compared.GetProperty((ENUM_EVENT_PROP_STRING)mode);
      string value_current=this.GetProperty((ENUM_EVENT_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+
//| Сравнивает объекты CEvent между собой по всем свойствам          |
//+------------------------------------------------------------------+
bool CEvent::IsEqual(CEvent *compared_event)
  {
   int beg=0, end=EVENT_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_INTEGER prop=(ENUM_EVENT_PROP_INTEGER)i;
      if(this.GetProperty(prop)!=compared_event.GetProperty(prop)) return false; 
     }
   beg=end; end+=EVENT_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_DOUBLE prop=(ENUM_EVENT_PROP_DOUBLE)i;
      if(this.GetProperty(prop)!=compared_event.GetProperty(prop)) return false; 
     }
   beg=end; end+=EVENT_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_STRING prop=(ENUM_EVENT_PROP_STRING)i;
      if(this.GetProperty(prop)!=compared_event.GetProperty(prop)) return false; 
     }
//---
   return true;
  }
//+------------------------------------------------------------------+
//| Расшифровывает код события и устанавливает торговое событие      |
//+------------------------------------------------------------------+
void CEvent::SetTypeEvent(void)
  {
//--- Установка Digits() символа события
   this.m_digits=(int)::SymbolInfoInteger(this.Symbol(),SYMBOL_DIGITS);
//--- Отложенный ордер установлен (проверяем на равенство коду события, так как здесь может быть только один флаг)
   if(this.m_event_code==TRADE_EVENT_FLAG_ORDER_PLASED)
     {
      this.m_trade_event=TRADE_EVENT_PENDING_ORDER_PLASED;
      this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
      return;
     }
//--- Отложенный ордер удалён (проверяем на равенство коду события, так как здесь может быть только один флаг)
   if(this.m_event_code==TRADE_EVENT_FLAG_ORDER_REMOVED)
     {
      this.m_trade_event=TRADE_EVENT_PENDING_ORDER_REMOVED;
      this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
      return;
     }
//--- Модифицирован отложенный ордер
   if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_ORDER_MODIFY))
     {
      //--- Если модифицирована цена установки
      if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_PRICE))
        {
         this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_PRICE;
         //--- Если модифицированы StopLoss и TakeProfit
         if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL) && this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_PRICE_SL_TP;
         //--- Если модифицирован StopLoss
         else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_PRICE_SL;
         //--- Если модифицирован TakeProfit
         else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_PRICE_TP;
        }
      //--- Если цена установки не модифицирована
      else
        {
         //--- Если модифицированы StopLoss и TakeProfit
         if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL) && this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_SL_TP;
         //--- Если модифицирован StopLoss
         else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_SL;
         //--- Если модифицирован TakeProfit
         else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
            this.m_trade_event=TRADE_EVENT_MODIFY_ORDER_TP;
        }
      this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
      return;
     }
//--- Модифицирована позиция
   if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_MODIFY))
     {
      //--- Если модифицированы StopLoss и TakeProfit
      if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL) && this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
         this.m_trade_event=TRADE_EVENT_MODIFY_POSITION_SL_TP;
      //--- Если модифицирован StopLoss
      else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL))
         this.m_trade_event=TRADE_EVENT_MODIFY_POSITION_SL;
      //--- Если модифицирован TakeProfit
      else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
         this.m_trade_event=TRADE_EVENT_MODIFY_POSITION_TP;
      this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
      return;
     }
//--- Позиция открыта (Проверяем наличие множества флагов в коде события)
   if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_OPENED))
     {
      //--- Если это изменение существующей позиции
      if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_CHANGED))
        {
         //--- Если это отложенный ордер активирован ценой
         if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_ORDER_ACTIVATED))
           {
            //--- Если это разворот позиции
            if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_REVERSE))
              {
               //--- проверяем флаг частичного открытия и устанавливаем торговое событие 
               //--- "разворот позиции активацией отложенного ордера" или "разворот позиции частичной активацией отложенного ордера"
               this.m_trade_event=
                 (
                  !this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? 
                  TRADE_EVENT_POSITION_REVERSED_BY_PENDING : 
                  TRADE_EVENT_POSITION_REVERSED_BY_PENDING_PARTIAL
                 );
               this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
               return;
              }
            //--- Если это добавление объёма к позиции
            else
              {
               //--- проверяем флаг частичного открытия и устанавливаем торговое событие 
               //--- "добавлен объём к позиции активацией отложенного ордера" или "добавлен объём к позиции частичной активацией отложенного ордера"
               this.m_trade_event=
                 (
                  !this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? 
                  TRADE_EVENT_POSITION_VOLUME_ADD_BY_PENDING : 
                  TRADE_EVENT_POSITION_VOLUME_ADD_BY_PENDING_PARTIAL
                 );
               this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
               return;
              }
           }
         //--- Если изменение позиции было осуществлено сделкой ро рынку
         else
           {
            //--- Если это разворот позиции
            if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_REVERSE))
              {
               //--- проверяем флаг частичного открытия и устанавливаем торговое событие "разворот позиции" или "разворот позиции частичным исполнением"
               this.m_trade_event=
                 (
                  !this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? 
                  TRADE_EVENT_POSITION_REVERSED_BY_MARKET : 
                  TRADE_EVENT_POSITION_REVERSED_BY_MARKET_PARTIAL
                 );
               this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
               return;
              }
            //--- Если это добавление объёма к позиции
            else
              {
               //--- проверяем флаг частичного открытия и устанавливаем торговое событие "добавлен объём к позиции" или "добавлен объём к позиции частичным исполнением"
               this.m_trade_event=
                 (
                  !this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? 
                  TRADE_EVENT_POSITION_VOLUME_ADD_BY_MARKET : 
                  TRADE_EVENT_POSITION_VOLUME_ADD_BY_MARKET_PARTIAL
                 );
               this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
               return;
              }
           }
        }
   //--- Если это открытие новой позиции
      else
        {
         //--- Если это отложенный ордер активирован ценой
         if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_ORDER_ACTIVATED))
           {
            //--- проверяем флаг частичного открытия и устанавливаем торговое событие "отложенный ордер активирован" или "отложенный ордер активирован частично"
            this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_PENDING_ORDER_ACTIVATED : TRADE_EVENT_PENDING_ORDER_ACTIVATED_PARTIAL);
            this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
            return;
           }
         //--- проверяем флаг частичного открытия и устанавливаем торговое событие "Позиция открыта" или "Позиция открыта частично"
         this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_POSITION_OPENED : TRADE_EVENT_POSITION_OPENED_PARTIAL);
         this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
         return;
        }
     }
     
//--- Позиция закрыта (Проверяем наличие множества флагов в коде события)
   if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_POSITION_CLOSED))
     {
      //--- если позиция закрыта по StopLoss
      if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_SL))
        {
         //--- проверяем флаг частичного закрытия и устанавливаем торговое событие "Позиция закрыта по StopLoss" или "Позиция закрыта по StopLoss частично"
         this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_POSITION_CLOSED_BY_SL : TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_SL);
         this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
         return;
        }
      //--- если позиция закрыта по TakeProfit
      else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_TP))
        {
         //--- проверяем флаг частичного закрытия и устанавливаем торговое событие "Позиция закрыта по TakeProfit" или "Позиция закрыта по TakeProfit частично"
         this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_POSITION_CLOSED_BY_TP : TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_TP);
         this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
         return;
        }
      //--- если позиция закрыта встречной
      else if(this.IsPresentEventFlag(TRADE_EVENT_FLAG_BY_POS))
        {
         //--- проверяем флаг частичного закрытия и устанавливаем торговое событие "Позиция закрыта встречной" или "Позиция закрыта встречной частично"
         this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_POSITION_CLOSED_BY_POS : TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_POS);
         this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
         return;
        }
      //--- Если позиция закрыта
      else
        {
         //--- проверяем флаг частичного закрытия и устанавливаем торговое событие "Позиция закрыта" или "Позиция закрыта частично"
         this.m_trade_event=(!this.IsPresentEventFlag(TRADE_EVENT_FLAG_PARTIAL) ? TRADE_EVENT_POSITION_CLOSED : TRADE_EVENT_POSITION_CLOSED_PARTIAL);
         this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
         return;
        }
     }
//--- Балансовая операция на счёте (уточняем событие по типу сделки)
   if(this.m_event_code==TRADE_EVENT_FLAG_ACCOUNT_BALANCE)
     {
      //--- Инициализируем торговое событие
      this.m_trade_event=TRADE_EVENT_NO_EVENT;
      //--- Возьмём тип сделки
      ENUM_DEAL_TYPE deal_type=(ENUM_DEAL_TYPE)this.GetProperty(EVENT_PROP_TYPE_DEAL_EVENT);
      //--- если сделка - балансовая операция
      if(deal_type==DEAL_TYPE_BALANCE)
        {
        //--- проверим профит сделки и установим событие (пополнение или снятие средств)
         this.m_trade_event=(this.GetProperty(EVENT_PROP_PROFIT)>0 ? TRADE_EVENT_ACCOUNT_BALANCE_REFILL : TRADE_EVENT_ACCOUNT_BALANCE_WITHDRAWAL);
        }
      //--- Остальные типы балансной операции совпадают с перечислением ENUM_DEAL_TYPE начиная от DEAL_TYPE_CREDIT
      else if(deal_type>DEAL_TYPE_BALANCE)
        {
        //--- установим это событие
         this.m_trade_event=(ENUM_TRADE_EVENT)deal_type;
        }
      this.SetProperty(EVENT_PROP_TYPE_EVENT,this.m_trade_event);
      return;
     }
  }
//+------------------------------------------------------------------+
//| Возвращает описание целочисленного свойства события              |
//+------------------------------------------------------------------+
string CEvent::GetPropertyDescription(ENUM_EVENT_PROP_INTEGER property)
  {
   return
     (
      property==EVENT_PROP_TYPE_EVENT              ?  CMessage::Text(MSG_EVN_TYPE)+": "+this.TypeEventDescription()                                                       :
      property==EVENT_PROP_TIME_EVENT              ?  CMessage::Text(MSG_EVN_TIME)+": "+TimeMSCtoString(this.GetProperty(property))                                       :
      property==EVENT_PROP_STATUS_EVENT            ?  CMessage::Text(MSG_EVN_STATUS)+": \""+this.StatusDescription()+"\""                                                 :
      property==EVENT_PROP_REASON_EVENT            ?  CMessage::Text(MSG_EVN_REASON)+": "+this.ReasonDescription()                                                        :
      property==EVENT_PROP_TYPE_DEAL_EVENT         ?  CMessage::Text(MSG_EVN_TYPE_DEAL)+": "+DealTypeDescription((ENUM_DEAL_TYPE)this.GetProperty(property))              :
      property==EVENT_PROP_TICKET_DEAL_EVENT       ?  CMessage::Text(MSG_EVN_TICKET_DEAL)+": #"+(string)this.GetProperty(property)                                        :
      property==EVENT_PROP_TYPE_ORDER_EVENT        ?  CMessage::Text(MSG_EVN_TYPE_ORDER)+": "+OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(property))           :
      property==EVENT_PROP_TYPE_ORDER_POSITION     ?  CMessage::Text(MSG_EVN_TYPE_ORDER_POSITION)+": "+OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(property))  :
      property==EVENT_PROP_TICKET_ORDER_POSITION   ?  CMessage::Text(MSG_EVN_TICKET_ORDER_POSITION)+": #"+(string)this.GetProperty(property)                              :
      property==EVENT_PROP_TICKET_ORDER_EVENT      ?  CMessage::Text(MSG_EVN_TICKET_ORDER_EVENT)+": #"+(string)this.GetProperty(property)                                 :
      property==EVENT_PROP_POSITION_ID             ?  CMessage::Text(MSG_EVN_POSITION_ID)+": #"+(string)this.GetProperty(property)                                        :
      property==EVENT_PROP_POSITION_BY_ID          ?  CMessage::Text(MSG_EVN_POSITION_BY_ID)+": #"+(string)this.GetProperty(property)                                     :
      property==EVENT_PROP_MAGIC_ORDER             ?  CMessage::Text(MSG_ORD_MAGIC)+": "+(string)this.GetProperty(property)                                               :
      property==EVENT_PROP_MAGIC_BY_ID             ?  CMessage::Text(MSG_EVN_MAGIC_BY_ID)+": "+(string)this.GetProperty(property)                                         :
      property==EVENT_PROP_TIME_ORDER_POSITION     ?  CMessage::Text(MSG_EVN_TIME_ORDER_POSITION)+": "+TimeMSCtoString(this.GetProperty(property))                        :
      property==EVENT_PROP_TYPE_ORD_POS_BEFORE     ?  CMessage::Text(MSG_EVN_TYPE_ORD_POS_BEFORE)+": "+OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(property))  :
      property==EVENT_PROP_TICKET_ORD_POS_BEFORE   ?  CMessage::Text(MSG_EVN_TICKET_ORD_POS_BEFORE)+": #"+(string)this.GetProperty(property)                              :
      property==EVENT_PROP_TYPE_ORD_POS_CURRENT    ?  CMessage::Text(MSG_EVN_TYPE_ORD_POS_CURRENT)+": "+OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(property)) :
      property==EVENT_PROP_TICKET_ORD_POS_CURRENT  ?  CMessage::Text(MSG_EVN_TICKET_ORD_POS_CURRENT)+": #"+(string)this.GetProperty(property)                             :
      ::EnumToString(property)
     );
  }
//+------------------------------------------------------------------+
//| Возвращает описание вещественного свойства события               |
//+------------------------------------------------------------------+
string CEvent::GetPropertyDescription(ENUM_EVENT_PROP_DOUBLE property)
  {
   int dg=(int)::SymbolInfoInteger(this.GetProperty(EVENT_PROP_SYMBOL),SYMBOL_DIGITS);
   int dgl=(int)DigitsLots(this.GetProperty(EVENT_PROP_SYMBOL));
   return
     (
      property==EVENT_PROP_PRICE_EVENT             ?  CMessage::Text(MSG_EVN_PRICE_EVENT)+": "+::DoubleToString(this.GetProperty(property),dg)                 :
      property==EVENT_PROP_PRICE_OPEN              ?  CMessage::Text(MSG_ORD_PRICE_OPEN)+": "+::DoubleToString(this.GetProperty(property),dg)                  :
      property==EVENT_PROP_PRICE_CLOSE             ?  CMessage::Text(MSG_ORD_PRICE_CLOSE)+": "+::DoubleToString(this.GetProperty(property),dg)                 :
      property==EVENT_PROP_PRICE_SL                ?  CMessage::Text(MSG_LIB_PROP_PRICE_SL)+": "+::DoubleToString(this.GetProperty(property),dg)               :
      property==EVENT_PROP_PRICE_TP                ?  CMessage::Text(MSG_LIB_PROP_PRICE_TP)+": "+::DoubleToString(this.GetProperty(property),dg)               :
      property==EVENT_PROP_VOLUME_ORDER_INITIAL    ?  CMessage::Text(MSG_EVN_VOLUME_ORDER_INITIAL)+": "+::DoubleToString(this.GetProperty(property),dgl)       :
      property==EVENT_PROP_VOLUME_ORDER_EXECUTED   ?  CMessage::Text(MSG_EVN_VOLUME_ORDER_EXECUTED)+": "+::DoubleToString(this.GetProperty(property),dgl)      :
      property==EVENT_PROP_VOLUME_ORDER_CURRENT    ?  CMessage::Text(MSG_EVN_VOLUME_ORDER_CURRENT)+": "+::DoubleToString(this.GetProperty(property),dgl)       :
      property==EVENT_PROP_VOLUME_POSITION_EXECUTED ? CMessage::Text(MSG_EVN_VOLUME_POSITION_EXECUTED)+": "+::DoubleToString(this.GetProperty(property),dgl)   :
      property==EVENT_PROP_PROFIT                  ?  CMessage::Text(MSG_LIB_PROP_PROFIT)+": "+::DoubleToString(this.GetProperty(property),this.m_digits_acc)  :
      property==EVENT_PROP_PRICE_OPEN_BEFORE       ?  CMessage::Text(MSG_EVN_PRICE_OPEN_BEFORE)+": "+::DoubleToString(this.GetProperty(property),dg)           :
      property==EVENT_PROP_PRICE_SL_BEFORE         ?  CMessage::Text(MSG_EVN_PRICE_SL_BEFORE)+": "+::DoubleToString(this.GetProperty(property),dg)             :
      property==EVENT_PROP_PRICE_TP_BEFORE         ?  CMessage::Text(MSG_EVN_PRICE_TP_BEFORE)+": "+::DoubleToString(this.GetProperty(property),dg)             :
      property==EVENT_PROP_PRICE_EVENT_ASK         ?  CMessage::Text(MSG_EVN_PRICE_EVENT_ASK)+": "+::DoubleToString(this.GetProperty(property),dg)             :
      property==EVENT_PROP_PRICE_EVENT_BID         ?  CMessage::Text(MSG_EVN_PRICE_EVENT_BID)+": "+::DoubleToString(this.GetProperty(property),dg)             :
      ::EnumToString(property)
     );
  }
//+------------------------------------------------------------------+
//| Возвращает описание строкового свойства события                  |
//+------------------------------------------------------------------+
string CEvent::GetPropertyDescription(ENUM_EVENT_PROP_STRING property)
  {
   return
     (
      property==EVENT_PROP_SYMBOL ? CMessage::Text(MSG_LIB_PROP_SYMBOL)+": \""+this.GetProperty(property)+"\"" :
      CMessage::Text(MSG_EVN_SYMBOL_BY_POS)+": \""+this.GetProperty(property)+"\""
     );
  }
//+------------------------------------------------------------------+
//| Возвращает наименование статуса события                          |
//+------------------------------------------------------------------+
string CEvent::StatusDescription(void) const
  {
   ENUM_EVENT_STATUS status=(ENUM_EVENT_STATUS)this.GetProperty(EVENT_PROP_STATUS_EVENT);
   return
     (
      status==EVENT_STATUS_MARKET_PENDING    ?  CMessage::Text(MSG_EVN_STATUS_MARKET_PENDING)   :
      status==EVENT_STATUS_MARKET_POSITION   ?  CMessage::Text(MSG_EVN_STATUS_MARKET_POSITION)  :
      status==EVENT_STATUS_HISTORY_PENDING   ?  CMessage::Text(MSG_EVN_STATUS_HISTORY_PENDING)  :
      status==EVENT_STATUS_HISTORY_POSITION  ?  CMessage::Text(MSG_EVN_STATUS_HISTORY_POSITION) :
      status==EVENT_STATUS_BALANCE           ?  CMessage::Text(MSG_LIB_PROP_BALANCE)            :
      CMessage::Text(MSG_EVN_STATUS_UNKNOWN)
     );
  }
//+------------------------------------------------------------------+
//| Возвращает наименование торгового события                        |
//+------------------------------------------------------------------+
string CEvent::TypeEventDescription(void) const
  {
   ENUM_TRADE_EVENT event=this.TypeEvent();
   return
     (
      event==TRADE_EVENT_NO_EVENT                              ?  CMessage::Text(MSG_EVN_NO_EVENT)                            :
      event==TRADE_EVENT_PENDING_ORDER_PLASED                  ?  CMessage::Text(MSG_EVN_PENDING_ORDER_PLASED)                :
      event==TRADE_EVENT_PENDING_ORDER_REMOVED                 ?  CMessage::Text(MSG_EVN_PENDING_ORDER_REMOVED)               :
      event==TRADE_EVENT_ACCOUNT_CREDIT                        ?  CMessage::Text(MSG_EVN_ACCOUNT_CREDIT)                      :
      event==TRADE_EVENT_ACCOUNT_CHARGE                        ?  CMessage::Text(MSG_EVN_ACCOUNT_CHARGE)                      :
      event==TRADE_EVENT_ACCOUNT_CORRECTION                    ?  CMessage::Text(MSG_EVN_ACCOUNT_CORRECTION)                  :
      event==TRADE_EVENT_ACCOUNT_BONUS                         ?  CMessage::Text(MSG_EVN_ACCOUNT_BONUS)                       :
      event==TRADE_EVENT_ACCOUNT_COMISSION                     ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION)                   :
      event==TRADE_EVENT_ACCOUNT_COMISSION_DAILY               ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_DAILY)             :
      event==TRADE_EVENT_ACCOUNT_COMISSION_MONTHLY             ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_MONTHLY)           :
      event==TRADE_EVENT_ACCOUNT_COMISSION_AGENT_DAILY         ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_AGENT_DAILY)       :
      event==TRADE_EVENT_ACCOUNT_COMISSION_AGENT_MONTHLY       ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_AGENT_MONTHLY)     :
      event==TRADE_EVENT_ACCOUNT_INTEREST                      ?  CMessage::Text(MSG_EVN_ACCOUNT_INTEREST)                    :
      event==TRADE_EVENT_BUY_CANCELLED                         ?  CMessage::Text(MSG_EVN_BUY_CANCELLED)                       :
      event==TRADE_EVENT_SELL_CANCELLED                        ?  CMessage::Text(MSG_EVN_SELL_CANCELLED)                      :
      event==TRADE_EVENT_DIVIDENT                              ?  CMessage::Text(MSG_EVN_DIVIDENT)                            :
      event==TRADE_EVENT_DIVIDENT_FRANKED                      ?  CMessage::Text(MSG_EVN_DIVIDENT_FRANKED)                    :
      event==TRADE_EVENT_TAX                                   ?  CMessage::Text(MSG_EVN_TAX)                                 :
      event==TRADE_EVENT_ACCOUNT_BALANCE_REFILL                ?  CMessage::Text(MSG_EVN_BALANCE_REFILL)                      :
      event==TRADE_EVENT_ACCOUNT_BALANCE_WITHDRAWAL            ?  CMessage::Text(MSG_EVN_BALANCE_WITHDRAWAL)                  :
      event==TRADE_EVENT_PENDING_ORDER_ACTIVATED               ?  CMessage::Text(MSG_EVN_ACTIVATED_PENDING)                   :
      event==TRADE_EVENT_PENDING_ORDER_ACTIVATED_PARTIAL       ?  CMessage::Text(MSG_EVN_ACTIVATED_PENDING_PARTIALLY)         :
      event==TRADE_EVENT_POSITION_OPENED                       ?  CMessage::Text(MSG_EVN_STATUS_MARKET_POSITION)              :
      event==TRADE_EVENT_POSITION_OPENED_PARTIAL               ?  CMessage::Text(MSG_EVN_POSITION_OPENED_PARTIALLY)           :
      event==TRADE_EVENT_POSITION_CLOSED                       ?  CMessage::Text(MSG_EVN_STATUS_HISTORY_POSITION)             :
      event==TRADE_EVENT_POSITION_CLOSED_PARTIAL               ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_PARTIALLY)           :
      event==TRADE_EVENT_POSITION_CLOSED_BY_POS                ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_BY_POS)              :
      event==TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_POS        ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_PARTIALLY_BY_POS)    :
      event==TRADE_EVENT_POSITION_CLOSED_BY_SL                 ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_BY_SL)               :
      event==TRADE_EVENT_POSITION_CLOSED_BY_TP                 ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_BY_TP)               :
      event==TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_SL         ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_PARTIALLY_BY_SL)     :
      event==TRADE_EVENT_POSITION_CLOSED_PARTIAL_BY_TP         ?  CMessage::Text(MSG_EVN_POSITION_CLOSED_PARTIALLY_BY_TP)     :
      event==TRADE_EVENT_POSITION_REVERSED_BY_MARKET           ?  CMessage::Text(MSG_EVN_POSITION_REVERSED_BY_MARKET)         :
      event==TRADE_EVENT_POSITION_REVERSED_BY_PENDING          ?  CMessage::Text(MSG_EVN_POSITION_REVERSED_BY_PENDING)        :
      event==TRADE_EVENT_POSITION_VOLUME_ADD_BY_MARKET         ?  CMessage::Text(MSG_EVN_POSITION_VOLUME_ADD_BY_MARKET)       :
      event==TRADE_EVENT_POSITION_VOLUME_ADD_BY_PENDING        ?  CMessage::Text(MSG_EVN_POSITION_VOLUME_ADD_BY_PENDING)      :
      
      event==TRADE_EVENT_POSITION_REVERSED_BY_MARKET_PARTIAL   ?  CMessage::Text(MSG_EVN_POSITION_REVERSE_PARTIALLY)          :
      event==TRADE_EVENT_POSITION_REVERSED_BY_PENDING_PARTIAL  ?  CMessage::Text(MSG_EVN_REASON_REVERSE_BY_PENDING_PARTIALLY) :
      event==TRADE_EVENT_POSITION_VOLUME_ADD_BY_MARKET_PARTIAL ?  CMessage::Text(MSG_EVN_REASON_ADD_PARTIALLY)                :
      event==TRADE_EVENT_POSITION_VOLUME_ADD_BY_PENDING_PARTIAL ? CMessage::Text(MSG_EVN_POSITION_VOLUME_ADD_BY_PENDING)      :

      event==TRADE_EVENT_TRIGGERED_STOP_LIMIT_ORDER            ?  CMessage::Text(MSG_EVN_REASON_STOPLIMIT_TRIGGERED)          :
      event==TRADE_EVENT_MODIFY_ORDER_PRICE                    ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_PRICE)                  :
      event==TRADE_EVENT_MODIFY_ORDER_PRICE_SL                 ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_PRICE_SL)               :
      event==TRADE_EVENT_MODIFY_ORDER_PRICE_TP                 ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_PRICE_TP)               :
      event==TRADE_EVENT_MODIFY_ORDER_PRICE_SL_TP              ? CMessage::Text(MSG_EVN_MODIFY_ORDER_PRICE_SL_TP)             :
      event==TRADE_EVENT_MODIFY_ORDER_SL_TP                    ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_SL_TP)                  :
      event==TRADE_EVENT_MODIFY_ORDER_SL                       ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_SL)                     :
      event==TRADE_EVENT_MODIFY_ORDER_TP                       ?  CMessage::Text(MSG_EVN_MODIFY_ORDER_TP)                     :
      event==TRADE_EVENT_MODIFY_POSITION_SL_TP                 ?  CMessage::Text(MSG_EVN_MODIFY_POSITION_SL_TP)               :
      event==TRADE_EVENT_MODIFY_POSITION_SL                    ?  CMessage::Text(MSG_EVN_MODIFY_POSITION_SL)                  :
      event==TRADE_EVENT_MODIFY_POSITION_TP                    ?  CMessage::Text(MSG_EVN_MODIFY_POSITION_TP)                  :
      ::EnumToString(event)
     );   
  }
//+------------------------------------------------------------------+
//| Возвращает наименование ордера/позиции/сделки                    |
//+------------------------------------------------------------------+
string CEvent::TypeOrderDealDescription(void) const
  {
   ENUM_EVENT_STATUS status=this.Status();
   return
     (
      status==EVENT_STATUS_MARKET_PENDING  || status==EVENT_STATUS_HISTORY_PENDING  ?  OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORDER_EVENT))      :
      status==EVENT_STATUS_MARKET_POSITION || status==EVENT_STATUS_HISTORY_POSITION ?  PositionTypeDescription((ENUM_POSITION_TYPE)this.GetProperty(EVENT_PROP_TYPE_DEAL_EVENT)) :
      status==EVENT_STATUS_BALANCE  ?  DealTypeDescription((ENUM_DEAL_TYPE)this.GetProperty(EVENT_PROP_TYPE_DEAL_EVENT))  :  
      CMessage::Text(MSG_ORD_UNKNOWN_TYPE)
     );
  }
//+------------------------------------------------------------------+
//| Возвращает наименование первого ордера позиции                   |
//+------------------------------------------------------------------+
string CEvent::TypeOrderFirstDescription(void) const
  {
   return OrderTypeDescription((ENUM_ORDER_TYPE)this.GetProperty(EVENT_PROP_TYPE_ORDER_POSITION));
  }
//+------------------------------------------------------------------+
//| Возвращает наименование ордера, изменившего позицию              |
//+------------------------------------------------------------------+
string CEvent::TypeOrderEventDescription(void) const
  {
   return OrderTypeDescription(this.TypeOrderEvent());
  }
//+------------------------------------------------------------------+
//| Возвращает наименование текущей позиции                          |
//+------------------------------------------------------------------+
string CEvent::TypePositionCurrentDescription(void) const
  {
   return PositionTypeDescription(this.TypePositionCurrent());
  }
//+------------------------------------------------------------------+
//| Возвращает наименование ордера до смены направления             |
//+------------------------------------------------------------------+
string CEvent::TypeOrderPreviousDescription(void) const
  {
   return OrderTypeDescription(this.TypeOrderPosPrevious());
  }
//+------------------------------------------------------------------+
//| Возвращает наименование позиции до смены направления             |
//+------------------------------------------------------------------+
string CEvent::TypePositionPreviousDescription(void) const
  {
   return PositionTypeDescription(this.TypePositionPrevious());
  }
//+------------------------------------------------------------------+
//| Возвращает наименование причины сделки/ордера/позиции            |
//+------------------------------------------------------------------+
string CEvent::ReasonDescription(void) const
  {
   ENUM_EVENT_REASON reason=this.Reason();
   return 
     (
      reason==EVENT_REASON_ACTIVATED_PENDING                ?  CMessage::Text(MSG_EVN_ACTIVATED_PENDING)                      :
      reason==EVENT_REASON_ACTIVATED_PENDING_PARTIALLY      ?  CMessage::Text(MSG_EVN_ACTIVATED_PENDING_PARTIALLY)            :
      reason==EVENT_REASON_STOPLIMIT_TRIGGERED              ?  CMessage::Text(MSG_EVN_REASON_STOPLIMIT_TRIGGERED)             :
      reason==EVENT_REASON_MODIFY                           ?  CMessage::Text(MSG_EVN_REASON_MODIFY)                          :
      reason==EVENT_REASON_CANCEL                           ?  CMessage::Text(MSG_EVN_REASON_CANCEL)                          :
      reason==EVENT_REASON_EXPIRED                          ?  CMessage::Text(MSG_EVN_REASON_EXPIRED)                         :
      reason==EVENT_REASON_DONE                             ?  CMessage::Text(MSG_EVN_REASON_DONE)                            :
      reason==EVENT_REASON_DONE_PARTIALLY                   ?  CMessage::Text(MSG_EVN_REASON_DONE_PARTIALLY)                  :
      reason==EVENT_REASON_VOLUME_ADD                       ?  CMessage::Text(MSG_EVN_REASON_ADD)                             :
      reason==EVENT_REASON_VOLUME_ADD_PARTIALLY             ?  CMessage::Text(MSG_EVN_REASON_ADD_PARTIALLY)                   :
      reason==EVENT_REASON_VOLUME_ADD_BY_PENDING            ?  CMessage::Text(MSG_EVN_POSITION_VOLUME_ADD_BY_PENDING)         :
      reason==EVENT_REASON_VOLUME_ADD_BY_PENDING_PARTIALLY  ?  CMessage::Text(MSG_EVN_REASON_ADD_BY_PENDING_PARTIALLY)        :
      reason==EVENT_REASON_REVERSE                          ?  CMessage::Text(MSG_EVN_REASON_REVERSE)                         :
      reason==EVENT_REASON_REVERSE_PARTIALLY                ?  CMessage::Text(MSG_EVN_POSITION_REVERSE_PARTIALLY)             :
      reason==EVENT_REASON_REVERSE_BY_PENDING               ?  CMessage::Text(MSG_EVN_POSITION_REVERSED_BY_PENDING)           :
      reason==EVENT_REASON_REVERSE_BY_PENDING_PARTIALLY     ?  CMessage::Text(MSG_EVN_REASON_REVERSE_BY_PENDING_PARTIALLY)    :
      reason==EVENT_REASON_DONE_SL                          ?  CMessage::Text(MSG_LIB_PROP_CLOSE_BY_SL)                       :
      reason==EVENT_REASON_DONE_SL_PARTIALLY                ?  CMessage::Text(MSG_EVN_REASON_DONE_SL_PARTIALLY)               :
      reason==EVENT_REASON_DONE_TP                          ?  CMessage::Text(MSG_LIB_PROP_CLOSE_BY_TP)                       :
      reason==EVENT_REASON_DONE_TP_PARTIALLY                ?  CMessage::Text(MSG_EVN_REASON_DONE_TP_PARTIALLY)               :
      reason==EVENT_REASON_DONE_BY_POS                      ?  CMessage::Text(MSG_EVN_REASON_DONE_BY_POS)                     :
      reason==EVENT_REASON_DONE_PARTIALLY_BY_POS            ?  CMessage::Text(MSG_EVN_REASON_DONE_PARTIALLY_BY_POS)           :
      reason==EVENT_REASON_DONE_BY_POS_PARTIALLY            ?  CMessage::Text(MSG_EVN_REASON_DONE_BY_POS_PARTIALLY)           :
      reason==EVENT_REASON_DONE_PARTIALLY_BY_POS_PARTIALLY  ?  CMessage::Text(MSG_EVN_REASON_DONE_PARTIALLY_BY_POS_PARTIALLY) :
      reason==EVENT_REASON_BALANCE_REFILL                   ?  CMessage::Text(MSG_EVN_BALANCE_REFILL)                         :
      reason==EVENT_REASON_BALANCE_WITHDRAWAL               ?  CMessage::Text(MSG_EVN_BALANCE_WITHDRAWAL)                     :
      reason==EVENT_REASON_ACCOUNT_CREDIT                   ?  CMessage::Text(MSG_EVN_ACCOUNT_CREDIT)                         :
      reason==EVENT_REASON_ACCOUNT_CHARGE                   ?  CMessage::Text(MSG_EVN_ACCOUNT_CHARGE)                         :
      reason==EVENT_REASON_ACCOUNT_CORRECTION               ?  CMessage::Text(MSG_EVN_ACCOUNT_CORRECTION)                     :
      reason==EVENT_REASON_ACCOUNT_BONUS                    ?  CMessage::Text(MSG_EVN_ACCOUNT_BONUS)                          :
      reason==EVENT_REASON_ACCOUNT_COMISSION                ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION)                      :
      reason==EVENT_REASON_ACCOUNT_COMISSION_DAILY          ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_DAILY)                :
      reason==EVENT_REASON_ACCOUNT_COMISSION_MONTHLY        ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_MONTHLY)              :
      reason==EVENT_REASON_ACCOUNT_COMISSION_AGENT_DAILY    ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_AGENT_DAILY)          :
      reason==EVENT_REASON_ACCOUNT_COMISSION_AGENT_MONTHLY  ?  CMessage::Text(MSG_EVN_ACCOUNT_COMISSION_AGENT_MONTHLY)        :
      reason==EVENT_REASON_ACCOUNT_INTEREST                 ?  CMessage::Text(MSG_EVN_ACCOUNT_INTEREST)                       :
      reason==EVENT_REASON_BUY_CANCELLED                    ?  CMessage::Text(MSG_EVN_BUY_CANCELLED)                          :
      reason==EVENT_REASON_SELL_CANCELLED                   ?  CMessage::Text(MSG_EVN_SELL_CANCELLED)                         :
      reason==EVENT_REASON_DIVIDENT                         ?  CMessage::Text(MSG_EVN_DIVIDENT)                               :
      reason==EVENT_REASON_DIVIDENT_FRANKED                 ?  CMessage::Text(MSG_EVN_DIVIDENT_FRANKED)                       :
      reason==EVENT_REASON_TAX                              ?  CMessage::Text(MSG_EVN_TAX)                                    :
      ::EnumToString(reason)
     );
  }
//+------------------------------------------------------------------+
//| Выводит в журнал свойства события                                |
//+------------------------------------------------------------------+
void CEvent::Print(const bool full_prop=false)
  {
   ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG),": \"",this.StatusDescription(),"\" =============");
   int beg=0, end=EVENT_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_INTEGER prop=(ENUM_EVENT_PROP_INTEGER)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=EVENT_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_DOUBLE prop=(ENUM_EVENT_PROP_DOUBLE)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=EVENT_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_EVENT_PROP_STRING prop=(ENUM_EVENT_PROP_STRING)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("================== ",CMessage::Text(MSG_LIB_PARAMS_LIST_END),": \"",this.StatusDescription(),"\" ==================\n");
  }
//+------------------------------------------------------------------+
