English 日本語
preview
Erstellen eines MQL5 Expert Advisors basierend auf der PIRANHA Strategie unter Verwendung von Bollinger Bändern

Erstellen eines MQL5 Expert Advisors basierend auf der PIRANHA Strategie unter Verwendung von Bollinger Bändern

MetaTrader 5Handelssysteme | 9 Dezember 2024, 11:14
211 0
Allan Munene Mutiiria
Allan Munene Mutiiria

Einführung

In diesem Artikel werden wir untersuchen, wie man einen Expert Advisor (EA) in MetaQuotes Language 5 (MQL5) erstellt, der auf der Strategie PIRANHA basiert und sich auf die Integration von Bollinger Bands konzentriert. Da Händler nach effektiven automatisierten Handelslösungen suchen, hat sich die PIRANHA-Strategie als systematischer Ansatz herauskristallisiert, der Marktschwankungen ausnutzt, was sie für viele Forex-Enthusiasten zu einer attraktiven Wahl macht.

Zunächst werden die Grundprinzipien der PIRANHA-Strategie erläutert, die eine solide Grundlage für ihre Umsetzung im automatisierten Handel bilden. Als Nächstes werden wir uns mit den Bollinger Bändern beschäftigen, einem beliebten technischen Indikator, der durch die Messung der Marktvolatilität hilft, potenzielle Ein- und Ausstiegspunkte zu identifizieren.

Anschließend führen wir Sie durch den Kodierungsprozess in MQL5 und heben dabei die wesentlichen Funktionen und die Logik hervor, die die Strategie bestimmen. Darüber hinaus werden wir das Testen der EA-Leistung, die Optimierung der Parameter und die besten Methoden für den Einsatz in einer Live-Handelsumgebung besprechen. In diesem Artikel werden wir unter anderem folgende Themen behandeln:

  1. Überblick über die PIRANHA-Strategie
  2. Bollinger-Bänder verstehen
  3. Blaupause der Strategie
  4. Implementation in MQL5
  5. Tests
  6. Schlussfolgerung

Am Ende dieses Artikels werden Sie mit dem Wissen ausgestattet sein, einen MQL5 Expert Advisor zu entwickeln, der die PIRANHA-Strategie und Bollinger Bänder effektiv nutzt und Ihren Handelsansatz verbessert. Fangen wir an.


Überblick über die PIRANHA-Strategie

Die PIRANHA-Strategie ist ein dynamisches Handelssystem, das die Preisbewegungen auf dem Devisenmarkt ausnutzen kann. Diese Strategie zeichnet sich durch eine schnelle und opportunistische Art des Handels aus, die nach dem flinken Raubfisch benannt wurde, dem diese Art des Fischfangs aufgrund seiner Schnelligkeit und Genauigkeit ähneln kann. Fähigkeiten: Die PIRANHA-Strategie ist eine auf der Volatilität basierende Strategie, die entwickelt wurde, um Händlern zu helfen, Ein- und Ausstiegspunkte des Marktes durch ihren äußerst relativen Ansatz genau zu bestimmen.

Eine Komponente der PIRANHA-Strategie, die aktiviert ist, ist die Anwendung von Bollinger-Bändern, die die übliche Indikatoren sind, um Händlern zu helfen, die Volatilität in ihrem Markt zu erkennen. Für unsere Methode werden wir ein 12-Perioden-Bollinger-Band verwenden, einfach weil es ein großartiges Werkzeug ist und im Laufe der Zeit eine Topologie aufweist, die uns gute Einblicke in das Kursverhalten gibt. Wir legen auch eine Standardabweichung von 2 fest, was im Wesentlichen bedeutet, dass wir die großen Kursbewegungen erfassen und gleichzeitig das Rauschen der kleinen Schwankungen herausfiltern. Diese Kanäle bilden eine Ober- und Untergrenze, die potenziell überkaufte oder überverkaufte Marktbedingungen darstellen. Fällt der Kurs unter das untere Band, ist dies eine gute Kaufgelegenheit, während ein Anstieg über das obere Band darauf hindeutet, dass ein Verkauf angebracht sein könnte. Nachfolgend finden Sie eine Abbildung:

STRATEGIE-ÜBERSICHT

Das Risikomanagement ist ein weiteres wichtiges Element der PIRANHA-Strategie. Er unterstreicht die Bedeutung des Kapitalschutzes durch klar definierte Stop-Loss- und Take-Profit-Levels. Bei unserer Strategie platzieren wir den Stop-Loss 100 Punkte unter dem Einstiegskurs für Kaufgeschäfte und setzen ein Take-Profit-Level 50 Punkte über dem Einstieg. Dieser disziplinierte Ansatz stellt sicher, dass wir potenzielle Verluste begrenzen und gleichzeitig Gewinne sichern können, was zu einer nachhaltigeren Handelsmethodik beiträgt.

Zusammenfassend lässt sich sagen, dass die PIRANHA-Strategie die technische Analyse mit einem Schwerpunkt auf Volatilität und Risikomanagement kombiniert. Wenn Händler diese Prinzipien und Einstellungen verstehen, können sie sich auf dem Devisenmarkt besser zurechtfinden und fundierte Entscheidungen treffen, die mit ihren Handelszielen übereinstimmen. Im weiteren Verlauf werden wir untersuchen, wie diese Strategie in MQL5 umgesetzt werden kann, um die PIRANHA-Strategie in einem automatisierten Handelssystem zum Leben zu erwecken.


Bollinger-Bänder verstehen

Händler können die Bollinger Bands, ein robustes technisches Analyseinstrument, verwenden, um potenzielle Kursbewegungen in einem volatilen Markt zu bestimmen. John Bollinger entwickelte den Indikator in den 1980er Jahren. Er besteht aus drei Komponenten: einem gleitenden Durchschnitt, einem oberen Band und einem unteren Band. Anhand der Berechnungen, die Händler durchführen, können sie abschätzen, ob sich ein Kurs in der einen oder anderen Richtung weit von seinem Durchschnitt entfernt.

Zunächst berechnen wir das mittlere Band (den gleitenden Durchschnitt), bei dem es sich in der Regel um einen einfachen gleitenden Durchschnitt über 20 Perioden (SMA) handelt. Die Formel für den SMA lautet:

SMA-FORMEL

Dabei steht 𝑃𝑖 für den Schlusskurs in jeder Periode und 𝑛 für die Anzahl der Perioden (in diesem Fall 20). Ein Beispiel: Wir haben die folgenden Schlusskurse der letzten 20 Perioden:

PeriodenSchlusskurs (𝑃𝑖)
11.1050
21.1070
31.1030
41.1080
51.1040
61.1100
71.1120
81.1150
91.1090
101.1060
111.1085
121.1105
131.1130
14 1.1110
15 1.1075
16 1.1055
17 1.1080
18 1.1095
19 1.1115
20 1.1120

Wir addieren diese Preise und teilen sie durch 20:

SMA-BERECHNUNG

Anschließend berechnen wir die Standardabweichung, die die Streuung der Schlusskurse vom SMA misst. Die Formel für die Standardabweichung (𝜎) lautet:

STD DEV FORMEL

Unter Verwendung unseres berechneten SMA von 1,1080 berechnen wir die quadrierten Differenzen für jeden Schlusskurs, nehmen dann ihren Durchschnitt und ziehen schließlich die Quadratwurzel. Die ersten paar quadrierten Differenzen sind zum Beispiel:

ERSTE QUADRIERTE DIFFERENZEN

Nach Berechnung aller 20 quadrierten Differenzen ergibt sich:

ALLE UNTERSCHIEDE

Nach der Berechnung des mittleren Bandes (SMA) und der Standardabweichung können wir nun das obere und untere Band bestimmen. Die Formeln lauten wie folgt:

  • Oberes Band = SMA + (k × σ)
  • Unteres Band = SMA - (k × σ)

Hier wird in der Regel k=2 gesetzt (was zwei Standardabweichungen entspricht). Setzen wir unsere Werte ein:

  1. Oberes Band = 1,1080 + (2 × 0,0030) = 1,1140
  2. Unteres Band = 1,1080 - (2 × 0,0030) = 1,1020

Daraus ergebenden sich folgende Bollinger-Bänder:

  • Mittleres Band (SMA): 1.1080
  • Oberes Band: 1.1140
  • Unteres Band: 1.1020

Diese drei Bereiche sind in der folgenden Abbildung dargestellt:

3 BÄNDER

Der Abstand zwischen diesen Bandbreiten verändert sich mit den Marktbedingungen. Wenn sie sich ausweiten, deutet dies auf eine zunehmende Volatilität hin - und bewegte Märkte neigen dazu, volatil zu sein. Wenn sich die Bandbreiten verengen, deutet dies auf eine Konsolidierung des Marktes hin. Händler suchen gerne nach Wechselwirkungen zwischen den Preisen und den Bändern, um Handelssignale zu generieren. Sie könnten dazu neigen, eine Preisinteraktion mit dem oberen Band als einen überkauften Markt und eine Preisinteraktion mit dem unteren Band als einen überverkauften Markt zu interpretieren.

Zusammenfassend lässt sich sagen, dass die Berechnungen für Bollinger Bänder die Umkehrung des SMA, die Standardabweichung und die oberen und unteren Bänder beinhalten. Das Verständnis dieser Berechnungen ist nicht nur eine Übung im quantitativen Analysieren, sondern gibt den Händlern das nötige Rüstzeug, um fundierte Handelsentscheidungen zu treffen, insbesondere bei der Anwendung der PIRANHA-Strategie in ihren Handelsbestrebungen.


Blaupause der Strategie

Blaupause für das obere Band: Verkaufsbedingung

Wenn der Kurs das obere Bollinger Band kreuzt und darüber schließt, signalisiert dies, dass der Markt überkauft sein könnte. Dieser Zustand deutet darauf hin, dass die Preise übermäßig gestiegen sind und wahrscheinlich eine Abwärtskorrektur erfahren werden. Daher betrachten wir dieses Szenario als ein Verkaufssignal. Wir eröffnen also eine Verkaufsposition, wenn der Schlusskurs des aktuellen Balkens über dem oberen Band liegt. Ziel ist es, von einer potenziellen Umkehr oder einem Rückschlag zu profitieren.

OBERES BAND - BLAUPAUSE

Blaupause des unteren Bands: Kaufbedingung

Umgekehrt ist es ein Zeichen dafür, dass der Markt überverkauft sein könnte, wenn der Kurs das untere Bollinger Band kreuzt und darunter schließt. Dieses Szenario deutet darauf hin, dass die Preise deutlich gesunken sind und nun wieder anziehen könnten. Dies wird daher als Kaufsignal gewertet. Wir eröffnen also eine Kaufposition, wenn der Schlusskurs des aktuellen Balkens unter dem unteren Band liegt, in Erwartung einer möglichen Umkehr nach oben.

UNTERES BAND - BLAUPAUSE

Diese visuellen Darstellungen des Strategieentwurfs werden hilfreich sein, wenn wir diese Handelsbedingungen in MQL5 implementieren und als Referenz für die Codierung präziser Ein- und Ausstiegsregeln dienen.


Implementation in MQL5

Nachdem wir alle Theorien über die Piranha-Handelsstrategie gelernt haben, wollen wir die Theorie automatisieren und einen Expert Advisor (EA) in MetaQuotes Language 5 (MQL5) für MetaTrader 5 erstellen.

Um einen Expert Advisor (EA) zu erstellen, klicken Sie auf Ihrem MetaTrader 5-Terminal auf die Registerkarte Tools und aktivieren Sie MetaQuotes Language Editor oder drücken Sie einfach F4 auf Ihrer Tastatur. Alternativ können Sie auch auf das IDE-Symbol (Integrated Development Environment) in der Symbolleiste klicken. Dadurch wird die Umgebung des MetaQuotes-Spracheditors geöffnet, die das Schreiben von Handelsrobotern, technischen Indikatoren, Skripten und Funktionsbibliotheken ermöglicht.

META-EDITOR ÖFFNEN

Sobald der MetaEditor geöffnet ist, navigieren Sie in der Symbolleiste zur Registerkarte „Datei“ und wählen Sie „Neue Datei“, oder drücken Sie einfach die Tastenkombination STRG + N, um ein neues Dokument zu erstellen. Alternativ könnten wir auch auf das Symbol New auf der Registerkarte Werkzeuge klicken. Daraufhin erscheint ein Popup-Fenster des MQL-Assistenten.

EA NEU ERSTELLEN

In dem sich öffnenden Assistenten markieren wir die Option Expert Advisor (template bzw. Vorlage) und klicken auf Weiter (Next).

MQL WIZARD

Wir geben in den allgemeinen Eigenschaften des Expert Advisors unter dem Abschnitt Name den Dateinamen Ihres Experten an. Nicht vergessen, den Backslash vor dem Namen des EA verwenden, um einen Ordner anzugeben oder zu erstellen, wenn er nicht existiert. Hier haben wir zum Beispiel standardmäßig „Experts\“. Das bedeutet, dass unser EA im Ordner Experts erstellt wird und wir ihn dort finden können. Die anderen Abschnitte sind ziemlich einfach, aber Sie können dem Link am Ende des Assistenten folgen, um zu erfahren, wie der Prozess genau abläuft.

