Discussion of article "Library for easy and quick development of MetaTrader programs (part VIII): Order and position modification events" - page 2

 

Artem, thanks again!
The method"void CEventsCollection::CreateNewEvent(COrderControl* order)" is used to create a trade event depending on the type of order change, i.e. it creates an event associated with any order change.....
And the reason of order change is sent to the created event is the same: EVENT_REASON_STOPLIMIT_TRIGGERED.

//--- Creating an event
   if(event!=NULL)
     {
      event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time());                        // Event time
      event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);  // Event cause (from the ENUM_EVENT_REASON enumeration)

If I am right please correct it, if not please explain what I did not see.

Thank you very much for the library you have simplified my labour in several times,
especially when the main work is not connected with programming.

 
BmC:

Artem, thanks again!
The method"void CEventsCollection::CreateNewEvent(COrderControl* order)" is used to create a trade event depending on the type of order change, i.e. it creates an event associated with any order change.....
And the reason of order change is sent to the created event is the same: EVENT_REASON_STOPLIMIT_TRIGGERED.

If I am right please correct it, if not please explain what I didn't see.

Thank you very much for the library you have simplified my labour in several times,
especially when the main work is not connected with programming.

Without linking to the exact location of the quoted lines, I can't understand what exactly you are talking about - just by searching (Shift+Ctrl+F) I couldn't find such code in all the library files...

event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);

Where is it located?

 
Here are the lines from the description in the very part of this article and the code at the end of the article:
//+------------------------------------------------------------------+
//|| Creates a trade event depending on the order change type ||
//+------------------------------------------------------------------+
void CEventsCollection::CreateNewEvent(COrderControl* order)
  {
   if(!::SymbolInfoTick(order.Symbol(),this.m_tick))
     {
      Print(DFUN,TextByLanguage("Failed to retrieve current prices by event symbol ","Failed to get current prices by event symbol "),order.Symbol());
      return;
     }
   CEvent* event=NULL;
//--- Pending StopLimit order triggered
   if(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE)
     {
      this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED;
      event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket());
     }
//--- Modification
   else
     {
      //--- Modified pending order price
      if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE;
      //--- Modified the price of the pending order and its StopLoss
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL;
      //--- Modified pending order price and its TakeProfit
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP;
      //--- Modified the price of the pending order, its StopLoss and TakeProfit
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss of pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL;
      //--- Modified TakeProfit of pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss and TakeProfit of the pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;

      //--- Modified StopLoss position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL;
      //--- Modified TakeProfit position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss and TakeProfit of position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
      
      //--- Create a modification event
      event=new CEventModify(this.m_trade_event_code,order.Ticket());
     }
//--- Creating an event
   if(event!=NULL)
     {
      event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time());                        // Event time
      event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);  // Event cause (from the ENUM_EVENT_REASON enumeration)
      event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // Order type, triggering of which resulted in the event
      event.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket());               // Ticket of the order that triggered the event
      event.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder());             // Event order type
      event.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket());              // Event Order Ticket
      event.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder());          // Type of the first position order
      event.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket());           // Ticket of the first position order
      event.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID());                 // Position identifier
      event.SetProperty(EVENT_PROP_POSITION_BY_ID,0);                               // Counter position identifier
      event.SetProperty(EVENT_PROP_MAGIC_BY_ID,0);                                  // Magic number of the counter position
         
      event.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev());      // Type of position order before the change of direction
      event.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket());           // Position order ticket before direction change
      event.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder());         // Order type of the current position
      event.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket());          // Ticket of the order of the current position
      
      event.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev());            // Order setting price before modification
      event.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev());           // StopLoss price before modification
      event.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev());         // TakeProfit price before modification
      event.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask);                // Ask price at the time of the event
      event.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid);                // Bid price at the time of the event
         
      event.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic());                      // Magic order number
      event.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev());           // Time of the first position order
      event.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev());                  // The price at which the event occurred
      event.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price());                       // Order setting price
      event.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price());                      // Order closing price
      event.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss());                      // StopLoss order price
      event.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit());                    // Price of TakeProfit order
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume());            // Requested order volume
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0);                        // Executed order volume
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume());            // Remaining (unexecuted) order volume
      event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0);                     // Executed position volume
      event.SetProperty(EVENT_PROP_PROFIT,0);                                       // Profit
      event.SetProperty(EVENT_PROP_SYMBOL,order.Symbol());                          // Order symbol
      event.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol());                    // Counter position symbol
      //--- Setting the schedule identifier of the control programme, decoding the event code and setting the event type
      event.SetChartID(this.m_chart_id);
      event.SetTypeEvent();
      //--- If the event object is not in the list - add it
      if(!this.IsPresentEventInList(event))
        {
         this.m_list_trade_events.InsertSort(event);
         //--- Send an event message and set the value of the last trade event
         event.SendEvent();
         this.m_trade_event=event.TradeEvent();
        }
      //--- If this event is already in the list - delete the new event object and display a debug message
      else
        {
         ::Print(DFUN_ERR_LINE,TextByLanguage("Such an event is already on the list.","This event is already in the list."));
         delete event;
        }
     }
  }
