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

 
Artyom Trishkin:


Thank you, this is an important and useful piece of work....

 
Vladimir Pastushak:

Thank you, this is an important and useful piece of work....

You are welcome

 
Hello Artyom - is there an easier way to get the ticket number after placing an order or opening a position? This seems overly complicated :-(
long CMySetup::PlaceOrder()
{
   bool order_ok;
   if (m_direction == POSITION_TYPE_BUY) {
      order_ok = m_engine.PlaceBuyLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, m_magic, m_comment, m_expiry);
   }
   else {
      order_ok = m_engine.PlaceSellLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, m_magic, m_comment, m_expiry);
   }

   if (order_ok) {
      CArrayObj* list = m_engine.GetListHistoryOrders();
      if (list != NULL) {
         list.Sort(SORT_BY_ORDER_TIME_OPEN);
         COrder* order = list.At(list.Total() - 1);
         if (order != NULL) {
            m_ticket = order.Ticket();
         }
      }
   }
   return m_ticket;
}
 
Dima Diall :
Hello Artyom - is there an easier way to get the ticket number after placing an order or opening a position? This seems overly complicated :-(

Test advisors display all the data of the last placed order or open position. This means that the library knows this data. It implements event functionality, and the library reports all set events. Accordingly, you need to control these events and get the object of the last order or position, and from it take a ticket (and all other parameters of the order or position). It is not yet possible to give any example. But I'll be back soon and I can help.
You can see for yourself where the test advisors take event data and print it to the log. Accordingly, you can access the same point from your program and take data from these events.

В тестовых советниках же показываются все данные последнего выставленного ордера или открытой позиции. Это означает, что библиотека знает эти данные. В ней реализован событийный функционал, и о всех установленных событиях библиотека сообщает. Соответственно, вам нужно контролировать эти события и получать объект последнего ордера или позиции, а из него брать тикет (и все остальные параметры ордера или позиции). Сейчас пока нет возможности привести какой-либо пример. Но в скором времени вернусь и смогу помочь.
Можете самостоятельно поглядеть откуда тестовые советники берут данные о событиях и распечатывают их в журнал. Соответственно, можете из своей программы получить доступ к той же точке и брать данные от этих событий.

 
Artyom Trishkin:

Test advisors display all the data of the last placed order or open position. This means that the library knows this data. It implements event functionality, and the library reports all set events. Accordingly, you need to control these events and get the object of the last order or position, and from it take a ticket (and all other parameters of the order or position). It is not yet possible to give any example. But I'll be back soon and I can help.
You can see for yourself where the test advisors take event data and print it to the log. Accordingly, you can access the same point from your program and take data from these events.

Yes, I understand -- I am having a have closer look and wondering if I am guaranteed to to have my event handler be called immediately and, if multiple orders/positions have be requested, what sort of analysis I need to carry out to ensure I correctly match the events with each request... all this just to find out the ticket number which for e.g. pending orders the library receives in 'm_result' inside CTradeObj::SetOrder() 

#ifdef __MQL5__
   return(!this.m_async_mode ? ::OrderSend(this.m_request,this.m_result) : ::OrderSendAsync(this.m_request,this.m_result));
#else 
   ::ResetLastError();
   int ticket=::OrderSend(this.m_request.symbol,
                          this.m_request.type,
                          this.m_request.volume,
                          this.m_request.price,
                          (int)this.m_request.deviation,
                          this.m_request.sl,
                          this.m_request.tp,
                          this.m_request.comment,
                          (int)this.m_request.magic,
                          this.m_request.expiration,
                          clrNONE);
// ...
   if(ticket!=WRONG_VALUE)
     {
      this.m_result.order=ticket;
      this.m_result.price=(::OrderSelect(ticket,SELECT_BY_TICKET) ? ::OrderOpenPrice() : this.m_request.price);
      this.m_result.volume=(::OrderSelect(ticket,SELECT_BY_TICKET) ? ::OrderLots() : this.m_request.volume);
      return true;
     }
// ...   
#endif

This is why I think it would be more useful that the ticket number (or -1 if unsuccessful) is returned from CEngine::PlaceBuyLimit() and all this family of methods, because when you place an order or open a position, most frequently you immediately want to record the ticket number so you can refer back to it later... Maybe it could even return a COrder* pointer or NULL if unsuccessful. In my humble opinion, forcing the DoEasy user to implement event-handling for this makes the library feel unnecessarily complicated.

Probably there is a good reason for your approach so not sure if you agree; if not, I'd be very interested to understand the reasoning behind your design decision ;-)

 
Dima Diall :

Yes, I understand -- I am having a have closer look and wondering if I am guaranteed to to have my event handler be called immediately and, if multiple orders/positions have be requested, what sort of analysis I need to carry out to ensure I correctly match the events with each request... all this just to find out the ticket number which for e.g. pending orders the library receives in 'm_result' inside CTradeObj::SetOrder()  

This is why I think it would be more useful that the ticket number (or -1 if unsuccessful) is returned from  CEngine::PlaceBuyLimit()  and all this family  of methods, because  when you place an order or open a position, most frequently you immediately want to record the ticket number so you can refer back to it later... Maybe it could even return a COrder* pointer  or NULL if unsuccessful.  In my humble opinion, forcing the DoEasy user to implement event-handling for this makes the library feel unnecessarily complicated.

Probably there is a good reason for your approach so not sure if you agree; if not, I'd be very interested to understand the reasoning behind your design decision ;-)

Everything is very simple. In MQL5, the success of sending a trade order to the server does not guarantee its execution. The success of sending is a millet check for the correctness of the parameters in a trade order. The execution of the order lies with the exchange. We can only use the fact of a change in the trading environment, and after detecting its change, move on. It is for this reason that I do not use the data received in the server response.

Всё очень просто. В MQL5 успешность отсылки торгового приказа на сервер не гарантирует его исполнения. Успешность отсылки - это просо проверка на корректность параметров в торговом приказе. Исполнение приказа лежит на стороне биржи. Мы можем лишь использовать факт изменения торгового окружения, и после обнаружения его изменения уже двигаться дальше. Именно по этой причине я не использую данные, полученные в ответе сервера.

 
Artyom Trishkin:

Everything is very simple. In MQL5, the success of sending a trade order to the server does not guarantee its execution. The success of sending is a millet check for the correctness of the parameters in a trade order. The execution of the order lies with the exchange. We can only use the fact of a change in the trading environment, and after detecting its change, move on. It is for this reason that I do not use the data received in the server response.

OK, I am trying to implement this approach in my EA framework to make it easier to manage using your TestDoEasyPart39.mq5 as a guide, but am having some issues with missed events -- still investigating/debugging (everything in tester mode for now)... I would appreciate other code examples of how you do this yourself in other EAs, if you can share some.

I am still using the library version from Part 39; is this the best version to use for the moment or you recommend upgrading to a newer version?

 
Dima Diall :

OK, I am trying to implement this approach in my EA framework to make it easier to manage using your TestDoEasyPart39.mq5 as a guide, but am having some issues with missed events -- still investigating/debugging (everything in tester mode for now)... I would appreciate other code examples of how you do this yourself in other EAs, if you can share some.

I am still using the library version from Part 39; is this the best version to use for the moment or you recommend upgrading to a newer version?

So far, all subsequent versions are devoted to the creation of indicators.

I'll be back to the advisors soon. There I will also check user messages that some trading events (occurring simultaneously) are lost.
And then I can show you how to use the event model of the library.

Пока все последующие версии посвящены созданию индикаторов.

Скоро опять вернусь к советникам. Там и проверю сообщения пользователей о том, что некоторые торговые события (происходящие одновременно) теряются.
И там же смогу тогда показать как использовать событийную модель библиотеки.

 
Artyom Trishkin:

So far, all subsequent versions are devoted to the creation of indicators.

I'll be back to the advisors soon. There I will also check user messages that some trading events (occurring simultaneously) are lost.
And then I can show you how to use the event model of the library.

When do you expect to start working again on features for expert advisors? Depending on your answer I may need to choose writing my own multiplatform class/methods for simplified placing orders, opening positions, etc... at least for my current project.

When handling trade events such as TRADE_EVENT_PENDING_ORDER_PLASED or TRADE_EVENT_POSITION_OPENED, how can I ensure that a given event corresponds to a particular trade request I submitted earlier? Currently I only have one order/position per symbol, so it's easy to check that the symbol of the event matches my request... However, later my EA should be able to open multiple orders/positions on the same symbol (using a single magic number), hopefully it is not necessary to compare entry price, SL, TP, etc... I was thinking maybe use different magic numbers, or that feature that packs group #1 & #2 into the magic number.

I am a little confused and not quite sure what is the best approach to match trade events to requests -- can you please help me with this for now? If I can reliably associate a trade request with its ticket number, I believe I can continue using DoEasy for this project.

Library for easy and quick development of MetaTrader programs (part XXVI): Working with pending trading requests - first implementation (opening positions)
Library for easy and quick development of MetaTrader programs (part XXVI): Working with pending trading requests - first implementation (opening positions)
  • www.mql5.com
I have already mentioned the concept of a pending request in a number of previous articles. In this article, we are going to figure out what it is and why we need it, as well as start implementing pending requests. When receiving and handling a trade server error, we sometimes need to wait and repeat the request. In the simplest case, waiting...
 
Dima Diall :

When do you expect to start working again on features for expert advisors? Depending on your answer I may need to choose writing my own multiplatform class/methods for simplified placing orders, opening positions, etc... at least for my current project.

When handling trade events such as  TRADE_EVENT_PENDING_ORDER_PLASED or  TRADE_EVENT_POSITION_OPENED , how can I ensure that a given event corresponds to a particular trade request I submitted earlier? Currently I only have one order/position per symbol, so it's easy to check that the symbol of the event matches my request... However, later my EA should be able to open multiple orders/positions on the same symbol (using a single magic number), hopefully it is not necessary to compare entry price, SL, TP, etc... I was thinking maybe use different magic numbers, or that  feature  that packs group #1 & #2 into the magic number .

I am a little confused and not quite sure what is the best approach to match trade events to requests -- can you please help me with this for now? If I can reliably associate a trade request with its ticket number, I believe I can continue using DoEasy for this project.

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.