English
preview
Aufbau des Kerzenmodells Trend-Constraint (Teil 4): Anpassen des Anzeigestils für jede Trendwelle

Aufbau des Kerzenmodells Trend-Constraint (Teil 4): Anpassen des Anzeigestils für jede Trendwelle

MetaTrader 5Handelssysteme | 1 Juli 2024, 15:00
126 0
Clemence Benjamin
Clemence Benjamin

Inhalt


Einführung

Nutzerdefinierte Zeichenstile können die visuelle Reiz von Charts verbessern, sodass sie ansprechender und leichter zu lesen sind. Ein gut gestalteter Chart kann die Nutzererfahrung verbessern und die Belastung der Augen bei langen Handelssitzungen verringern. Durch die Anpassung des Zeichenstils an spezifische Bedürfnisse können Händler effizientere und effektivere Handels-Setups erstellen. Die Verwendung von Histogrammen zur Darstellung von Volumendaten oder Linien für gleitende Durchschnitte kann beispielsweise die Interpretation dieser Indikatoren auf einen Blick erleichtern. Zeichenstile wie Pfeile oder Symbole können verwendet werden, um bestimmte Ereignisse oder Signale auf dem Chart zu markieren, z. B. Kauf-/Verkaufspunkte, was das Erkennen von Handelsmöglichkeiten erleichtert.

MQL5 bietet eine Vielzahl von Zeichenstilen für Indikatoren auf MetaTrader 5. Diese visuellen Elemente bieten Händlern einen analytischen Vorteil, wenn sie auf dem MetaTrader 5-Chart dargestellt werden, und helfen bei der schnellen Anpassung an die Marktstimmung. Die Einbeziehung dieser verschiedenen Zeichenstile verbessert nicht nur die Ästhetik der Charts, sondern ermöglicht es den Händlern auch, fundierte Entscheidungen auf der Grundlage einer umfassenden Analyse der Marktdynamik zu treffen. Händler können Kursbewegungen effektiv interpretieren, Trends erkennen und mögliche Umschwünge präziser vorhersehen. MQL5 ist reich an 18 Arten von grafischen Darstellungen. In diesem Artikel wollen wir tiefer einsteigen und untersuchen, wie wir einen dieser Anzeigestile in unser Modell implementieren können.

Anstatt nur einen Pfeil für unsere Warnung zu zeichnen, wollen wir eine fortschrittlichere Grafik auf dem Chart erstellen, um es noch einfacher zu machen. Denken Sie daran, dass unser Ziel in dieser Serie darin besteht, unser Modell „Trend Constraint“ so zu verfeinern, dass es dem Sentiment unserer D1-Kerzenform entspricht und ein umfassendes visuelles Signal im Chart darstellt. MQL5-Zeichenstile können in Bezug auf Farbe, Dicke und Stil (z. B. gestrichelte oder durchgezogene Linien) angepasst werden, was den Händlern hilft, ihre Charts entsprechend ihren Vorlieben zu personalisieren und die Lesbarkeit zu verbessern.  Verschiedene Zeichenstile ermöglichen es den Händlern, Daten klarer und präziser darzustellen. Die Verwendung von Linien, Histogrammen oder Kerzen kann beispielsweise die Interpretation von Kursbewegungen und Markttrends erleichtern.

    Die verschiedenen in MQL5 verfügbaren Zeichenstile bieten Händlern zahlreiche Vorteile. Sie dienen dazu, die Klarheit, Präzision und Anpassbarkeit der Datenvisualisierung zu verbessern. Diese verschiedenen Stile erweitern die Möglichkeiten der technischen Analyse, ermöglichen den Einsatz fortschrittlicher Charttechniken und erleichtern dynamische Echtzeit-Updates. Darüber hinaus ermöglichen die Anpassungsfähigkeit und der Einfallsreichtum der MQL5-Zeichenstile den Händlern, einzigartige Indikatoren und Analyseinstrumente zu entwickeln und so ihre Handelsstrategien und ihr Verständnis der Marktlandschaft zu erweitern. Ein umfassendes Verständnis dieses Themas finden Sie in der MQL5-Referenz, in der Sie sich eingehend mit den Zeichenstilen beschäftigen.


    Wiederholung

    In den vorangegangenen Artikeln dieser Serie (Teil 1, Teil 2 und Teil 3) bestand das Ziel darin, jedes Signal auf das Sentiment der D1-Kerze zu beschränken. Das Konzept besteht darin, dass, wenn die D1-Kerze steigt (close>open) ist, der Gesamttrend des Tages in den niedrigeren Zeitrahmen in der Regel aufwärts gerichtet ist. Durch den Einsatz fortschrittlicher Analysemethoden auf niedrigeren Zeitebenen können wir Einstiegspunkte identifizieren und Signale generieren, die mit dem aktuellen Trend übereinstimmen. In jeder Phase haben wir unseren Quellcode verbessert, neue Funktionen integriert und unser Modell weiterentwickelt. In der Artikelserie haben wir Pfeile als Designelement für jede Iteration unseres Indikators verwendet und die Verwendung der Schriftart Wingdings für optionale Anzeigeelemente erforscht.

    Wir haben 200 und 100 gleitende Durchschnitte zu einem Handelsinstrument auf dem MQL5-Chart hinzugefügt, um eine Strategie zu entwickeln. Durch die Analyse des Verhaltens dieser eingebauten Indikatoren konnten wir ein signifikantes, periodisches Kreuzen feststellen. Daraufhin wurde ein personalisierter Indikator mit einem Alarmsystem entwickelt, der uns auf solche Ereignisse hinweist und eine mögliche Trendumkehr anzeigt. Die Anpassung der MA-Werte auf höhere Werte kann dazu beitragen, Signale bei Marktschwankungen herauszufiltern. In Teil 3 habe ich den Ansatz weiter verfeinert, indem ich eine anpassbare MA-Periodeneingabe eingeführt habe, um verschiedene Periodenwerte zu untersuchen und das optimale Setup für Trendumkehrungen zu bestimmen.

    input int Slow_MA_period = 200;
    input int Fast_MA_period = 100;

    Die Software bietet die Möglichkeit zur sofortigen Anpassung der in der visuellen Darstellung angezeigten Eingabekonfigurationen. Um seine Attribute zu ändern, verwenden Sie entweder die Tastenkombination Strg + I, während Sie den MetaTrader 5-Chart betrachten, oder klicken Sie einfach mit der rechten Maustaste, um das Indikatormenü aufzurufen, und wählen Sie Trend Constraint V1.03.

    Optimierung der MA für Trendumkehrungen

     Abb. 1: Optimierung der MA-Periode für beste Trendumkehr-Einstellungen.

    Nachdem Sie das Programm unter Verwendung dieser Eingabekonfigurationen kompiliert haben, finden Sie das Quelldokument direkt am Ende dieses Artikels. Im Folgenden finden Sie den neuesten Code für Trend Constraint V1.03:

    /// Program after adding Moving Average optimization feature for reversals
    ///Indicator Name: Trend Constraint
    #property copyright "Clemence Benjamin"
    #property link      "https://mql5.com"
    #property version   "1.03"
    #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 4
    #property indicator_plots 4
    
    #property indicator_type1 DRAW_ARROW
    #property indicator_width1 5
    #property indicator_color1 0xFF3C00
    #property indicator_label1 "Buy"
    
    #property indicator_type2 DRAW_ARROW
    #property indicator_width2 5
    #property indicator_color2 0x0000FF
    #property indicator_label2 "Sell"
    
    #property indicator_type3 DRAW_ARROW
    #property indicator_width3 1
    #property indicator_color3 0x04CC04
    #property indicator_label3 "Buy Reversal"
    
    #property indicator_type4 DRAW_ARROW
    #property indicator_width4 1
    #property indicator_color4 0xE81AC6
    #property indicator_label4 "Sell Reversal"
    
    #define PLOT_MAXIMUM_BARS_BACK 5000
    #define OMIT_OLDEST_BARS 50
    
    //--- indicator buffers
    double Buffer1[];
    double Buffer2[];
    double Buffer3[];
    double Buffer4[];
    
    input double Oversold = 30;
    input double Overbought = 70;
    input int Slow_MA_period = 200;
    input int Fast_MA_period = 100;
    datetime time_alert; //used when sending alert
    input bool Audible_Alerts = true;
    input bool Push_Notifications = true;
    double myPoint; //initialized in OnInit
    int RSI_handle;
    double RSI[];
    double Open[];
    double Close[];
    int MA_handle;
    double MA[];
    int MA_handle2;
    double MA2[];
    int MA_handle3;
    double MA3[];
    int MA_handle4;
    double MA4[];
    double Low[];
    double High[];
    
    void myAlert(string type, string message)
      {
       if(type == "print")
          Print(message);
       else if(type == "error")
         {
          Print(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
         }
       else if(type == "order")
         {
         }
       else if(type == "modify")
         {
         }
       else if(type == "indicator")
         {
          if(Audible_Alerts) Alert(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
          if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
         }
      }
    
    //+------------------------------------------------------------------+
    //| 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);
       SetIndexBuffer(2, Buffer3);
       PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       PlotIndexSetInteger(2, PLOT_ARROW, 236);
       SetIndexBuffer(3, Buffer4);
       PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       PlotIndexSetInteger(3, PLOT_ARROW, 238);
       //initialize myPoint
       myPoint = Point();
       if(Digits() == 5 || Digits() == 3)
         {
          myPoint *= 10;
         }
       RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
       if(RSI_handle < 0)
         {
          Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, 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, 400, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle2 < 0)
         {
          Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle3 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_EMA, PRICE_CLOSE);
       if(MA_handle3 < 0)
         {
          Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle4 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle4 < 0)
         {
          Print("The creation of iMA has failed: MA_handle4=", 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);
       ArraySetAsSeries(Buffer3, true);
       ArraySetAsSeries(Buffer4, true);
       //--- initial zero
       if(prev_calculated < 1)
         {
          ArrayInitialize(Buffer1, EMPTY_VALUE);
          ArrayInitialize(Buffer2, EMPTY_VALUE);
          ArrayInitialize(Buffer3, EMPTY_VALUE);
          ArrayInitialize(Buffer4, EMPTY_VALUE);
         }
       else
          limit++;
       datetime Time[];
       
       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(RSI_handle) <= 0) 
          return(0);
       if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
       ArraySetAsSeries(RSI, true);
       if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total);
       ArraySetAsSeries(Open, true);
       if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total);
       ArraySetAsSeries(Close, true);
       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(BarsCalculated(MA_handle3) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
       ArraySetAsSeries(MA3, true);
       if(BarsCalculated(MA_handle4) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total);
       ArraySetAsSeries(MA4, 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);
       if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
       ArraySetAsSeries(Time, 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(RSI[i] < Oversold
          && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value
          && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close
          && MA[i] > MA2[i] //Moving Average > Moving Average
          && MA3[i] > MA4[i] //Moving Average > Moving Average
          )
            {
             Buffer1[i] = Low[1+i]; //Set indicator value at Candlestick Low
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer1[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 2
          if(RSI[i] > Overbought
          && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value
          && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close
          && MA[i] < MA2[i] //Moving Average < Moving Average
          && MA3[i] < MA4[i] //Moving Average < Moving Average
          )
            {
             Buffer2[i] = High[1+i]; //Set indicator value at Candlestick High
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer2[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 3
          if(MA3[i] > MA4[i]
          && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average
          )
            {
             Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer3[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 4
          if(MA3[i] < MA4[i]
          && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average
          )
            {
             Buffer4[i] = High[i]; //Set indicator value at Candlestick High
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer4[i] = EMPTY_VALUE;
            }
         }
       return(rates_total);
      }
    //Thank you, friend. You have reached this stage and you can do more+


    MQL5 Darstellungsarten

    MQL5 bietet eine breite Palette von Zeichenstilen für Indikatoren. Bei der Entwicklung von Indikatoren besteht das Hauptziel in der Regel darin, Systeme zu entwickeln, die die Nutzer sowohl durch akustische als auch durch visuelle Hinweise informieren können. Dies trägt zur Rationalisierung der Handelsabläufe bei, da die Händler nicht mehr ständig die Charts beobachten müssen, da der Computer diese Aufgabe übernimmt. Ich möchte Ihnen einen kurzen Überblick über einige Zeichenstile geben, die in MQL5 verwendet werden können, wie DRAW_ARROW, DRAW_LINE, DRAW_HISTOGRAM, DRAW_FILLING und DRAW_NONE. Die nachstehende Tabelle enthält eine kurze Zusammenfassung. Detaillierte Informationen über Zeichenstile finden Sie in der MQL5-Referenz

    ZEICHENSTIL BESCHREIBUNG
    DRAW_ARROW Zeichnet Pfeile an bestimmten Punkten. Wird häufig verwendet, um Kauf-/Verkaufssignale oder andere wichtige Ereignisse hervorzuheben.
    DRAW_LINE Wird verwendet, um eine Linie zu zeichnen, die Datenpunkte verbindet. Ideal für gleitende Durchschnitte, Trendlinien und andere linienbasierte Indikatoren.
    DRAW_HISTOGRAM Zeigt Daten als Balken oder Histogramme an. Nützlich für Volumen, MACD-Histogramme und andere balkenartige Indikatoren.
    DRAW_FILLING Wird verwendet, um den Bereich zwischen zwei Linien in einem Chart zu füllen, und bietet eine visuell intuitive Möglichkeit, Datenbereiche, Streuung oder Unterschiede zwischen zwei Indikatoren darzustellen.
    DRAW_NONE Wird verwendet, um einen Indikator zu definieren, der keine visuelle Darstellung auf dem Chart zeichnet.


    Implementierung des Stils DRAW_LINE in unserem System

    Nutzen wir die Funktion DRAW_LINE, um unsere Trends auf dem MetaTrader 5-Chart auf besondere Weise darzustellen. In der Vergangenheit ist es uns gelungen, unseren Indikator so einzurichten, dass er Trendumkehrungen durch das Kreuzen von gleitenden Durchschnitten höherer Perioden erkennt. Unser Ziel ist es nun, die visuelle Darstellung von Informationen zu verbessern, ohne das Chart mit zu vielen Elementen zu überfrachten. Diese neue Ergänzung wird es uns ermöglichen, eine einzige Linie zu entwerfen, die Trends aufzeigt und ihre Farbe automatisch mit jeder neuen Richtung ändert. Mit unseren derzeitigen 4 Puffern wollen wir unsere Möglichkeiten durch die Einführung von Puffer 5 und Puffer 6 für Version 1.04 erweitern.

    • Puffer 5 : So zeichnen wir eine blaue Linie, wenn der MA 100 über dem MA 200 liegt
    ///properties
    #property indicator_type5 DRAW_LINE
    #property indicator_style5 STYLE_SOLID
    #property indicator_width5 2
    #property indicator_color5 0xFFAA00
    #property indicator_label5 "Buy Trend"

    • Puffer 6: So zeichnen wir eine rote Linie, wenn der MA 100 unter dem MA 200 liegt

    #property indicator_type6 DRAW_LINE
    #property indicator_style6 STYLE_SOLID
    #property indicator_width6 2
    #property indicator_color6 0x0000FF
    #property indicator_label6 "Sell Trend"
    Anmerkung: Der obige Abschnitt dient als Platzhalter für zusätzliche Informationen. Weitere Einzelheiten finden Sie im nachstehenden Code. Das Pufferlayout ist nicht starr, sondern lässt Variationen der Werte zu, solange die ursprüngliche Absicht konsequent beibehalten wird.

    Hauptcode für Trend Constraint v1.04

    ///Indicator Name: Trend Constraint
    #property copyright "Clemence Benjamin"
    #property link      "https://mql5.com"
    #property version   "1.04"
    #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 6
    #property indicator_plots 6
    
    #property indicator_type1 DRAW_ARROW
    #property indicator_width1 5
    #property indicator_color1 0xFF3C00
    #property indicator_label1 "Buy"
    
    #property indicator_type2 DRAW_ARROW
    #property indicator_width2 5
    #property indicator_color2 0x0000FF
    #property indicator_label2 "Sell"
    
    #property indicator_type3 DRAW_ARROW
    #property indicator_width3 2
    #property indicator_color3 0xE8351A
    #property indicator_label3 "Buy Reversal"
    
    #property indicator_type4 DRAW_ARROW
    #property indicator_width4 2
    #property indicator_color4 0x1A1AE8
    #property indicator_label4 "Sell Reversal"
    
    #property indicator_type5 DRAW_LINE
    #property indicator_style5 STYLE_SOLID
    #property indicator_width5 2
    #property indicator_color5 0xFFAA00
    #property indicator_label5 "Buy Trend"
    
    #property indicator_type6 DRAW_LINE
    #property indicator_style6 STYLE_SOLID
    #property indicator_width6 2
    #property indicator_color6 0x0000FF
    #property indicator_label6 "Sell Trend"
    
    #define PLOT_MAXIMUM_BARS_BACK 5000
    #define OMIT_OLDEST_BARS 50
    
    //--- indicator buffers
    double Buffer1[];
    double Buffer2[];
    double Buffer3[];
    double Buffer4[];
    double Buffer5[];
    double Buffer6[];
    
    input double Oversold = 30;
    input double Overbought = 70;
    input int Slow_MA_period = 200;
    input int Fast_MA_period = 100;
    datetime time_alert; //used when sending alert
    input bool Audible_Alerts = true;
    input bool Push_Notifications = true;
    double myPoint; //initialized in OnInit
    int RSI_handle;
    double RSI[];
    double Open[];
    double Close[];
    int MA_handle;
    double MA[];
    int MA_handle2;
    double MA2[];
    int MA_handle3;
    double MA3[];
    int MA_handle4;
    double MA4[];
    double Low[];
    double High[];
    int MA_handle5;
    double MA5[];
    int MA_handle6;
    double MA6[];
    
    void myAlert(string type, string message)
      {
       if(type == "print")
          Print(message);
       else if(type == "error")
         {
          Print(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
         }
       else if(type == "order")
         {
         }
       else if(type == "modify")
         {
         }
       else if(type == "indicator")
         {
          if(Audible_Alerts) Alert(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
          if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
         }
      }
    
    //+------------------------------------------------------------------+
    //| 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);
       SetIndexBuffer(2, Buffer3);
       PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       PlotIndexSetInteger(2, PLOT_ARROW, 236);
       SetIndexBuffer(3, Buffer4);
       PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       PlotIndexSetInteger(3, PLOT_ARROW, 238);
       SetIndexBuffer(4, Buffer5);
       PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       SetIndexBuffer(5, Buffer6);
       PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
       //initialize myPoint
       myPoint = Point();
       if(Digits() == 5 || Digits() == 3)
         {
          myPoint *= 10;
         }
       RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
       if(RSI_handle < 0)
         {
          Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, 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, 400, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle2 < 0)
         {
          Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
       if(MA_handle3 < 0)
         {
          Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle4 < 0)
         {
          Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle5 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle5 < 0)
         {
          Print("The creation of iMA has failed: MA_handle5=", INVALID_HANDLE);
          Print("Runtime error = ", GetLastError());
          return(INIT_FAILED);
         }
       
       MA_handle6 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE);
       if(MA_handle6 < 0)
         {
          Print("The creation of iMA has failed: MA_handle6=", 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);
       ArraySetAsSeries(Buffer3, true);
       ArraySetAsSeries(Buffer4, true);
       ArraySetAsSeries(Buffer5, true);
       ArraySetAsSeries(Buffer6, true);
       //--- initial zero
       if(prev_calculated < 1)
         {
          ArrayInitialize(Buffer1, EMPTY_VALUE);
          ArrayInitialize(Buffer2, EMPTY_VALUE);
          ArrayInitialize(Buffer3, EMPTY_VALUE);
          ArrayInitialize(Buffer4, EMPTY_VALUE);
          ArrayInitialize(Buffer5, EMPTY_VALUE);
          ArrayInitialize(Buffer6, EMPTY_VALUE);
         }
       else
          limit++;
       datetime Time[];
       
       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(RSI_handle) <= 0) 
          return(0);
       if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
       ArraySetAsSeries(RSI, true);
       if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total);
       ArraySetAsSeries(Open, true);
       if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total);
       ArraySetAsSeries(Close, true);
       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(BarsCalculated(MA_handle3) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
       ArraySetAsSeries(MA3, true);
       if(BarsCalculated(MA_handle4) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total);
       ArraySetAsSeries(MA4, 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);
       if(BarsCalculated(MA_handle5) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle5, 0, 0, rates_total, MA5) <= 0) return(rates_total);
       ArraySetAsSeries(MA5, true);
       if(BarsCalculated(MA_handle6) <= 0) 
          return(0);
       if(CopyBuffer(MA_handle6, 0, 0, rates_total, MA6) <= 0) return(rates_total);
       ArraySetAsSeries(MA6, true);
       if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
       ArraySetAsSeries(Time, 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(RSI[i] < Oversold
          && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value
          && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close
          && MA[i] > MA2[i] //Moving Average > Moving Average
          && MA3[i] > MA4[i] //Moving Average > Moving Average
          )
            {
             Buffer1[i] = Low[1+i]; //Set indicator value at Candlestick Low
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer1[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 2
          if(RSI[i] > Overbought
          && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value
          && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close
          && MA[i] < MA2[i] //Moving Average < Moving Average
          && MA3[i] < MA4[i] //Moving Average < Moving Average
          )
            {
             Buffer2[i] = High[1+i]; //Set indicator value at Candlestick High
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer2[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 3
          if(MA5[i] > MA6[i]
          && MA5[i+1] < MA6[i+1] //Moving Average crosses above Moving Average
          )
            {
             Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer3[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 4
          if(MA5[i] < MA6[i]
          && MA5[i+1] > MA6[i+1] //Moving Average crosses below Moving Average
          )
            {
             Buffer4[i] = High[i]; //Set indicator value at Candlestick High
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer4[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 5
          if(MA5[i] > MA6[i] //Moving Average > Moving Average
          )
            {
             Buffer5[i] = MA6[i]; //Set indicator value at Moving Average
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Trend"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer5[i] = EMPTY_VALUE;
            }
          //Indicator Buffer 6
          if(MA5[i] < MA6[i] //Moving Average < Moving Average
          )
            {
             Buffer6[i] = MA6[i]; //Set indicator value at Moving Average
             if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Trend"); //Alert on next bar open
             time_alert = Time[1];
            }
          else
            {
             Buffer6[i] = EMPTY_VALUE;
            }
         }
       return(rates_total);
      }
    //You are the best coder


    Unser innovatives Programm demonstriert jetzt erweiterte Fähigkeiten, indem es die Farbe einer einzelnen Linie anpasst, sobald ein neuer Kurs erstellt wird. Diese Funktion vereinfacht das Chart durch die Einbindung von Farben und verbessert so das Signalsystem zusammen mit anderen visuellen und auditiven Benachrichtigungen. Die folgenden Bilder veranschaulichen die Auswirkungen dieser neuen Funktion.

    Trend Constraint V1.04 für USDJPY

    Abb. 2: Trend Constraint V1.04 für USDJPY

    Trend Constrain V1.04 mit Boom 500 Index

    Abb. 3: Trend Constraint V1.04 mit Boom 500 Index

    Mein Status der D1-Kerzen

    Um unserem Modell eine neue Funktion hinzuzufügen, wollen wir den Status der D1-Kerze schnell überprüfen, sobald wir auf MetaTrader 5 umschalten und unser Modell verwenden. Ich habe beschlossen, hier ein Skript einzuführen, das den Status der D1-Kerze auf dem Chart anzeigt, auch wenn der Chart auf anderen Zeitrahmen als D1 läuft. Diese Verbesserung hilft bei der schnellen Identifizierung des Kerzenstatus, insbesondere bei der Arbeit mit M1-Zeitrahmen, bei denen D1-Periodentrenner bei bestimmten Zoomstufen möglicherweise nicht sichtbar sind. Schauen wir uns nun den unten angegebenen MQL5-Skriptcode an:

    //My_D1_candlestatus.mql5
    //Author: Clemence Benjamin
    //Link: 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 script_show_inputs
    #property strict
    
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
      {
       //--- Get the opening and closing prices of the current D1 candle
       double openPrice = iOpen(NULL, PERIOD_D1, 0);
       double closePrice = iClose(NULL, PERIOD_D1, 0);
       
       //--- Determine if the candle is bullish or bearish
       string candleStatus;
       if(closePrice > openPrice)
         {
          candleStatus = " D1 candle is bullish.";
         }
       else if(closePrice < openPrice)
         {
          candleStatus = " D1 candle is bearish.";
         }
       else
         {
          candleStatus = " D1 candle is neutral.";// when open price is equal to close price
         
         }
       
       //--- Print the status on the chart
       Comment(candleStatus);
       
       //--- Also print the status in the Experts tab for logging
       Print(candleStatus);
      }
    //+------------------------------------------------------------------+
    
    


    Verständnis der Funktionen und Variablen des Skripts My_D1_Candlestatus.mq5

    Funktionen und Variable Beschreibung
    OnStart() Dies ist die Hauptfunktion des Skripts, die ausgeführt wird, wenn das Skript gestartet wird. Es ruft die Eröffnungs- und Schlusskurse der aktuellen D1-Kerze ab, bestimmt, ob die Kerze auf oder abwärts oder neutral zeigt, und zeigt diese Informationen dann mit Comment() auf dem Chart an.
    iOpen() und iClose() Diese Funktionen rufen die Eröffnungs- und Schlusskurse der aktuellen D1-Kerze ab.

    candleStatus Eine String-Variable zur Speicherung der Statusmeldung der aktuellen D1-Kerze.
    Comment() Mit dieser Funktion wird die Statusmeldung auf dem Chart angezeigt.
    Print() Diese Funktion protokolliert die Statusmeldung auf der Registerkarte „Experten“ zur zusätzlichen Protokollierung.

    Nachdem Sie den Code kompiliert haben, können Sie das Skript finden und es gemäß den Anweisungen in der Illustration ausführen. Das Skript zeigt einen Kommentar an, der den Kerzenstatus des aktuellen Tages angibt.

    Ausführung des Skripts My_D1_candlestatus.mq5

    Abb. 4: Ausführung des Skripts My_D1_candlestatus.mq5


    Andere Alternativen zu MQL5 Draw Styles

    MetaTrader 5 verfügt über eine breite Palette von Zeichenhilfen für die praktische Markteinschätzung, wie Linien, Kanäle und Zahlen, die sich alle bequem in der Meta Trader-Plattform befinden. Durch die Vertiefung in ein starkes Verständnis der objektorientierten Programmiersprache MQL5 und ihrer Verbindungen mit Python und C++ haben Händler die Möglichkeit, personalisierte Hilfsmittel und Erweiterungen zu entwickeln. Händler können diese Tools nutzen, um ihre technischen Analysefähigkeiten zu verbessern und fundiertere Handelsentscheidungen zu treffen. Dank der Flexibilität und der Anpassungsmöglichkeiten, die MetaTrader 5 bietet, haben Händler die Möglichkeit, ihre Handelserfahrung an ihre Vorlieben und Strategien anzupassen. 


    Schlussfolgerung

    Wir haben erfolgreich eine neue Funktion in unser Programm integriert und dabei positive Ergebnisse erzielt, die das Potenzial haben, die kommende Version zu beeinflussen, wenn wir in den folgenden Artikeln von einem Indikator zu einem EA übergehen. Die Zeichenstile in MQL5 bieten Händlern bemerkenswerte Vorteile, da sie die Klarheit, Präzision und Anpassbarkeit der Datenvisualisierung verbessern. Diese Stile verstärken die technischen Analysefähigkeiten, erleichtern fortgeschrittene Charttechniken und unterstützen interaktive Echtzeit-Updates. Darüber hinaus ermöglicht die Flexibilität und Kreativität der MQL5-Zeichenstile den Händlern, eigene Indikatoren und Analysewerkzeuge zu entwickeln, die ihre Handelsansätze und das allgemeine Marktverständnis bereichern.

    Unser Modell entwickelt sich mit verfeinerter Präzision weiter und bietet sofortige visuelle Einblicke auf Knopfdruck. Das Skript vermittelt sofort den Status der D1-Kerze, während die Funktion DRAW_LINE die Trends in einem niedrigeren Zeitrahmen verständlich hervorhebt. Ich habe die Quelldateien für alle hier besprochenen Funktionen beigefügt. Ich vertraue darauf, dass Sie die Fortschritte verfolgen und Erkenntnisse gewinnen; bitte teilen Sie uns Ihre Kommentare mit und beteiligen Sie sich an Diskussionen.


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

    Verschaffen Sie sich einen Vorteil auf jedem Markt (Teil II): Vorhersage technischer Indikatoren Verschaffen Sie sich einen Vorteil auf jedem Markt (Teil II): Vorhersage technischer Indikatoren
    Wussten Sie, dass die Vorhersage bestimmter technischer Indikatoren genauer ist als die Vorhersage des zugrunde liegenden Preises eines gehandelten Symbols? Lernen Sie mit uns, wie Sie diese Erkenntnisse für bessere Handelsstrategien nutzen können.
    MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 20): Symbolische Regression MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 20): Symbolische Regression
    Die symbolische Regression ist eine Form der Regression, die von minimalen bis gar keinen Annahmen darüber ausgeht, wie das zugrunde liegende Modell, das die untersuchten Datensätze abbildet, aussehen würde. Obwohl sie mit Bayes'schen Methoden oder neuronalen Netzen implementiert werden kann. Shen wir uns an, wie eine Implementierung mit genetischen Algorithmen helfen kann, eine im MQL5-Assistenten verwendbare Expertensignalklasse anzupassen.
    Integrieren Sie Ihr eigenes LLM in Ihren EA (Teil 3): Training Ihres eigenen LLM mit CPU Integrieren Sie Ihr eigenes LLM in Ihren EA (Teil 3): Training Ihres eigenen LLM mit CPU
    Angesichts der rasanten Entwicklung der künstlichen Intelligenz sind Sprachmodelle (language models, LLMs) heute ein wichtiger Bestandteil der künstlichen Intelligenz, sodass wir darüber nachdenken sollten, wie wir leistungsstarke LLMs in unseren algorithmischen Handel integrieren können. Für die meisten Menschen ist es schwierig, diese leistungsstarken Modelle auf ihre Bedürfnisse abzustimmen, sie lokal einzusetzen und sie dann auf den algorithmischen Handel anzuwenden. In dieser Artikelserie werden wir Schritt für Schritt vorgehen, um dieses Ziel zu erreichen.
    MQL5-Assistent-Techniken, die Sie kennen sollten (Teil 19): Bayes'sche Inferenz MQL5-Assistent-Techniken, die Sie kennen sollten (Teil 19): Bayes'sche Inferenz
    Die Bayes'sche Inferenz ist die Anwendung des Bayes-Theorems, um die Wahrscheinlichkeitshypothese zu aktualisieren, wenn neue Informationen zur Verfügung stehen. Dies führt intuitiv zu einer Anpassung in der Zeitreihenanalyse, und so schauen wir uns an, wie wir dies bei der Erstellung von nutzerdefinierten Klassen nicht nur für das Signal, sondern auch für das Money-Management und Trailing-Stops nutzen können.