NEUER EA-NAME

Nachdem Sie den gewünschten Expert Advisor-Dateinamen eingegeben haben, klicken Sie auf Weiter, dann auf Weiter und schließlich auf Fertig stellen. Nachdem wir all dies getan haben, können wir nun unsere Strategie programmieren.

Zunächst definieren wir einige Metadaten über den Expert Advisor (EA). Dazu gehören der Name des EA, die Copyright-Informationen und ein Link zur MetaQuotes-Website. Wir geben auch die Version des EA an, die auf „1.00“ eingestellt ist.

//+------------------------------------------------------------------+
//|                                                      PIRANHA.mq5 |
//|                        Allan Munene Mutiiria, Forex Algo-Trader. |
//|                                     https://forexalgo-trader.com |
//+------------------------------------------------------------------+

//--- Properties to define metadata about the Expert Advisor (EA)
#property copyright "Allan Munene Mutiiria, Forex Algo-Trader."   //--- Copyright information
#property link      "https://forexalgo-trader.com"               //--- Link to the creator's website
#property version   "1.00"                                       //--- Version number of the EA

Beim Laden des Programms werden Informationen angezeigt, die dem unten gezeigten Bild entsprechen.

METADATA

Zunächst binden wir eine Handelsinstanz ein, indem wir #include am Anfang des Quellcodes verwenden. Dadurch erhalten wir Zugriff auf die Klasse CTrade, mit der wir ein Handelsobjekt erstellen werden. Dies ist von entscheidender Bedeutung, da wir sie zur Eröffnung von Handelsgeschäften benötigen.

//--- Including the MQL5 trading library
#include <Trade/Trade.mqh>      //--- Import trading functionalities
CTrade obj_Trade;               //--- Creating an object of the CTrade class to handle trading operations

Der Präprozessor wird die Zeile #include <Trade/Trade.mqh> durch den Inhalt der Datei Trade.mqh ersetzen. Die spitzen Klammern zeigen an, dass die Datei Trade.mqh aus dem Standardverzeichnis entnommen wird (normalerweise ist es das Terminal-Installationsverzeichnis\MQL5\Include). Das aktuelle Verzeichnis wird bei der Suche nicht berücksichtigt. Die Zeile kann an beliebiger Stelle im Programm platziert werden, aber in der Regel werden alle Einschlüsse am Anfang des Quellcodes platziert, um den Code besser zu strukturieren und die Referenz zu erleichtern. Die Deklaration des Objekts obj_Trade der Klasse CTrade ermöglicht uns dank der MQL5-Entwickler einen einfachen Zugriff auf die in dieser Klasse enthaltenen Methoden.

CTRADE CLASS

Wir müssen Indikator-Handles erstellen, damit wir die erforderlichen Indikatoren in die Strategie aufnehmen können.

//--- Defining variables for Bollinger Bands indicator and price arrays
int handleBB = INVALID_HANDLE;  //--- Store Bollinger Bands handle; initialized as invalid
double bb_upper[], bb_lower[];  //--- Arrays to store upper and lower Bollinger Bands values

Hier deklarieren und initialisieren wir eine einzelne Integer-Variable, „handleBB“, die als Handle für den Bollinger Bands-Indikator in unserem Expert Advisor dienen wird. In MQL5 ist ein Handle ein eindeutiger Bezeichner, der einem Indikator zugewiesen wird, sodass es einfach ist, diesen Indikator im gesamten Code zu referenzieren. Indem wir „handleBB“ anfangs auf INVALID_HANDLE setzen, stellen wir sicher, dass das Programm nicht auf ein ungültiges Indikator-Handle verweist, bevor es richtig erstellt wurde, und verhindern so unerwartete Fehler. Neben dem Handle definieren wir auch zwei dynamische Arrays, „bb_upper“ und „bb_lower“, die die oberen bzw. unteren Bollinger-Band-Werte speichern werden. Diese Arrays helfen uns, den aktuellen Zustand des Indikators zu erfassen und zu analysieren, und bieten eine zuverlässige Grundlage für die Ausführung unserer Handelsstrategie auf der Grundlage der Bollinger Band-Bedingungen. Auch hier müssen wir sicherstellen, dass wir nur eine einzige Position in einer Richtung eröffnen.

//--- Flags to track if the last trade was a buy or sell
bool isPrevTradeBuy = false, isPrevTradeSell = false;  //--- Prevent consecutive trades in the same direction

Hier deklarieren und initialisieren wir zwei boolesche Flags, „isPrevTradeBuy“ und „isPrevTradeSell“, um die Richtung des letzten ausgeführten Handels zu verfolgen. Beide sind zunächst auf false gesetzt, was bedeutet, dass noch kein Handel stattgefunden hat. Diese Flags spielen eine entscheidende Rolle bei der Verwaltung unserer Handelslogik, indem sie sicherstellen, dass der Expert Advisor keine aufeinanderfolgenden Trades in dieselbe Richtung eröffnet. Wenn zum Beispiel der vorherige Handel ein Kauf war, wird „isPrevTradeBuy“ auf true gesetzt und verhindert einen weiteren Kaufhandel, bis ein Verkaufshandel stattgefunden hat. Dieser Mechanismus wird dazu beitragen, redundante Handelsgeschäfte zu vermeiden und eine ausgewogene Handelsstrategie beizubehalten.

Als Nächstes benötigen wir OnInit. Die Funktion ist wichtig, weil sie automatisch aufgerufen wird, wenn der Expert Advisor (EA) auf einem Chart initialisiert wird. Diese Funktion ist für die Einrichtung des EA zuständig, einschließlich der Erstellung der erforderlichen Indikator-Handles, der Initialisierung von Variablen und der Vorbereitung von Ressourcen. Mit anderen Worten: OnInit ist eine integrierte Funktion, die sicherstellt, dass alles richtig konfiguriert ist, bevor der EA mit der Verarbeitung von Marktdaten beginnt. Sie lautet wie folgt.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){
   // OnInit is called when the EA is initialized on the chart
//...
}

In OnInit müssen wir das Indikator-Handle initialisieren, damit ihm Datenwerte zugewiesen werden.

   //--- Create Bollinger Bands indicator handle with a period of 12, no shift, and a deviation of 2
   handleBB = iBands(_Symbol, _Period, 12, 0, 2, PRICE_CLOSE);  

