Ändern Externer Parameter von MQL4 Programmen ohne Neustart

Alexey Koshevoy | 25 März, 2016

Einführung


Jeder, der jemals ein Programm gestartet hat oder einen Indikator zur Ausführung, wurde mit der Möglichkeit konfrontiert vorläufig externe Parameter einzurichten, die häufig dem Erfolg des Programms zugrunde liegen. Es gibt eine Möglichkeit Parameter während der Programmausführung zu ändern. Aber wie kann dann das ohne Initialisierung gemacht werden? In einigen Fällen kann dies die Verwaltung vorher geöffnete Ordern zu verwalten. In diesem Artikel versuchen wir dieses Problem so flexibel wie möglich zu lösen.

Aufgabenstellung

Wir werden dieses Problem für Expert Advisors betrachten, anstatt für Indikatoren. Für Indikatoren ist dieses Problem nicht so akut, obwohl die Methoden universell sind und Sie können sie auf alle Programme anwenden.

Bei klassischem EA Schreiben muss der Kontext bei jedem Tick erstellt werden. Es kann zwei Arten von Kontexten geben - der Kontext des Status und der Handelskontext. Der Kontext des Status beinhaltet den aktuellen Status von Indikatoren und anderer der Entscheidungsfindung zum Öffnen/Schließen/Ändern von Ordern zugrunde liegende Elemente. Der Handelskontext beinhaltet die Informationen über offene Ordern, deren Status und Mengen. Nachdem der Handelskontext analysiert wurde, treffen Trader Entscheidungen darüber, was mit ihren Ordern machen. Kontexte sind durch Typen bedingt aufgeteilt. Diese Klassifikation wurde der Einfachheit halber eingeführt.

Wenn der Kontext bei jedem Tick wiederhergestellt werden kann, stellt sich das Problem nicht. Sie können externe Parameter frei ändern und Ihr Programm wird weiter entsprechend seiner Logik funktionieren. Zuerst wird es die Initialisierung geben, dann berechnet der EA Werte von Indikatoren, "nimmt" offene Ordern "auf" und führt eine Anzahl an Operationen entsprechend der gesammelten Informationen durch. Alles ist einfach und transparent.

Betrachten wir jetzt eine Situation, in der eine exaktere Parameter ändernde Technologie notwendig ist, die nicht zu einen kompletten Programm-Neustart führt.

Beispiel 1.
Unter unseren offenen Ordern gibt es einige, die auf eine besondere Weise verarbeitet werden. Das heißt, wir müssen diese unter anderen durch unseren EA geöffneten Ordern ermitteln. Zu diesem Zweck können wir einige Parameter nutzen: Ticket, Magic Number, Currency, Comment. Die Magic Number wird verwendet, um unsere Aufträge von anderen im System zu trennen, die von anderen EAs oder manuell geöffnet wurden. 'Währung', zusätzlich zu der 'Magic Number', ermöglicht uns den gleichen EA für verschiedene Währungspaare zu nutzen. Es bleiben nur zwei Parameter, die für jede Order einzigartig sein können. 'Comment' ist der ist der geeignetste, er kann alle textlichen Informationen enthalten, hat aber einen Nachteil - er kann auf der Serverseite geändert werden, beispielsweise bei teilweisem Schließen. 'Ticket' ist für jede Order einzigartig, aber die Ticketnummer alleine ist nicht ausreichend um Ordern in Klassen aufzuteilen. also muss das Ticket der Ordern mit einigen anderen Informationen verglichen werden. Wie wir in diesem Fall sehen können, wäre es am praktischsten, den 'Ticket' Parameter zu verwenden und die Tickets entsprechend nach Order-Klassen zu speichern. Dementsprechend, bei einem Neustart, wird das die Tickets enthaltene Array verloren gehen, also werden wir nicht in der Lage sein Informationen über die virtuellen Klassen von Ordern wiederherzustellen

