Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XIII): События объекта "аккаунт""

 

Опубликована статья Библиотека для простого и быстрого создания программ для MetaTrader (Часть XIII): События объекта "аккаунт":

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

Теперь запустим советник в тестере и откроем побольше позиций — чтобы быстро поймать событие увеличения средств и написанную нами обработку данного события — закрытие самой прибыльной позиции:


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

Автор: Artyom Trishkin

 

Спасибо за отличную и полезную работу @Artyom Trishkin, хочу задать вопрос здесь;

Я думаю, что необходимо сохранять состояние движка и загружать его при следующем запуске скриптов/EA, чтобы возобновить перехват событий и определить изменения в закрытом времени советника.

Но у него есть виртуальные функции CObject Save/Load, и они возвращают true без каких-либо действий.

Вопрос: Что нужно сохранять и как получить доступ к ним для сохранения?

 
Mohammad Bazrkar :

Спасибо за вашу замечательную и полезную работу @ Артём Тришкин, хочу задать вопрос;

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

Но у него есть виртуальные функции CObject Save / Load, которые возвращают true без каких-либо действий.

Вопрос: Что мы должны сохранять и как получить к ним доступ?

Чтобы воспользоваться виртуальными функциями, их нужно реализовать у объектов-наследников. Как это делается, описано в статье о создании коллекции аккаунтов. В ней каждый из объектов аккаунта записывается в файл, а затем считывается из него.

Я планирую постепенно сохранить в файлах все объекты, хранящиеся в различных библиотечных коллекциях. Но пока занят торговыми классами для библиотеки.

 

У меня возникла проблема при использовании ResetLastTradeEvent, и я собираюсь сообщить о ней здесь,

Я читаю последние события, получая их список, проверяя, есть ли новые события или нет; потому что сохранение состояния последнего события и сравнение его при следующих проверках - не лучшее решение. Например, если два отложенных ордера размещаются в разное время без каких-либо других событий между ними, мы пропустим второй.

Итак, я проверяю события, делаю свои действия и ResetLastTradeEvent и ищу новые значения != _NO_EVENT . так в чем же проблема?

При вызове LastTradeEvent возвращается m_last_trade_event

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

так что:

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

Также я сделал некоторые изменения, чтобы функция Clear() выполняла свою работу в списках и массивах.

Вот мой пример использования

   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 :

У меня возникла проблема при использовании ResetLastTradeEvent, и я собираюсь сообщить о ней здесь,

Я читаю последние события, получая их список, проверяя, есть ли новые события или нет; потому что сохранение состояния последнего события и сравнение его при следующих проверках - не лучшее решение. Например, если два отложенных ордера размещаются в разное время без каких-либо других событий между ними, мы пропустим второй.

Итак, я проверяю события, делаю свои действия и ResetLastTradeEvent и ищу новые значения != _NO_EVENT . так в чем же проблема?

при вызове LastTradeEvent возвращается m_last_trade_event

Итак:

Также я сделал некоторые изменения, чтобы функция Clear() выполняла свою работу в списках и массивах.

Вот мой пример использования

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

engine.m_events.Clear();

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

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

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

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

engine.m_events.Clear();

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

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

Я пытался получить все события с помощью цикла for в последнем блоке кода, который я отправил в предыдущем комментарии.

Я получал старые события по каждому новому, поэтому я уничтожил приватные и сделал все публичными; это неправильный способ, но я все равно сделал это, чтобы убедиться, что список очищается (с v13).

Спасибо за улучшения в следующих статьях. Я проверю их как можно скорее.

 
Mohammad Bazrkar :

Я пытался получить все события с помощью цикла for в последнем блоке кода, который я отправил в предыдущем комментарии.

Я получал старые события по каждому новому, поэтому я уничтожил приватные и сделал все публичными; это неправильный способ, но я все равно сделал это, чтобы убедиться, что список очищается (с v13).

Спасибо за улучшения в следующих статьях. Я проверю их как можно скорее.

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

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

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

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

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

 
Mohammad Bazrkar :

Я пытался получить все события с помощью цикла for в последнем блоке кода, который я отправил в предыдущем комментарии.

