English Русский 日本語
preview
Aufbau des Kerzenmodells Trend-Constraint (Teil 9): Expert Advisor für mehrere Strategien (I)

Aufbau des Kerzenmodells Trend-Constraint (Teil 9): Expert Advisor für mehrere Strategien (I)

MetaTrader 5Handelssysteme | 4 Dezember 2024, 10:16
128 0
Clemence Benjamin
Clemence Benjamin

Hauptinhalt:



Einführung

Von Beginn dieser Artikelserie an haben wir uns darauf konzentriert, unsere Experten auf die vorherrschende Stimmung der Tageskerzen (D1) abzustimmen. Die Form der Tageskerze diente als Hauptmerkmal. Wir mussten jedoch auf niedrigere Zeitrahmen heruntergehen, um Einstiegsebenen im D1-Markt zu identifizieren. Zum Beispiel wollten wir, dass der Markt auf dem Zeitrahmen M1 extreme Niveaus des Relative Strength Index (RSI) erreicht, um dem Expert Advisor potenzielle Trades zu signalisieren. In diesem frühen Stadium haben wir nicht zu viele Strategien eingeführt, um den Inhalt für Anfänger leicht verständlich zu halten.

Es gibt jedoch eine umfangreiche Sammlung von Strategien, die wir studieren und in den Algorithmus unseres Trend Constraint Expert Advisors integrieren können. Heute werden wir uns einige bekannte Strategien ansehen, die von einflussreichen Persönlichkeiten des Handels entwickelt wurden, die ich als die „Väter des Marktes“ bezeichne. In dieser Phase unserer Diskussion werden wir unser Verständnis vertiefen und gleichzeitig das ursprüngliche Thema unseres Titels beibehalten. Wir werden uns auch mit den Einschränkungen der Strategien befassen, die wir in unserer früheren Entwicklung erörtert haben und die sich in erster Linie auf RSI und Constraining-Logik konzentrierten. Außerdem werden wir untersuchen, wie neue Strategien in den Expert Advisor integriert werden können.

Bevor wir tiefer in die sieben Top-Strategien eintauchen, lassen Sie uns zurückspulen und die einschränkende Logik in unserem Code rekapitulieren: 

 Eine Bedingung für eine Aufwärtskerze (bullish) in MQL5:

void OnTick()
{
    // Determine current daily trend (bullish )
    double daily_open = iOpen(_Symbol, PERIOD_D1, 0);
    double daily_close = iClose(_Symbol, PERIOD_D1, 0);

    bool is_bullish = daily_close > daily_open;
}

Eine Bedingung für eine Abwärtskerze (bearish) in MQL5:

void OnTick()
{
    // Determine current daily trend (bearish)
    double daily_open = iOpen(_Symbol, PERIOD_D1, 0);
    double daily_close = iClose(_Symbol, PERIOD_D1, 0);

    
    bool is_bearish = daily_close < daily_open;
}

Im obigen Code dient die Stimmung aus dem höheren Zeitrahmen als einschränkender Faktor. In diesem Fall haben wir uns für den Zeitrahmen D1 entschieden.

Umsetzung der Nebenbedingung:

Nachdem wir nun die Auf- und Abwärtsstimmung unserer Tageskerze ermittelt haben, können wir die Funktion „if()“ neben unserer Einstiegsbedingungslogik verwenden. 

Für einen Aufwärtstag:

 if (is_bullish)
    {
        // Logic for bullish trend
        Print("The daily trend is bullish.");

   // You can add your trading logic here, for example:
        // if (OrderSelect(...)) { /* Place buy order */ }
    }

Für einen Abwärtstag:

 if (is_bearish)
    {
        // Logic for bearish trend
        Print("The daily trend is bearish.");
        // You can add your trading logic here, for example:
        // if (OrderSelect(...)) { /* Place sell order */ }
    }

Am Ende dieser Erörterung können Sie vielleicht feststellen:

1. Andere Strategien und der Mann dahinter.

2. Einbindung der neuen Strategie in die Module des bestehenden Expert Advisors.