Beispiel 2.
Ein universeller Mechanismus ist entwickelt, der es uns ermöglicht Änderungen in dem Status von Ordern zu analysieren. Das heißt, wir haben zwei Kontexte von Orderstatus. Die erste Liste ist bei dem aktuellen Tick, während die zweite bei dem vorherigen Tick ist. Beim Analysieren der Informationen, können wir Schlussfolgerungen darüber zeihen, welche Order geöffnet/geändert/geschlossen wurde und über den Grund solcher Operationen. Diese Methode ist praktisch für das EA Debuggen und für die Handelslogik-Entwicklung. Ihr Nachteil ist jedoch, dass es notwendig ist die Orderstatus bei dem vorhergehenden Tick zu speichern. Dementsprechend werden diese Daten bei einem EA Neustart verloren gehen..

Beispiel 3.
Ein EA empfängt externe Daten. Es spielt keine Rolle, auf welche Art oder von wo die Daten ankommen. Es ist wichtig, dass, wenn wir diese Daten sammeln müssen zur Verarbeitung und ihre Historie nicht abfragen können, wir einen Kontext während der gesamten Arbeit des EA erstellen müssen. Das Ändern externer Parameter wird zu einem Neustart führen und wir müssen die Daten von einer externen Quelle erneut sammeln.

Beispiel 4.
Ein MQL4 Programm wird als kompilierte Datei verteilt. Somit kann der Anwender seinen Code nicht verändern oder den Algorithmus sehen. Es ist ein hervorragender Schutz Ihres geistigen Eigentums. Das Programm kann jedoch einige externe Variablen haben, und es ist nicht sehr komfortabel diese jedes Mal zu ändern, anstatt es einmal z machen und mit den neuen Werten zu kompilieren. Obwohl dieses Beispiel nicht direkt das Problem der Kontext-Speicherung betrifft, ist es sehr typisch im Licht der hier zu lösenden Probleme.

Wenn Sie EAs erstellen, sollten Sie Ihre Logik auf eine solche Weise konstruieren, die das Speichern des Kontexts während Operationen vermeidet. Eine solche Entwicklung kann viel komplizierter sein, in diesem Fall wird das System aber so stabil ie möglich sein. Wenn wir das Speichern des Kontexts jedoch nicht vermeiden können, wird die berücksichtigte Methode und helfen die EA Einstellungen flexibel zu verwalten, ohne die Daten beim Ändern ihrer Parameter zu verlieren.

Anwendung

Um die Probleme in den obigen Beispielen zu lösen, wollen wir einen Komplex entwickeln, der unsere externen Parameter von MQL4 Programmen verwalten soll. Was kann mit einem solchen System getan werden?

Per Definition, können wir die externen Parameter aller Typen ändern:

• Integer
• Bool
• Double
• String
• Datetime

Wir sollten allerdings nicht mit dem zufrieden sein, was bereits erreicht wurde. Um das gesamte Potential dieses Ansatzes zu erkennen, sollten wir die Funktionsprinzipien des Systems an einem sehr einfachen Beispiel betrachten.

Der Komplex arbeitet wir folgt. In der Phase der Initialisierung, speichert das MQL4 Programm alle Werte, die durch den Benutzer geändert werden können in die entsprechende Datei. Das externe Programm öffnet diese Datei, liest die Daten, platziert sie auf dem Bildschirm und der Benutzer beginnt zu arbeiten. Sobald der Benutzer einen der Parameter in dem externen Programmändert, wird die Datei modifiziert. Das heißt, der neue durch den Benutzer eingestellte Wert wird an die Stelle des alten geschrieben. Nun wird das MWL4 Programm, in dem 'start' Funktionsaufruf, die Datendatei auf geänderte Werte prüfen und, wenn Änderungen gefunden werden, die entsprechenden Funktionen aufrufen. Die Funktionen verarbeiten die Änderungen in externen Werten mit der Ausführung voreingestellter Algorithmen. In den meisten Fällen ist es ausreichend, die neuen Werte einfach zu den Variablen zuzuweisen. Das ist es, wie ein Zyklus des Änderungskomplexes für externe Parameter in etwa arbeitet.

