English Русский 中文 Español 日本語 Português
preview
Aufbau eines Modells von Kerzen, Trend und Nebenbedingungen (Teil 1): Für EAs und technische Indikatoren

Aufbau eines Modells von Kerzen, Trend und Nebenbedingungen (Teil 1): Für EAs und technische Indikatoren

MetaTrader 5Handel | 3 Juni 2024, 12:22
178 0
Clemence Benjamin
Clemence Benjamin

Inhalt

  1. Einführung
  2. Anatomie der Kerzen höherer Zeitrahmen
  3. Strategieentwicklung (Kreuzen gleitender Durchschnitte) plus Code
  4. Begründung der Nebenbedingung und ihrer Anwendung sowie des Codes
  5. Vorteile der Verwendung des Codes
  6. Schlussfolgerung


    Einführung

    Alternativ zur Verwendung von gleitenden Durchschnitten zur Bestimmung von Markttrends kann die auf- oder abwärts Natur von Kerzen mit höherem Zeitrahmen wertvolle Einblicke in die Marktrichtung liefern. So gibt es zum Beispiel innerhalb einer D1- oder H4-Kerze eine signifikante Aktivität, die im M1-Zeitrahmen und sogar Ticks erkennbar ist, und, die ihre Entstehung beeinflussen. Händler können sich einen Vorteil verschaffen, indem sie die Kaufgelegenheiten nutzen, die sich durch steigende D1-Kerzen ergeben, und während der Abwärtsphasen verkaufen. Die Kombination mit nativen technischen Indikatoren auf niedrigeren Zeitebenen hilft dabei, Einstiegspunkte zu finden und bietet Händlern einen strategischen Vorteil. Bei einer Aufwärts-Tageskerze sollten Händler geduldig warten, bis sich günstige Marktbedingungen einstellen, bevor sie zuversichtlich auf den Trend setzen.

    Dieser Artikel zielt darauf ab, die aktuelle Kerze mit Hilfe des MQL5-Codes als auf- oder abwärts zu klassifizieren und eine Bedingung festzulegen, nur zu verkaufen, wenn sie abwärts ist, und zu kaufen, wenn sie aufwärts ist.

    Dieses Modell zielt darauf ab, den Signalgenerator auf die Erzeugung von Signalen zu beschränken, die dem aktuellen Trend der Kerzen entsprechen. Stellen Sie sich einen Zaun vor, der bestimmten Lebewesen aufgrund ihrer Körpergröße den Zutritt zu Ihrem Garten verwehrt, während er anderen den Zutritt erlaubt. Wir wenden ein ähnliches Konzept an, um ausgewählte Signale herauszufiltern und nur die optimalsten beizubehalten. Das Modell erreicht dies, indem es die Kerzen- und Markttrends auf höheren Zeitebenen analysiert und so eine virtuelle Barriere schafft, die nur Signale durchlässt, die mit dem vorherrschenden Trend übereinstimmen. Dieser selektive Filterungsprozess erhöht die Genauigkeit und Zuverlässigkeit der generierten Signale und stellt sicher, dass dem Nutzer nur die günstigsten Handelsmöglichkeiten präsentiert werden.

    Am Ende dieses Artikels sollten Sie in der Lage sein:

    1. die Preisaktion mit der gesamten D1-Kerze auf zu Verfügung stehenden, mikroskopischen Zeitrahmen zu verstehen.
    2. einen MA Crossover-Indikator Buffer zu erstellen, der die Nebenbedingung höher Zeitrahmen enthält,
    3. das Konzept des Herausfilterns der besten Signale aus einer bestimmten Strategie zu verstehen.

    Anatomie der Kerzen höherer Zeitrahmen

    Boom 500 index, D1 Kerze anatomie M5,13.04.24

    ABBILDUNG 1.1: Die Anatomie von D1 auf dem Zeithorizont M5 für den synthetischen Boom 500 Index.

    Das obige Bild zeigt eine rote D1-Kerzenleiste ganz links und eine M5-Kursbewegung auf der rechten Seite, die zwischen den Tagesperioden-Trennzeichen liegt. Es ist ein deutlicher Abwärtstrend zu erkennen, der durch den rückläufigen Charakter der Tageskerze unterstützt wird, was auf eine höhere Wahrscheinlichkeit von Verkäufen hindeutet. Das Setup legt den Schwerpunkt auf die Ausführung von Handelsgeschäften in Übereinstimmung mit der Tageskerze, was die Entstehung einer Nebenbedingung aus der Entwicklung eines Trends auf einem höheren Zeitrahmen widerspiegelt.

    Strategieentwicklung (Kreuzen gleitender Durchschnitte)

     Die Entwicklung einer Handelsstrategie erfordert eine Kombination aus Analyse, Testen und kontinuierlicher Verfeinerung. Eine erfolgreiche Handelsstrategie sollte auf einem gründlichen Verständnis des Marktes sowie auf klaren Regeln und Leitlinien beruhen, die zu befolgen sind. Es ist wichtig, die Strategie ständig zu überwachen und anzupassen, wenn sich die Marktbedingungen ändern, um sich auf neue Trends und Möglichkeiten einzustellen. Durch die kontinuierliche Analyse von Daten, Backtests verschiedener Ansätze und Anpassungen bei Bedarf können Händler ihre Erfolgschancen auf dem Markt erhöhen.

    Bevor wir zu unserer MA-Crossover-Strategie übergehen, fassen wir im Folgenden die wichtigsten Tipps für die Strategieentwicklung zusammen:

    1. Definieren Sie Ihre Ziele und Ihre Risikotoleranz
    2. Verstehen Sie den Markt
    3. Wählen Sie Ihren Handelsstil  
    4. Eintritts- und Austrittsregeln entwickeln  
    5. Risikomanagement-Strategien umsetzen
    6. Testen Sie Ihre Strategie mit der Kurshistorie
    7. Optimieren und verfeinern
    8. Papierhandel auf einem Demokonto vor einem Echtgeldkonto
    9.  Überwachen und Auswerten
      Hier werden wir einen einfachen Indikator für die Überschreitung des gleitenden Durchschnitts entwickeln, der einen Pfeil anzeigt und eine Benachrichtigung auslöst, sobald die Überschreitung eintritt. Im Folgenden sind die Schritte für unsere Strategieentwicklungskriterien aufgeführt.
      1. Legen Sie die Bedingungen der Strategie fest (in diesem Fall Kreuzung des EMA7 über oder unter dem EMA21).
      2. Legen Sie den Anzeigestil für den Indikator fest, der ein Pfeil oder eine beliebige geometrische Form sein kann, die in MetaTrader 5 verfügbar ist.
      3. (Optional) wenn der Indikator vom Nutzer angepasst werden kann, setzen Sie die Eingaben.

      Ich habe mich entschlossen, den endgültigen Code hier ohne große Erklärungen einzufügen, um mich auf den Algorithmus der Nebenbedingungen, unser Hauptthema in diesem Artikel, zu konzentrieren. Das folgende Programm ist bereit, Kauf- und Verkaufssignale zu kompilieren und zu generieren. Nach dem Code werden wir die Ergebnisse auf dem mt5-Chart analysieren und das Problem identifizieren, das der Constraint-Algorithmus beheben wird.

      //Indicator Name: Trend Constraint
      #property copyright "Clemence Benjamin"
      #property link      "https://mql5.com"
      #property version   "1.00"
      #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
      
      //--- indicator settings
      #property indicator_chart_window
      #property indicator_buffers 2
      #property indicator_plots 2
      
      #property indicator_type1 DRAW_ARROW
      #property indicator_width1 5
      #property indicator_color1 0xFFAA00
      #property indicator_label1 "Buy"
      
      #property indicator_type2 DRAW_ARROW
      #property indicator_width2 5
      #property indicator_color2 0x0000FF
      #property indicator_label2 "Sell"
      
      #define PLOT_MAXIMUM_BARS_BACK 5000
      #define OMIT_OLDEST_BARS 50
      
      //--- indicator buffers
      double Buffer1[];
      double Buffer2[];
      
      double myPoint; //initialized in OnInit
      int MA_handle;
      double MA[];
      int MA_handle2;
      double MA2[];
      double Low[];
      double High[];
      
      void myAlert(string type, string message)
        {
         if(type == "print")
            Print(message);
         else if(type == "error")
           {
            Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
           }
         else if(type == "order")
           {
           }
         else if(type == "modify")
           {
           }
        }
      
      // Custom indicator initialization function                         
      int OnInit()
        {   
         SetIndexBuffer(0, Buffer1);
         PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(0, PLOT_ARROW, 241);
         SetIndexBuffer(1, Buffer2);
         PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(1, PLOT_ARROW, 242);
         //initialize myPoint
         myPoint = Point();
         if(Digits() == 5 || Digits() == 3)
           {
            myPoint *= 10;
           }
         MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle < 0)
           {
            Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle2 < 0)
           {
            Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         return(INIT_SUCCEEDED);
        }
      
      //Custom indicator iteration function                              
      int OnCalculate(const int rates_total,
                      const int prev_calculated,
                      const datetime& time[],
                      const double& open[],
                      const double& high[],
                      const double& low[],
                      const double& close[],
                      const long& tick_volume[],
                      const long& volume[],
                      const int& spread[])
        {
         int limit = rates_total - prev_calculated;
         //--- counting from 0 to rates_total
         ArraySetAsSeries(Buffer1, true);
         ArraySetAsSeries(Buffer2, true);
         //--- initial zero
         if(prev_calculated < 1)
           {
            ArrayInitialize(Buffer1, EMPTY_VALUE);
            ArrayInitialize(Buffer2, EMPTY_VALUE);
           }
         else
            limit++;
         
         if(BarsCalculated(MA_handle) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
         ArraySetAsSeries(MA, true);
         if(BarsCalculated(MA_handle2) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
         ArraySetAsSeries(MA2, true);
         if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
         ArraySetAsSeries(Low, true);
         if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
         ArraySetAsSeries(High, true);
         //--- main loop
         for(int i = limit-1; i >= 0; i--)
           {
            if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
            
            //Indicator Buffer 1
            if(MA[i] > MA2[i]
            && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
            )
              {
               Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
              }
            else
              {
               Buffer1[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 2
            if(MA[i] < MA2[i]
            && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
            )
              {
               Buffer2[i] = High[i]; //Set indicator value at Candlestick High
              }
            else
              {
               Buffer2[i] = EMPTY_VALUE;
              }
           }
         return(rates_total);
        }
      //copy the code to meta editor to compile it

        Am 24.04.12 zeigt das Chart der EURUSD-Testergebnisse den Beginn einer Periode an, die auf dem M1-Zeitrahmen beobachtet wird. Die Überkreuzungen sind durch Pfeile gekennzeichnet, die ihre Position angeben - rot für Verkaufssignale und blau für Käufe. Dennoch zeigt sich bei einer breiteren Betrachtung ein deutlicher Abwärtstrend, der auf eine fallende D1-Kerze hindeutet. Das Kreuzen der Indikatoren gibt beide Signale aus und ignoriert dabei den vorherrschenden Trend, was ein erhebliches Problem darstellt. Die widersprüchlichen Signale schaffen ein schwieriges Szenario für Händler, die versuchen, sich auf dem Markt zurechtzufinden. Während die M1-Zeitrahmen auf potenzielle kurzfristige Gelegenheiten hindeuten, gibt der übergreifende Abwärtstrend der D1-Kerze Anlass zu Bedenken hinsichtlich der Nachhaltigkeit etwaiger Aufwärtsbewegungen. In diesem Artikel werden wir dieses Problem angehen, indem wir unsere Signale auf den D1-Trend beschränken.

        Kreuzungs-Signale der gleitende Durchschnitte

        ABBILDUNG 1.2 : Testergebnis des MA-Crossover-Indikators vor der Nebenbedingung

        Die D1-Kerze ist fallend, wobei sowohl Kauf- als auch Verkaufspfeile durch die MA-Crossover-Bedingung erzeugt werden. Viele Signale werden als falsch oder außerhalb des Trends angesehen, was durch die Einbeziehung der Trendbeschränkung des höheren Zeitrahmens korrigiert werden kann. Die nachstehende Tabelle wurde anhand der Chartdaten vom Tagesbeginn bis zum Tagesabschluss erstellt. 

        Signalart Einheiten
        Verkaufssignale 29
        Kaufsignale 28
        Gesamt 57
        Falsche Trendsignale 41
        Erfolgreiche Signale 25


        Begründung der Nebenbedingung und ihrer Anwendung

        Stellen Sie sich eine Mischung aus Maiskörnern und Hirse vor, von denen das eine gröber ist als das andere. Um sie zu sortieren, verwenden wir ein Sieb. Dadurch werden die Maiskörner einbehalten, sodass nur die Hirse durchgesiebt werden kann, was eine gewisse Kontrolle ermöglicht. Diese Analogie steht im Einklang mit dem Konzept des hier untersuchten höheren Zeitrahmens. Er wirkt wie ein Filter, der bestimmte Signale herausfiltert und nur diejenigen zurückhält, die mit dem vorherrschenden Trend übereinstimmen. Die Beschränkung auf einen höheren Zeitrahmen, ähnlich wie ein Sieb, verfeinert unseren Fokus und ermöglicht es uns, die wesentlichen Elemente der Marktentwicklung zu erkennen. Indem wir das Rauschen durchforsten, können wir die zugrunde liegende Dynamik besser erfassen, was eine fundiertere Entscheidungsfindung erleichtert. Dieser strategische Ansatz verbessert unsere Fähigkeit, durch die Komplexität der Finanzlandschaft zu navigieren, und stellt sicher, dass wir uns an der übergeordneten Richtung orientieren, ähnlich wie die Hirse, die sich vom Maiskorn trennt und die wahre Essenz der Marktbewegung offenbart.

        Definition der Art der D1-Kerze als Nebenbedingung für die Trend-Nebenbedingung, die wir zuvor kodiert haben.
        • Ich habe meine aktuelle Markteinschätzung als auf- oder abwärts definiert, indem ich den Schlusskurs des Vortages, der dem Eröffnungskurs des aktuellen Tages ähnelt, mit den Schlusskursen der M1-Kerzen des unteren Zeitrahmens verglichen habe.
        • Für eine AUFWÄRTS-Kerze:

          Schluss der vorherigen M1-Kerze >= Schluss der vorherigen D1-Kerze

          Für eine ABWÄRTS-Kerze:

          Schluss der vorherigen M1-Kerze <= Schluss der vorherigen D1-Kerze

          Die Mathematik legt nahe, dass wir bei einer Aufwärts-D1-Kerze als Trendtreiber nur Kaufsignale erhalten und bei einer Abwärts-D1-Kerze das Gegenteil der Fall ist.

          Wir haben uns für den Schluss des unteren Zeitrahmens als Vergleichspunkt zu unserer D1-Eröffnung entschieden, anstatt andere Aspekte wie den Geld- und Briefkurs oder den Schluss des aktuellen Tages zu verwenden, da letzterer keine Pfeile auf dem Chart zeigt, wie es bei dieser Strategie und diesem Indikatorstil gewünscht ist. Wenn wir uns also auf den Schlusskurs des unteren Zeitrahmens im Verhältnis zu unserem D1-Eröffnungskurs konzentrieren, können wir unsere Strategie effektiv mit den gewünschten visuellen Hinweisen und Indikatoren auf dem Chart abstimmen. Dieser Ansatz sorgt für mehr Klarheit und Präzision bei unseren Handelsentscheidungen und gewährleistet einen strafferen und effizienteren Analyseprozess.  

        • Schauen wir uns den Code an. Der Code ist gut strukturiert und leicht zu verstehen.
         if(Close[1+barshift_M1[i]] >= Open[1+barshift_D1[i]] //Candlestick Close >= Candlestick Open
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }

        Der obige Code stellt die Bedingung für eine Aufwärts-D1-Kerze dar. Denken Sie daran, dass das Umgekehrte auch für fallende Kurse gilt.

        • Abschließend stelle ich den endgültigen Code vor, bei dem die Beschränkung nahtlos in den Indikator für den gleitenden Durchschnittsübergang integriert ist.
        /Indicator Name: Trend Constraint
        #property copyright "Clemence Benjamin"
        #property link      "https://mql5.com"
        #property version   "1.00"
        #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
        
        //--- indicator settings
        #property indicator_chart_window
        #property indicator_buffers 2
        #property indicator_plots 2
        
        #property indicator_type1 DRAW_ARROW
        #property indicator_width1 5/
        #property indicator_color1 0xFFAA00
        #property indicator_label1 "Buy"
        
        #property indicator_type2 DRAW_ARROW
        #property indicator_width2 5
        #property indicator_color2 0x0000FF
        #property indicator_label2 "Sell"
        
        #define PLOT_MAXIMUM_BARS_BACK 5000
        #define OMIT_OLDEST_BARS 50
        
        //--- indicator buffers
        double Buffer1[];
        double Buffer2[];
        
        double myPoint; //initialized in OnInit
        int MA_handle;
        double MA[];
        int MA_handle2;
        double MA2[];
        double Close[];
        double Close2[];
        double Low[];
        double High[];
        
        void myAlert(string type, string message)
          {
           if(type == "print")
              Print(message);
           else if(type == "error")
             {
              Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
             }
           else if(type == "order")
             {
             }
           else if(type == "modify")
             {
             }
          }
        
        // Custom indicator initialization function                         
        int OnInit()
          {   
           SetIndexBuffer(0, Buffer1);
           PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(0, PLOT_ARROW, 241);
           SetIndexBuffer(1, Buffer2);
           PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(1, PLOT_ARROW, 242);
           //initialize myPoint
           myPoint = Point();
           if(Digits() == 5 || Digits() == 3)
             {
              myPoint *= 10;
             }
           MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle < 0)
             {
              Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle2 < 0)
             {
              Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           return(INIT_SUCCEEDED);
          }
        
        // Custom indicator iteration function                              
        int OnCalculate(const int rates_total,
                        const int prev_calculated,
                        const datetime& time[],
                        const double& open[],
                        const double& high[],
                        const double& low[],
                        const double& close[],
                        const long& tick_volume[],
                        const long& volume[],
                        const int& spread[])
          {
           int limit = rates_total - prev_calculated;
           //--- counting from 0 to rates_total
           ArraySetAsSeries(Buffer1, true);
           ArraySetAsSeries(Buffer2, true);
           //--- initial zero
           if(prev_calculated < 1)
             {
              ArrayInitialize(Buffer1, EMPTY_VALUE);
              ArrayInitialize(Buffer2, EMPTY_VALUE);
             }
           else
              limit++;
           
           datetime TimeShift[];
           if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total);
           ArraySetAsSeries(TimeShift, true);
           int barshift_M1[];
           ArrayResize(barshift_M1, rates_total);
           int barshift_D1[];
           ArrayResize(barshift_D1, rates_total);
           for(int i = 0; i < rates_total; i++)
             {
              barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]);
              barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]);
           }
           if(BarsCalculated(MA_handle) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
           ArraySetAsSeries(MA, true);
           if(BarsCalculated(MA_handle2) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
           ArraySetAsSeries(MA2, true);
           if(CopyClose(Symbol(), PERIOD_M1, 0, rates_total, Close) <= 0) return(rates_total);
           ArraySetAsSeries(Close, true);
           if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close2) <= 0) return(rates_total);
           ArraySetAsSeries(Close2, true);
           if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
           ArraySetAsSeries(Low, true);
           if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
           ArraySetAsSeries(High, true);
           //--- main loop
           for(int i = limit-1; i >= 0; i--)
             {
              if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
              
              if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue;
              if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue;
              
              //Indicator Buffer 1
              if(MA[i] > MA2[i]
              && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
              && Close[1+barshift_M1[i]] >= Close2[1+barshift_D1[i]] //Candlestick Close >= Candlestick Close
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }
              //Indicator Buffer 2
              if(MA[i] < MA2[i]
              && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
              && Close[1+barshift_M1[i]] <= Close2[1+barshift_D1[i]] //Candlestick Close <= Candlestick Close
              )
                {
                 Buffer2[i] = High[i]; //Set indicator value at Candlestick High
                }
              else
                {
                 Buffer2[i] = EMPTY_VALUE;
                }
             }
           return(rates_total);
          }

        Das Ergebnis des obigen Codes ist hervorragend. Bitte beachten Sie das nachstehende Bild.

        Trend-Nebenbedingung mit kreuzenden Gleitenden Durchschnitten

        ABBILDUNG 1.4: Angewendete Trend-Nebenbedingung mit einem erstaunlichen Ergebnis

        Signalart Einheiten
        Verkaufssignal 27
        Kaufsignal 1
        Gesamt 28
        Falsche Trendsignale 3
        Erfolgreiche Signale 25

        Aus der obigen Tabelle ist ersichtlich, dass die Trend-Nebenbedingung mit höherem Zeitrahmen als Filter eine positive Wirkung hat und zu mehr Gewinn statt Verlust führt, was ihn ideal für EAs macht. Vergleicht man die vorherige und die aktuelle Ergebnistabelle, so stellt man fest, dass die erfolgreichen Signale ihren Wert beibehalten haben, während alle falschen Signale reduziert wurden. Diese Verbesserung der Signalgenauigkeit deutet auf einen positiven Trend in unserer Datenanalysemethode hin. Durch die Verfeinerung unserer Algorithmen und Kriterien haben wir das Auftreten von Fehlsignalen wirksam minimiert und die Zuverlässigkeit unserer Ergebnisse insgesamt erhöht. In Zukunft werden diese Fortschritte zweifellos zu einer fundierteren Entscheidungsfindung und zu besseren Ergebnissen in unseren Strategien beitragen.


        Die Vorteile der Verwendung des Codes

        Die Vorteile, die sich aus der Beschränkung auf Trends mit größerem Zeithorizont ergeben, verbessern die Klarheit der Marktrichtung, verringern die Tendenz zu Übertreibungen und fördern einen disziplinierteren Ansatz bei Handelsentscheidungen. Diese Methode kann auch eine breitere Perspektive bieten, die es den Händlern ermöglicht, sich nicht von kurzfristigen Schwankungen leiten zu lassen und ihre Strategien auf den vorherrschenden langfristigen Trend abzustimmen. Indem sie sich auf das Gesamtbild konzentrieren, sind Händler besser in der Lage, Störfaktoren herauszufiltern und fundiertere Entscheidungen auf der Grundlage des zugrunde liegenden Trends zu treffen. Dieser Ansatz fördert die Geduld und ein tieferes Verständnis der Marktdynamik, was letztlich zu beständigeren und profitableren Handelsergebnissen führt. Darüber hinaus können Beschränkungen für Trends in größeren Zeiträumen als wertvolle Instrumente für das Risikomanagement dienen, die es Händlern ermöglichen, auf der Grundlage einer strategischen Einschätzung der Marktbedingungen klare Einstiegs- und Ausstiegspunkte festzulegen.

        Zusammengefasst,

        • Verbesserte Genauigkeit der signalgebenden Indikatoren
        • Besseres Risikomanagement
        • Gesteigerte Rentabilität
        • Weniger Arbeit
        • Weniger Signale


        Schlussfolgerung

        Kerzen mit höherem Zeitrahmen üben einen bedeutenden Einfluss auf die Trends mit niedrigerem Zeitrahmen aus, unabhängig davon, ob es sich um Aufwärts- oder Abwärtstrends handelt, und steuern im Wesentlichen die Märkte. Auf der Grundlage verschiedener Studien ist es ratsam, bei steigenden Tageskerzen auf niedrigeren Zeitebenen zu kaufen und bei fallenden Kerzen zu verkaufen. Für mich persönlich könnte die Einbeziehung des Konzepts der Trendbeschränkungen für größere Zeiträume, wie dieses, bei der Entwicklung von EA und Indikatoren für nachhaltige positive Ergebnisse entscheidend sein. Es stellt sich die Frage: Sollen wir nun gleitende Durchschnitte als Trendbestimmungsinstrumente verwerfen? Vielleicht wird der nächste Artikel mehr Licht in diese Angelegenheit bringen, wenn wir uns eingehender mit der Verfeinerung und Weiterentwicklung dieses Konzepts beschäftigen. Im Anhang finden Sie die Quellcode-Dateien, die Sie im Meta-Editor und die Ex5-Dateien in der MetaTrader 5-Plattform anzeigen können.


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

        Lernen Sie Schritt für Schritt, wie Sie die Fair Value Gap (FVG)/Ungleichgewichte handeln können: Ein Ansatz des Smart Money-Konzepts Lernen Sie Schritt für Schritt, wie Sie die Fair Value Gap (FVG)/Ungleichgewichte handeln können: Ein Ansatz des Smart Money-Konzepts
        Eine Schritt-für-Schritt-Anleitung zur Erstellung und Implementierung eines automatisierten Handelsalgorithmus in MQL5 auf der Grundlage der Handelsstrategie Fair Value Gap (FVG). Eine detaillierte Anleitung zur Erstellung eines Expertenberaters, die sowohl für Anfänger als auch für erfahrene Händler nützlich sein kann.
        Entwicklung eines MQTT-Clients für MetaTrader 5: ein TDD-Ansatz — Finale Entwicklung eines MQTT-Clients für MetaTrader 5: ein TDD-Ansatz — Finale
        Dieser Artikel ist der letzte Teil einer Serie, die unsere Entwicklungsschritte für einen nativen MQL5-Client für das MQTT 5.0-Protokoll beschreibt. Obwohl die Bibliothek noch nicht produktionsreif ist, werden wir in diesem Teil unseren Client verwenden, um ein nutzerdefiniertes Symbol mit Ticks (oder Kursen) zu aktualisieren, die von einem anderen Broker stammen. Am Ende dieses Artikels finden Sie weitere Informationen über den aktuellen Status der Bibliothek, was ihr noch fehlt, um vollständig mit dem MQTT 5.0-Protokoll kompatibel zu sein, eine mögliche Roadmap und wie Sie die Entwicklung verfolgen und zu ihr beitragen können.
        Nutzerdefinierte Indikatoren (Teil 1): Eine schrittweise Einführung in die Entwicklung von einfachen nutzerdefinierten Indikatoren in MQL5 Nutzerdefinierte Indikatoren (Teil 1): Eine schrittweise Einführung in die Entwicklung von einfachen nutzerdefinierten Indikatoren in MQL5
        Erfahren Sie, wie Sie mit MQL5 nutzerdefinierte Indikatoren erstellen können. Dieser Einführungsartikel führt Sie durch die Grundlagen des Aufbaus einfacher nutzerdefinierter Indikatoren und demonstriert einen praktischen Ansatz zur Codierung verschiedener nutzerdefinierter Indikatoren für alle MQL5-Programmierer, die neu in diesem interessanten Thema sind.
        MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 15): Support-Vektor-Maschinen mit dem Newtonschen Polynom MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 15): Support-Vektor-Maschinen mit dem Newtonschen Polynom
        Support-Vektor-Maschinen klassifizieren Daten auf der Grundlage vordefinierter Klassen, indem sie die Auswirkungen einer Erhöhung der Dimensionalität untersuchen. Es handelt sich um eine überwachte Lernmethode, die angesichts ihres Potenzials, mit mehrdimensionalen Daten umzugehen, ziemlich komplex ist. In diesem Artikel wird untersucht, wie die sehr einfache Implementierung von 2-dimensionalen Daten mit dem Newton'schen Polynom bei der Klassifizierung von Preis-Aktionen effizienter durchgeführt werden kann.