3. Implementierung einer magischen Zahl.

Zusammenfassend lässt sich sagen, dass die drei oben genannten Schlüsselpunkte den Händlern ein besseres Verständnis der verschiedenen Strategien und der dahinter stehenden Beweggründe vermitteln und ihnen Einblicke in die Implementierung von MQL5 geben, um neue Strategien in bestehenden Code zu integrieren.

Bevor wir mit der Entwicklung des Hauptcodes beginnen, wollen wir uns im nächsten Abschnitt auf die Erörterung dieser Strategien auf der Grundlage meiner Recherchen konzentrieren. Sie werden sehen, dass es notwendig ist, unsere Expert Advisor-Strategien zu erweitern, zumal sich der Markt ständig weiterentwickelt. Diese Verbundstrategien sind für die Anpassung an jedes Marktszenario unerlässlich. Wenn eine Strategie versagt, gibt es immer eine andere, die eingesetzt werden kann. Ich habe mich bemüht, die mathematischen Aspekte, die jeder Strategie zugrunde liegen, aufzudecken, da diese mathematischen Funktionen ein grundlegendes Element für die effiziente Entwicklung von Algorithmen sind.

Nach der Überprüfung des aktuellen Expert Advisors bin ich auf einige Warnungen gestoßen, die Sie vielleicht bemerkt haben, wenn Sie die Seite verfolgt haben. Bitte sehen Sie sich das folgende Bild an:

Warnung

Eine Warnung des Kompiler

Der Fehler befand sich in Zeile 78 und Spalte 28, wie unten hervorgehoben:

Warnung

Warnung in Zeile 78, Spalte 28

Diese Warnung ist eine der am einfachsten zu behebenden, da sie selbsterklärend ist. Hier ist ein Codeteil mit der Korrektur:

long position_type = PositionGetInteger(POSITION_TYPE);

Bei der obigen Korrektur wurde int durch long ersetzt.

Der aktuelle Quellcode unseres Trend Constraint Expert Advisors wird hier zur Verfügung gestellt, aber Sie können die Quelldatei auch in einem früheren Artikel nachlesen. Üben Sie unbedingt das Debuggen des Codes, wie wir es oben getan haben, bevor Sie die neuen Funktionen implementieren.

//+------------------------------------------------------------------+
//|                                      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 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
        {
         long 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));
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+


Die Erörterung der 7 ausgewählten, berühmten Strategien

Der Handel auf dem Forex-Markt erfordert eine Mischung aus Geschick und Strategie. Im Laufe der Jahre haben sich verschiedene Ansätze herauskristallisiert, die Händlern helfen können, ihre Erfolgschancen zu maximieren. Im Folgenden werde ich kurz auf sieben effektive Forex-Handelsstrategien eingehen, die jeweils auf grundlegenden mathematischen Prinzipien und Theorien beruhen, die von einflussreichen Wirtschaftswissenschaftlern und Händlern entwickelt wurden. Sobald die Strategie im Kopf verankert ist, wird es einfacher, die Programmierkenntnisse umzusetzen und einen Algorithmus für die Strategie zu erstellen.

(i) Trendfolge-Strategie

Die Trendfolgestrategie basiert auf den Prinzipien von Charles Dow, der Ende des 19. Jahrhunderts (1896) die Dow-Theorie formulierte. Dow vertrat die Ansicht, dass sich die Märkte in Trends bewegen und dass das Erkennen dieser Trends erhebliche Handelschancen bieten kann. In der Mathematik der Trendfolge werden häufig gleitende Durchschnitte verwendet, wobei Händler den einfachen gleitenden Durchschnitt (SMA) zur Glättung von Kursschwankungen einsetzen.

Die eigentliche Formel für den einfachen gleitenden Durchschnitt (SMA) lautet:

SMA

wobei:

  • N ist die Anzahl der Perioden (oder Datenpunkte).
  • (P_i) ist der Preis (oder Wert) in der (i-ten) Periode.