Aus dem obigen Beispiel können wir erkennen, dass die Erstellung eines stabilen Dialogs zwischen dem MWL4 Programm und dem externen Progamm am wichtigsten ist, damit der Komplex erfolgreich arbeitet. Jetzt müssen wir die Mittel um Methoden wählen, um den Dialog zu organisieren. Allerdings, auch für einen einfachsten Ansatz ohne die Verwendung von DLs, können wir uns mehr erlauben, als nur die Änderung externer Parameter.

Betrachten wir einige Beispiel, die zusätzliche Funktionen dieses Ansatzes offenbaren. da wir einen bilateralen Dialog haben, kann das MQL4 Programm auf die Anfragen eines externen Programm antworten.

Zum Beispiel, ein Benutzer ändert den Wert einer Variable. Das externe Programm schreibt den neuen Wert der Variable in die Datei und ändert den Status auf "wartend auf eine Aktion des MQL4 Programms". Bei der Verarbeitung der Datei, berücksichtigt das MQL4 Programm nur Variablen die diesen Status haben, andere wurden nicht verändert. Bei der Verarbeitung der gefundenen Variablen, ändert sich deren Status auf "Änderung akzeptiert". Somit können wir in einem externen Programm die in dem MQL4 Programm ausgeführten Änderungen sofort sehen. Es ist eine nützliche Funktion für die Überwachung.

Versuchen wir die Funktion "action" umzusetzen. Wir müssen erreichen, dass die Änderung einer Variable in einem externen Proramm nicht zu der Änderung der entsprechenden Variable in MQL4 führt, sondern in der einmaligen Ausführung einer bestimmten Aktion. Die kann wie folgt realisiert werden. Die Variable wird in einem externen Programm geändert. Die Variable kann die Werte 0 und 1 annehmen. Ist der Wert 1, führt das MQL4 Programm ewine bestimmte Aktionaus und weist der Variable den Wert 0 zu. Jetzt kann diese Aktion von dem externen Programm erneut ausgeführt werden. Dies ist mehr, als nur das Ändern von Variablen. Mit diesen Aktionen können wir viele nützliche Funktionen umsetzen. Die Aktionen sind sehr ähnlich wie MQL4 Skripte, haben aber einen wesentlichen Unterschied. Ein Skript kann in jedem Augenblick des MetaTrader 4 Terminal-Betriebs ausgeführt werden, während eine Aktion nur dann durchgeführt werden kann, sobald die 'start' Funktion aufgerufen wird. Das heißt, in dem Moment der aktuellen Kursänderung.

Am Ende betrachten wir ein Beispiel dafür, wie wir die Methode zur Datenübertragung aus einer externen Quelle an ein MQL4 Programm verwenden. Nehmen wir an, wir müssen keine externen Daten ändern, aber ein MQL4 Programm, oder vielmehr ein EA, muss von einer externen Quelle verwaltet werden. Die externe Quelle verarbeitet die Daten, macht Berechnungen und, basierend auf den erhaltenen Ergebnissen, trifft eine Entscheidung über das Öffnen/Schließen von Ordern. Um eine Order zu öffnen, ist es notwendig die wichtigsten Parameter zu übergeben und den Befehl zum Öffnen an das Programm. Die Order-Parameter haben den "wartend" Status, da deren Änderungen das Programm nicht zum Ausführen der Aktionen zwingen soll. In diesem Beispiel ist es die action Variable, die das Ereignis zum Lesen der Orderöffnung-Parameter ist.

Wir berücksichtigten drei Aspekte bei der Verwendung des Komplexes. Der erste ist das Übergeben von Parametern mit dem Status in eine Richtung, von einem externen Programm in ein MQL4 Programm. In diesem Fall wird der Dialog über die Änderung des Werts für den Status umgesetzt. Der zweite ist die Anfrage zum Ausführen bestimmter Aktionen. in dem Dialog wird der Wert der Variable und der Wert des Status geändert. Der dritte und einfachste Aspekt, ist das Entnehmen von Informationen aus der gespeicherten Datei. Es wird kein Dialog verwendet.

Entwickeln des Komplex

