English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
Benutzerdefinierte Indikatoren in MQL5 für Anfänger

Benutzerdefinierte Indikatoren in MQL5 für Anfänger

MetaTrader 5Beispiele | 11 Januar 2016, 13:11
3 746 0
Nikolay Kositsin
Nikolay Kositsin

Einleitung

Grundlage eines umfassenden Verständnisses jedes rationalen Themas (egal ob Mathematik, Musik oder Programmierung) beginnt mit dem Studium seiner Grundlagen. Natürlich ist es toll, wenn man sich damit bereits in jungen Jahren beschäftigt, da man die Grundlagen dann wesentlich leichter versteht und man sich schneller ein spezifisches und umfassendes Wissen aneignet.

Leider beginnen die meisten Menschen mit dem Studium der Finanz- und Aktienmärkte erst im mittleren Alter, und da fällt das Lernen schon schwerer. In diesem Beitrag möchte ich Ihnen die ersten Hürden beim Verständnis von MQL5 und beim Schreiben von benutzerdefinierten Indikatoren für den MetaTrader 5 Client-Terminal überwinden helfen.

Der SMA-Indikator als einfaches Beispiel

Eine Sache versteht man am effektivsten und vernünftigsten, wenn man gleich versucht, praktische Probleme zu lösen. Unsere Betrachtung der benutzerdefinierten Indikatoren beginnt also mit dem Studium des einfachen Indikators, der einen Code enthält, der die Grundlagen des Ablaufs eines Indikators in MQL5 darstellt.

Sehen wir uns als Beispiel den bekanntesten Indikator für technischen Analysen an - den Einfachen Gleitender Mittelwert (SMA). Seine Berechnung ist einfach:

SMA = SUMME (CLOSE (i), MAPeriod) / MAPeriod

wobei:

  • • SUMME — Summe der Werte;
  • • CLOSE (i) — Schlusskurs des i. Bars
  • • MAPeriod — Anzahl der zu mittelnden Bars (Mittelwertzeitraum).

Hier ist ein Code dieses Indikators ohne jede Extras:

//+------------------------------------------------------------------+
//|                                                          SMA.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
  
input int MAPeriod = 13;
input int MAShift = 0; 
  
double ExtLineBuffer[]; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
   SetIndexBuffer(0, ExtLineBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_SHIFT, MAShift);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MAPeriod - 1);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
  {
   if (rates_total < MAPeriod - 1)
    return(0);
    
   int first, bar, iii;
   double Sum, SMA;
   
   if (prev_calculated == 0)
    first = MAPeriod - 1 + begin;
   else first = prev_calculated - 1;

   for(bar = first; bar < rates_total; bar++)
    {
     Sum = 0.0;
     for(iii = 0; iii < MAPeriod; iii++)
      Sum += price[bar - iii];
     
     SMA = Sum / MAPeriod;
      
     ExtLineBuffer[bar] = SMA;
    }
     
   return(rates_total);
  }
//+------------------------------------------------------------------+

Und das ist das Ergebnis seiner Arbeit im MetaTrader 5 Client-Terminal:

Wir müssen also zunächst zwei Punkte berücksichtigen: Erstens, welchen Zweck jeder String des Codes verfolgt und zweitens, die Interaktion zwischen diesem Programmcode und dem Client-Terminal.

Wie man Kommentare verwendet

Beim ersten Blick auf den Indikator-Code fallen einem folgende Objekte auf.

//+------------------------------------------------------------------+
//|                                                          SMA.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

Hier muss darauf hingewiesen werden, dass sie nicht direkt mit dem Code zusammenhängen, sondern nur Kommentare darstellen. Sie dienen der Lesbarkeit des Codes und zeigen einen gewissen semantischen Content in einigen Teilen des Codes. Zur weiteren Vereinfachung des Codes könnte man diese Kommentare natürlich ohne irgendwelche Probleme für den Code auch entfernen, doch würde er dann seine knappe Klarheit fürs Verständnis einbüßen. In unserem Fall beschäftigen wir uns mit  einzeiligen Kommentaren, die immer mit einem Zeichenpaar "//" beginnen und mit einem Zeichen für den Zeilenumbruch enden.