Mit dieser Formel wird der Durchschnittspreis über N Perioden berechnet. Unterstützende Forschungen, wie die Arbeiten von Richard Dennis und sein „Turtles“-Experiment in den 1980er Jahren, zeigen, dass das Verfolgen von Trends zu erheblichen Gewinnen führen kann, insbesondere in Märkten mit starken Trends.

(ii) Range Trading

Der Handel mit Handelsspannen basiert auf den Konzepten von Unterstützungs- und Widerstandsniveaus, die für die technische Analyse von entscheidender Bedeutung sind. Diese Konzepte wurden gut dokumentiert von J. Welles Wilder in seinem Buch „New Concepts in Technical Trading Systems“ (1978). Händler erkennen die Unterstützung als ein Preisniveau, bei dem das Kaufinteresse einen Rückgang verhindert, während der Widerstand einen Kursanstieg verhindert. Die mathematische Grundlage für die Berechnung von Pivot- oder Umkehr-Punkten, eine gängige Methode zur Identifizierung dieser Niveaus, ist gegeben durch:

Die eigentliche Formel für den Pivot-Punkt (PP) lautet:

Pivot-Punkt

wobei:

  • High ist der höchste Kurs des vorangegangenen Handelszeitraums.
  • Low ist der niedrigste Kurs des vorangegangenen Handelszeitraums.
  • Close ist der Schlusskurs des vorangegangenen Handelszeitraums.

Diese Formel berechnet den zentralen Drehpunkt, der in der technischen Analyse verwendet wird, um potenzielle Unterstützungs- und Widerstandsniveaus für den kommenden Handelszeitraum zu bestimmen. Untersuchungen, wie die von John Murphy in „Technical Analysis of the Financial Markets“ (1986), betonen, dass Unterstützungs- und Widerstandsniveaus oft als psychologische Indikatoren dienen, die Händlern helfen können, fundierte Entscheidungen zu treffen.

(iii) Breakout Trading

Der Breakout-Handel macht sich die Überzeugung zunutze, dass erhebliche Kursbewegungen auftreten, wenn die Kurse etablierte Unterstützungs- oder Widerstandsniveaus durchbrechen. Richard Davoud Donchian führte diese Strategie in den 1950er Jahren ein, und seine Arbeit mit Donchian-Kanälen legt den Schwerpunkt auf die Nutzung der Volatilität zur Identifizierung von Ausbruchspunkten. Händler berechnen Donchian-Kanäle anhand des höchsten Hochs (HH) und des niedrigsten Tiefs (LL) über einen bestimmten Zeitraum:

(Oberes Band = HH)

(Unteres Band = LL)

Donchian-Kanäle

Donchian Channel

Die Forschung im Bereich Behavioral Finance stützt die Idee, dass Händler aufgrund des Herdenverhaltens häufig Ausbrüchen folgen, wodurch die Dynamik in Richtung des Ausbruchs verstärkt wird. Die von Forschern wie Daniel Kahneman and Amos Tversky in ihrer 1979 veröffentlichten Arbeit „Prospect Theory: An Analysis of Decision under Risk“ zeigt auf, wie psychologische Faktoren das Handelsverhalten bei Ausbrüchen beeinflussen.

(iv) Carry Trade

Beim Carry-Trade werden die Zinsunterschiede zwischen zwei Währungen auf der Grundlage der Zinsparitätstheorie (IRP) genutzt. Dieser Grundsatz hat seine Wurzeln in den Wirtschaftstheorien, die zu Beginn des 20. Jahrhunderts formuliert wurden, vor allem von Ökonomen wie Paul Samuelson in Werken wie „Foundations of Economic Analysis“ (1947).

Die Grundformel für die Berechnung der erwarteten Rendite eines Carry Trades lautet wie folgt:

ER

wobei:

  • (i_high) und (i_low) sind die Zinssätze der Hochzins- bzw. Niedrigzinswährung.
  • (Delta S) stellt die erwartete Änderung des Wechselkurses dar. 
 Kenneth Rogoff hebt in seinem Beitrag von 1998 hervor, wie Abweichungen von der Zinsparität profitable Handelsmöglichkeiten schaffen können.