Hier erstellen wir das Handle für den Bollinger-Bänder-Indikator, indem wir die Funktion iBands aufrufen, die den Indikator anhand der angegebenen Parameter generiert. Wir übergeben dieser Funktion mehrere Argumente: _Symbol bezieht sich auf das Währungspaar, das wir analysieren, und _Period bezeichnet den Zeitrahmen für den Indikator, der von Minuten bis zu Stunden oder Tagen reichen kann. Die Parameter für die Bollinger-Bänder umfassen eine Periode von 12, die die Anzahl der zur Berechnung des Indikators verwendeten Balken angibt, eine Verschiebung von 0, was bedeutet, dass die Bänder nicht angepasst werden, und eine Standardabweichung von 2, die bestimmt, wie weit die Bänder vom gleitenden Durchschnitt entfernt sind. Die Verwendung von PRICE_CLOSE zeigt an, dass wir unsere Berechnungen auf die Schlusskurse der Balken stützen werden. Sobald dies erfolgreich ausgeführt wird, speichert unsere Handle-Variable „handleBB“ einen gültigen Zugang zu dem Bollinger-Bänder-Indikator, sodass wir ihn für den Datenabruf und die Analyse referenzieren können. Daher müssen wir prüfen, ob das Handle erfolgreich erstellt wurde, bevor wir fortfahren.

   //--- Check if the Bollinger Bands handle was created successfully
   if (handleBB == INVALID_HANDLE){
      Print("ERROR: UNABLE TO CREATE THE BB HANDLE. REVERTING");  //--- Print error if handle creation fails
      return (INIT_FAILED);  //--- Return initialization failed
   }

Hier wird überprüft, ob das Handle für den Bollinger Bands-Indikator erfolgreich erstellt wurde, indem geprüft wird, ob es den Wert INVALID_HANDLE hat. Wenn der Handle ungültig ist, wird eine Fehlermeldung mit dem Wortlaut „ERROR: UNABLE TO CREATE THE BB HANDLE. REVERTING“, was hilft, Probleme während des Initialisierungsprozesses zu erkennen. Wir geben dann INIT_FAILED zurück, was bedeutet, dass der Expert Advisor nicht ordnungsgemäß initialisiert werden konnte. Wenn dies gelingt, setzen wir die Datenfelder als Zeitreihen ein.

   //--- Set the arrays for the Bollinger Bands to be time-series based (most recent data at index 0)
   ArraySetAsSeries(bb_upper, true);  //--- Set upper band array as series
   ArraySetAsSeries(bb_lower, true);  //--- Set lower band array as series
   
   return(INIT_SUCCEEDED);  //--- Initialization successful

Hier konfigurieren wir die Arrays für die Bollinger-Bänder, „bb_upper“ und „bb_lower“, so, dass sie als Zeitreihendaten behandelt werden, indem wir die Funktion ArraySetAsSeries aufrufen und den zweiten Parameter auf true setzen. Dadurch wird sichergestellt, dass die aktuellsten Daten bei Index 0 gespeichert werden, was bei der Analyse der Marktbedingungen einen leichteren Zugriff auf die neuesten Werte ermöglicht. Indem wir die Arrays auf diese Weise organisieren, passen wir unsere Datenstruktur an die typische Verwendung in Handelsalgorithmen an, bei denen die aktuellsten Informationen oft die wichtigsten sind. Schließlich geben wir INIT_SUCCEEDED zurück, was bedeutet, dass der Initialisierungsprozess erfolgreich abgeschlossen wurde und der Expert Advisor mit seinen Operationen fortfahren kann.

Bis zu diesem Punkt hat alles im Initialisierungsabschnitt korrekt funktioniert. Der vollständige Quellcode, der für die Initialisierung des Programms verantwortlich ist, lautet wie folgt:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Create Bollinger Bands indicator handle with a period of 12, no shift, and a deviation of 2
   handleBB = iBands(_Symbol, _Period, 12, 0, 2, PRICE_CLOSE);  
   
   //--- Check if the Bollinger Bands handle was created successfully
   if (handleBB == INVALID_HANDLE){
      Print("ERROR: UNABLE TO CREATE THE BB HANDLE. REVERTING");  //--- Print error if handle creation fails
      return (INIT_FAILED);  //--- Return initialization failed
   }
   
   //--- Set the arrays for the Bollinger Bands to be time-series based (most recent data at index 0)
   ArraySetAsSeries(bb_upper, true);  //--- Set upper band array as series
   ArraySetAsSeries(bb_lower, true);  //--- Set lower band array as series
   
   return(INIT_SUCCEEDED);  //--- Initialization successful
  }

Als Nächstes gehen wir zum OnDeinit-Ereignishandler über, einer Funktion, die aufgerufen wird, wenn das Programm deinitialisiert wird.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   // OnDeinit is called when the EA is removed from the chart or terminated
//...
}

Die Funktion OnDeinit wird aufgerufen, wenn der Expert Advisor (EA) aus dem Chart entfernt wird oder wenn das Terminal heruntergefahren wird. Wir müssen diese Funktion verwenden, um eine korrekte Wartung und Ressourcenverwaltung zu gewährleisten. Wenn der EA beendet wird, müssen wir alle Handles zu Indikatoren freigeben, die wir in der Initialisierungsphase erstellt haben. Wenn wir dies nicht tun würden, könnten wir Speicherplätze zurücklassen, die wir genutzt haben, was ineffizient wäre; wir wollten auf keinen Fall riskieren, dass wir Ressourcen zurücklassen, die wir nicht brauchen. Aus diesem Grund ist OnDeinit wichtig und Aufräumarbeiten sind in jeder Programmierumgebung von entscheidender Bedeutung.

IndicatorRelease(handleBB); //--- Release the indicator handle

Hier rufen wir einfach die Funktion „IndicatorRelease“ mit dem Argument „handleBB“ auf, um das Handle des Bollinger Bands Indikators freizugeben, das wir zuvor erstellt haben. Die Bereinigung ist für die Aufrechterhaltung der Leistung der Plattform von entscheidender Bedeutung, insbesondere wenn Sie mehrere Expert Advisors verwenden oder die Plattform über längere Zeiträume hinweg betreiben. Der vollständige Quellcode für die Freigabe von Ressourcen lautet also wie folgt:

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--- Function to handle cleanup when the EA is removed from the chart
   IndicatorRelease(handleBB); //--- Release the indicator handle
  }

Als Nächstes müssen wir bei jeder Kursaktualisierung nach Handelsmöglichkeiten suchen. Dies wird mit der Ereignisbehandlung von OnTick erreicht.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
   // OnTick is called whenever there is a new market tick (price update)

//...

}

