Discussion of article "Library for easy and quick development of MetaTrader programs (part XIII): Account object events"

 

New article Library for easy and quick development of MetaTrader programs (part XIII): Account object events has been published:

The article considers working with account events for tracking important changes in account properties affecting the automated trading. We have already implemented some functionality for tracking account events in the previous article when developing the account object collection.

Now launch the EA in the tester and open more positions to quickly detect the equity increase event followed by closing the most profitable position:


As we can see, the most profitable position is automatically closed when the equity exceeds the specified value. The journal displays the messages about the tracked account event.

Author: Artyom Trishkin

 

Thanks for your great and helpful job @Artyom Trishkin, I should ask a question here;

I think it is necessary to Save engine state and Load it in next run of scripts/EAs to resume capturing events and identify changes in EA closed time.

But it has CObject Save/Load virtual functions and returning true with no action.

Q: What should we save and how access them to save?

 
Mohammad Bazrkar :

Thank you for your wonderful and useful work @ Artyom Trishkin , I have to ask a question here;

I think that it is necessary to save the state of the engine and load it the next time the scripts / advisors are started, in order to resume capturing events and detect changes in the closed time of the adviser.

But it has virtual CObject Save / Load functions that return true without any action.

Q: What should we save and how to get access to them?

To take advantage of virtual functions, they need to be implemented at objects-heirs. See how this is done and described in the article on creating a collection of accounts. In it, each of the account objects is written to a file, and then read from the file.

I plan to gradually save all the objects stored in different library collections to files. But while busy with trade classes for the library.

 

I had a problem in using ResetLastTradeEvent and I'm going to report it here,

I'm reading latest events by getting List of them, checking is there any new events or not; because saving latest event state and comparing it in next checks, is not good solution. Image you like to watch pending orders placing event. if two pending orders place in different time without any other events between them, we miss second one.

so, I check events, doing my stuff and ResetLastTradeEvent and looking for new values != _NO_EVENT . so, what is the problem?

it is returning m_last_trade_event when you call LastTradeEvent

   ENUM_TRADE_EVENT     LastTradeEvent(void)                      const { return this.m_last_trade_event;            }

so:

   void ResetLastTradeEvent(void)
   {
      this.m_events.ResetLastTradeEvent();
      this.m_last_trade_event = TRADE_EVENT_NO_EVENT;
   }    

Also I made some modifications to make sure Clear() function do its job in Lists and Arrays.

Here is my use case

   if(engine.LastTradeEvent()!=TRADE_EVENT_NO_EVENT) {
      CArrayObj* list=engine.GetListAllOrdersEvents();
      if(list!=NULL) {
         int total=list.Total();
         for(int i=0; i<total ; i++){
            CheckThisEvent(list.At(i));
         }
      }
      //--
      engine.m_events.Clear();
      engine.ResetLastTradeEvent();
   }
 
Mohammad Bazrkar :

I had a problem in using ResetLastTradeEvent and I'm going to report it here,

I'm reading latest events by getting List of them, checking is there any new events or not; because saving latest event state and comparing it in next checks, is not good solution. Image you like to watch pending orders placing event. if two pending orders place in different time without any other events between them, we miss second one.

so, I check events, doing my stuff and ResetLastTradeEvent and looking for new values != _NO_EVENT . so, what is the problem?

it is returning m_last_trade_event when you call LastTradeEvent

so:

Also I made some modifications to make sure Clear() function do its job in Lists and Arrays.

Here is my use case

Это, к сожалению, неправильное решение. Вы перенесли список m_events в публичную секцию класса? Вы очищаете весть список событий?

engine.m_events.Clear();

Тем самым вы разрушаете структуру коллекции событий. А ведь не зря же список m_events находится в приватной секции класса CEngine - к этим спискам запрещён доступ извне.

Да, я знаю, что сравнение прошлого события с текущим - это не правильно, и это было сделано лишь для проверки получения событий, а не для полноценной работы с ними.
В последней версии библиотеки (статья 23), которая уже готова к выходу, возвращается флаг произошедшего торгового события в управляющую программу. И последнее событие всегда можно получить.
А в статье 24 будет доступен список всех событий, произошедших одновременно, например - удаление множества отложенных ордеров. Каждое событие будет отображено в программе. И к каждому из этих событий можно будет получить доступ для работы с ними.

-----------------------------------------------------

This, unfortunately, is the wrong decision. Have you moved the m_events list to the public section of the class? Are you clearing the news list of events?

engine.m_events.Clear();

Thus, you destroy the structure of the collection of events. But it is not in vain that the m_events list is located in the private section of the CEngine class - access to these lists is prohibited from outside.