(v) Scalping

Scalping ist eine Hochfrequenzhandelsstrategie, die kleine Kursbewegungen ausnutzt und sich auf die Marktmikrostrukturtheorie (MMT) stützt. Diese Theorie hat sich durch die Arbeit verschiedener Forscher entwickelt, darunter Lawrence Harris in „Market Making and the Financial Performance of Nasdaq Firms“ (1998). Scalper führen mehrere Handelsgeschäfte innerhalb kurzer Zeiträume aus und versuchen, von winzigen Kursänderungen zu profitieren.

Zu den wichtigen Kennzahlen für „Scalper“ gehören die Geld-Brief-Spannen und die Analyse des Auftragsflusses, die häufig anhand verschiedener Kennzahlen berechnet werden:

Profit

wobei:

  • (Selling Price) ist der Preis, zu dem der Vermögenswert verkauft wird.

  • (Buying Price) ist der Preis, zu dem der Vermögenswert ursprünglich erworben wurde.

  • (Transaction Costs) sind alle mit dem Kauf- und Verkaufsprozess verbundenen Gebühren oder Kosten (z. B. Maklergebühren, Steuern).

Das Risikomanagement ist von entscheidender Bedeutung, da einige wenige ungünstige Abschlüsse zu erheblichen Verlusten führen können.

(vi) Fundamentalanalyse

Die Fundamentalanalyse umfasst die Untersuchung von Wirtschaftsindikatoren und geopolitischen Faktoren, die sich auf die Bewertung von Währungen auswirken. Dieser Ansatz, der von Benjamin Graham und David Dodd in „Security Analysis“ (1934) entwickelt wurde, betont die Bedeutung der Bewertung des inneren Wertes von Währungen. Händler nutzen verschiedene Indikatoren, wie das Wachstum des Bruttoinlandsprodukts (BIP) und die Arbeitslosenquote, um fundierte Entscheidungen zu treffen. Mathematische Techniken, wie das Kurs-Gewinn-Verhältnis (KGV) für Aktien, können ebenfalls angepasst werden;

P^E

wobei:

  • (Market Price per share) ist der aktuelle Preis einer Aktie des Unternehmens.

  • Earnings per Share (EPS) ist der Gewinn des Unternehmens, der auf jede im Umlauf befindliche Stammaktie entfällt.

Umfangreiche Untersuchungen belegen die Wirksamkeit der Fundamentalanalyse, insbesondere bei wichtigen Wirtschaftsberichten oder Ankündigungen der Zentralbanken, die oft zu erheblichen Marktbewegungen führen.


(vii) Verwendung technischer Indikatoren

Die technische Analyse, die sich auf die Ideen von Charles Dow und anderen stützt, geht davon aus, dass vergangene Kursbewegungen Aufschluss über das zukünftige Verhalten geben können. Verschiedene technische Indikatoren, wie der Relative Strength Index (RSI), werden zur Messung der Marktdynamik verwendet. Der RSI wird nach der folgenden Formel berechnet: 

RSI

wobei:

  • (RS) stellt die durchschnittlichen Gewinne und Verluste über einen bestimmten Zeitraum dar.

RS

Unterstützende Forschungen, wie die von Thomas Bulkowski in „Encyclopedia of Candlestick Charts“ (2008), zeigen, dass bestimmte Muster und Indikatoren die Handelspräzision verbessern können, indem sie es Händlern ermöglichen, Marktbewegungen auf der Grundlage historischer Kursbewegungen zu antizipieren. Jede dieser Strategien basiert auf grundlegenden Theorien, mathematischen Prinzipien und umfangreichen Forschungsergebnissen, die die Entscheidungen von Händlern auf dem Forex-Markt beeinflussen. Das Verständnis der Feinheiten dieser Strategien kann die Fähigkeit eines Händlers, sich in der Komplexität des Devisenhandels zurechtzufinden, erheblich verbessern und letztlich zu fundierteren und profitableren Handelsergebnissen führen. Durch den durchdachten Einsatz dieser Strategien können Händler einen robusten Handelsansatz entwickeln, der auf ihre individuellen Präferenzen und Risikotoleranzen zugeschnitten ist.