Die Funktion OnTick führt jedes Mal, wenn es einen neuen Tick oder eine Änderung der Marktbedingungen gibt, aktuelle Kursinformationen aus und verarbeitet sie. Sie ist ein wesentlicher Bestandteil der Funktionsweise unseres Expert Advisors (EA), denn hier läuft unsere Handelslogik ab, deren Handelsbedingungen hoffentlich so strukturiert sind, dass sie zu profitablen Trades führen. Wenn sich die Marktdaten ändern, bewerten wir die aktuelle Marktlage und entscheiden, ob wir eine Position eröffnen oder schließen. Die Funktion wird so oft ausgeführt, wie sich die Marktbedingungen ändern, um sicherzustellen, dass unsere Strategie in Echtzeit funktioniert und auf die aktuellen Preise und Wertveränderungen unserer Marktindikatoren reagiert.

Um über die aktuellen Marktbedingungen auf dem Laufenden zu bleiben, müssen wir die Werte der aktuellen Kursnotierungen erhalten.

   //--- Get current Ask and Bid prices
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);  //--- Normalize Ask price to correct digits
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);  //--- Normalize Bid price to correct digits

Hier erhalten wir die aktuellsten Geld- und Briefkurse für das gehandelte Symbol. Um diese Preise zu erhalten, verwenden wir die Funktion SymbolInfoDouble. Der Briefkurs ist SYMBOL_ASK und der Geldkurs SYMBOL_BID. Nachdem wir die Preise erhalten haben, verwenden wir die Funktion NormalizeDouble, um die Preise auf die durch _Digits definierte Anzahl von Dezimalstellen zu runden. Dieser Schritt ist von entscheidender Bedeutung, da er sicherstellt, dass unsere Handelsoperationen mit standardisierten und genauen Preisen durchgeführt werden. Würden wir die Preise nicht runden, könnten Fließkommaungenauigkeiten zu irreführenden Ergebnissen bei den Berechnung mit den Preisen führen. Anschließend kopieren wir die Indikatorwerte zur Verwendung bei Analysen und Handelsgeschäften.

   //--- Retrieve the most recent Bollinger Bands values (3 data points)
   if (CopyBuffer(handleBB, UPPER_BAND, 0, 3, bb_upper) < 3){
      Print("UNABLE TO GET UPPER BAND REQUESTED DATA. REVERTING NOW!");  //--- Error if data fetch fails
      return;
   }
   if (CopyBuffer(handleBB, LOWER_BAND, 0, 3, bb_lower) < 3){
      Print("UNABLE TO GET LOWER BAND REQUESTED DATA. REVERTING NOW!");  //--- Error if data fetch fails
      return;
   }

Hier verwenden wir die Funktion CopyBuffer, um die jüngsten Werte der Bollinger-Bänder abzurufen, und zwar jeweils drei Datenpunkte für das obere und das untere Band. Der erste Aufruf von CopyBuffer fordert Daten aus dem oberen Band an, beginnend bei Index 0, und speichert sie in dem Array „bb_upper“. Wenn die Funktion einen Wert kleiner als 3 zurückgibt, bedeutet dies, dass der Datenabruf nicht erfolgreich war, was uns veranlasst, eine Fehlermeldung zu drucken: „UNABLE TO GET UPPER BAND REQUESTED DATA. REVERTING NOW!“ Anschließend beenden wir die Funktion, um eine weitere Ausführung zu verhindern. Ein ähnliches Verfahren wird für das untere Band angewandt, um sicherzustellen, dass wir auch eventuelle Fehler beim Abrufen der Daten behandeln. Beachten Sie, dass wir bei der Referenzierung der Pufferindizes anstelle von Puffernummern Bezeichner von Indikatorzeilen verwenden, die beim Kopieren von Werten des Bollinger Bands Indikators zulässig sind. Das ist der einfachste Weg, um Verwirrung zu vermeiden, aber die Logik bleibt bestehen. Hier ist eine visuelle Darstellung der Puffernummern.

PUFFER-VISUALISIERUNG

Da wir einen Vergleich zwischen den Indikatorwerten und den Preisen vornehmen müssen, müssen wir die für uns relevanten Preise der Balken ermitteln, in diesem Fall die Höchst- und Tiefstpreise.

   //--- Get the low and high prices of the current bar
   double low0 = iLow(_Symbol, _Period, 0);    //--- Lowest price of the current bar
   double high0 = iHigh(_Symbol, _Period, 0);  //--- Highest price of the current bar

Hier erhalten wir die Tiefst- und Höchstpreise des aktuellen Balkens, indem wir die Funktionen iLow und iHigh aufrufen. Die Funktion iLow ermittelt den niedrigsten Preis für den aktuellen Bar (Index 0) für das angegebene Symbol (_Symbol) und den angegebenen Zeitrahmen (_Period) und speichert diesen Wert in der Variablen „low0“. Ähnlich holt iHigh den höchsten Preis des aktuellen Balkens und weist ihn der Variablen „high0“ zu. Wir müssen noch sicherstellen, dass wir ein einziges Signal in einem Balken ausführen. Hier ist die Logik, die angewandt wird.

   //--- Get the timestamp of the current bar
   datetime currTimeBar0 = iTime(_Symbol, _Period, 0);  //--- Time of the current bar
   static datetime signalTime = currTimeBar0;           //--- Static variable to store the signal time

Hier wird der Zeitstempel des aktuellen Balkens mit Hilfe der Funktion iTime ermittelt, die die Zeit des angegebenen Balkens (Index 0) für das angegebene Symbol (_Symbol) und den Zeitrahmen (_Period) zurückgibt. Dieser Zeitstempel wird in der Variablen „currTimeBar0“ gespeichert. Zusätzlich deklarieren wir eine statische Variable namens „signalTime“ und initialisieren sie mit dem Wert „currTimeBar0“. Indem wir „signalTime“ statisch machen, stellen wir sicher, dass sein Wert zwischen den Funktionsaufrufen bestehen bleibt, sodass wir das letzte Mal, als ein Handelssignal generiert wurde, verfolgen können. Dies ist für unsere Strategie von entscheidender Bedeutung, da es uns hilft, zu verhindern, dass mehrere Signale im selben Balken ausgelöst werden, und sicherstellt, dass wir nur auf ein Signal pro Periode reagieren. Nachdem wir all dies getan haben, können wir nun damit beginnen, die Signale zu überprüfen. Als Erstes prüfen wir, ob ein Kaufsignal vorliegt.

   //--- Check for a buy signal when price crosses below the lower Bollinger Band
   if (low0 < bb_lower[0]){
      Print("BUY SIGNAL @ ", TimeCurrent());  //--- Log the buy signal with the current time

   }