Um den Komplex zu entwickeln, müssen wir eine Anzahl an Problemen lösen. Zunächst müssen wir die Dokumentstruktur für die Übertragung von Informationen zwischen Programmen entwickeln. Dann müssen wir ein Protokoll für die Übertragung dieses Dokuments auswählen. Schließlich müssen wir eine Bibliothek schreiben, für die Arbeit mit dem System unter Verwendung von MQL4 oder jeder anderen für ein bestimmtes externes Programm geeigneten Programmiersprache.

Entwicklung der Dokumentstruktur
Die Entwicklung der Dokumentstruktur ist eine der wichtigsten Aufgaben für den Komplex. Das Dokument muss alle oben beschriebenen Aspekte widerspiegeln.

Für die Informationsspeicherung wäre die XML-Technologie der universellste Ansatz. Allerdings treten dabei eine Anzahl an Problemen aus. Zunächst hat MQL4 keine eingebetteten Mittel für die Arbeit mit XML über DLLs, dann wird das gesamte System mehrfach komplizierter werden. Also verwenden wir eine Standard-Textdatei und unsere eigene Struktur der Datendarstellung.

Das Hauptziel des Dokuments ist eine Variable oder ein Wert. Der Wert hat hat eine klar definierte Struktur, bestehend aus den folgenden Elementen:

• Tittl
• Typ
• Status
• Wert

Betrachten wir sie einen nach dem anderen:

Titel – der Name der Variable. Er wird von Programmen verwendet um das Objekt zu erkennen.

Typ – der Typ der Variable. Entsprechend dem Typ der Variable, wird sich die Verarbeitungslogik ändern. Die Typen werden über nummerische Werte bestimmt.

Type Description Analog in MQL Value
0Boolean oder r logisch
bool0 – false, 1 - true
1StringstringEine Reihe von Zeichen.
2Integer characterintGrenzwerte entsprechend den MQL4 Regeln.
3Real characterdoubleGrenzwerte entsprechend den MQL4 Regeln. Trennzeichen ist der Punkt.
4DatedatetimeDas Format der Erfassung entsprechend den MQL4 Regeln.
5Actionno equivalent0 – keine Ausführung notwendig, 1 - Ausführung ist notwendig.


Status – eine Status Variable. Sie wird durch einen nummerischen Wert besdtimmt. Betrachten wir eine Tabelle mögliche Variationen:

Value Description
0Wartend. Keine Verarbeitung notwendig.
1Anfrage zur Änderung. Das MQL4 Programm muss auf diesen Status-Wert antworten.
2Keine Verarbeitung notwendig. Es ist der Wert der Variable, es ist ein Wert für Variablen, die für ein anderes Ereignis als eine direkte Ändeerung verarbeitet werden muss.

Wert – der Wert der Variable. Die Regeln der Erfassung des Wertes sind abhängig von dem Variablen-Typ.
Parameter Interaktion.

Externes Programm. Ändern des Werts.

Wenn Status=0, dann zum Ändern des Wertes von 'Value' der Wert von Status=1.
Wenn Status=1, dann zum Ändern des Wertes von 'Value' der Wert von 'Status' ändert sich nicht.
Wenn Status=2, dann zum Ändern des Wertes von 'Value' der Wert von 'Status' ändert sich nicht.

Externes Programm. Ändern des Werts stornieren.

Es gibt Situationen, in denen ein Wert versehentlich geändert oder durch den falschen Wert ersetzt wurde, oder der Benutzer ändert seine/ihre Meinung über die Änerung des Werts, nachdem er die Änderung bestätigt hat. Betrachten wir die Möglichkeit diese Prozedur zu stornieren. Es muss jedcoh berücksichtigt werden, dass, wenn das MQL4 Programm die Datei mit den Änderungen bereits verarbeitet hat, nichts storniert werden kann.

Wenn Status=1, dann ist der 'Wert' geändert auf den vorherigen, und Status=0.
Wenn Status=2, dann ist der 'Wert' geändert auf den vorherigen, aber der Wert von 'Status' ändert sich nicht.

MQL4 Programm. Änderungen verarbeiten.