Einbindung einer magischen Zahl

Magische Zahlen in MQL5 dienen als zentrales organisatorisches Werkzeug, ähnlich wie eine einzigartige Signatur, die ein Expert Advisor (EA) verwendet, um seine Trades zu markieren. Stellen Sie sich das so vor, dass jeder EA seine eigene persönliche Kennung hat, die er auf jeden Handel, den er eröffnet, stempelt. Dies ist besonders nützlich bei Konten, auf denen mehrere Strategien gleichzeitig laufen, da es dem EA hilft, seine Operationen sauber von anderen zu trennen.

Wenn Sie die magische Zahl als Eingabeparameter definieren, sind Sie flexibel und können die EA-Einstellungen anpassen, ohne in den Quellcode zurückgehen zu müssen. Wenn der EA die offenen Positionen durchsucht, verwendet er diese Zahl, um schnell herauszufinden, welche Handelsgeschäfte für ihn in Frage kommen.

Die Funktion PositionGetInteger(POSITION_MAGIC) ruft die magische Zahl ab, die jedem Handelsgeschäft zugeordnet ist, sodass der EA entscheiden kann, ob er eine Position ändern, überwachen oder schließen möchte. Für einen Händler oder Entwickler bedeutet dies, dass er sich weniger Sorgen über versehentliche Interferenzen zwischen verschiedenen Strategien machen muss und die Fehlersuche einfacher ist, da jeder Handel zu seiner Ausgangsstrategie zurückverfolgt werden kann. Die Einbeziehung und effektive Verwaltung magischer Zahlen gewährleistet also, dass Ihre Handelsstrategien auf den Finanzmärkten präzise und gut organisiert bleiben.

Hier ist ein Codeschnipsel, der die Einbindung zeigt:

input int MagicNumber = 12345678; // Define a unique magic number for the EA

// Within the OnTick() or relevant function
for (int i = 0; i < PositionsTotal(); i++) {
    if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) {
        long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

        if (currentMagicNumber == MagicNumber) { // Check if the position belongs to this EA
            // Perform actions on this position, like closing or modifying
        }
    }
}

// When opening a new trade
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = price - StopLoss * _Point;
double tp = price + TakeProfit * _Point;

if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy")) {
    Print("Buy order placed with Magic Number: ", MagicNumber);
} else {
    Print("Error placing buy order: ", GetLastError());


Umsetzung der Trendfolgestrategie

Von den oben ausgewählten Strategien können die meisten nicht in unserem Programm implementiert werden, da ihnen einige Daten fehlen, die zum gegenwärtigen Zeitpunkt erforderlich sind, um sie zu nutzen. So ist z.B. der Carry Trade mit diesem Code allein nicht durchführbar, da er Zinsdifferenzen beinhaltet, und für die Fundamentalanalyse sind externe Wirtschaftsdaten erforderlich, die das BIP, die Beschäftigungsquoten usw. enthalten. Um weitere Untersuchungen in der Zukunft zu vermeiden, werden wir uns auf die praktikabelste Strategie konzentrieren.

Trendfolge ist ein Ansatz, bei dem die Richtung eines anhaltenden Markttrends ermittelt und gehandelt wird, wobei Techniken wie gleitende Durchschnitte zur Bestätigung der Trendrichtung eingesetzt werden. Unser Expertencode verwendet bereits den RSI, um überkaufte oder überverkaufte Bedingungen zu beurteilen, aber die Integration von gleitenden Durchschnitten kann den Entscheidungsprozess weiter verfeinern. Hier verwenden wir einen kurzfristigen gleitenden Durchschnitt (50-Periode) und einen langfristigen gleitenden Durchschnitt (200-Periode), um die Richtung des Trends zu bestimmen. Wenn der kurzfristige Durchschnitt den langfristigen Durchschnitt übersteigt, ist dies ein Signal für einen Aufwärtstrend; umgekehrt deutet ein Unterschreiten auf einen Abwärtstrend hin. Die Integration dieser Methode hilft bei der Bestätigung von Auf- oder Abwärtstrends und erhöht die Genauigkeit der Handelseinträge neben den RSI-Bedingungen.

 Hier ist unser Codeschnipsel zur Berechnung der gleitenden Durchschnitte vor der Integration in das Hauptprogramm.

//Calculate moving averages
double ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma_long = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE, 0);

//Determine the trend  direction
bool is_uptrend = ma_short > ma_long;
bool is_downtrend = ma_short < ma_long;

if (is_bullish && is_uptrend && rsi_value < RSI_Oversold)
{
   // Implement buy order logic here
}

if (is_bearish && is_downtrend && rsi_value > RSI_Overbought)
{
   // Implement sell order logic here
}

Um eine Trendfolgestrategie effektiv in einen bestehenden Expert Advisor (EA) einzubauen, verbessern wir zunächst die Initialisierungs- und Verarbeitungslogik innerhalb seiner Module. Beginnend mit der Funktion OnInit() führen wir die Berechnung von zwei kritischen Exponential Moving Averages (EMAs) ein, typischerweise eine 50-Periode für kurzfristige Trends und eine 200-Periode für langfristige Trends, unter Verwendung der Funktion iMA.

Im weiteren Verlauf der Methode OnTick() werden diese EMAs bei jedem neuen Markttick neu berechnet, sodass der EA die aktuelle Markttrendrichtung bestimmen kann; ein Crossover, bei dem der kurzfristige EMA über den langfristigen steigt, signalisiert einen Aufwärtstrend, während ein Crossover, bei dem er unter den langfristigen fällt, einen Abwärtstrend anzeigt.

Indem wir diese Trendsignale mit der bestehenden RSI-Analyse integrieren, schaffen wir Bedingungen, unter denen der Algorithmus Kaufaufträge während eines bestätigten Aufwärtstrends eröffnet, wenn der RSI überverkauft ist, und Verkaufsaufträge während eines Abwärtstrends, wenn der RSI überkauft ist.

Wir verwenden die Klasse CTrade für die Ausführung und legen die Parameter für Stop-Loss, Take-Profit und Trailing-Stop sorgfältig fest, um ein solides Risikomanagement zu gewährleisten. Darüber hinaus ist in derselben Schleife OnTick() ein System integriert, das bestehende Positionen im Falle einer Trendumkehr ordnungsgemäß schließt und so jeden Handel mit der verifizierten Marktrichtung in Einklang bringt. Durch diese strategischen Aktualisierungen ist der EA geschickt darauf zugeschnitten, eine Trendfolgestrategie anzuwenden, die sich nahtlos in seine aktuellen Funktionen einfügt und die allgemeine Handelseffizienz verbessert.

Hier finden Sie ein vollständig integriertes Programm:

//+------------------------------------------------------------------+
//|                                      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 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
input int    MagicNumber = 12345678;     // Magic number for this EA

// Global variables
double rsi_value;
int rsi_handle;
CTrade trade;  // Declare an instance of the CTrade class

// Variables for moving averages
double ma_short;
double ma_long;

//+------------------------------------------------------------------+
//| 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()
  {
   // Calculate moving averages
   ma_short = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
   ma_long  = iMA(_Symbol, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE);

   // Determine trend direction
   bool is_uptrend = ma_short > ma_long;
   bool is_downtrend = ma_short < ma_long;

   // 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 = 0; i < PositionsTotal(); i++) // Correct loop initialization
     {
      if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))  // Select position by symbol
        {
         long position_type = PositionGetInteger(POSITION_TYPE);
         long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);
         ulong ticket = PositionGetInteger(POSITION_TICKET);

         if (currentMagicNumber == MagicNumber) // Ensure only this EA's orders are checked
           {
            if ((position_type == POSITION_TYPE_BUY && is_downtrend) ||
                (position_type == POSITION_TYPE_SELL && is_uptrend))
              {
               trade.PositionClose(ticket);
              }
           }
        }
     }

   // Check for buy condition (uptrend + RSI oversold)
   if (is_uptrend && rsi_value < RSI_Oversold)
     {
      // No open positions? Place a buy order
      bool open_position = false;

      for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
        {
         if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))
           {
            long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

            if (currentMagicNumber == MagicNumber)
              {
               open_position = true;
               break;
              }
           }
        }

      if (!open_position)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         double sl = price - StopLoss * _Point;
         double tp = price + TakeProfit * _Point;

         // Open a buy order
         if (trade.Buy(Lots, _Symbol, price, sl, tp, "TrendFollowing Buy"))
            Print("Buy order placed with Magic Number: ", MagicNumber);
         else
            Print("Error placing buy order: ", GetLastError());
        }
     }

   // Check for sell condition (downtrend + RSI overbought)
   if (is_downtrend && rsi_value > RSI_Overbought)
     {
      // No open positions? Place a sell order
      bool open_position = false;

      for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
        {
         if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i)))
           {
            long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

            if (currentMagicNumber == MagicNumber)
              {
               open_position = true;
               break;
              }
           }
        }

      if (!open_position)
        {
         double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
         double sl = price + StopLoss * _Point;
         double tp = price - TakeProfit * _Point;

         // Open a sell order
         if (trade.Sell(Lots, _Symbol, price, sl, tp, "TrendFollowing Sell"))
            Print("Sell order placed with Magic Number: ", MagicNumber);
         else
            Print("Error placing sell order: ", GetLastError());
        }
     }

   // Apply trailing stop
   for (int i = 0; i < PositionsTotal(); i++) // Correct loop initialization
     {
      if (PositionGetSymbol(i) == _Symbol && PositionSelect(PositionGetSymbol(i))) // Select position by symbol
        {
         long currentMagicNumber = PositionGetInteger(POSITION_MAGIC);

         if (currentMagicNumber == MagicNumber) // Apply trailing stop only to this EA's positions
           {
            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));
                    }
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+


Testergebnisse

Ich habe den Expert Advisor mit dem B00M 500 Index getestet und die Aufträge beobachtet. Es gibt jedoch noch viel zu tun, um zu verhindern, dass mehrere Aufträge gleichzeitig aufgegeben werden. Die Performance eines 10.000-Dollar-Demokontos zeigt positive Ergebnisse, aber die Ergebnisse sind bei echten und kleineren Konten möglicherweise nicht die gleichen. Es ist wichtig zu wissen, dass dieses System keine Gewinne garantiert; es ist für Bildungszwecke, Experimente und Forschung gedacht.

Start des Experten

Start des Expert Advisors auf Boom 500 Index

tester

Boom 500 Index-Testergebnis 2019


Schlussfolgerung

Zusammenfassend lässt sich sagen, dass sich unsere Diskussion über den Aufbau eines Multiple Strategies Expert Advisor mit MQL5 darauf konzentrierte, die Ursprünge der wichtigsten bestehenden Strategien zu verstehen und eine Trendfolgestrategie neben Schlüsselelementen wie dem Relative Strength Index (RSI) zu integrieren. Die Trendfolgekomponente nutzt gleitende Durchschnitte, um die Richtung des Markttrends zu bestimmen, und ermöglicht es Händlern, ihre Positionen an längerfristigen Bewegungen auszurichten, die oft stabiler und potenziell profitabler sind. Durch die Verwendung dieser gleitenden Durchschnitte kann unser System Auf- und Abwärtstrends erkennen und so fundierte Handelsentscheidungen auf der Grundlage klar definierter Marktrichtungen treffen.

Die strategische Einbindung einer Trendfolgemethode ergänzt die Verwendung des RSI, der für die Erkennung überkaufter und überverkaufter Marktbedingungen unerlässlich ist. Zusammen bilden diese Komponenten einen abgerundeten Ansatz, der sowohl die Trenddynamik erfasst als auch mit dem grundlegenden Konzept der Serie, dem Trend Constraint, übereinstimmt. Eine weitere entscheidende Verbesserung, die während unserer Entwicklung vorgenommen wurde, war die Integration von magischen Zahlen - eine ursprünglich fehlende Funktion, die für ein präzises Handelsmanagement in Umgebungen mit mehreren Strategien entscheidend ist. Magische Zahlen dienen als eindeutige Identifikatoren, die dazu beitragen, Strategien voneinander zu trennen, und es den Händlern ermöglichen, jede Strategie unabhängig zu verfolgen und zu verwalten.

Von den sieben Strategien, die wir in Betracht gezogen haben, haben wir bisher nur eine umgesetzt, sodass viele potenzielle Entwicklungen noch zu erforschen sind. Kompilieren und testen Sie die beigefügte Quelldatei, um ihre Leistung zu bewerten und Ideen für die Implementierung in Ihren eigenen Projekten zu sammeln. Viel Spaß beim Handeln!

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

Beigefügte Dateien |
Datenwissenschaft und ML(Teil 30): Das Power-Paar für die Vorhersage des Aktienmarktes, Convolutional Neural Networks (CNNs) und Recurrent Neural Networks (RNNs) Datenwissenschaft und ML(Teil 30): Das Power-Paar für die Vorhersage des Aktienmarktes, Convolutional Neural Networks (CNNs) und Recurrent Neural Networks (RNNs)
In diesem Artikel untersuchen wir die dynamische Integration von Convolutional Neural Networks (CNNs) und Recurrent Neural Networks (RNNs) in der Börsenprognose. Nutzen wir die Fähigkeit von CNNs, Muster zu extrahieren, und die Fähigkeit der RNNs, sequentielle Daten zu verarbeiten. Wir wollen sehen, wie diese leistungsstarke Kombination die Genauigkeit und Effizienz von Handelsalgorithmen verbessern kann.
Vom Neuling zum Experten: Umfassende Fehlersuche in MQL5 Vom Neuling zum Experten: Umfassende Fehlersuche in MQL5
Die Problemlösung kann eine prägnante Routine für die Beherrschung komplexer Fertigkeiten, wie die Programmierung in MQL5, schaffen. Dieser Ansatz ermöglicht es Ihnen, sich auf die Lösung von Problemen zu konzentrieren und gleichzeitig Ihre Fähigkeiten zu entwickeln. Je mehr Probleme Sie lösen, desto mehr fortgeschrittenes Fachwissen erwerben Sie. Ich persönlich glaube, dass die Fehlersuche der effektivste Weg ist, das Programmieren zu beherrschen. Heute werden wir den Prozess der Codebereinigung durchgehen und die besten Techniken besprechen, um ein unordentliches Programm in ein sauberes, funktionales Programm zu verwandeln. Lesen Sie diesen Artikel und gewinnen Sie wertvolle Erkenntnisse.
Erstellen eines Expert Advisor, der Telegram integriert (Teil 7): Befehlsanalyse für die Automatisierung von Indikatoren auf Charts Erstellen eines Expert Advisor, der Telegram integriert (Teil 7): Befehlsanalyse für die Automatisierung von Indikatoren auf Charts
In diesem Artikel zeigen wir Ihnen, wie Sie Telegram-Befehle in MQL5 integrieren können, um das Hinzufügen von Indikatoren in Trading-Charts zu automatisieren. Wir behandeln den Prozess des Parsens von Nutzerbefehlen, deren Ausführung in MQL5 und das Testen des Systems, um einen reibungslosen indikatorbasierten Handel zu gewährleisten.
Neuronale Netze leicht gemacht (Teil 93): Adaptive Vorhersage im Frequenz- und Zeitbereich (letzter Teil) Neuronale Netze leicht gemacht (Teil 93): Adaptive Vorhersage im Frequenz- und Zeitbereich (letzter Teil)
In diesem Artikel setzen wir die Umsetzung der Ansätze des ATFNet-Modells fort, das die Ergebnisse von 2 Blöcken (Frequenz und Zeit) innerhalb der Zeitreihenprognose adaptiv kombiniert.