Hier prüfen wir, ob ein potenzielles Kaufsignal vorliegt, indem wir auswerten, ob der niedrigste Preis des aktuellen Balkens, der in der Variablen „low0“ gespeichert ist, niedriger ist als der Wert des letzten unteren Bollinger Bandes, das im Array „bb_lower“ bei Index 0 gespeichert ist. Ist „low0“ kleiner als „bb_lower[0]“, bedeutet dies, dass der Kurs unter das untere Band gefallen ist, was auf eine potenziell überverkaufte Situation und eine mögliche Kaufgelegenheit hinweist. Wenn diese Bedingung erfüllt ist, protokolliert das Programm mit der Funktion Print eine Meldung, in der „BUY SIGNAL @“ zusammen mit der aktuellen Zeit, die mit der Funktion TimeCurrent ermittelt wurde, angezeigt wird. Mit Hilfe dieses Alarms können wir verfolgen, wann Kaufsignale erkannt werden, wodurch der Entscheidungsprozess des EA transparent und nachvollziehbar wird. Wenn wir dies ausführen, erhalten wir die folgende Ausgabe.

KAUFSIGNAL 1

Aus der Ausgabe geht hervor, dass die Signale bei jedem Tick gedruckt werden, bei dem die bullischen Bedingungen erfüllt sind. Wir möchten das Signal einmal pro Balken ausgeben, wenn die Bedingungen erfüllt sind. Um dies zu erreichen, gehen wir nach der folgenden Logik vor.

   //--- Check for a buy signal when price crosses below the lower Bollinger Band
   if (low0 < bb_lower[0] && signalTime != currTimeBar0){
      Print("BUY SIGNAL @ ", TimeCurrent());  //--- Log the buy signal with the current time
      signalTime = currTimeBar0;              //--- Update signal time to avoid duplicate trades
   }

Hier verfeinern wir unsere Kaufsignalbedingung, indem wir eine zusätzliche Prüfung hinzufügen, um sicherzustellen, dass wir keine doppelten Aufträge innerhalb desselben Balkens generieren. Zunächst wurde nur überprüft, ob der niedrigste Kurs des aktuellen Balkens, der in der Variablen „low0“ gespeichert ist, unter dem letzten Wert des unteren Bollinger Bandes („bb_lower[0]“) lag. Jetzt fügen wir eine sekundäre Bedingung ein: „signalTime != currTimeBar0“, die sicherstellt, dass der Zeitstempel des aktuellen Balkens („currTimeBar0“) sich von der letzten aufgezeichneten Signalzeit („signalTime“) unterscheidet. Anschließend aktualisieren wir „signalTime“ auf „currTimeBar0“, um zu bestätigen, dass wir nur ein Kaufsignal pro Balken berücksichtigen, auch wenn der Preis mehrmals unter die Bandbreite fällt. Wenn wir die Aktualisierung durchführen, erhalten wir die folgende Ausgabe.

EINZELBALKEN KAUFSIGNAL

Das war ein Erfolg. Wir können nun sehen, dass wir die Signale einmal pro Balken drucken. Wir können dann weiter auf die generierten Signale reagieren, indem wir Kaufpositionen eröffnen.

      if (PositionsTotal() == 0 && !isPrevTradeBuy){
         obj_Trade.Buy(0.01, _Symbol, Ask, Ask - 100 * _Point, Ask + 50 * _Point);  //--- Open a buy position with predefined parameters
         isPrevTradeBuy = true; isPrevTradeSell = false;  //--- Update trade flags
      }

Hier fügen wir Bedingungen hinzu, um sicherzustellen, dass ein Kaufgeschäft nur unter bestimmten Umständen ausgeführt wird. Zunächst prüfen wir, ob die Gesamtzahl der offenen Positionen gleich Null ist, indem wir die Funktion PositionsTotal verwenden, die sicherstellt, dass derzeit keine anderen Geschäfte aktiv sind. Als Nächstes überprüfen wir, dass der letzte ausgeführte Handel kein Kauf war, indem wir „!isPrevTradeBuy“ auswerten. Dies verhindert aufeinanderfolgende Kaufaufträge und stellt sicher, dass unser EA keine neue Kaufposition eröffnet, wenn der vorherige Handel bereits ein Kauf war.

Wenn beide Bedingungen erfüllt sind, eröffnen wir eine Kaufposition mit „obj_Trade.Buy“. Wir geben das Auftragsvolumen als „0,01“ Lots an, mit dem aktuellen Handelssymbol (_Symbol) und dem „Ask“-Kurs. Die Stop-Loss- und Take-Profit-Levels werden auf 100 bzw. 50 Punkte unter bzw. über dem Briefkurs festgelegt und definieren unsere Risikomanagementregeln. Nach erfolgreicher Eröffnung eines Kaufgeschäfts werden die Handelsflags aktualisiert: „isPrevTradeBuy" wird auf „true" und „isPrevTradeSell" auf „false" gesetzt, was anzeigt, dass das letzte Geschäft ein Kauf war und ein weiteres Kaufgeschäft verhindert wird, bis ein Verkaufssignal ausgelöst wird. Für die Verkaufslogik wird ein ähnlicher Ansatz wie folgt verwendet.

   //--- Check for a sell signal when price crosses above the upper Bollinger Band
   else if (high0 > bb_upper[0] && signalTime != currTimeBar0){
      Print("SELL SIGNAL @ ", TimeCurrent());  //--- Log the sell signal with the current time
      signalTime = currTimeBar0;               //--- Update signal time to avoid duplicate trades
      if (PositionsTotal() == 0 && !isPrevTradeSell){
         obj_Trade.Sell(0.01, _Symbol, Bid, Bid + 100 * _Point, Bid - 50 * _Point);  //--- Open a sell position with predefined parameters
         isPrevTradeBuy = false; isPrevTradeSell = true;  //--- Update trade flags
      }
   }

Wenn wir das Programm kompilieren und ausführen, erhalten wir die folgende Ausgabe.

KAUFPOSITION

Wir können sehen, dass wir die Kaufposition erfolgreich ausgeführt haben. Nach Abschluss der Implementierung haben wir die PIRANHA-Strategie unter Verwendung von Bollinger-Bändern integriert und das Programm so konfiguriert, dass es auf der Grundlage definierter Bedingungen auf Kauf- und Verkaufssignale reagiert. Im nächsten Abschnitt werden wir uns auf das Testen des Programms konzentrieren, um seine Leistung zu bewerten und die Parameter für optimale Ergebnisse fein abzustimmen.


Tests

Nach Abschluss der Implementierung besteht der nächste wichtige Schritt darin, den Expert Advisor (EA) gründlich zu testen, um seine Leistung zu bewerten und seine Parameter zu optimieren. Ein effektives Testen stellt sicher, dass sich die Strategie unter verschiedenen Marktbedingungen wie erwartet verhält, und minimiert das Risiko unvorhergesehener Probleme beim Handel. Hier werden wir den MetaTrader 5 Strategy Tester verwenden, um ein Backtesting und eine Optimierung durchzuführen, um die bestmöglichen Eingabewerte für unsere Strategie zu finden.