Yes, I know that comparing a past event with a current one is not correct, and this was done only to verify receipt of events, and not to fully work with them.
In the latest version of the library (article 23), which is already ready for release, the flag of the occurred trading event is returned to the control program. And the last event is always available.
And in article 24, a list of all events that occurred simultaneously will be available, for example, the removal of many pending orders. Each event will be displayed in the program. And each of these events can be accessed to work with them.
 

I was trying to get all events by that for loop in last code block which I sent it in previous comment.

I was getting old events by every new one, so I destroyed private and made everything public; it is not right way, but I did it anyway to make sure that list is clearing (with v13). 

Thank you for improvements in next articles. I will check them as soon as possible.

 
Mohammad Bazrkar :

I was trying to get all events by that for loop in last code block which I sent it in previous comment.

I was getting old events by every new one, so I destroyed private and made everything public; it is not right way, but I did it anyway to make sure that list is clearing (with v13). 

Thank you for improvements in next articles. I will check them as soon as possible.

Так как в статьях описываются все этапы создания библиотеки, то я, к сожалению, не счёл необходимым дать сразу полный доступ к списку торговых событий, а дал лишь доступ к последнему событию. А последнее событие всегда возвращается то, которое произошло последним - не важно когда - прямо сейчас, или час назад. Оно всё равно является последним событием, и оно же и возвращается. И я упустил из виду, что два одинаковых события по названию, но разные по свойствам, уже потребуется кому-то получать. По этой причине и не было доведено до нормального состояния получение торговых событий. В классах коллекций аккаунтов и символов уже созданы и работают методы получения всех событий аккаунта или символов, и их легко получить в своих программах. Точно таким же образом в ближайших двух статьях будет дана возможность получения и торговых событий.

К слову - это ещё не всё, что будет реализовано. Далее будут созданы методы для поиска и получения любых данных и событий в своих программах. И сделано это будет весьма удобным и наглядным способом - не нужно будет получать списки, искать и фильтровать данные, а просто вводить префикс с точкой (set., get., find.) и из выпадающего списка (после точки) выбирать нужный метод. Это планировалось ещё на этапе обдумывания концепции библиотеки, но делаться всё будет только тогда, когда будет готов весь базовый функционал библиотеки.
Также будет дана возможность работать с графикой - будет полноценная графическая оболочка, знающая о всех собранных библиотекой данных. Плюс - интерактивные пользовательские графические объекты...

---------------------------------

Since the articles describe all the stages of creating a library, I, unfortunately, did not consider it necessary to give full access to the list of trade events at once, but gave only access to the latest event. And the last event always returns the one that happened last - no matter when - right now, or an hour ago. It is still the last event, and it returns. And I lost sight of the fact that two identical events by name, but different in properties, will already require someone to receive. For this reason, receiving trading events was not brought to normal. In the classes of collections of accounts and symbols, methods have already been created and work to get all the events of the account or symbols, and they are easy to get in their programs. In exactly the same way, the next two articles will give an opportunity to receive trading events.

By the way - this is not all that will be implemented. Next, methods will be created to search and retrieve any data and events in their programs. And this will be done in a very convenient and visual way - you will not need to receive lists, search and filter data, but simply enter a prefix with a dot (set., get., find.) And select the desired method from the drop-down list (after the dot). This was planned at the stage of thinking over the concept of the library, but everything will be done only when all the basic functionality of the library is ready.
It will also be given the opportunity to work with graphics - there will be a full-fledged graphical shell that knows about all the data collected by the library. Plus - interactive custom graphic objects ...

 
Mohammad Bazrkar :

I was trying to get all events by that for loop in last code block which I sent it in previous comment.

I was getting old events by every new one, so I destroyed private and made everything public; it is not right way, but I did it anyway to make sure that list is clearing (with v13). 

Thank you for improvements in next articles. I will check them as soon as possible.

В русском сегменте ресурса вышла статья, в которой есть доступ к последнему событию из программы...

---------------------------------------

An article appeared in the Russian segment of the resource in which there is access to the last event from the program:

Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXIII): Основной торговый класс - контроль допустимых параметров
Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXIII): Основной торговый класс - контроль допустимых параметров
  • www.mql5.com
Продолжаем развивать торговый класс. У нас готовы торговые методы, работающие с "чистыми" условиями. Перед отправкой торгового приказа на сервер мы уже проверяем возможность его отправки — отсутствие ограничений на торговлю как со стороны торгового сервера, так и со стороны терминала и программы. Но этого, конечно же мало. Нам необходимо ещё...
 

Thank you Artyom, I found it before,

I think there is a bug: when we Open or Close more than one trades in the same second, it is missing one of them or only detect one of them; also it is detecting twice some times!

let me show you my logs

2019.10.14 15:58:14.489 MT4EventsEA EURUSD,M1: uninit reason 4

