Discussion of article "Library for easy and quick development of MetaTrader programs (part XXI): Trading classes - Base cross-platform trading object" - page 3

 
Artyom Trishkin:
If you need to compare a trade request and a position, then the easiest way is to set the position identifier (not magic). Each request has its own identifier. The magic of the advisor can be left one for all positions. Then by the identifier (it is written in the magic of a position or order and will never be lost), you can accurately match the request and position/order at any time.

Is it something like this?

Trade Request:

ulong order_magic = m_engine.SetCompositeMagicNumber(m_magic, 0, 0, m_order_id);
bool submit_ok    = m_engine.PlaceBuyLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, order_magic, m_comment, m_expiry);

Event Handler:

void CMyRobot::EngineEventHandler(int event_id, const long &lparam, const double &dparam, const string &sparam, bool testing, long chart_id)
{
   if (sparam != m_symbol) return;                                                  //--- skip event-handling if mismatched symbols

   if (event_id > SERIES_EVENTS_NO_EVENT && event_id < SERIES_EVENTS_NEXT_CODE) {   //--- HANDLING OF TIMESERIES EVENTS
      if (event_id == SERIES_EVENTS_NEW_BAR) {                                      // "new bar" event: lparam = period | dparam = date/time
         this.RefreshAllIndicators(1);
         this.ExecuteFSM(1, chart_id);                                              // execute finite state machine (NB: new bar's index = 1)
      }
   }
   else
   if (event_id > TRADE_EVENT_NO_EVENT && event_id < TRADE_EVENTS_NEXT_CODE) {      //--- HANDLING OF TRADING EVENTS
      CArrayObj *event_list = m_engine.GetListAllOrdersEvents();                    // get the list of trading events
      if (event_list == NULL) return;
      
      //--- compute event index shift relative to the end of the list
      //--- when back-testing, the shift value is passed in the 'lparam' parameter to the event handler
      //--- in normal operation, trading events are sent one by one and handled in OnChartEvent()
      int shift = testing ? (int)lparam : 0;
      CEvent *event = event_list.At(event_list.Total() - 1 - shift);
      if (event == NULL || event.GetPendReqID() != m_order_id) return;
      
      switch (event.TypeEvent())
      {
         case TRADE_EVENT_PENDING_ORDER_PLASED:                                     //--- pending order placed
            if (m_state_curr == FSM_PENDING_ORDER && m_ticket == WRONG_VALUE)
                m_ticket = event.TicketOrderEvent();
            break;
      
         // ...
      }
   }
}
 

Problem: the CEvent::GetPendReqID() method I need above is protected!! Any better ideas without me having to changw the DoEasy source code? In my humble opinion, these methods should be public ;-)

class CEvent : public CObject
  {
//...
protected:
//--- Return (1) the specified magic number, the ID of (2) the first group, (3) second group, (4) pending request from the magic number value
   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;                                }
//...
};
 
Dima Diall :

Problem: the CEvent::GetPendReqID() method I need above is protected !! Any better ideas without me having to changw the DoEasy source code? In my humble opinion, these methods should be public ;-)

You need to watch the CEngine class - only it gives access to the library to user programs.

All other classes are for the needs of the library, and are not intended for users, with the exception of the library service functions that are available in the program after connecting the library to it.

 
Artyom Trishkin:

You need to watch the CEngine class - only it gives access to the library to user programs.

All other classes are for the needs of the library, and are not intended for users, with the exception of the library service functions that are available in the program after connecting the library to it.

Can you please give me an example? I am looking at CEngine class and see that it is possible to extract a list of events, check their type etc... so I can access each event but don't find any obvious way to read specific event details packed in the magic number (groups & request ID) from the CEngine object  -- as I see it, I still need to read this information directly from the CEvent object instances as in my event handler example above in my robot's even-handler method, i.e. CEvent:GetPendReq()

class CEngine
  {
//...
//...
//--- Return (1) the list of order, deal and position events, (2) base trading event object by index and the (3) number of new trading events
   CArrayObj           *GetListAllOrdersEvents(void)                    { return this.m_events.GetList();                     }
   CEventBaseObj       *GetTradeEventByIndex(const int index)           { return this.m_events.GetTradeEventByIndex(index);   }
   int                  GetTradeEventsTotal(void)                 const { return this.m_events.GetTradeEventsTotal();         }
//--- Reset the last trading event
   void                 ResetLastTradeEvent(void)                       { this.m_events.ResetLastTradeEvent();                }
//--- Return the (1) last trading event, (2) the last event in the account properties and (3) the last event in symbol properties
   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;                    }
//--- Return the (1) hedge account, (2) working in the tester, (3) account event, (4) symbol event and (5) trading event flag
   bool                 IsHedge(void)                             const { return this.m_is_hedge;                             }
   bool                 IsTester(void)                            const { return this.m_is_tester;                            }
   bool                 IsAccountsEvent(void)                     const { return this.m_accounts.IsEvent();                   }
   bool                 IsSymbolsEvent(void)                      const { return this.m_symbols.IsEvent();                    }
   bool                 IsTradeEvent(void)                        const { return this.m_events.IsEvent();                     }
//...
//...
  };
 
Dima Diall :

Не могли бы вы привести мне пример? Я смотрю на класс CEngine и вижу, что можно извлечь список событий, проверить их тип и т. Д., Поэтому я могу получить доступ к каждому событию, но не нахожу очевидного способа прочитать конкретные детали события, упакованные в магическое число (группы и идентификатор запроса) из объекта CEngine   - как я вижу, мне все еще нужно читать эту информацию непосредственно из экземпляров объекта CEvent, как в моем примере обработчика событий выше в методе обработчика четных событий моего робота, то есть CEvent :: GetPendReqID ()

Wait a little, please. The next article in the ru-segment will be about advisors, and there I will try to explain.

 
Artyom Trishkin:

Wait a little, please. The next article in the ru-segment will be about advisors, and there I will try to explain.

OK, cool - thank you...