Wir beginnen mit dem Einrichten unserer anfänglichen Eingabeparameter für die Werte von Stop Loss (SL) und Take Profit (TP), die das Risikomanagement der Strategie maßgeblich beeinflussen. In der ursprünglichen Implementierung wurden die SL und TP mit festen Pip-Werten definiert. Um der Strategie jedoch genügend Raum zum Atmen zu geben und Marktbewegungen besser zu erfassen, werden wir die Eingabeparameter während der Tests flexibler gestalten und optimieren. Aktualisieren wir den Code wie folgt:

//--- INPUTS
input int sl_points = 500;
input int tp_points = 250;

//---

   //--- Check for a buy signal when price crosses below the lower Bollinger Band
   if (low0 < bb_lower[0] && signalTime != currTimeBar0){
      Print("BUY SIGNAL @ ", TimeCurrent());  //--- Log the buy signal with the current time
      signalTime = currTimeBar0;              //--- Update signal time to avoid duplicate trades
      if (PositionsTotal() == 0 && !isPrevTradeBuy){
         obj_Trade.Buy(0.01, _Symbol, Ask, Ask - sl_points * _Point, Ask + tp_points * _Point);  //--- Open a buy position with predefined parameters
         isPrevTradeBuy = true; isPrevTradeSell = false;  //--- Update trade flags
      }
   }
   
   //--- Check for a sell signal when price crosses above the upper Bollinger Band
   else if (high0 > bb_upper[0] && signalTime != currTimeBar0){
      Print("SELL SIGNAL @ ", TimeCurrent());  //--- Log the sell signal with the current time
      signalTime = currTimeBar0;               //--- Update signal time to avoid duplicate trades
      if (PositionsTotal() == 0 && !isPrevTradeSell){
         obj_Trade.Sell(0.01, _Symbol, Bid, Bid + sl_points * _Point, Bid - tp_points * _Point);  //--- Open a sell position with predefined parameters
         isPrevTradeBuy = false; isPrevTradeSell = true;  //--- Update trade flags
      }
   }

Die Eingaben ermöglichen uns eine dynamische Optimierung für verschiedene Symbole und Handelsgüter. Sobald wir dies ausführen, erhalten wir die folgende Ausgabe.

ABSCHLIESSENDER TEST

Das war ein Erfolg! Wir können daraus schließen, dass das Programm wie erwartet funktioniert hat. Der letzte Quellcodeausschnitt, der für die Erstellung und Umsetzung der Piranha-Strategie verantwortlich ist, lautet wie folgt:

//+------------------------------------------------------------------+
//|                                                      PIRANHA.mq5 |
//|                        Allan Munene Mutiiria, Forex Algo-Trader. |
//|                                     https://forexalgo-trader.com |
//+------------------------------------------------------------------+

//--- Properties to define metadata about the Expert Advisor (EA)
#property copyright "Allan Munene Mutiiria, Forex Algo-Trader."   //--- Copyright information
#property link      "https://forexalgo-trader.com"               //--- Link to the creator's website
#property version   "1.00"                                       //--- Version number of the EA

//--- Including the MQL5 trading library
#include <Trade/Trade.mqh>      //--- Import trading functionalities
CTrade obj_Trade;               //--- Creating an object of the CTrade class to handle trading operations

input int sl_points = 500;
input int tp_points = 250;

//--- Defining variables for Bollinger Bands indicator and price arrays
int handleBB = INVALID_HANDLE;  //--- Store Bollinger Bands handle; initialized as invalid
double bb_upper[], bb_lower[];  //--- Arrays to store upper and lower Bollinger Bands values

//--- Flags to track if the last trade was a buy or sell
bool isPrevTradeBuy = false, isPrevTradeSell = false;  //--- Prevent consecutive trades in the same direction

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Create Bollinger Bands indicator handle with a period of 12, no shift, and a deviation of 2
   handleBB = iBands(_Symbol, _Period, 12, 0, 2, PRICE_CLOSE);  
   
   //--- Check if the Bollinger Bands handle was created successfully
   if (handleBB == INVALID_HANDLE){
      Print("ERROR: UNABLE TO CREATE THE BB HANDLE. REVERTING");  //--- Print error if handle creation fails
      return (INIT_FAILED);  //--- Return initialization failed
   }
   
   //--- Set the arrays for the Bollinger Bands to be time-series based (most recent data at index 0)
   ArraySetAsSeries(bb_upper, true);  //--- Set upper band array as series
   ArraySetAsSeries(bb_lower, true);  //--- Set lower band array as series
   
   return(INIT_SUCCEEDED);  //--- Initialization successful
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--- Function to handle cleanup when the EA is removed from the chart
   IndicatorRelease(handleBB); //--- Release the indicator handle
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Retrieve the most recent Bollinger Bands values (3 data points)
   if (CopyBuffer(handleBB, UPPER_BAND, 0, 3, bb_upper) < 3){
      Print("UNABLE TO GET UPPER BAND REQUESTED DATA. REVERTING NOW!");  //--- Error if data fetch fails
      return;
   }
   if (CopyBuffer(handleBB, LOWER_BAND, 0, 3, bb_lower) < 3){
      Print("UNABLE TO GET LOWER BAND REQUESTED DATA. REVERTING NOW!");  //--- Error if data fetch fails
      return;
   }
   
   //--- Get current Ask and Bid prices
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);  //--- Normalize Ask price to correct digits
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);  //--- Normalize Bid price to correct digits

   //--- Get the low and high prices of the current bar
   double low0 = iLow(_Symbol, _Period, 0);    //--- Lowest price of the current bar
   double high0 = iHigh(_Symbol, _Period, 0);  //--- Highest price of the current bar
   
   //--- Get the timestamp of the current bar
   datetime currTimeBar0 = iTime(_Symbol, _Period, 0);  //--- Time of the current bar
   static datetime signalTime = currTimeBar0;           //--- Static variable to store the signal time

   //--- Check for a buy signal when price crosses below the lower Bollinger Band
   if (low0 < bb_lower[0] && signalTime != currTimeBar0){
      Print("BUY SIGNAL @ ", TimeCurrent());  //--- Log the buy signal with the current time
      signalTime = currTimeBar0;              //--- Update signal time to avoid duplicate trades
      if (PositionsTotal() == 0 && !isPrevTradeBuy){
         obj_Trade.Buy(0.01, _Symbol, Ask, Ask - sl_points * _Point, Ask + tp_points * _Point);  //--- Open a buy position with predefined parameters
         isPrevTradeBuy = true; isPrevTradeSell = false;  //--- Update trade flags
      }
   }
   
   //--- Check for a sell signal when price crosses above the upper Bollinger Band
   else if (high0 > bb_upper[0] && signalTime != currTimeBar0){
      Print("SELL SIGNAL @ ", TimeCurrent());  //--- Log the sell signal with the current time
      signalTime = currTimeBar0;               //--- Update signal time to avoid duplicate trades
      if (PositionsTotal() == 0 && !isPrevTradeSell){
         obj_Trade.Sell(0.01, _Symbol, Bid, Bid + sl_points * _Point, Bid - tp_points * _Point);  //--- Open a sell position with predefined parameters
         isPrevTradeBuy = false; isPrevTradeSell = true;  //--- Update trade flags
      }
   }
  }