Я получал старые события по каждому новому, поэтому я уничтожил приватные и сделал все публичными; это неправильный способ, но я все равно сделал это, чтобы убедиться, что список очищается (с v13).

Спасибо за улучшения в следующих статьях. Я проверю их как можно скорее.

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

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

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

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

Спасибо, Артем, я нашел это раньше,

Я думаю, что есть ошибка: когда мы открываем или закрываем несколько сделок в одну секунду, он пропускает одну из них или обнаруживает только одну из них; также он обнаруживает дважды в некоторых случаях!

Позвольте мне показать вам мои логи

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: Баланс счета уменьшился на -0.75 USD (5445.52 USD)

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Маржинальный уровень уменьшился на -16456.49% (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, строка 767: Это событие уже есть в списке.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Маржинальный уровень снизился на -32915.87% (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Позиция открыта: 2019.10.14 15:27:13.000 - EURUSD Open 0.01 Buy #542264335 [0.01 рыночный ордер Buy #542264335] по цене 1.10304

2019.10.14 15:57:18.002 MT4EventsEA EURUSD,M1: - Позиция открыта: 2019.10.14 15:27:12.000 - EURUSD Open 0.01 Buy #542264333 [0.01 рыночный ордер Buy #542264333] по цене 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: - Позиция открыта: 2019.10.14 15:27:11.000 - EURUSD Открыт 0.01 Buy #542264331 [0.01 рыночный ордер Buy #542264331] по цене 1.10301

2019.10.14 15:56:17.144 MT4EventsEA EURUSD,M1: 2019.10.14 15:26:11.000: Маржинальный уровень уменьшился на -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 по цене 1.10301, прибыль -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 по цене 1.10301, прибыль -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 по цене 1.10304, прибыль -0.14 USD

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

вот история торговли счета MT4:

и это мой код:

void OnTick() { DoChecks(); }
void OnTimer() { DoChecks(); }
//+------------------------------------------------------------------+
//| Моя проверочная функция|
//+------------------------------------------------------------------+
void DoChecks() {
   engine.OnTimer();

   //\\\\//\\\\ Торговые мероприятия
   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();
   }

   //\\\\//\\\\ События по счетам
   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();
   }

}


Что вы думаете об этом, есть ли какие-то проблемы в моей реализации?

 
Mohammad Bazrkar:

Спасибо, Артём, я его уже находил,

Я думаю, что есть ошибка: когда мы открываем или закрываем более одной сделки в одну секунду, он пропускает одну из них или определяет только одну из них; также он определяет дважды в некоторых случаях!

Позвольте мне показать вам мои логи

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: Баланс счета уменьшился на -0.75 USD (5445.52 USD)

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Маржинальный уровень уменьшился на -16456.49% (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, строка 767: Это событие уже есть в списке.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Маржинальный уровень снизился на -32915.87% (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Позиция открыта: 2019.10.14 15:27:13.000 - EURUSD Open 0.01 Buy #542264335 [0.01 рыночный ордер Buy #542264335] по цене 1.10304

2019.10.14 15:57:18.002 MT4EventsEA EURUSD,M1: - Позиция открыта: 2019.10.14 15:27:12.000 - EURUSD Open 0.01 Buy #542264333 [0.01 рыночный ордер Buy #542264333] по цене 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: - Позиция открыта: 2019.10.14 15:27:11.000 - EURUSD Открыт 0.01 Buy #542264331 [0.01 рыночный ордер Buy #542264331] по цене 1.10301

2019.10.14 15:56:17.144 MT4EventsEA EURUSD,M1: 2019.10.14 15:26:11.000: Маржинальный уровень уменьшился на -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 по цене 1.10301, прибыль -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 по цене 1.10301, прибыль -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 по цене 1.10304, прибыль -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Позиция закрыта: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 по цене 1.10304, прибыль -0.14 USD

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

вот история торговли счета MT4:

и это мой код:


Что вы думаете об этом, есть ли какие-либо проблемы в моей реализации?

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

 
Artyom Trishkin:

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

Спасибо за полезные ответы и статьи.