Natürlich kann der Verfasser in Kommentaren alles hineinschreiben, was für ein späteres Verständnis dieses Codes nötig ist. In unserem Fall, stehen im ersten Teil der kommentierten Strings, der Name des Indikators sowie Angaben zum Verfasser. Der zweite und dritte Teil der Kommentare teilt sich die Funktionen  OnInit() und OnCalculate(). Die letzte Zeile am Schluss beendet einfach nur den Programmcode.

Struktur des SMA-Codes

Wir sehen also, dass der gesamte Code unseres Indikators in drei Teile unterteilt werden kann:

1. Der Code, der auf globaler Ebeneohne Klammern geschrieben ist, befindet sich zwischen den ersten beiden Kommentaren.
2. Beschreibung der OnInit() Funktion.

3. Beschreibung der OnCalculate() Funktion.

Hier muss darauf hingewiesen werden, dass beim Programmieren die Bedeutung von Funktion wesentlich weiter gefasst ist als in der Mathematik. In Programmiersprachen z.B. erhalten mathematische Funktionen immer einige Eingabe-Parameter und liefern berechnete Werte. Zusätzlich können Funktionen in MQL5 zudem auch einige Chart-, Handels- und Dateiabläufe usw. ausführen.

Jeder in MQL5 geschriebene Indikator besitzt in der Tat immer ein paar minimale, vom Benutzer geschriebene Teilesets, deren Inhalt individuell ist und von den Funktionen eines erzeugten Indikators abhängt.

Neben diesen Komponenten kann dieses Minimalset an Funktionen auch die Beschreibung einer anderen MQL5-Funktion enthalten - OnDeInit():

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+  
void OnDeinit(const int reason)
  {

  }

Da wir sie hier nicht brauchen, habe ich sie weggelassen.

Interaktion zwischen SMA und dem MetaTrader Client-Terminal

Sehen wir uns nun die Arbeit der erstellten Datei SMA.ex5 an, die wir erhalten haben, nachdem wir im MetaEditor auf "Erstellen" gedrückt haben, sodass SMA.mq5 geöffnet wurde. In diesem Zusammenhang sei darauf hingewiesen, dass Textdateien mit der Erweiterung .mq5 nur ein Quellcode im Textformat sind, der vor einer Verwendung im Client-Terminal zuerst erstellt werden sollte.

Nachdem der Indikator an ein Chart aus dem Navigator-Fenster angehängt wird, führt MetaTrader den Code des ersten Teils des Indikators aus. Danach ruft er die Funktion OnInit() für eine einzelne Ausführung der Funktion auf. Bei jeder neuen Kursschwankung (nach Eintreffen der neuen Notierung) berechnet er danach die OnCalculate()-Funktion und führt konsequenterweise den Code dieser Funktion aus.  WENN OnDeInit() im Indikator vorhanden wäre, würde MetaTrader diese Funktion einmal aufrufen, und zwar nach Abtrennen des Indikators vom Chart oder nach einer Veränderung des Zeitrahmens.

Jetzt sind uns die Bedeutung und der Zweck aller Teile des Indikators klar. Im ersten Teil des Codes auf globaler Ebene gibt es einige einfache Operatoren, die ausgeführt werden, nachdem der Indikator einmal gestartet wird. Zusätzlich gibt es noch eine Deklarierung von Variablen, die in allen Blöcken des Indikators "sichtbar" sind und die sich ihre Werte merken, während der Indikator auf dem Chart ist.

Die nur einmal ausgeführten Konstanten und Funktionen sollten innerhalb der OnInit()-Funktion sein, da es ungeschickt wäre, sie im Block der Funktion OnCalculate() zu platzieren. Der Code zur Berechnung des Indikators, mit dem seine Werte für jeden Bar errechnet werden können, sollte in der Funktion OnCalculate() stehen.

Die Vorgänge, die ggf. all den unnützen Rest vom Chart löschen, wenn der Indikator entfernt wird, sollten innerhalb von OnDeInit() stehen. Dies ist z.B. notwendig für das Löschen der, vom Indikator erzeugten, graphischen Objekte.

Nach diesen Erklärungen können wir uns nun einem detaillierten Studium des oben angesprochenen Indikator-Codes zuwenden.

Programm-Code eines SMA-Indikators