Das MQL4 Programm berücksichtigt Änderungen nur dann, wenn die Variable 'Status' gleich 1 ist. Per Definition spielt es keine Rolle, welcher Variablen-Typ geändert wurde, da wir vir verabeitende Funktion für jede Änderung abbrechen. Der Unterschied liegt nur darin, wo die 'Wert' einen Wert haben wird oder nicht, das heißt, ob die Änderung der Variable eine Änderung ist oder eine Anfrage zur Ausführung einer Aktion. Betrachten wir dies im Detail.

Wenn Status=1 und 'Typ' reicht von 0 bis 4, dann 'Wert' verwenden und den 'Status' auf 0 ändern.
Wenn Status=1 und Typ=5, dann eine Aktion ausführen und den 'Status' auf 0 ändern und den 'Wert' auf 0 ändern.
Wenn wir im Verlauf der Ausführung der Aktion zusätzliche Werte mit Status=2 verwenden, änder der Wert von 'Status' sich nach der Verwendung nicht.

Betrachten wir einige Beispiele.

Beispiel 1. Ändern einer Variable.
Nehmen wir die Variable Var1 des Integer Typs mit dem Wert von 10. Die Variable ist in dem "wartend" Status.

Titel=Var1
Type2
Status=0
Wert=10

In dem externen Programm ändern Sie den Wert von Var1 auf 30. Jetzt haben wir:
Titel=Var1
Typ=2
Status=1
Wert=30

Der Wert von 'Wert' hat sich geändert, als auch der Wert von 'Status' sich geändert hat auf "Anfrage zur Änderungsverarbeitung".

Das MQL4 Programm erkennt die Änderung, ruft die benötigte Funktion auf und modifiziert das Dokument:
Titel=Var1
Typ=2
Status=0
Wert=30

Der Wert von 'Wert' wurde akzeptiert und der Wert von 'Status' wurde auf "wartend" geändert.

Beispiel 2. Ausführen einer Aktion.
Nehmen wir die Variable Var2 des Action-Typ. Die Variable ist in dem "wartend" Status.

Titel=Var2
Typ=5
Status=0
Wert=0

In dem externen Programm ändern wir den Wert von Var2 auf 1. Wenn wir ein wenig nach oben scheuen, können wir sagen, dass wir, um Fehler bei der Zuordnung eines falschen Werts in dem externen Programm zu vermeiden, eine Schaltfläche verwenden, kein Eingabefeld. Jetzt haben wir:
Titel=Var2
Typ=5
Status=1
Wert=1

Der Wert von 'Wert' wurde geändert, und auch der Wert von 'Status' wurde auf "Anfrage zur Änderungsverarbeitung" geändert.

Das MQL4 Programm erkennt sie Änderungen, ruft die benötigte Funktion aus und modifiziert das Dokument:
Titel=Var2
Typ=5
Status=0
Wert=0

Der Wert von 'Wert' wurde auf 0 geändert, während der Wert von 'Status' auf "wartend" geändert wurde.
Wir können sehen, dass, bei der Ausführung einer Aktion, die Werte von 'Status' und von 'Wert' sich ändern werden. Wenn die Variable geändert wurde, wird sich nur der Wert von 'Status' auch ändern, während der Wert der Variable der gleiche bleibt.

Auswahl eines Übertragungsprotokolls
Unter den vielen Mitteln zur Datenübertragung zwischen MQL4 Programmen und einem externen Programm, wählen wir Datei (file). Die Verwendung von Datei benötigt keine Entwicklung zusätzlicher Bibliotheken für MT4. Die Methode ist eher universell,kleiner Speicherbedarf und einfach in seiner Umsetzung. Sie hat eine Reihe von Nachteilen, die einfach beseitigt werden können und keine kritischen Beschränkungen.

Das MQL4 Programm kann auf die Änderungen in der Datei der Variablen nur auf ein bestimmtes Ereignis reagieren, nämlich: auf die Änderung des aktuellen Kurses auf dem aktuellen Währungspaar.

