
Aufbau des Kerzenmodells Trend-Constraint (Teil 8): Entwicklung eines Expert Advisors (II)
Inhalt:
Einführung
In unserem letzten Artikel haben wir uns mit der Erstellung eines Expert Advisors (EA) befasst, der den Trend Constraint V1.09-Indikator verwendet und durch das manuell ausgeführte Trend Constraint R-R-Skript zur Platzierung von Risiko- und Belohnungsrechtecken ergänzt wird. Dieses Setup lieferte zwar aufschlussreiche Handelssignale und eine verbesserte Visualisierung, erforderte aber manuelle Eingriffe, die rationalisiert werden könnten. Angesichts der Schnelllebigkeit von Handelsumgebungen wird der Bedarf an einer effizienteren Lösung deutlich. Viele Händler wünschen sich integrierte Systeme, die autonom funktionieren und den Bedarf an ständiger Überwachung und manueller Ausführung verringern.
Dieser Artikel ist der nächste Schritt in unserer Serie und führt Sie durch die Entwicklung eines unabhängigen Expert Advisors (EA), der nicht nur die Trendanalyse-Funktionen von Trend Constraint V1.09 nutzt, sondern auch Risiko-Rendite-Funktionen direkt in den EA integriert. Unser Ziel ist es, Händlern mit MQL5 auf der MetaTrader 5-Plattform eine All-in-One-Lösung zu bieten, die eine verbesserte Automatisierung und einen nahtlosen Betrieb ermöglicht, um mit den Marktanforderungen Schritt zu halten.
Um dies zu erreichen, werden wir die in Teil 1, Teil 2 und Teil 3 behandelten grundlegenden Schritte wiederholen und uns die Logik ausleihen, die der EA für die Erfüllung seiner Handelsaufgaben benötigt. Jetzt werden wir alle diese Teile und ihre Logik kombinieren, um den Expert Advisor zu schreiben.
Nachfolgend finden Sie eine Zusammenfassung der Bedingungen, die im Indikator, wie er in MQL5 implementiert ist, Signale erzeugen:
Kaufen (Long) Bedingung:
Verkaufen (Short) Bedingung:
- Die Tageskerze muss aufwärts sein.
- Auf einem niedrigeren Zeitrahmen innerhalb einer steigenden D1-Kerze benötigen wir ein Zusammentreffen mehrerer Signale. Insbesondere sollte der eingebaute Indikator, z. B. der Relative Strength Index (RSI), einen überverkauften Zustand anzeigen, und der schnelle Durchschnitt muss über dem langsamen liegen.
- Die Tageskerze muss fallen.
- Auf einem niedrigeren Zeitrahmen innerhalb einer fallenden D1-Kerze benötigen wir ein Zusammentreffen mehrerer Signale. Insbesondere sollte der integrierte Indikator, z. B. der Relative Strength Index (RSI), einen überkauften Zustand anzeigen, und der schnelle Durchschnitt muss unter dem langsam fallen.
Erstellen des Expert Advisors
Wir verwenden die MetaEditor-Anwendung, um unser MQL5-Expertenprogramm zu schreiben. Das Wichtigste ist, dass Sie die Grundlage im Auge behalten. Nachfolgend finden Sie eine Zusammenfassung der Struktur unseres EA.
Zusammenfassung der Architektur der meisten EA-Programme:
- Initialisierung (OnInit): Richtet die erforderlichen Indikatoren und Variablen ein.
- Hauptschleife (OnTick): Verarbeitet die eingehende Ticks, um die Marktbedingungen zu bewerten und Handelsentscheidungen zu treffen.
- Handelsmanagement (OnTrade): Berücksichtigt die handelsbezogenen Ereignissen.
- Testen (OnTester und verwandte Funktionen): Sie bieten eine Struktur für die Optimierung und Bewertung der Leistung des EA im Strategy Tester.
- Nutzerinteraktion (OnChartEvent): Optional, aber es ermöglicht die Interaktion mit dem EA über Chart-Ereignisse.
Ich glaube, dass der grobe Entwurf im nachstehenden Blockdiagramm dazu beitragen wird, unser angestrebtes Ergebnis zu verdeutlichen, sodass es leichter zu verstehen ist.
Ein grobes Blockdiagramm der EA-Teile und wie sie zusammenhängen
Diese Struktur gewährleistet, dass unser EA gut organisiert und in der Lage ist, die verschiedenen Aufgaben, die für die Umsetzung unserer Handelsstrategie erforderlich sind, effektiv zu bewältigen. Ich werde den Entwicklungsprozess in Unterabschnitte unterteilen, aber fortgeschrittene Entwickler können die Phasen (i) und (ii) überspringen und direkt zu Unterabschnitt (iii) übergehen.(i) Starten des Standard-EA (Vorlage) in MetaEditor.
(ii) Anpassen der Vorlage.
(iii) Schreiben der Logik des Experten Trend Constraint in die vorbereitete Vorlage.
(i) Starten der EA-Vorlage
Drücken Sie in MetaEditor die Tastenkombination Strg + N, um eine neue Datei zu öffnen, und wählen Sie „Expert Advisor (Template)“, wie in der Abbildung unten gezeigt:
Einen neuen Expert Advisor starten (Vorlage)
Bitte beachten Sie, dass die Angaben zum Autor und die Links bereits vorhanden sind, wenn ich ein neues Projekt starte, da ich bereits frühere Projekte auf meinem Computer habe. Sie können sie anpassen.
(ii) Anpassen der Vorlage
Mit diesem Schreiben möchte ich nicht nur meine Programmierkenntnisse unter Beweis stellen, sondern auch diejenigen ansprechen, die gerade erst anfangen, den Prozess zu verstehen, damit sie die erworbenen Fähigkeiten in Zukunft anwenden können. An dieser Stelle sehen wir uns die Vorlage an, die für einen Neuling vielleicht nicht sehr sinnvoll erscheint. Bevor wir mit der Codierung von dem Skelett der Vorlage beginnen, werde ich die wichtigsten benötigten Funktionen herausgreifen und kurz erläutern. Wir werden dann die Details ausfüllen und den EA-Code für unsere Bedürfnisse schreiben. Dieser Ansatz ist von entscheidender Bedeutung, denn er ermöglicht es Ihnen, ohne Schwierigkeiten andere Projekte zu starten, die sich von dem unterscheiden, was wir gerade behandeln.
Das Skelett bildet die Grundlage, auf der wir später die Logik für unseren EA aufbauen werden.
Hier ist die von MetaEditor generierte Vorlage:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { //--- double ret=0.0; //--- //--- return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { //--- } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { //--- } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- } //+------------------------------------------------------------------+
Gehen wir von der Vorlage aus und besprechen wir die wichtigsten Funktionen, die für unsere Expert Advisors wichtig sind:
- OnInit(): Diese Funktion wird einmal ausgeführt, wenn der EA initialisiert wird, und richtet Indikatoren, Variablen oder Ressourcen ein, die für den Betrieb erforderlich sind. Eine ordnungsgemäße Initialisierung stellt sicher, dass alle erforderlichen Ressourcen zur Verfügung stehen, bevor der EA mit der Verarbeitung von Marktdaten beginnt. Für unseren Expert Advisor „Trend Constraint“ werden hier normalerweise der RSI-Indikator und andere wichtige Variablen initialisiert.
- OnDeinit(): Diese Funktion wird aufgerufen, wenn der EA deinitialisiert wird, z. B. wenn er aus einem Chart entfernt wird oder das Terminal heruntergefahren wird. Es wird verwendet, um Ressourcen zu bereinigen, wie das Freigeben von Indikator-Handles oder das Schließen von Dateien, um Speicherlecks oder andere Probleme zu vermeiden.
- OnTick(): Diese Hauptfunktion wird jedes Mal ausgelöst, wenn ein neuer Tick (Preisaktualisierung) für das Symbol empfangen wird, an das der EA gebunden ist. In unserem „Trend Constraint Expert Advisor“ würde dies die Logik zur Überprüfung der Marktbedingungen, z. B. des D1-Trends und des RSI-Niveaus, und zum Treffen von Handelsentscheidungen wie dem Öffnen oder Schließen von Positionen beinhalten.
- OnTrade(): Diese Funktion wird aufgerufen, wenn ein Handelsereignis eintritt, wie z. B. die Platzierung, Änderung oder Schließung eines Auftrags, und ist entscheidend für die Überwachung des Handelsstatus und die Reaktion auf Änderungen. So können Sie beispielsweise verfolgen, wann ein Handel eröffnet wird, und das Verhalten des EA entsprechend anpassen.
- OnTester(): Diese Funktion wird während des Strategietests verwendet, um einen „double“-Wert zurückzugeben, der als nutzerdefiniertes Kriterium für die Optimierung dient. Hier können Sie eine nutzerdefinierte Metrik, wie z.B. Gewinnfaktor oder Drawdown, definieren, um die Leistung des EAs beim Testen im Strategy Tester zu bewerten.
- OnTesterInit(), OnTesterPass(), und OnTesterDeinit(): Diese Funktionen sind speziell für das Testen und Optimieren von Strategien gedacht und verwalten den Start, die laufenden Durchläufe und das Ende von Tests im Strategy Tester. Sie bieten eine bessere Kontrolle über den Testprozess, indem sie Ressourcen initialisieren, Daten sammeln und nach den Tests aufräumen.
- OnChartEvent(): Diese Funktion verarbeitet Chart-Ereignisse, wie Mausklicks oder Tastendrücke, und ermöglicht so die Interaktion mit dem EA, während er läuft. Wenn Ihr EA eine Nutzerinteraktion beinhaltet, z. B. das Ändern von Parametern oder das Auslösen von Aktionen durch Chart-Ereignisse, ist diese Funktion unerlässlich.
Wenn wir diese Funktionen verstehen, können wir sehen, wie wir die Logik in ihnen strukturieren können. Die von der Vorlage bereitgestellten Funktionen sind jedoch möglicherweise nicht ausreichend für die Komplexität des von uns entwickelten EA. Möglicherweise sind zusätzliche Funktionen erforderlich, deren Einbeziehung wir begründen und erläutern müssen, um die spezifischen Anforderungen unseres „Trend Constraint Expert“ zu erfüllen.
Zusätzliche Funktionen, die nicht in der Expert Advisor-Vorlage enthalten, aber für unser Projekt notwendig sind:- Indikatorfunktionen (z.B. iRSI): Wird zur Berechnung von Indikatoren wie dem RSI verwendet, die für Ihre Handelsstrategie unerlässlich sind.
- Handelsfunktionen (Klasse CTrade): Dient zur Verwaltung von Aufträgen und Positionen, z. B. zum Erteilen von Kauf-/Verkaufsaufträgen, zum Setzen von Stop-Loss und zum Ändern von Positionen.
//+------------------------------------------------------------------+ //| Trend Constraint Expert Advisor.mq5| //| Copyright 2024, Clemence Benjamin| //| https://www.mql5.com/en/users/billionaire2024/seller| //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialization code here rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } // Any other initialization tasks return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Cleanup code here IndicatorRelease(rsi_handle); // Release RSI indicator handle // Any other deinitialization tasks } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Main trading logic goes here // Determine market conditions (e.g., daily trend, RSI levels) // Check for trade conditions and execute orders if necessary // Implement trailing stop logic if necessary } //+------------------------------------------------------------------+ //| Trade event function | //+------------------------------------------------------------------+ void OnTrade() { // Handle trade events (e.g., order placement, modification, closure) } //+------------------------------------------------------------------+ //| Tester function | //+------------------------------------------------------------------+ double OnTester() { double ret = 0.0; // Custom optimization criteria (if any) go here return(ret); } //+------------------------------------------------------------------+ //| TesterInit function | //+------------------------------------------------------------------+ void OnTesterInit() { // Initialization for testing (if needed) } //+------------------------------------------------------------------+ //| TesterPass function | //+------------------------------------------------------------------+ void OnTesterPass() { // Actions after each optimization pass (if needed) } //+------------------------------------------------------------------+ //| TesterDeinit function | //+------------------------------------------------------------------+ void OnTesterDeinit() { // Cleanup after testing (if needed) } //+------------------------------------------------------------------+ //| Chart event function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // Handle chart events (e.g., mouse clicks, key presses) here } //+------------------------------------------------------------------+
(iii) Schreiben der Expertenlogik von Trend Constraint.
Nun können wir mit dem Schreiben der Logik für jede Funktion, die unseren Expert Advisor ausmacht, fortfahren. Bauen wir unser Programm Schritt für Schritt auf:
Einbinden der Handelsbibliothek:
Wir beginnen mit der Einbindung der Handelsbibliothek, die notwendig ist, weil die Klasse CTrade in dieser Bibliothek die Funktionen bereitstellt, die für die Ausführung von Handelsoperationen wie das Öffnen, Ändern und Schließen von Positionen erforderlich sind. Durch die Einbindung dieser Bibliothek ermöglichen wir dem EA, mit dem Markt zu interagieren und die Handelsgeschäfte programmatisch zu verwalten.
#include <Trade\Trade.mqh> // Include the trade libraryDefinieren von Eingabeparametern:
Als Nächstes legen wir die Eingabeparameter fest, die der Nutzer an seine Handelspräferenzen anpassen kann. Zu diesen Parametern gehören die RSI-Periode, überkaufte und überverkaufte Niveaus, Losgröße, Stop-Loss, Take-Profit und Trailing-Stop. Durch das Schreiben dieser Eingabezeilen stellen wir sicher, dass der EA an unterschiedliche Marktbedingungen angepasst werden kann. Das Programm verwendet diese Werte, um zu entscheiden, wann es in den Handel einsteigt und wann es ihn beendet.
// Input parameters input int RSI_Period = 14; // RSI period input double RSI_Overbought = 70.0; // RSI overbought level input double RSI_Oversold = 30.0; // RSI oversold level input double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in pointsGlobale Variablen deklarieren:
Dann deklarieren wir globale Variablen wie RSI_value und RS1_handle, die den RSI-Wert bzw. das Handle sowie eine Instanz der Klasse CTrade speichern. Durch die Deklaration dieser Variablen stellen wir sicher, dass der EA seinen Zustand über verschiedene Funktionen hinweg beibehalten kann, sodass das Programm bei Bedarf auf diese Werte zugreifen und sie während seiner Arbeit ändern kann.
// Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade classInitialisierung des Expert Advisors:
In der Funktion OnInit erstellen wir das RSI-Indikator-Handle mit der Funktion iRSI. Dieser Schritt ist von entscheidender Bedeutung, da das Programm dieses Handle benötigt, um die RSI-Werte bei jedem Tick abzurufen. Wenn das Handle nicht erstellt werden kann, haben wir das Programm so geschrieben, dass es INIT_FAILED zurückgibt und verhindert, dass der EA ohne diese wichtige Komponente läuft. Dadurch wird sichergestellt, dass das Programm nur dann läuft, wenn es vollständig für die Analyse von Marktdaten ausgerüstet ist.
int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); }Deinitialisierung des Expert Advisors:
Um die Ressourcen effektiv zu verwalten, implementieren wir die Funktion OnDeinit, um das RSI-Indikator-Handle freizugeben, wenn der EA aus dem Chart entfernt wird. Durch das Schreiben dieses Bereinigungscodes verhindern wir Speicherlecks und stellen sicher, dass die Ressourcen ordnungsgemäß freigegeben werden. Das Programm führt diese Bereinigung automatisch durch, wenn es deinitialisiert wird, um eine optimale Leistung zu gewährleisten.
void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); }Implementierung der zentralen Handelslogik:
Die zentrale Handelslogik befindet sich in der Funktion OnTick, die wir so gestalten, dass sie bei jedem Markttick ausgeführt wird. Zunächst schreiben wir einen Code, um den aktuellen Tagestrend zu ermitteln, indem wir die Eröffnungs- und Schlusskurse der Tageskerze vergleichen. Anhand dieser Analyse kann das Programm erkennen, ob der Markt steigt oder fällt, was für fundierte Handelsentscheidungen unerlässlich ist.
void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open;Abrufen von RSI-Werten:
Anschließend wird der RSI-Wert mithilfe von CopyBuffer und dem zuvor erstellten RSI-Handle abgerufen. Damit stellen wir sicher, dass das Programm beurteilen kann, ob sich der Markt in einem überkauften oder überverkauften Zustand befindet. Das Programm verwendet diesen RSI-Wert bei seiner Entscheidungsfindung, um festzustellen, ob es die Bedingungen für den Abschluss eines Handelsgeschäfts erfüllt.
// Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0];Schließen von Positionen bei Trendwechsel:
Außerdem enthalten wir eine Logik zum Schließen offener Positionen, wenn sich der Markttrend ändert. Wenn der Trend beispielsweise von einem Aufwärtstrend zu einem Abwärtstrend wechselt, wird der EA alle offenen Kaufpositionen schließen und umgekehrt. Durch diese Absicherung stellen wir sicher, dass das Programm mit der vorherrschenden Marktstimmung übereinstimmt, was für die Risikominimierung entscheidend ist.
// Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } }Prüfen auf Kauf- und Verkaufsbedingungen:
Für die Kauf- und Verkaufsbedingungen schreiben wir eine Logik, die bei Kaufaufträgen auf einen Aufwärtstrend in Kombination mit einem überverkauften RSI und bei Verkaufsaufträgen auf einen Abwärtstrend in Kombination mit einem überkauften RSI prüft. Durch die Programmierung dieser Bedingungen stellen wir sicher, dass der EA nur dann in den Handel einsteigt, wenn sowohl die Trend- als auch die Momentum-Indikatoren übereinstimmen. Das Programm überwacht diese Bedingungen und führt den Handel entsprechend aus, sodass ein disziplinierter Ansatz für den Handel gewährleistet ist.
// Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } }Implementierung eines Trailing-Stop-Mechanismus:
Schließlich setzen wir einen Trailing-Stop-Mechanismus ein, um Gewinne zu schützen, wenn sich der Markt zugunsten einer offenen Position entwickelt. Durch das Schreiben dieser Trailing-Stop-Logik stellen wir sicher, dass der EA den Stop-Loss dynamisch anpasst, um Gewinne zu sichern, während der Handel fortgesetzt werden kann, solange der Markt günstig bleibt. Das Programm verwaltet den Trailing-Stop automatisch und stellt sicher, dass er auf Marktbewegungen reagiert, um Gewinne zu maximieren und Verluste zu minimieren.
// Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } }
Unser endgültiges Programm mit Kopfzeile und anderen Eigenschaften:
//+------------------------------------------------------------------+ //| Trend Constraint Expert.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property description "A System that seeks to Long D1 Bullish sentiment and short D1 Bearish sentiment" #property strict #include <Trade\Trade.mqh> // Include the trade library // Input parameters input int RSI_Period = 14; // RSI period input double RSI_Overbought = 70.0; // RSI overbought level input double RSI_Oversold = 30.0; // RSI oversold level input double Lots = 0.1; // Lot size input double StopLoss = 100; // Stop Loss in points input double TakeProfit = 200; // Take Profit in points input double TrailingStop = 50; // Trailing Stop in points // Global variables double rsi_value; int rsi_handle; CTrade trade; // Declare an instance of the CTrade class //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Create an RSI indicator handle rsi_handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE); if (rsi_handle == INVALID_HANDLE) { Print("Failed to create RSI indicator handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Release the RSI indicator handle IndicatorRelease(rsi_handle); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Determine current daily trend (bullish or bearish) double daily_open = iOpen(_Symbol, PERIOD_D1, 0); double daily_close = iClose(_Symbol, PERIOD_D1, 0); bool is_bullish = daily_close > daily_open; bool is_bearish = daily_close < daily_open; // Get the RSI value for the current bar double rsi_values[]; if (CopyBuffer(rsi_handle, 0, 0, 1, rsi_values) <= 0) { Print("Failed to get RSI value"); return; } rsi_value = rsi_values[0]; // Close open positions if the trend changes for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { int position_type = PositionGetInteger(POSITION_TYPE); ulong ticket = PositionGetInteger(POSITION_TICKET); // Get the position ticket if ((position_type == POSITION_TYPE_BUY && is_bearish) || (position_type == POSITION_TYPE_SELL && is_bullish)) { trade.PositionClose(ticket); // Use the ulong variable directly } } } // Check for buy condition (bullish trend + RSI oversold) if (is_bullish && rsi_value < RSI_Oversold) { // No open positions? Place a buy order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; // Open a buy order trade.Buy(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Buy"); } } // Check for sell condition (bearish trend + RSI overbought) if (is_bearish && rsi_value > RSI_Overbought) { // No open positions? Place a sell order if (PositionsTotal() == 0) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = price + StopLoss * _Point; double tp = price - TakeProfit * _Point; // Open a sell order trade.Sell(Lots, _Symbol, price, sl, tp, "TrendConstraintExpert Sell"); } } // Apply trailing stop for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelect(PositionGetSymbol(i))) // Corrected usage { double price = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double current_price; if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_BID); if (current_price - price > TrailingStop * _Point) { if (stopLoss < current_price - TrailingStop * _Point) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price - TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { current_price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if (price - current_price > TrailingStop * _Point) { if (stopLoss > current_price + TrailingStop * _Point || stopLoss == 0) { trade.PositionModify(PositionGetInteger(POSITION_TICKET), current_price + TrailingStop * _Point, PositionGetDouble(POSITION_TP)); } } } } } } //+------------------------------------------------------------------+ //HAPPY DEVELOPING!
Wenn wir dieses Stadium erreicht haben, können wir mit dem Testen unseres Programms fortfahren. Im Folgenden habe ich meine Testerfahrungen zusammengefasst.
Tester
Um den „Trend Constraint Expert“ im Strategy Tester von MetaTrader 5 zu testen, werden wir zunächst einen Backtest mit historischen Daten einrichten, um die Leistung des EAs zu bewerten. Dieser Prozess ermöglicht es uns, die Handelsstrategie unter verschiedenen Marktbedingungen zu simulieren und so die Rentabilität, das Risikomanagement und die Gesamteffektivität zu analysieren. Wir müssen den gewünschten Zeitrahmen (in diesem Fall den M1-Zeitrahmen), die Eingabeparameter und die Handelsumgebung auswählen und beobachten, wie gut sich der EA an die Trendfolgelogik und die RSI-Bedingungen hält. Dieser Test ist entscheidend für die Feinabstimmung des Experten, bevor der Live-Handel in Betracht gezogen wird. Ich bin ein Fan des Boom 500 Index und liebe es, den EA auf diesem schönen Paar zu testen.
Einstellungen des Strategietesters: Der Experte Trend-Constraint
Trend-Constraint Performance im Tester
Testergebnis 01/2023-12/2023
Schlussfolgerung
Ich freue mich, dass wir zum Abschluss dieser wunderbaren, lehrbuchartigen Diskussion gekommen sind. Unser Ziel war es, einen unabhängigen Expert Advisor (EA) zu entwickeln, der keine spezifischen Indikatoren benötigt. Ich hoffe, dass diese Diskussion Sie dazu inspiriert hat, die Struktur der EA-Entwicklung zu verstehen und einen soliden Ausgangspunkt zu schaffen. Wir haben uns auf die grundlegendsten Konzepte konzentriert, um sicherzustellen, dass die Grundlagen leicht zu erfassen sind. Die Möglichkeit, den EA durch die Eingabe verschiedener Faktoren anzupassen, erlaubt das Experimentieren mit Werten, um die profitabelsten Einstellungen zu finden.
Wir haben erfolgreich einen funktionierenden Expert Advisor entwickelt, der auf unserer ursprünglichen Idee basiert, und wir können die Orderausführungen im Tester beobachten. Es gibt jedoch noch erheblichen Spielraum für Verbesserungen. Der Trend-Constraint-Experte muss weiter verfeinert werden, insbesondere in Bezug auf die Einstiegsbedingungen, um die Rentabilität im Einklang mit den vorherrschenden Tagestrends zu verbessern. Diesmal haben wir keine magische Zahl angegeben, und beim Testen auf einem echten Demokonto habe ich festgestellt, dass der EA andere, bereits erteilte Aufträge beeinflusst hat.
Ein Vorteil dieser Entwicklung im Vergleich zu unserer vorherigen, die auf einem installierten Indikator beruhte, ist, dass wir jetzt eine einzige portable Datei haben, die wir ausführen können. Das bedeutet nicht, dass unsere früheren Bemühungen umsonst waren; vielmehr haben wir wertvolle Lektionen gelernt, und die Werkzeuge aus diesem Projekt sind auch für künftige Unternehmungen nützlich. Unser Ziel ist es, den EA weiter zu verfeinern, um im weiteren Verlauf unserer Serie die bestmöglichen Ergebnisse zu erzielen.
Als Nächstes werden wir eine magische Zahl eingeben, unsere Eingabetechniken verbessern und unsere Kreativität bei dieser Entwicklung weiter steigern. Viel Spaß beim Handeln!
Datei | Beschreibung |
---|---|
Trend Constraint Expert.mq5 | Quellcode. |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15322





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.