Die erste Gruppe der Codezeilen beginnt mit der Operator #property, die die Festlegung zusätzlicher Parameter und Indikatoreinstellungen erlaubt. Die vollständige Liste aller möglichen Programmeigenschaften ist in der Dokumentation von MQL5 zu finden. Wenn nötig, können auch zusätzliche Indikator-Eigenschaften geschrieben werden. In unserem Fall haben wir 5 Codezeilen, der jeweiliger Zweck in den Kommentaren beschrieben ist:

//---- the indicator will be plotted in the main window
#property indicator_chart_window
//---- one buffer will be used for the calculations and plot of the indicator
#property indicator_buffers 1
//---- only one graphic plot is used 
#property indicator_plots   1
//---- the indicator should be plotted as a line
#property indicator_type1   DRAW_LINE
//---- the color of the indicator's line is red 
#property indicator_color1  Red 

Beachten Sie, dass am Ende jeder Zeile keine Strichpunkte (";") stehen dürfen. Das hat folgenden Grund: In unserem Fall handelt es sich tatsächlich um die Definition von Konstanten, jedoch anders dargestellt.

Unser einfacher, gleitender Mittelwert (SMA) hat nur 2 Parameter, die von einem Benutzer verändert werden können - der Mittelwertzeitraum und die waagrechte Verschiebung (in Bars) des Indikators entlang der Zeitachsen. Diese zwei Parameter sollten als Eingabe-Variablen des Indikators deklariert werden, wie es in zwei weiteren Codezeilen deklariert ist:

//---- indicator input parameters
input int MAPeriod = 13; //averaging period
nput int MAShift = 0; //horizontal shift (in bars)

Beachten Sie, dass nach der Deklarierung dieser Eingabe-Parameter Kommentare folgen, die als Namen der Eingabe-Parameter im "Eigenschaften"-Fenster des Indikators erscheinen.


In unserem Beispiel sind diese Namen viel deutlicher als die Variablennamen des Indikators. Diese Kommentare sollten also einfach sein.

Die letzte Codezeile, diejenige ohne Klammern, ist die Deklarierung des dynamischen Arrays ExtLineBuffer[].

//---- the declaration of the dynamic array
//that will be used further as an indicator's buffer
double ExtLineBuffer[];  

Sie wurde als eine globale Variable deklariert und zwar aus mehreren Gründen:

Erstens sollte dieses Array in den Indikator-Buffer konvertiert werden. Es ist im Block der OnInit()-Funktion implementiert. Zweitens wird der Indikator-Buffer selbst innerhalb der OnCalculate()-Funktion verwendet. Und drittens speichert dieses Array die Werte des Indikators, die dann als Kurve auf dem Chart graphisch dargestellt werden. Da sie ja als eine globale Variable deklariert wurde, steht sie allen Blöcken des Indikators zur Verfügung und speichert stets seine Werte, solange bis der Indikator vom Chart abgetrennt wird.

Der Inhalt der OnInit()-Funktion wird von nur drei Operators dargestellt, die in den MetaTrader Client-Terminal eingebaute Funktionen sind.

Der Aufruf der ersten Funktion weist dem Zeroth Indikator-Buffer einen eindimensionalen dynamischen Array ExtLineBuffer[] zu. Zwei Aufrufe einer anderen Funktion mit anderen Eingabe-Parameter-Werten erlauben, den Indikator entlang der Kursachse zu verschieben und zugleich auch seine graphische Darstellung vom Bar mit der Zahl des Mittelwertzeitraums festzulegen.

void OnInit()
  {
//----+
//---- assign the dynamic array ExtLineBuffer with 0th indicator's buffer
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//---- set plot shift along the horizontal axis by MAShift bars
   PlotIndexSetInteger(0,PLOT_SHIFT,MAShift);
//---- set plot begin from the bar with number MAPeriod
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod);
//----+
  }

Der letzte Aufruf der PlotIndexSetInteger() Funktion übergibt den dem Mittelwertzeitraum entsprechenden Wert an einen anderen Indikator (via des Parameters begin der Funktion OnCalculate()), wenn diese Funktion auf die Werte unseres Indikators angewendet wird. Die Logik ist einfach: in den Bars des ersten Mittelwertzeitraums-1 gibt es nichts zu mitteln, daher ist die graph. Darstellung dieses Indikators überflüssig. Dennoch sollte dieser Wert übertragen werden, um den Ursprung der Berechnungen eines anderen Indikators zu verschieben.