Wir können eine Überprüfung der Datei der Variablen von einem externen Programm zu jeder Zeit starten. Wir sollten optimale Zeitintervalle für die Überprüfung wählen, um die Ressourcen unseres PCs nicht zu überlasten und die Datei nicht für einen zu langen Zeitraum zu besetzen, da sie gleichzeitig von dem MQL4 Programm verwendet werden kann. Die Änderungen in dem externen Programm werden hauptsächlich von Hand gemacht, das heißt, nicht so schnell wie von einem Computer, also wäre es sinnvoll nicht öfter als einmal in der halben Sekunde zu prüfen, um die Situation zu verfolgen. Dieser Parameter muss, natürlich, einstellbar sein, und Sie sollten den Zeitintervall empirisch für sich selbst wählen.

Während dem Versuch die Datei mit dem MQL4 Programm zu öffnen, kann sie zum Schreiben durch das externe Programm geöffnet werden. Deshalb sollte wir solche Situationen vorhersehen und mehrere Versuche zum Aufrufen der Datei innerhalb einer Verarbeitung realisieren, um unsere Zeit nicht durch das Warten auf eine Kursänderung zu verschwenden. Das gleiche gilt für das externe Programm: Wenn die Datei durch das MQL4 Programm verwendet wird, sollten Sie mehrere Versuche zum Aufrufen der Datei in bestimmten Zeitintervallen unternehmen.

Anpassung an MQL4

Variablen

int    ExVH_VarCnt;
string ExVH_FileName;
string ExVH_Project;
 
string ExVH_Title[];
string ExVH_Type[];
string ExVH_Status[];
string ExVH_Value[];

Benutzerfunktionen

bool ExVH_Open(string FileName)
{
   bool Result=true;
   ExVH_FileName=FileName;
   if (!ExVH_i_Load())
      Result=false;
   if (Result)
      if (!ExVH_i_GetVarCnt())
         Result=false;
   if (Result)
      ExVH_i_Disassemble();
   return(Result);
}
 
int ExVH_Close()
{
   ExVH_i_Assemble();
   ExVH_i_Save();
 
}
 
int ExVH_GetStatus(int Id)
{
   if ((Id<1)||(Id>ExVH_VarCnt))
      return(-1);
   else
      return(StrToInteger(ExVH_Status[Id-1]));
}
 
int ExVH_SetStatus(int Id, int Status)
{
   int Result;
   if ((Id<1)||(Id>ExVH_VarCnt))
      Result=-1;
   else
   {
      Result=1;
      ExVH_Status[Id-1]=Status;
   }
   return(Result);
}
 
string ExVH_GetValue(int Id)
{
   if ((Id<1)||(Id>ExVH_VarCnt))
      return("N/A");
   else
      return(ExVH_Value[Id-1]);
}

Funktion für Interne Verwendung

bool ExVH_i_Load()
{
   bool Result=true;
   ExVH_Project="";
   int i=0;
   int FS=0;
   int handle;
   int Buf[];
   handle=FileOpen(ExVH_FileName,FILE_BIN|FILE_READ);
   if(handle>0)
   {
      FS=FileSize(handle);
      ArrayResize(Buf,FS);
      while(!FileIsEnding(handle)) 
      {
         Buf[i] = FileReadInteger(handle, CHAR_VALUE);
         i++;
      }
      
      FileClose(handle);
      string Str="";
      for (i=0;i<FS;i++)
         Str=Str+CharToStr(Buf[i]);  
      ExVH_Project=Str;
   } else 
      Result=false;
   return(Result);
}
 
bool ExVH_i_Save()
{
   bool Result=true;
   int handle=FileOpen(ExVH_FileName,FILE_BIN|FILE_WRITE);
   if(handle>0)
   {
      FileWriteString(handle,ExVH_Project,StringLen(ExVH_Project));
      FileClose(handle);
   } else
      Result=false;
   return(Result);
}
 
bool ExVH_i_GetVarCnt()
{
   bool Result=true;
   string Value=ExVH_i_GetVarValue("Var_Cnt");
   if (Value=="N/A")
      Result=false;
   else
      ExVH_VarCnt=StrToInteger(Value);
   return(Result);
}
 