underline this line!
 
Artyom Trishkin:

Without linking to the exact location of the quoted lines, I can't understand what exactly you are talking about - just by searching (Shift+Ctrl+F) I couldn't find such code in all the library files...

Where is it located?

Maybe you have already fixed it in the next chapters of the library description? To me your library is very suitable for my strategy and I understand it very thoroughly, as you have made besides the library a methodology for correct programming.
 
BmC:
Here are the lines from the description in the very part of this article and the code at the end of the article: underline this line!

At the moment - in the current version of the library, the method looks like this:

//+------------------------------------------------------------------+
//|| Creates a trade event depending on the order change type ||
//+------------------------------------------------------------------+
void CEventsCollection::CreateNewEvent(COrderControl* order)
  {
   ENUM_EVENT_REASON reason=WRONG_VALUE;
   if(!::SymbolInfoTick(order.Symbol(),this.m_tick))
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_NOT_GET_CURR_PRICES),order.Symbol());
      return;
     }
   CEvent* event=NULL;
//--- Pending StopLimit order triggered
   if(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE)
     {
      reason=EVENT_REASON_STOPLIMIT_TRIGGERED;
      this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED;
      event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket());
     }
//--- Modification
   else
     {
      //--- Modified pending order price
      if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE;
      //--- Modified the price of the pending order and its StopLoss
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL;
      //--- Modified pending order price and its TakeProfit
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP;
      //--- Modified the price of the pending order, its StopLoss and TakeProfit
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss of pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL;
      //--- Modified TakeProfit of pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss and TakeProfit of the pending order
      else if(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;

      //--- Modified StopLoss position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL;
      //--- Modified TakeProfit position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP;
      //--- Modified StopLoss and TakeProfit of position
      else if(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT)
         this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
      
      //--- Create a modification event
      reason=EVENT_REASON_MODIFY;
      event=new CEventModify(this.m_trade_event_code,order.Ticket());
     }
//--- Creating an event
   if(event!=NULL)
     {
      event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time());                        // Event time
      event.SetProperty(EVENT_PROP_REASON_EVENT,reason);                            // Event cause (from the ENUM_EVENT_REASON enumeration)
      event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // Order type, triggering of which resulted in the event
      event.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket());               // Ticket of the order that triggered the event
      event.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder());             // Event order type
      event.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket());              // Event Order Ticket
      event.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder());          // Type of the first position order
      event.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket());           // Ticket of the first position order
      event.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID());                 // Position identifier
      event.SetProperty(EVENT_PROP_POSITION_BY_ID,0);                               // Counter position identifier
      event.SetProperty(EVENT_PROP_MAGIC_BY_ID,0);                                  // Magic number of the counter position
         
      event.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev());      // Type of position order before the change of direction
      event.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket());           // Position order ticket before direction change
      event.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder());         // Order type of the current position
      event.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket());          // Ticket of the order of the current position
      
      event.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev());            // Order setting price before modification
      event.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev());           // StopLoss price before modification
      event.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev());         // TakeProfit price before modification
      event.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask);                // Ask price at the time of the event
      event.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid);                // Bid price at the time of the event
         
      event.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic());                      // Magic order number
      event.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev());           // Time of the first position order
      event.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev());                  // The price at which the event occurred
      event.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price());                       // Order setting price
      event.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price());                      // Order closing price
      event.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss());                      // StopLoss order price
      event.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit());                    // Price of TakeProfit order
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume());            // Requested order volume
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0);                        // Executed order volume
      event.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume());            // Remaining (unexecuted) order volume
      event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0);                     // Executed position volume
      event.SetProperty(EVENT_PROP_PROFIT,0);                                       // Profit
      event.SetProperty(EVENT_PROP_SYMBOL,order.Symbol());                          // Order symbol
      event.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol());                    // Counter position symbol
      //--- Decoding the event code and setting the event type
      event.SetTypeEvent();
      //--- If the event object is not in the list - add it
      if(!this.IsPresentEventInList(event))
        {
         this.m_list_trade_events.InsertSort(event);
         //--- Send an event message and set the value of the last trade event
         this.m_trade_event=event.TradeEvent();
         this.m_is_event=true;
         event.SendEvent();
         CBaseObjExt::EventAdd(this.m_trade_event,order.Ticket(),order.Price(),order.Symbol());
        }
      //--- If this event is already in the list - delete the new event object and display a debug message
      else
        {
         ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_EVENT_ALREADY_IN_LIST));
         delete event;
        }
     }
  }