//+------------------------------------------------------------------+

Backtest-Ergebnisse:

BACKTEST-ERGEBNISSE

Backtest-Grafik:

BACKTEST-GRAFIK

In dieser Testphase haben wir die Eingabeparameter optimiert und die Leistung der Strategie mit dem Strategietester überprüft. Die Anpassungen, die wir an den Stop-Loss- und Take-Profit-Werten vorgenommen haben, verleihen der PIRANHA-Strategie mehr Flexibilität. Sie kann nun Marktschwankungen ausgleichen. Wir haben bestätigt, dass die Strategie wie beabsichtigt funktioniert und günstige Ergebnisse erzielt, wenn wir sie backtesten und optimieren.


Schlussfolgerung

In diesem Artikel haben wir die Entwicklung eines MetaQuotes Language 5 (MQL5) Expert Advisors untersucht, der auf der PIRANHA-Strategie basiert und Bollinger-Bänder zur Identifizierung potenzieller Kauf- und Verkaufssignale verwendet. Wir begannen mit dem Verständnis der Grundlagen der PIRANHA-Strategie, gefolgt von einem detaillierten Überblick über die Bollinger-Bänder, wobei ihre Rolle bei der Erkennung von Marktvolatilität und der Festlegung von Handelsein- und -ausstiegen hervorgehoben wurde.

Während der Implementierung haben wir den Schritt-für-Schritt-Codierungsprozess veranschaulicht, Indikator-Handles konfiguriert und die Handelslogik implementiert. Um eine optimale Leistung zu gewährleisten, haben wir kritische Eingaben angepasst und das Programm mit dem Strategy Tester von MetaTrader 5 getestet, um die Wirksamkeit der Strategie unter verschiedenen Marktbedingungen zu überprüfen.

Haftungsausschluss: Die in diesem Artikel dargestellten Informationen dienen nur zu Bildungszwecken. Er soll Einblicke in die Erstellung eines Expert Advisors (EA) auf Basis der PIRANHA-Strategie geben und als Grundlage für die Entwicklung weiterführender Systeme mit weiteren Optimierungen und Tests dienen. Die besprochenen Strategien und Methoden garantieren keine Handelsergebnisse, und die Verwendung dieser Inhalte erfolgt auf eigene Gefahr. Sorgen Sie immer für gründliche Tests und berücksichtigen Sie mögliche Marktbedingungen, bevor Sie eine automatisierte Handelslösung einsetzen.

Insgesamt dient dieser Artikel als Leitfaden für die Automatisierung der PIRANHA-Strategie und ihre Anpassung an Ihren Handelsstil. Wir hoffen, dass er wertvolle Einblicke bietet und dazu anregt, sich weiter mit der Erstellung anspruchsvoller Handelssysteme in MQL5 zu beschäftigen. Viel Spaß beim Kodieren und ein erfolgreicher Handel!

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16034

Beigefügte Dateien |
PIRANHA.mq5 (5.57 KB)
Selbstoptimierender Expert Advisor mit MQL5 und Python (Teil V): Tiefe Markov-Modelle Selbstoptimierender Expert Advisor mit MQL5 und Python (Teil V): Tiefe Markov-Modelle
In dieser Diskussion werden wir eine einfache Markov-Kette auf einen RSI-Indikator anwenden, um zu beobachten, wie sich der Preis verhält, nachdem der Indikator wichtige Niveaus durchlaufen hat. Wir kamen zu dem Schluss, dass die stärksten Kauf- und Verkaufssignale für das NZDJPY-Paar entstehen, wenn der RSI im Bereich von 11-20 bzw. 71-80 liegt. Wir werden Ihnen zeigen, wie Sie Ihre Daten manipulieren können, um optimale Handelsstrategien zu erstellen, die direkt aus den vorhandenen Daten gelernt werden. Darüber hinaus wird demonstriert, wie ein tiefes neuronales Netz so trainiert werden kann, dass es lernt, die Übergangsmatrix optimal zu nutzen.
Der Header im Connexus (Teil 3): Die Verwendung von HTTP-Headern für Anfragen beherrschen Der Header im Connexus (Teil 3): Die Verwendung von HTTP-Headern für Anfragen beherrschen
Wir entwickeln die Connexus-Bibliothek weiter. In diesem Kapitel wird das Konzept der Header im HTTP-Protokoll erläutert. Es wird erklärt, was sie sind, wozu sie dienen und wie man sie in Anfragen verwendet. Wir behandeln die wichtigsten Header, die bei der Kommunikation mit APIs verwendet werden, und zeigen praktische Beispiele, wie sie in der Bibliothek konfiguriert werden können.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 42): ADX-Oszillator MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 42): ADX-Oszillator
Der ADX ist ein weiterer relativ beliebter technischer Indikator, der von einigen Händlern verwendet wird, um die Stärke eines vorherrschenden Trends zu messen. Als Kombination von zwei anderen Indikatoren stellt er einen Oszillator dar, dessen Muster wir in diesem Artikel mit Hilfe der MQL5-Assistentengruppe und ihrer Unterstützungsklassen untersuchen.
Klassische Strategien neu interpretieren (Teil IX): Analyse mehrerer Zeitrahmen (II) Klassische Strategien neu interpretieren (Teil IX): Analyse mehrerer Zeitrahmen (II)
In der heutigen Diskussion untersuchen wir die Strategie der Analyse mehrerer Zeitrahmen, um zu erfahren, in welchem Zeitrahmen unser KI-Modell am besten abschneidet. Unsere Analyse führt uns zu dem Schluss, dass die monatlichen und stündlichen Zeitrahmen Modelle mit relativ niedrigen Fehlerquoten für das EURUSD-Paar ergeben. Wir haben dies zu unserem Vorteil genutzt und einen Handelsalgorithmus entwickelt, der KI-Prognosen auf dem monatlichen Zeitrahmen erstellt und seine Handelsgeschäfte auf dem stündlichen Zeitrahmen ausführt.