Es ist keine vollständige Liste an eingebauten Funktionen, die in benutzerdefinierten Indikatoren verwendet werden, daher können sie in diesem Block des Indikators gefunden werden. Für Details, vgl. die MQL5 Dokumentation.

Sehen wir uns zum Schluss noch den Code der OnCalculate()-Funktion an. In dieser Funktion gibt es keine benutzerdefinierten Aufrufe, so wie in der Funktion OnInit(), da diese Funktionen vom MetaTrader Client-Terminal aufgerufen werden. Aus diesem Grund sind die Eingabe-Parameter der Funktion als Konstanten deklariert.

int OnCalculate(
                const int rates_total,    // number of available bars in history at the current tick
                const int prev_calculated,// number of bars, calculated at previous tick
                const int begin,          // index of the first bar
                const double &price[]     // price array for the calculation
                )

Diese Eingabe-Parameter können nicht verändert werden; ihre Werte werden vom Client-Terminal zur weiteren Verwendung im Code dieser Funktion weiter gegeben. Die Eingabe-Variablen von OnCalculate sind in der MQL5 Dokumentation beschrieben. Die Funktion OnCalculate() liefert ihre Werte für den Client-Terminal mit Hilfe der Rückgabe-Funktion (rates_total). Der Client-Terminal erhält diesen Wert der aktuellen Kursschwankung nach der Ausführung von OnCalculate() und gibt den Wert an einen anderen Parameter prev_calculated weiter. Es ist also immer möglich, den Bereich der Bar-Indices festzulegen und sofort Berechnungen nur für neue Indikatorwerte auszuführen, die nach der vorigen Kursschwankung erschienen sind.

In diesem Zusammenhang muss darauf hingewiesen werden, dass die Bars im MetaTrader Client-Terminal von links nach rechts angeordnet sind, sodass ein sehr alter Bar (der linke), der im Chart dargestellt wird, den Index 0 besitzt und der nächste Bar Index 1, usw. Die Elemente des Buffers ExtLineBuffer[] sind ebenso angeordnet.

Die einfache Codestruktur innerhalb der Funktion OnCalculate unseres Indikators ist universell und typisch für viele technische Analyse-Indikatoren typisch. Sehen wir sie uns mal im Detail an. Die Logik der OnCalculate() Funktion ist wie folgt:

1. Prüfung ob die, für die Berechnungen notwendigen Balken vorhanden sind.
2. Deklarierung lokaler Variablen.
3. Abfrage des Index des Startbars für die Berechnung.
4. Die primäre Berechnungsschleife des Indikators. 5. Lieferung des Wertes von rates_total an den Client-Terminal mit Hilfe von operator return().

Meiner Meinung nach ist die erste Bezeichnung klar. Wenn z.B. der Mittelwertzeitraum des Gleitenden Mittelwerts 200 ist, der Client-Terminal jedoch nur 100 Bars hat, muss keine Berechnung durchgeführt werden, da eben nicht genügend Balken für eine Berechnung vorhanden sind. Also müssen wir mit Hilfe des Operators Lieferung 0 an den Client-Terminal liefern.

//---- check for the presence of bars, sufficient for the calculation
   if(rates_total<MAPeriod-1+begin)
      return(0);

Unser Indikator kann auf die Daten eines anderen Indikators angewendet werden, der auch einige wenige Bars für die Berechnung hat.   Die Verwendung der Konstante begin muss diese Tatsache allerdings berücksichtigen. Für Details, vgl. den Beitrag Anwenden von Indikatoren auf Indikatoren.

Die in diesem Block deklarierten lokalen Variablen sind nur für Zwischenberechnungen innerhalb der OnCalculate() Funktion notwendig. Diese Variablen werden nach dem Aufruf der Funktion vom RAM des Computers freigegeben.

//---- declaration of local variables 
   int first,bar,iii;
   double Sum,SMA;

Mit dem Start-Index der primären Schleife (Variable first) sollte man auf jeden Fall sehr vorsichtig umgehen. Beim ersten Aufruf dieser Funktion (kann mit dem Wert des Parameters prev_calculated) festgelegt werden) müssen wir die Berechnung von Indikatorwerten für alle Bars durchführen. Für alle weiteren Kursschwankung des Client-Terminals müssen wir die Berechnung nur für jeden neu auftauchenden Bar durchführen. Dies geschieht in drei Codezeilen:

//---- calculation of starting index first of the main loop
   if(prev_calculated==0) // check for the first start of the indicator
      first=MAPeriod-1+begin; // start index for all the bars
   else first=prev_calculated-1; // start index for the new bars

Der Bereich der Variablenveränderungen im primären Schleifen-Operator der Indikator-Neuberechnungen ist bereits erläutert worden.

//---- main loop of the calculation
   for(bar=first;bar<rates_total;bar++)

Die Bearbeitung der Bars in der primären Schleife läuft in aufsteigender Reihenfolge ab (Bar++), also von links nach rechts, also ganz normal und korrekt. In unserem Indikator könnte sie auch auf andere Weise implementiert werden (in umgekehrter Reihenfolge). Bei Indikatoren empfiehlt sich jedoch die Verwendung der aufsteigenden Reihenfolge. Die Variable der primären Schleife heißt eigentlich "Bar", doch viele Programmierer nennen sie auch gerne "i". Ich bezeichne sie auch lieber als "Bar", da der Code dann klarer und lesbarer wird.

Der in der primären Schleife implementierte Mittelwertalgorithmus ist einfach.

     {
      Sum=0.0;
       //---- summation loop for the current bar averaging
      for(iii=0;iii<MAPeriod;iii++)
         Sum+=price[bar-iii]; // Sum = Sum + price[bar - iii]; // eqaual to 
      
      //---- calculate averaged value
      SMA=Sum/MAPeriod;

      //---- set the element of the indicator buffer with the value of SMA we have calculated
      ExtLineBuffer[bar]=SMA;
     }

In der zweiten Schleife führen wir die kumulative Addition der Kurse der vorigen Bars des Zeitraums durch und teilen sie durch diesen Mittelwertzeitraum. Als Ergebnis erhalten wird den Endwert des SMA (einfacher gleitender Mittelwert).

Nachdem die primäre Schleife beendet ist, liefert die OnCalculate Funktion die Anzahl der verfügbaren Bars der Variable rates_total. Beim nächsten Aufruf der OnCalculate() Funktion, wird dieser Wert vom Client-Terminal an die Variable prev_calculated weitergegeben. Und dieser Wert, um 1 vermindert, wird dann als Start-Index für die primäre Schleife angewendet.

Hier ist der komplette Quellcode des Indikators mit den detaillierten Kommentaren für jede Codezeile:

//+------------------------------------------------------------------+
//|                                                          SMA.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
//---- the indicator will be plotted in the main window
#property indicator_chart_window
//---- one buffer will be used for the calculations and plot of the indicator
#property indicator_buffers 1
//---- only one graphic plot is used 
#property indicator_plots   1
//---- the indicator should be plotted as a line
#property indicator_type1   DRAW_LINE
//---- the color of the indicator's line is red 
#property indicator_color1  Red 

//---- indicator input parameters
input int MAPeriod = 13; //Averaging period
input int MAShift = 0; //Horizontal shift (in bars)

//---- the declaration of the dynamic array
//that will be used further as an indicator's buffer
double ExtLineBuffer[]; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
//----+
//---- assign the dynamic array ExtLineBuffer with 0th indicator's buffer
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//---- set plot shift along the horizontal axis by MAShift bars
   PlotIndexSetInteger(0,PLOT_SHIFT,MAShift);
//---- set plot begin from the bar with number MAPeriod
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod);  
//----+
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,    // number of available bars in history at the current tick
                const int prev_calculated,// number of bars, calculated at previous tick
                const int begin,          // index of the first bar
                const double &price[]     // price array for the calculation
                )
  {
//----+   
   //---- check for the presence of bars, sufficient for the calculation
   if (rates_total < MAPeriod - 1 + begin)
    return(0);
   
   //---- declaration of local variables 
   int first, bar, iii;
   double Sum, SMA;
   
   //---- calculation of starting index first of the main loop
   if(prev_calculated==0) // check for the first start of the indicator
      first=MAPeriod-1+begin; // start index for all the bars
   else first=prev_calculated-1; // start index for the new bars

   //---- main loop of the calculation
   for(bar = first; bar < rates_total; bar++)
    {    
      Sum=0.0;
      //---- summation loop for the current bar averaging
      for(iii=0;iii<MAPeriod;iii++)
         Sum+=price[bar-iii]; // It's equal to: Sum = Sum + price[bar - iii];
         
      //---- calculate averaged value
      SMA=Sum/MAPeriod;

      //---- set the element of the indicator buffer with the value of SMA we have calculated
      ExtLineBuffer[bar]=SMA;
    }
//----+     
   return(rates_total);
  }