//+------------------------------------------------------------------+

So, either it was a bug and it has been fixed long ago, or it is not critical in the discussed version of the library. I don't remember exactly how it was....

 
Artyom Trishkin:

At the moment - in the current version of the library, the method looks like this:

So, either it was a bug and it has been fixed long ago, or it is not critical in the discussed version of the library. I don't remember exactly how it was...

This is very important, from the author it's even more important. If you have not abandoned your original idea. To help novice programmers like me with my work. When you are a beginner (a student) and you are just learning a programming language, or programming in general, there are a lot of doubts and questions when studying your work (library). In this case I wasn't sure until the last moment whether it was a mistake or your intention. I went through your code more than once. And for me it is very important: "either I didn't understand the author's meaning, or it is just a typo of the author in his big project."
And how do you say that it is not critical?! This is wrong on your part, thereby you and I are just confusing the readers. Who study or learn as I do, from your library.

 
BmC:

This is very important, from the author it's even more important. If you haven't given up on your original idea. To help novice programmers like me with my work. When you are a beginner (a student) and you are just learning a programming language, or programming in general, there are a lot of doubts and questions when studying your work (library). In this case I wasn't sure until the last moment whether it was a mistake or your intention. I went through your code more than once. And for me it is very important: "either I didn't understand the author's meaning, or it's just a typo of the author in his big project."
And how do you say that it's not critical?! This is wrong on your part, thereby you and I are just confusing the readers. Who study or learn as I do, from your library.

:)

I showed you the code with the corrections highlighted in colour. Put them in the version of the library attached to this article.

Of course, I don't remember whether it was my mistake or it is not critical in this version and therefore it passed by my eyes during debugging. After all, it's already forty-odd articles, and this one was so long ago. Most likely it was a bug, which was corrected in subsequent articles - a lot of things in the library are already created on the fly. Of course there was, and more than one, test versions of the library. But since the beginning of the description of its creation much has been revised and added. That's why this series of articles is positioned as a description of the creation of the library. In this way I try to involve the reader in the process of its creation. With trials and errors, and with instructions on how to fix them - to make the whole process visible - to reveal, so to speak, "all the pains of creation" :) :)

So, I apologise for any confusion in your understanding of what is going on.....
Just make the changes suggested above. Or leave it until the article where it will be corrected.

 
I want to get the last event symbol, ticket and type (open, close, modify), how to do it properly?
 
Andrii Miknevich:
I want to get the last event symbol, ticket and type (open, close, modification), how to do it correctly?