void ExVH_i_Disassemble()
{
   int i;
   ArrayResize(ExVH_Title, ExVH_VarCnt);
   ArrayResize(ExVH_Type, ExVH_VarCnt);
   ArrayResize(ExVH_Status, ExVH_VarCnt);
   ArrayResize(ExVH_Value, ExVH_VarCnt);
   
   for (i=0;i<ExVH_VarCnt;i++)
   {
      ExVH_Title[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Title");
      ExVH_Type[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Type");
      ExVH_Status[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Status");
      ExVH_Value[i]=ExVH_i_GetVarValue("Var"+(i+1)+"_Value");
   } 
}
 
void ExVH_i_Assemble()
{
   ExVH_Project="[ExVH 1.0]\r\n\r\n";
   ExVH_Project=ExVH_Project+"Var_Cnt="+ExVH_VarCnt+"\r\n\r\n";
 
   int i;
   for (i=0;i<ExVH_VarCnt;i++)
   {
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Title="+ExVH_Title[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Type="+ExVH_Type[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Status="+ExVH_Status[i]+"\r\n";
      ExVH_Project=ExVH_Project+"Var"+(i+1)+"_Value="+ExVH_Value[i]+"\r\n\r\n";
   } 
}
 
string ExVH_i_GetVarValue(string VarName)
{
   string Result="N/A";
   int Start,Stop;
   VarName=VarName+"=";
   Start=StringFind(ExVH_Project,VarName,0);
   if (Start!=-1)
   {
      Start=Start+StringLen(VarName);
      Stop=StringFind(ExVH_Project,CharToStr('\n'),Start);
      if (Stop!=-1)
      {
         Stop=Stop-1;
         Result=StringSubstr(ExVH_Project,Start,Stop-Start);
      }
   }
   return(Result);
}

Anpassung für C++

Das Projekt wurde in C++ Builder 2007 geschrieben. Das Archiv der Quellcodes mit dem Namen ExVH_CPP.zip ist an den Artikel angehangen.

Testen

Realisieren wir ein kleines demonstratives Beispiel, das die meisten Möglichkeiten zeigen wird.
Also, erstellen wir das Test-Dokument:


[ExVH 1.0]

Var_Cnt=5

Var1_Title=Boolean test
Var1_Type=0
Var1_Status=2
Var1_Value=0

Var2_Title=String test
Var2_Type=1
Var2_Status=2
Var2_Value=Hello world!

Var3_Title=Integer test
Var3_Type=2
Var3_Status=0
Var3_Value=12345

Var4_Title=Double test
Var4_Type=3
Var4_Status=0
Var4_Value=123.45

Var5_Title=Action test
Var5_Type=5
Var5_Status=0
Var5_Value=0

Wir speichern das Dokument als ExVH.evh in dem Ordner [MetaTrader]/experts/files/.

Die Signatur [ExVH 1.0] ermöglicht uns das Dokument beim Öffnen zu erkennen und informiert über die Version der verwendeten Dokumentstruktur. Wenn die Dokumentstruktur sich ändert, muss auch die Signatur geändert werden. das ermöglicht uns Vermischen zu vermeiden, wenn die Dokument-Dateierweiterung nicht geändert wird.

Var_Cnt=5. Dieser Datensatz informiert uns darüber, dass das Dokument 5 Variablen enthält.

Dann folgt der Datensatz vom gleichen Typ, der die Informationen über jede Variable enthält. Die Datensätze werden nach den obigen Spezifikationen erstellt.

VarX_Title=
VarX_Type=
VarX_Status=
VarX_Value=

Somit haben wir zwei Variablen (Var1 and Var2), die gelesen werden müssen sobald eine Aktion auftritt (Var5), und zwei Variablen (Var3 und Var4), deren Änderungen unabhängig voneinander betrachtet werden müssen.
Das MQL4 Programm muss die entsprechende Benachrichtigung auf dem Bildschirm anzeigen, sobald Änderungen in den Variablen gemacht wurden.


Test MQL4 Code

int init()
{
   return(0);
}
 
int deinit()
{
   return(0);
}
 
int start()
{
   if (!ExVH_Open("ExVH.evh"))
      return(0);
   
   // Checking for action status
   if (ExVH_GetStatus(5)==1)
   {
      Alert("Actioned!");
      string VarValue;
      if (ExVH_GetValue(1)=="1")
         VarValue="true";
      else 
         VarValue="false";
      
      // Boolean variable value
      Alert("Boolean test variable="+VarValue);
      
      // String variable value
      Alert("String test variable="+ExVH_GetValue(2));
      
      ExVH_SetStatus(5,0);
   }
   
   // Integer variable value
   if (ExVH_GetStatus(3)==1)
   {
      Alert("Integer test variable has been changed. New value="+ExVH_GetValue(3));
      ExVH_SetStatus(3,0);
   }
   
   // Double variable value
   if (ExVH_GetStatus(4)==1)
   {
      Alert("Double test variable has been changed. New value="+ExVH_GetValue(4));
      ExVH_SetStatus(4,0);
   }
   
   ExVH_Close();
   return(0);
}


Staren und Testen
Es spielt keine Rolle, welcher Teil des Komplex zuerst startet. Lassen wir es MetaTrader 4 in diesem Fall sein. Kopieren Sie die Datei ExVH_Demo.mq4 vorläufig in den Ordner [MetaTrader]/experts/ und starten Sie dann das Terminal. Das Dokument ExVH.evh wurde bereits in den Proramm-Code geschrieben. Starten Sie den EA. Es sollte nicht passieren, da der EA auf Änderungen in der Datei wartet.

Starten Sie die vorläufig auf dem PC installierte ExVH.exe.


Allgemeine Ansicht des Programms



Öffnen Sie das 'Projekt' und wählen Sie 'Öffnen'…


Öffnen des Dokuments



Das Programm lädt Variablen und wir können sie nun ändern.

In der 'Status' Spalte werden zwei Werte angegeben: idle (Warten, Leerlauf) und Changed by ExVH (Änderungen wurden durch ein externes Programm gemacht). So wird der Bildschirm aussehen, nachdem wir unsere 'Action' aktiviert haben.


Allgemeine Ansicht des Programms mit aktivierter 'Action'



Änderungen für unterschiedliche Typen an Variablen werden auf unterschiedliche Weise gemacht.

Für eine boolean Variable gibt das Programm ein von zwei Benachrichtigungen aus:



 

Für 'Action' Aktivierung gibt , gibt es diese aus:





Für alle anderen Arten von Formularen, ein einheitliches Formular.


Formular zum ändern der Werte von Variablen



Nach einer Anzahl an Änderungen, kann das 'Benachrichtigung'-Fenster wie folgt erscheinen:


Beispiel Message Box während der Programmausführung


Nachteile

Jede gute Idee hat ihre Vorteile und Nachteile.


• Diese Methode kann nicht aktiv für das Backtesten verwendet werden.
• Ändern der Parameter kann der Logik Ihres EA widersprechen. Sie sollten die Änderungen in Variablen sehr sorgfältig verarbeiten. Es ist eher ein Merkmal, als ein Nachteil.
• Die Ausführung von Befehlen ist nur bei der Ankunft eines neuen Tick möglich.

Was sonst getan werden kann

Die Funktionalität des Systems kann in verschiedene Richtungen verbessert werden. Das Handlungsfeld ist praktisch grenzenlos.

• Ändern von Parametern nach verschiedenen Szenarien. Zum Beispiel, für Passwörter können Sie eine Möglichkeit haben eingegebene Informationen zu verbergen.
• Verschlüsseltes Speichern der Datei, um in der Lage zu sein Passwörter zu verbergen.
• Sie können das Datentransfer-Protokoll ändern und es zuverlässiger und sicherer machen.

Fazit


Wir betrachteten die Wege zum Ändern der Werte interner Variablen von MQL Programmen. Jetzt habe wir die Möglichkeit externe und andere Variablen zu verwalten, ohne das Programm neu zu starten.

An den Artikel angehangene Dateien

File Beschreibung
ExVH_Demo.mq4Test EA
ExVH_Project.zipVorbereitete Projektdatei
ExVH_CPP.zipQuellcodes des externen Programms
ExVH_Install.zipExterner Programm -Installer

Hinweis. ExVH_Install wurde mit einer Demo-Version des Advanced Installer Programms gemacht.