Diskussion zum Artikel "Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil XIII): Ereignisse des Kontoobjekts"

 

Neuer Artikel Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil XIII): Ereignisse des Kontoobjekts :

Der Artikel behandelt die Arbeit mit Kontoereignissen, um wichtige Änderungen in den Kontoeigenschaften zu verfolgen, die den automatisierten Handel beeinflussen. Wir haben bereits im vorherigen Artikel bei der Entwicklung der Kollektion von Kontoobjekten einige Funktionen zur Verfolgung von Kontoereignissen implementiert.

Starten Sie nun den EA im Tester und eröffnen Sie weitere Positionen, um das Ereignis der Eigenkapitalerhöhung schnell zu erkennen, gefolgt vom Schließen der profitabelsten Position:



Wie wir sehen können, wird die profitabelste Position automatisch geschlossen, wenn das Eigenkapital den angegebenen Wert erreicht. Das Journal zeigt die Meldungen über das verfolgte Kontoereignis an.

Autor: Artyom Trishkin

 

Vielen Dank für Ihre großartige und hilfreiche Arbeit @Artyom Trishkin, ich sollte hier eine Frage stellen;

Ich denke, es ist notwendig, den Zustand der Engine zu speichern und beim nächsten Durchlauf von Skripten/EAs zu laden, um die Erfassung von Ereignissen fortzusetzen und Änderungen in der geschlossenen EA-Zeit zu identifizieren.

Aber es hat CObject Save/Load virtuelle Funktionen und gibt true ohne Aktion zurück.

F: Was sollten wir speichern und wie können wir darauf zugreifen, um es zu speichern?

 
Mohammad Bazrkar :

Vielen Dank für Ihre wunderbare und nützliche Arbeit @ Artyom Trishkin, ich habe hier eine Frage zu stellen;

Ich denke, dass es notwendig ist, den Zustand der Engine zu speichern und ihn beim nächsten Start der Skripte / Berater zu laden, um die Erfassung von Ereignissen fortzusetzen und Änderungen in der geschlossenen Zeit des Beraters zu erkennen.

Aber es hat virtuelle CObject Save / Load-Funktionen, die ohne jede Aktion true zurückgeben.

F: Was sollten wir speichern und wie erhalten wir Zugang zu ihnen?

Um die Vorteile der virtuellen Funktionen zu nutzen, müssen sie in den Erben von Objekten implementiert werden. Wie das geht, wird im Artikel über die Erstellung einer Kontensammlung beschrieben. Darin wird jedes der Kontenobjekte in eine Datei geschrieben und dann aus der Datei gelesen.

Ich habe vor, nach und nach alle in verschiedenen Bibliothekssammlungen gespeicherten Objekte in Dateien zu speichern. Aber während ich mit Handelsklassen für die Bibliothek beschäftigt bin.

 

Ich hatte ein Problem bei der Verwendung von ResetLastTradeEvent und ich werde es hier berichten,

Ich lese die letzten Ereignisse, indem ich eine Liste von ihnen erhalte und prüfe, ob es neue Ereignisse gibt oder nicht; denn den letzten Ereignisstatus zu speichern und ihn bei den nächsten Prüfungen zu vergleichen, ist keine gute Lösung. Stellen Sie sich vor, Sie möchten das Ereignis " Pending Orders Place" beobachten. Wenn zwei Pending Orders zu unterschiedlichen Zeiten ohne andere Ereignisse dazwischen platziert werden, verpassen wir das zweite Ereignis.

Ich überprüfe also die Ereignisse, mache meine Sachen und ResetLastTradeEvent und suche nach neuen Werten != _NO_EVENT . was ist also das Problem?

es gibt m_last_trade_event zurück, wenn man LastTradeEvent aufruft

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

also:

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

Ich habe auch einige Änderungen vorgenommen, um sicherzustellen, dass die Clear()-Funktion ihre Aufgabe in Listen und Arrays erfüllt.

Hier ist mein Anwendungsfall

   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 :

Ich hatte ein Problem bei der Verwendung von ResetLastTradeEvent und ich werde es hier berichten,

Ich lese die letzten Ereignisse, indem ich eine Liste von ihnen erhalte und prüfe, ob es neue Ereignisse gibt oder nicht; denn den letzten Ereignisstatus zu speichern und ihn bei den nächsten Prüfungen zu vergleichen, ist keine gute Lösung. Stellen Sie sich vor, Sie möchten das Ereignis " Pending Orders Place" beobachten. Wenn zwei Pending Orders zu unterschiedlichen Zeiten ohne andere Ereignisse dazwischen stattfinden, verpassen wir das zweite.

Ich überprüfe also die Ereignisse, mache mein Zeug und ResetLastTradeEvent und suche nach neuen Werten != _NO_EVENT . was ist also das Problem?

es gibt m_last_trade_event zurück, wenn Sie LastTradeEvent aufrufen

also:

Außerdem habe ich einige Änderungen vorgenommen, um sicherzustellen, dass die Funktion Clear() ihre Aufgabe in Listen und Arrays erfüllt.

Hier ist mein Anwendungsfall

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

engine.m_events.Clear();

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

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

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

Das ist leider die falsche Entscheidung. Haben Sie die Liste m_events in den öffentlichen Bereich der Klasse verschoben? Löschen Sie die Liste der Ereignisse in den Nachrichten?

engine.m_events.Clear();

Damit zerstören Sie die Struktur der Ereignissammlung. Aber es ist nicht umsonst, dass die m_events-Liste im privaten Bereich der CEngine-Klasse liegt - der Zugriff auf diese Listen ist von außen verboten.

Ja, ich weiß, dass der Vergleich eines vergangenen Ereignisses mit einem aktuellen nicht korrekt ist, und dies wurde nur gemacht, um den Empfang von Ereignissen zu überprüfen, und nicht, um vollständig mit ihnen zu arbeiten.
In der neuesten Version der Bibliothek (Artikel 23), die bereits zur Freigabe bereit ist, wird das Kennzeichen des aufgetretenen Handelsereignisses an das Steuerprogramm zurückgegeben. Und das letzte Ereignis ist immer verfügbar.
Und in Artikel 24 wird eine Liste aller Ereignisse verfügbar sein, die gleichzeitig eingetreten sind, z.B. die Löschung vieler schwebender Aufträge. Jedes Ereignis wird im Programm angezeigt. Und auf jedes dieser Ereignisse kann zugegriffen werden, um mit ihnen zu arbeiten.
 

Ich habe versucht, alle Ereignisse durch die for-Schleife im letzten Code-Block zu erhalten, die ich im vorherigen Kommentar gesendet habe.

Ich war immer alte Ereignisse durch jede neue, so dass ich zerstört private und machte alles öffentlich; es ist nicht der richtige Weg, aber ich tat es trotzdem, um sicherzustellen, dass die Liste ist Clearing (mit v13).

Vielen Dank für die Verbesserungen in den nächsten Artikeln. Ich werde sie so bald wie möglich überprüfen.

 
Mohammad Bazrkar :

Ich habe versucht, alle Ereignisse durch die for-Schleife im letzten Codeblock zu erhalten, den ich in meinem vorherigen Kommentar gesendet habe.

Ich war immer alte Ereignisse durch jede neue, so dass ich zerstört private und machte alles öffentlich; es ist nicht der richtige Weg, aber ich tat es trotzdem, um sicherzustellen, dass die Liste ist Clearing (mit v13).

Vielen Dank für die Verbesserungen in den nächsten Artikeln. Ich werde sie so bald wie möglich überprüfen.

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

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

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

Da in den Artikeln alle Phasen der Erstellung einer Bibliothek beschrieben werden, hielt ich es leider nicht für notwendig, die Liste der Handelsereignisse auf einmal vollständig zugänglich zu machen, sondern nur das letzte Ereignis. Und das letzte Ereignis gibt immer dasjenige zurück, das zuletzt stattgefunden hat - egal wann - jetzt gerade oder vor einer Stunde. Es ist immer noch das letzte Ereignis, und es wird zurückgegeben. Und ich habe die Tatsache aus den Augen verloren, dass zwei dem Namen nach identische, aber in ihren Eigenschaften unterschiedliche Ereignisse bereits jemanden erfordern, der sie empfängt. Aus diesem Grund wurde das Empfangen von Handelsereignissen nicht in den Normalzustand versetzt. In den Klassen der Sammlungen von Konten und Symbolen wurden bereits Methoden erstellt und arbeiten, um alle Ereignisse des Kontos oder der Symbole zu erhalten, und sie sind leicht in ihre Programme zu bekommen. Auf genau dieselbe Weise werden die nächsten beiden Artikel die Möglichkeit bieten, Handelsereignisse zu erhalten.

Das ist übrigens noch nicht alles, was implementiert werden wird. Als Nächstes werden Methoden erstellt, um beliebige Daten und Ereignisse in ihren Programmen zu suchen und abzurufen. Und dies wird auf eine sehr bequeme und visuelle Art und Weise geschehen - Sie brauchen keine Listen zu empfangen, Daten zu suchen und zu filtern, sondern geben einfach ein Präfix mit einem Punkt ein (set., get., find.) und wählen die gewünschte Methode aus der Dropdown-Liste (nach dem Punkt). Dies war in der Phase der Überlegungen zum Konzept der Bibliothek geplant, aber alles wird erst gemacht, wenn die Grundfunktionen der Bibliothek fertig sind.
Es wird auch die Möglichkeit gegeben werden, mit Grafiken zu arbeiten - es wird eine vollwertige grafische Shell geben, die über alle von der Bibliothek gesammelten Daten Bescheid weiß. Plus - interaktive benutzerdefinierte grafische Objekte ...

 
Mohammad Bazrkar :

Ich habe versucht, alle Ereignisse durch die for-Schleife im letzten Codeblock zu erhalten, den ich in meinem vorherigen Kommentar gesendet habe.

Ich war immer alte Ereignisse durch jede neue, so dass ich zerstört private und machte alles öffentlich; es ist nicht der richtige Weg, aber ich tat es trotzdem, um sicherzustellen, dass die Liste ist Clearing (mit v13).

Vielen Dank für die Verbesserungen in den nächsten Artikeln. Ich werde sie so bald wie möglich überprüfen.

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

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

Im russischen Segment der Ressource ist ein Artikel erschienen, in dem auf das letzte Ereignis des Programms eingegangen wird:

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

Danke Artyom, ich habe es schon gefunden,

Ich glaube, es gibt einen Fehler: Wenn wir mehr als einen Handel in der gleichen Sekunde öffnen oder schließen, wird einer von ihnen übersehen oder nur einer von ihnen erkannt; außerdem wird er manchmal doppelt erkannt!

Lassen Sie mich Ihnen meine Logs zeigen

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

2019.10.14 15:57:28.424 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Kontostand um -0.75 USD (5445.52 USD) gesunken

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Marginlevel um -16456.49% gesunken (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, Zeile 767: Dieses Ereignis ist bereits in der Liste.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 zu Preis 1.10304, Gewinn -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 zum Preis von 1.10304, Gewinn -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Marginlevel um -32915.87% gesunken (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Position eröffnet: 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 eröffnet: 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: Marginlevel um 49372.35% erhöht (49372.35%)

2019.10.14 15:57:17.175 MT4EventsEA EURUSD,M1: - Position eröffnet: 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 gesunken um -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 zu Preis 1.10301, Gewinn -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 zum Preis von 1.10301, Gewinn -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 zum Preis von 1.10304, Gewinn -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 zum Preis von 1.10304, Gewinn -0.14 USD

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

hier ist die Handelshistorie des MT4-Kontos:

Und das ist mein Code:

void OnTick() { DoChecks(); }
void OnTimer() { DoChecks(); }
//+------------------------------------------------------------------+
//| Meine Prüffunktion|
//+------------------------------------------------------------------+
void DoChecks() {
   engine.OnTimer();

   //\\//\\ Handelsveranstaltungen
   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();
   }

   //\\//\\ Kontoereignisse
   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();
   }

}


Was denken Sie darüber, gibt es irgendein Problem in meiner Implementierung?

 
Mohammad Bazrkar:

Danke, Artyom, ich habe es schon gefunden,

Ich glaube, es gibt einen Fehler: Wenn wir mehr als einen Handel in der gleichen Sekunde öffnen oder schließen, wird einer von ihnen übersehen oder nur einer von ihnen erkannt; außerdem wird er manchmal doppelt erkannt!

Lassen Sie mich Ihnen meine Logs zeigen

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

2019.10.14 15:57:28.424 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Kontostand um -0.75 USD (5445.52 USD) gesunken

2019.10.14 15:57:28.423 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:22.000: Marginlevel um -16456.49% gesunken (0.00%)

2019.10.14 15:57:27.895 MT4EventsEA EURUSD,M1: CEventsCollection::CreateNewEvent, Zeile 767: Dieses Ereignis ist bereits in der Liste.

2019.10.14 15:57:27.474 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:27:13.000 - EURUSD Close Buy #542264335 zu Preis 1.10304, Gewinn -0.14 USD

2019.10.14 15:57:27.472 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:27:12.000 - EURUSD Close Buy #542264333 zum Preis von 1.10304, Gewinn -0.14 USD

2019.10.14 15:57:19.095 MT4EventsEA EURUSD,M1: 2019.10.14 15:27:13.000: Marginlevel um -32915.87% gesunken (16456.49%)

2019.10.14 15:57:18.844 MT4EventsEA EURUSD,M1: - Position eröffnet: 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 eröffnet: 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: Marginlevel um 49372.35% erhöht (49372.35%)

2019.10.14 15:57:17.175 MT4EventsEA EURUSD,M1: - Position eröffnet: 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 gesunken um -12343.32% (0.00%)

2019.10.14 15:56:16.800 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:40.000 - EURUSD Close Buy #542263747 zu Preis 1.10301, Gewinn -0.07 USD

2019.10.14 15:56:16.798 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:41.000 - EURUSD Close Buy #542263749 zum Preis von 1.10301, Gewinn -0.07 USD

2019.10.14 15:56:16.347 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 zum Preis von 1.10304, Gewinn -0.14 USD

2019.10.14 15:56:15.926 MT4EventsEA EURUSD,M1: - Position geschlossen: 2019.10.14 15:22:42.000 - EURUSD Close Buy #542263753 zum Preis von 1.10304, Gewinn -0.14 USD

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

hier ist die Handelshistorie des MT4-Kontos:

und das ist mein Code:


Was denken Sie darüber, gibt es irgendein Problem in meiner Implementierung?

Warten Sie auf den nächsten Artikel im russischen Segment der Ressource.
Im nächsten Artikel ist die Verfolgung von Handelsereignissen, die gleichzeitig in einem Zyklus aufgetreten sind, bereits fertig und funktioniert.
Er enthält auch ein Beispiel für die Verfolgung von Handelsereignissen in einem Berater.

 
Artyom Trishkin:

Warten Sie auf den nächsten Artikel im russischen Segment der Ressource.
Im nächsten Artikel ist die Verfolgung von Handelsereignissen, die gleichzeitig in einem Zyklus aufgetreten sind, bereits fertig und funktioniert.
Er enthält auch ein Beispiel für die Verfolgung von Handelsereignissen in einem Berater.

Ich danke Ihnen für Ihre hilfreichen Antworten und Artikel.