I see Artyom is so busy that he doesn't appear on the forum at all.)))))))) Maybe I can give you a hint, once I experimented with his library. Today I went through those experiments and found such a function. The comment says that the function gets a list of all open positions.

void OrderActivated()
{
Print(__FUNCTION__, "***", ENUM_TRADE_EVENT(engine.LastTradeEvent()));
//--- Get the list of all open positions
CArrayObj* list = engine.GetListMarketPosition();
if(list == NULL || list.Total() == 0)
return;
int index = CSelect::FindOrderMax(list, ORDER_PROP_TIME_OPEN);
COrder *pos = list.At(index);
if(pos == NULL)
return;

pos.Print();
}/*******************************************************************/

Unfortunately, I can't explain what it's for, I've forgotten everything, but maybe you can figure it out....

Well... if you can't, wait. Artem will find time and reply.

 

When a tick is received, on which a pending order is set and simultaneously activated (triggered) (I tested with Buy Stop), your engine does not register all events...

The TRADE_EVENT_PENDING_ORDER_PLASED event is received, but not TRADE_EVENT_PENDING_ORDER_ACTIVATED.

My code is something like this:

//+------------------------------------------------------------------+
//| Process trade events|
//+------------------------------------------------------------------+ 
void ProcessTradeEvents(void)
  {
   static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
   static CEvent *last_processed=NULL;
   
   if(engine.LastTradeEvent()!=last_event)
     {      
      if(last_event==TRADE_EVENT_NO_EVENT)
         return;
      CArrayObj *list=engine.GetListAllOrdersEvents();
      if(list==NULL)
         return;
      list=CSelect::ByEventProperty(list,EVENT_PROP_SYMBOL,Symbol(),EQUAL);
      if(list==NULL || list.Total()<=0)
         return;      
      last_event=engine.LastTradeEvent();
      //--- get index of old event
      int index_of_old_event=0;
      if(last_processed==NULL)
         index_of_old_event=-1;
      else
        {
         for(int i=list.Total()-1;i>=0;i--)
           {
            CEvent *event=list.At(i);
            if(event==NULL)
               return;
            ENUM_TRADE_EVENT event_type=event.TypeEvent();
            if(last_processed!=NULL && event.IsEqual(last_processed))
              {
               index_of_old_event=i;
               break;
              }
           }
        }
      //--- checking all new events
      for(int i=index_of_old_event+1;i<list.Total();i++)
        {
         CEvent *event=list.At(i);
         if(event==NULL)
            break;
         if(last_processed!=NULL && event.IsEqual(last_processed))
            break; 
         Print(__FUNCTION__+": event : ",event.TypeEventDescription());
         switch(event.TypeEvent())
           {
            case TRADE_EVENT_PENDING_ORDER_PLASED:
              {
               // some code
              }
            break;
            case TRADE_EVENT_PENDING_ORDER_REMOVED:
              {
               // some code
              }
            break;
            case TRADE_EVENT_PENDING_ORDER_ACTIVATED:
              {
               // some code
              }
            break;

            case TRADE_EVENT_POSITION_CLOSED:
              {
               // some code
              }
            break;
            case TRADE_EVENT_POSITION_CLOSED_BY_SL:
              {
               // some code
              }
            break;
            case TRADE_EVENT_POSITION_CLOSED_BY_TP:
              {
                // some code
              }
            break;
            case TRADE_EVENT_MODIFY_ORDER_PRICE:
              {
                // some code
              }
            break;

            case TRADE_EVENT_MODIFY_POSITION_SL:
              {
                // some code
              }
            break;
            case TRADE_EVENT_MODIFY_POSITION_TP:
              {
                // some code
              }
            break;
           }
        }
      last_processed=list.At(list.Total()-1);
      Comment("\nLast trade event: ",last_processed.TypeEventDescription());
     }
  }

I first find the index of the old (processed) event in the loop, and then starting from it, I loop through all the new ones until the end. So, in a situation where on one tick a limit order is set and striggeren receives one event about setting... Please comment.

I call ProcessTradeEvents() in OnTick() following engine.OnTick(rates_data).
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Свойства ордеров - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5