2019.10.14 15:57:28.424 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Account balance decreased by -0.75 USD (5445.52 USD)

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Margin level decreased by -16456.49% (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, Line 767: This event already in the list.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 at price 1.10304, profit -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 at price 1.10304, profit -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Margin level decreased by -32915.87% (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:13.000 - EURUSD Open 0.01 Buy #542264335 [0.01 Market order Buy #542264335] at price 1.10304

2019.10.14 15:57:18.002 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:12.000 - EURUSD Open 0.01 Buy #542264333 [0.01 Market order Buy #542264333] at price 1.10304

2019.10.14 15:57:17.547 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:12.000: Margin level increased by 49372.35% (49372.35%)

2019.10.14 15:57:17.175 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:11.000 - EURUSD Open 0.01 Buy #542264331 [0.01 Market order Buy #542264331] at price 1.10301

2019.10.14 15:56:17.144 MT4EventsEA EURUSD,M1: 2019.10.14 15:26:11.000: Margin level decreased by -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 at price 1.10301, profit -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 at price 1.10301, profit -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 at price 1.10304, profit -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 at price 1.10304, profit -0.14 USD

2019.10.14 15:56:09.140 MT4EventsEA EURUSD,M1: initialized

here is MT4 Account's Trade History:

and it is my code:

void OnTick() { DoChecks(); }
void OnTimer() { DoChecks(); }
//+------------------------------------------------------------------+
//| My Checking function                                             |
//+------------------------------------------------------------------+
void DoChecks() {
   engine.OnTimer();

   //\\//\\ Trade Events
   if(engine.LastTradeEvent()!=TRADE_EVENT_NO_EVENT) { //engine.LastTradeEvent()!=last_trade_event
      CArrayObj* list=engine.GetListAllOrdersEvents();
      if(list!=NULL) {
         int total=list.Total();
         for(int i=0; i<total ; i++){
            CheckTradeEvent(list.At(i));
         }
      }
      //--
      engine.ResetLastTradeEvent();
   }

   //\\//\\ Account events
   if(engine.LastAccountEvent()!=ACCOUNT_EVENT_NO_EVENT){
      CArrayInt* list=engine.GetListAccountEvents();
      if(list!=NULL){
         int total=list.Total();
         for(int i=0;i<total;i++){
            ENUM_ACCOUNT_EVENT event=(ENUM_ACCOUNT_EVENT)list.At(i);
            if(event==NULL){ continue; }
            CheckAccountEvent(event);
         }
      }
      //--
      engine.ResetLastAccountEvent();
   }

}


What do you think about it, is there any problem in my implementation?

 
Mohammad Bazrkar:

Thank you Artyom, I found it before,

I think there is a bug: when we Open or Close more than one trades in the same second, it is missing one of them or only detect one of them; also it is detecting twice some times!

let me show you my logs

2019.10.14 15:58:14.489 MT4EventsEA EURUSD,M1: uninit reason 4

2019.10.14 15:57:28.424 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Account balance decreased by -0.75 USD (5445.52 USD)

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Margin level decreased by -16456.49% (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, Line 767: This event already in the list.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 at price 1.10304, profit -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 at price 1.10304, profit -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Margin level decreased by -32915.87% (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:13.000 - EURUSD Open 0.01 Buy #542264335 [0.01 Market order Buy #542264335] at price 1.10304

2019.10.14 15:57:18.002 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:12.000 - EURUSD Open 0.01 Buy #542264333 [0.01 Market order Buy #542264333] at price 1.10304

2019.10.14 15:57:17.547 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:12.000: Margin level increased by 49372.35% (49372.35%)

2019.10.14 15:57:17.175 MT4EventsEA EURUSD,M1: - Position opened: 2019.10.14 15:27:11.000 - EURUSD Open 0.01 Buy #542264331 [0.01 Market order Buy #542264331] at price 1.10301

2019.10.14 15:56:17.144 MT4EventsEA EURUSD,M1: 2019.10.14 15:26:11.000: Margin level decreased by -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 at price 1.10301, profit -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 at price 1.10301, profit -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 at price 1.10304, profit -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Position closed: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 at price 1.10304, profit -0.14 USD

2019.10.14 15:56:09.140 MT4EventsEA EURUSD,M1: initialized

here is MT4 Account's Trade History:

and it is my code:


What do you think about it, is there any problem in my implementation?

Wait for the next article in the Russian segment of the resource.
In the next article, tracking of trading events that occurred simultaneously in one cycle is already ready and working.
And it also provides an example of tracking trading events in an adviser.

 
Artyom Trishkin:

Wait for the next article in the Russian segment of the resource.
In the next article, tracking of trading events that occurred simultaneously in one cycle is already ready and working.
And it also provides an example of tracking trading events in an adviser.

Thank you for your helpful replies and articles.

Reason: