Startseite Technischer Indikator Beitrag

Trendanzeige für alle Zeitrahmen in einem Panel: MetaTrader 4 Indikator

Anhang
15620.zip (2.17 KB, Herunterladen 0 mal)

In diesem Beitrag möchte ich euch einen grafischen Indikator vorstellen, der auf dem Slope-Direction-Trend Indikator basiert und in mehreren Varianten veröffentlicht wurde. Doch keine dieser Versionen zeigt alle Zeitrahmen in einem einzigen grafischen Panel auf eurem Bildschirm an.

Wenn ihr mehr Informationen zu diesem Indikator sucht, könnt ihr hier nachsehen: MQL5 Suche.

Ich habe diesen Indikator modifiziert, um ein grafisches Panel zu erstellen, das alle Zeitrahmen anzeigt, und ich habe einige kleine Anpassungen am Originalcode vorgenommen. Eine der Änderungen ermöglicht es dem Nutzer, die zweite Methode des gleitenden Durchschnitts zur Glättung auszuwählen. Während der Originalcode den Linear Weighted Ansatz für die zweite Berechnung verwendet hat, gebe ich dem Nutzer die Wahl, die Methode zur Glättung zu wählen. Wenn wir bei beiden Berechnungen Linear Weighted verwenden, reagiert der Indikator zu empfindlich und könnte somit falsche Signale zur aktuellen Trendrichtung liefern. Durch die Verwendung des einfachen gleitenden Durchschnitts als zweite Methode erhalten wir einen Trend, der besser anzeigt, wohin sich der Preis bewegt.

Eine weitere Änderung, die ich vorgenommen habe, ist die Möglichkeit, nicht nur die Richtung des Trends (steigend, fallend oder seitwärts) zu bestimmen, sondern auch dessen Wert. Darüber werde ich in einem zukünftigen Artikel schreiben, in dem ich erkläre, wie man einen doppelten SlopeDirection Indikator verwendet und ein Expert Advisor damit erstellt.

SlopeDirection 

Schauen wir uns jetzt kurz den Code an. Zuerst definiere ich alle Objekt-Namen, die ich verwenden werde. Es ist gute Praxis, diese einmal zu definieren, da der Code so nur einmal Speicherplatz für die Benennung reserviert.

// Trendrichtungen definieren
#define     UPTREND           1
#define     DOWNTREND         -1
#define     FLATTREND         0

// Objekte definieren
#define     TrendPanel        "TrendPanel"
#define     InfoLine1         "InfoLine1"
#define     InfoLine2         "InfoLine2"
#define     TrendLabel        "Trend:  M1  M5  M15  M30  H1  H4  D1  W1  MN"
#define     TrendUp           "\233"
#define     TrendDown         "\234"
#define     TrendFlat         "\232"
#define     TrendUnknown      "\251"
#define     StatObjectError   "%s(%d) Fehler beim Erstellen von '%s'.  Fehler = %d"

Als Nächstes definiere ich zwei Arrays. Eines mit den Pixelpositionen für jeden der 9 Zeitrahmen und das andere mit den Zeitrahmen. Diese werden als globale Variablen definiert.

// Globale Variablen definieren
int      TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 };
int      TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };

Die OnInit() Funktion unseres Indikators ruft eine Funktion auf, um das Panel und die Objekte innerhalb des Panels zu erstellen. Sie führt auch eine schnelle Überprüfung der Balken durch, die zur Berechnung des Trends verwendet werden – weniger als 3 macht nicht viel Sinn.

//+------------------------------------------------------------------+
//| Initialisierungsfunktion des benutzerdefinierten Indikators                         |
//+------------------------------------------------------------------+
int   OnInit()
{
   // Objekte für das Indikatorpanel erstellen
   if(Create_Panel() && BarCount >= 3)
      return(INIT_SUCCEEDED);
   else
      return(INIT_FAILED);
}

Ich werde nicht ins Detail gehen, wie die Funktion GetTrend() genau funktioniert, dafür gibt es bereits gute Dokumentationen auf dieser Seite. Wir schauen uns einfach die grafische DisplayTrend() Funktion an.

//+------------------------------------------------------------------+
//| Zeige den aktuellen Trend für alle Zeitrahmen an
//+------------------------------------------------------------------+
void  DisplayTrend(void)
{
   int      i, cntr, Trend, LastTrend;
   string   str;
   
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method);
      if(Trend == FLATTREND)
      {
         // Ich bin flach, finde die letzte Trendrichtung
         cntr = 1;
         do 
         { 
            LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++);
         } while(LastTrend == Trend);
        ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red));
        ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6);
      }
      else
      {
        ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red));
        ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1));
      }
   }
}

Im Grunde genommen durchlaufen wir einfach das TrendPeriods[] Array (um alle Zeitrahmen zu erhalten) und setzen den Trendpfeil entsprechend der Trendrichtung dieses Zeitrahmens. Wenn der Trend flach ist, finden wir die erste Richtung, die nicht flach ist, um zu wissen, woher der Trend kam, damit wir den Seitenpfeil in der Farbe dieser Richtung anzeigen können.

Die Create_Panel() Funktion in unserem OnInit() erstellt die Objekte, die an der unteren linken Seite des Bildschirms verankert sind, und verwendet das TrendPosition[], um die Pfeile an die richtige Stelle zu setzen.

//+------------------------------------------------------------------+
//| Erstelle das Trendpanel in der unteren linken Ecke des Bildschirms
//+------------------------------------------------------------------+
bool  Create_Panel(void)
{

   int      i;
   string   str;
   
   // Erstelle das Trendindikatorfenster
   if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0))
   {
      ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29);
      ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0);
      ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red);
      ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true);
      ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n");
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); }

   if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15);
      ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); }
   
   if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5);
      ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); }

   // Erstelle das Trendobjekt und zeige den aktuellen Trend an    
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      if(ObjectCreate(str, OBJ_LABEL, 0, 0, 0))
      {
         ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER);
         ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]);
         ObjectSet(str, OBJPROP_YDISTANCE, 5);
         ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(0, str, OBJPROP_HIDDEN, true);
         ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n");
      }
      else
      { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); }
   }

   // Zeige den aktuellen Trend an
   DisplayTrend();
      
   // Alles gut
   return(true);
}

Diese Funktion gibt TRUE zurück, wenn alle Objekte erfolgreich erstellt wurden, oder FALSE, wenn ein Fehler beim Erstellen eines Objekts aufgetreten ist. Der Vorteil ist, dass der Indikator im EXPERT-Tab eurer Konsole den Fehlercode und die Zeilennummer des Codes, in dem der Fehler aufgetreten ist, anzeigt.

Wir müssen auch den Trendindikator für jeden neuen Tick, den wir empfangen, aktualisieren. Dies geschieht, indem wir DisplayTrend() in unserer start() Funktion aufrufen.

//+------------------------------------------------------------------+
//| Iterationsfunktion des benutzerdefinierten Indikators                              |
//+------------------------------------------------------------------+
int   start()
{
   // Zeige den aktuellen Trend für alle Zeitrahmen an
   DisplayTrend();   

   return(0);
}

Zu guter Letzt löschen wir alle Objekte, die vom Indikator erstellt wurden, wenn wir den Indikator schließen.

//+------------------------------------------------------------------+
//| Deinitialisierungsfunktion                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Lösche die Objekte des Indikators
   if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel);
   if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1);
   if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2);
   for(int i=1; i<10; i++)
      if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0));
}

Das ist alles! Ihr habt nun ein nützliches Indikatorpanel, das den aktuellen Trend für alle Zeitrahmen in der unteren linken Ecke eures Bildschirms anzeigt.

Viel Spaß beim Traden!


Verwandte Beiträge

Kommentar (0)