//+------------------------------------------------------------------+

Diese Art Code ist wesentlich leichter zu verstehen und zu lesen.

Ich würde gerne noch auf ein anderes Merkmal hinweisen, mit das Verständnis des Codes vereinfacht werden kann. Man kann durchaus Leerräume und leere Zeilen verwenden, um den Code eindeutig klar zu machen.

Fazit

Das ist das ganze Geheimnis der Interaktion zwischen dem Code des benutzerdefinierten Indikators und dem MetaTrader Client-Terminal. Natürlich ist das ganze Thema noch viel umfassender als was wir uns hier angesehen haben. Doch dieser Beitrag sollte ja nur Anfänger in die Grundlagen einweihen. Für Details also bitte die Dokumentation ansehen.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/37

Beigefügte Dateien |
sma.mq5 (1.78 KB)
sma_.mq5 (3.32 KB)
Handels-Ereignisse im Expert Advisor mit Hilfe der OnTrade() Funktion bearbeiten Handels-Ereignisse im Expert Advisor mit Hilfe der OnTrade() Funktion bearbeiten
MQL5 brachte eine Menge an Innovationen, inkl. die Bearbeitung verschiedenartiger Ereignisse (Timer-Ereignisse, Handels-Ereignisse, benutzerdefinierte Ereignisse, usw). Mit diesen Ereignissen umgehen zu können, gestattet Ihnen die Erzeugung komplett neuer Arten an Programmen für den automatischen und halb-automatischen Handel. In diesem Beitrag betrachten wir uns Handels-Ereignisse und schreiben einen Code für die OnTrade() Funktion, die das Handels-Ereignis bearbeiten wird.
Verwendung von Objektzeigern in MQL5 Verwendung von Objektzeigern in MQL5
In MQL5 werden alle Objekte standardmäßig per Verweis übertragen, doch gibt es eine Möglichkeit, Objektzeiger zu verwenden. Dazu muss jedoch eine Prüfung des Zeigers durchgeführt werden, da das Objekt u.U. nicht initialisiert ist. In diesem Fall wird das MQL5-Programm mit schwerwiegendem Fehler beendet und entladen. Die automatisch erzeugten Objekte verursachen diesen Fehler nicht, sind in diesem Sinn also recht sicher. In diesem Beitrag versuchen wir den Unterschied zwischen Objektverweis und Objektzeiger zu erklären und werfen einen Blick darauf, wie man sichere Codes schreibt, die diese Zeiger verwenden.
Wie man in MQL5 Indikatoren aufruft Wie man in MQL5 Indikatoren aufruft
Mit der neuen, zur Verfügung stehenden Version der MQL Programmiersprache hat sich nicht nur der Ansatz im Umgang mit Indikatoren verändert, sondern es haben sich auch neue Möglichkeiten ihrer Erzeugung ergeben. Zudem hat man jetzt noch mehr Flexibilität bei der Arbeit mit den Indikator-Buffern - man kann jetzt die gewünschte Richtung der Indizierung angeben und genau so viele Indikatorwerte bekommen, wie man möchte. In diesem Beitrag werden die einfachen Methoden zum Aufruf von Indikatoren und Abruf von Daten aus dem Indikator-Buffer erklärt.
Einführung in MQL5: Schreiben eines einfachen Expert Advisor und benutzerdefinierten Indikators Einführung in MQL5: Schreiben eines einfachen Expert Advisor und benutzerdefinierten Indikators
Die im MetaTrader 5 Client Terminal enthaltene MetaQuotes Programming Language 5 (MQL5) bietet im Vergleich zu MQL4 zahlreiche neue Möglichkeiten und bessere Performance. Dieser Beitrag hilft Ihnen dabei, sich mit dieser neuen Programmiersprache vertraut zu machen. In diesem Beitrag werden einfache Beispiele zum Schreiben eines Expert Advisors und eines benutzerdefinierten Indikators vorgestellt. Wir werden auch auf einige Details der MQL5-Sprache eingehen, die notwendig sind, um diese Beispiele zu verstehen.