English
preview
Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 18): Einführung in die Quarters-Theorie (III) - Quarters Board

Entwicklung eines Toolkit zur Analyse von Preisaktionen (Teil 18): Einführung in die Quarters-Theorie (III) - Quarters Board

MetaTrader 5Beispiele | 27 Juni 2025, 08:13
17 0
Christian Benjamin
Christian Benjamin

Inhalt


Einführung

In unserer Einführung in die Quarters-Theorie haben wir mit dem Skript Quarters Drawer das die erste Komponente darstellt. Dieses Skript automatisiert das Zeichnen der Viertel (Quarters) in einem Chart und bietet boolesche Umschaltmöglichkeiten, um die Sichtbarkeit der einzelnen Stufen zu steuern.

input bool   DrawLargeQuarters  = true;     // Draw intermediate large quarter lines.
input bool   DrawSmallQuarters  = false;    // Draw small quarter lines.
input bool   DrawOvershootAreas = true;     // Mark overshoot/undershoot areas for large quarter lines.

Zum Beispiel kann die Einstellung DrawSmallQuarters auf true gesetzt, werden die Linien der kleinen Viertel angezeigt, während die Einstellung DrawLargeQuarters auf false gesetzt wird, werden die Linien der großen Viertel ausgeblendet. Der gleiche Ansatz gilt für die Überschreitungen und Unterschreitungen Ebenen. Mit dieser Funktion können Sie sich auf bestimmte Ebenen konzentrieren und das Chart sauber und übersichtlich halten. Wenn Sie alle Ebenen anzeigen möchten, aktivieren Sie einfach alle Schalter.

Haben Sie es jemals als mühsam empfunden, immer wieder in den Code einzutauchen, nur um eine Einstellung umzuschalten? In diesem Artikel stellen wir Ihnen das Quarters Board vor, ein erweitertes Tool, mit dem Sie boolesche Flags mit einem einzigen Tastendruck im Live-Chart automatisch ein- oder ausschalten können. Anstatt den Code zu bearbeiten, um das Flag DrawSmallQuarters zu ändern, können Sie jetzt Anpassungen direkt im Chart vornehmen, was den Prozess für jeden Händler vereinfacht. Wenn Sie z. B. nur die großen Viertel sehen wollen, genügt ein einfacher Tastendruck, um dies zu erreichen.


Übersicht

Wie bereits in der Einleitung erwähnt, können Sie mit diesem Werkzeug die im Chart angezeigten Ebenen umschalten, ohne zum Code zurückkehren zu müssen, um ein boolesches Flag zu bearbeiten. Das Quarter Board ist ein Expert Advisor mit vier Schaltflächen: Large Quarters (große Viertel), Small Quarters (kleine Viertel), Overshoot/Undershoot (Über-/Unterschreitung) und Trend Direction (Trendrichtung). Durch Drücken einer beliebigen Schaltfläche wird die entsprechende Ebene umgeschaltet: Der Text der Schaltfläche wird grün, wenn die Ebene aktiv ist, und rot, wenn sie deaktiviert ist.

Die Schaltfläche „Trendrichtung“ ist eine zusätzliche Funktion, die Echtzeit-Marktinformationen liefert. Mit nur einem Klick wird ein einfacher gleitender 50-Perioden-Durchschnitt berechnet und mit dem aktuellen Marktpreis verglichen. So können Sie schnell feststellen, ob der Markt nach oben, nach unten oder seitwärts tendiert. Die Schaltfläche ändert sogar ihre Farbe, um ihren aktiven Status anzuzeigen, und bietet so eine klare und nutzerfreundliche Methode zur Überwachung von Markttrends direkt in Ihrem Chart. Im folgenden Abschnitt erfahren Sie mehr über die Logik, die der Funktionalität unseres EAs zugrunde liegt.


Logik

Dieser EA ist so konzipiert, dass er sowohl nutzerfreundlich als auch in hohem Maße anpassungsfähig ist. Die Einstellungen lassen sich leicht anpassen, die Nutzeroberfläche ist übersichtlich und gut organisiert, und die auf Tasten basierenden Steuerelemente gewährleisten eine reibungslose Interaktion. Durch die automatische Handhabung des Hinzufügens und Entfernens von Viertellinien hält der EA das Chart übersichtlich und konzentriert sich auf relevante Kursniveaus. Der Live-Trendkommentar bietet einen weiteren Einblick und hilft Händlern, die Marktrichtung schnell abzuschätzen, ohne den Bildschirm zu überladen. Mit visuellen und analytischen Werkzeugen, die zusammenarbeiten, vereinfacht dieser EA die Handelsentscheidungen, während die Dinge intuitiv und effizient bleiben.

Globale Konfiguration und Struktur

Der EA beginnt mit der Definition von Schlüsselparametern, die bestimmen, wie Kursniveaus und Chartelemente angezeigt werden sollen. Mit den Eingabeeinstellungen können Händler Werte wie die Abstände zwischen den wichtigsten Kursniveaus und die für verschiedene Linien verwendeten Farben anpassen. Diese Einstellungen bieten Flexibilität und ermöglichen es den Nutzern, das Erscheinungsbild des EA zu ändern, ohne seine Kernlogik zu verändern. Der Code enthält auch mehrere globale boolesche Variablen, die als Schalter fungieren und bestimmte Funktionen wie große Viertellinien oder Trendkommentare aktivieren oder deaktivieren. Makros werden verwendet, um Chartobjekten konsistente Namen zuzuweisen und sicherzustellen, dass jedes Element im gesamten Skript einheitlich referenziert wird. Die Organisation dieser Einstellungen an einem Ort erleichtert die Anpassung von Parametern und die Behebung von Problemen, ohne dass mehrere Codeabschnitte durchsucht werden müssen.
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com/en/users/lynnchris"
#property version   "1.0"
#property strict

//---- Input parameters for drawing levels ----------------------------
input double MajorStep = 0.1000;   // Difference between major whole numbers

//---- Color settings ---------------------------------------------------
input color  MajorColor         = 0x2F4F4F; // Dark Slate Gray for major lines.
input color  LargeQuarterColor  = 0x8B0000; // Dark Red for large quarter lines.
input color  SmallQuarterColor  = 0x00008B; // Dark Blue for small quarter lines.
input color  OvershootColor     = clrRed;   // Red for overshoot/undershoot lines.

//---- Line styles and thickness settings -----------------------------
input ENUM_LINE_STYLE MajorLineStyle       = STYLE_SOLID;
input int    MajorLineWidth                 = 4;
input ENUM_LINE_STYLE LargeQuarterLineStyle  = STYLE_DOT;
input int    LargeQuarterLineWidth          = 3;
input ENUM_LINE_STYLE OvershootLineStyle     = STYLE_DASH;
input int    OvershootLineWidth             = 1;
input ENUM_LINE_STYLE SmallQuarterLineStyle  = STYLE_SOLID;
input int    SmallQuarterLineWidth          = 1;

//---- Panel and button settings --------------------------------------
input int PanelX       = 10;
input int PanelY       = 10;
input int PanelWidth   = 250;
input int ButtonHeight = 30;
input int ButtonSpacing= 5;

//---- Global toggle variables ----------------------------------------
bool g_DrawLargeQuarters   = true;
bool g_DrawSmallQuarters   = false;
bool g_DrawOvershootAreas  = true;
bool g_DrawTrendDirection  = false;

//---- Object names for panel and buttons -----------------------------
#define PANEL_NAME       "LevelsPanel"
#define BUTTON_LARGE     "btnLargeQuarters"
#define BUTTON_SMALL     "btnSmallQuarters"
#define BUTTON_OVERSHOOT "btnOvershoot"
#define BUTTON_TREND     "btnTrendDirection"
#define TREND_LABEL      "TrendDirectionLabel"

Initialisierung des Bedienfelds und der Schaltflächen

Sobald die Konfiguration festgelegt ist, baut der EA die Nutzeroberfläche auf. Es wird ein Hintergrundfeld erstellt, in dem alle Schaltflächen gruppiert sind und das ein strukturiertes Layout bietet. Das Panel wird durch ein rechteckiges Etikett simuliert, dessen Abmessungen durch Änderung der Texteigenschaften angepasst werden. Die Schaltflächen werden dann im Verhältnis zum Bedienfeld positioniert, wobei der richtige Abstand und die richtige Ausrichtung gewährleistet werden.

Mit diesen Schaltflächen können Händler Funktionen wie große Viertel, kleine Viertel, Überschreitungsbereiche und Trendrichtungskommentare umschalten. Jede Schaltfläche hat eine einheitliche Breite und Höhe, sodass ein sauberes, übersichtliches Aussehen entsteht. Die Einrichtung macht es den Nutzern leicht, mit dem EA zu interagieren, da sie bestimmte Elemente mit einem einzigen Klick aktivieren oder deaktivieren können. Durch die Beibehaltung eines einheitlichen Layouts stellt der EA sicher, dass alle Steuerelemente leicht zugänglich und visuell eindeutig sind.

void CreatePanel()
  {
   if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0))
     {
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray);
      ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, "\n\n\n\n");
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED);
     }
  }

Umgang mit Nutzerinteraktionen

Die Nutzerinteraktion ist ein wesentlicher Aspekt des EA, der über ein Ereignisbehandlungssystem verwaltet wird. Das Skript wartet auf Chartereignisse und prüft insbesondere, ob eine Schaltfläche angeklickt wurde. Wenn eine Taste gedrückt wird, erkennt das System anhand des Namens der Taste, welche Funktion aktiviert werden soll. Einmal erkannt, wird die entsprechende Funktion ein- oder ausgeschaltet. Wenn Sie beispielsweise auf die Taste des großen Viertels drücken, können Sie diese Preisstufen ein- und ausblenden.

Um die Nutzerfreundlichkeit zu erhöhen, werden die Farben der Schaltflächen sofort aktualisiert, sodass ein klares, visuelles Feedback gegeben wird - aktive Schaltflächen können grün werden, während inaktive Schaltflächen rot bleiben. Dieses System stellt sicher, dass jede Funktion unabhängig arbeitet, sodass Konflikte vermieden werden und das Tool in Echtzeit auf Nutzereingaben reagieren kann. Durch die effiziente Strukturierung der Ereignisbehandlung bleibt der EA auch unter schnelllebigen Marktbedingungen stabil und einfach zu bedienen.

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam == BUTTON_LARGE)
        {
         g_DrawLargeQuarters = !g_DrawLargeQuarters;
         UpdateButtonColors();
         DrawQuarterLines();
        }
      else if(sparam == BUTTON_TREND)
        {
         g_DrawTrendDirection = !g_DrawTrendDirection;
         UpdateButtonColors();
         if(g_DrawTrendDirection)
            UpdateTrendComment();
         else
            DeleteTrendComment();
        }
      // Similar handling for other buttons...
     }
  }

Zeichnen und Entfernen von Viertellinien

Eine der Kernfunktionen des EA ist die Darstellung von Kursniveaus im Chart. Der Prozess beginnt mit der Ermittlung des aktuellen Marktpreises und der Berechnung der wichtigsten Preisgrenzen. Die Hauptebenen werden immer gezeichnet, während zusätzliche Ebenen wie große Viertel, kleine Viertel und Überschreitungszonen nur angezeigt werden, wenn die entsprechenden Schaltflächen aktiviert sind. Um das Chart sauber zu halten, entfernt der EA zunächst alle zuvor gezeichneten Linien, bevor er neue Linien platziert.

Dadurch wird verhindert, dass sich überlappende oder veraltete Linien die Anzeige überlagern. Jede Viertels-Methode folgt einer strukturierten Berechnung, die sicherstellt, dass die Preisniveaus korrekt aufeinander abgestimmt sind. Wenn eine Funktion ausgeschaltet ist, entfernt das Skript die entsprechenden Linien, sodass der Händler die volle Kontrolle über die Anzeige hat. Auf diese Weise wird sichergestellt, dass das Chart übersichtlich bleibt und nur die wichtigsten Informationen auf der Grundlage der Nutzerpräferenzen angezeigt werden.

void DrawQuarterLines()
  {
   DeleteQuarterLines();
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep;
   DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle);
   if(g_DrawLargeQuarters)
     {
      double LQIncrement = MajorStep / 4.0;
      for(int i = 1; i < 4; i++)
        {
         double level = lowerMajor + i * LQIncrement;
         DrawHorizontalLine("LargeQuarter_" + IntegerToString(i), level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle);
         // Overshoot/Undershoot handling...
        }
     }
   // Additional code for small quarters...
  }

Trend-Kommentar-Anzeige

Neben den grafischen Elementen bietet der EA den Händlern auch eine textuelle Analyse der Markttrends. Er berechnet einen einfachen gleitenden Durchschnitt (SMA) über einen bestimmten Zeitraum und vergleicht ihn mit dem aktuellen Kurs. Liegt der Kurs über dem SMA, wird der Trend als Aufwärtstrend betrachtet; liegt er darunter, ist es ein Abwärtstrend. Gibt es nur wenig Bewegung um den SMA, wird der Markt als neutral eingestuft. Diese Analyse wird als Textbeschriftung im Chart angezeigt, direkt unter der Schaltfläche Trendrichtung, um die Sichtbarkeit zu gewährleisten, ohne andere Elemente zu beeinträchtigen. Der Kommentar wird dynamisch aktualisiert und bietet Echtzeiteinblicke, wenn sich die Marktbedingungen ändern. Diese Funktion ergänzt die Grafik der Viertel, indem sie den Händlern eine zusätzliche Analyseebene bietet und ihnen hilft, fundiertere Entscheidungen zu treffen.

void UpdateTrendComment()
  {
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double smaValue = 0.0;
   int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE);
   if(handle != INVALID_HANDLE)
     {
      double buffer[];
      if(CopyBuffer(handle, 0, 1, 1, buffer) > 0)
         smaValue = buffer[0];
      IndicatorRelease(handle);
     }
   string trendComment = (currentPrice > smaValue) ? "Uptrend" :
                         (currentPrice < smaValue) ? "Downtrend" : "Sideways";
                         
   int trendLabelY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing) + ButtonHeight + ButtonSpacing;
   if(ObjectFind(0, TREND_LABEL) == -1)
     {
      ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, PanelX + 10);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14);
     }
   ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, "Trend Direction: " + trendComment);
  }

Vollständiger EA-Code

//+------------------------------------------------------------------+
//|                                             Quarters Board EA.mq5|
//|                                Copyright 2025, Christian Benjamin|
//|                           https://www.mql5.com/en/users/lynnchris|
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com/en/users/lynnchris"
#property version   "1.0"
#property strict

//---- Input parameters for drawing levels ----------------------------
input double MajorStep = 0.1000;   // Difference between major whole numbers

//---- Color settings ---------------------------------------------------
input color  MajorColor         = 0x2F4F4F; // Dark Slate Gray for major lines.
input color  LargeQuarterColor  = 0x8B0000; // Dark Red for large quarter lines.
input color  SmallQuarterColor  = 0x00008B; // Dark Blue for small quarter lines.
input color  OvershootColor     = clrRed;   // Red for overshoot/undershoot lines.

//---- Line styles and thickness settings -----------------------------
input ENUM_LINE_STYLE MajorLineStyle       = STYLE_SOLID;
input int    MajorLineWidth                 = 4;
input ENUM_LINE_STYLE LargeQuarterLineStyle  = STYLE_DOT;
input int    LargeQuarterLineWidth          = 3;
input ENUM_LINE_STYLE OvershootLineStyle     = STYLE_DASH;
input int    OvershootLineWidth             = 1;
input ENUM_LINE_STYLE SmallQuarterLineStyle  = STYLE_SOLID;
input int    SmallQuarterLineWidth          = 1;

//---- Panel and button settings --------------------------------------
input int PanelX       = 10;
input int PanelY       = 10;
input int PanelWidth   = 250;
input int ButtonHeight = 30;
input int ButtonSpacing= 5;

//---- Global toggle variables ----------------------------------------
bool g_DrawLargeQuarters   = true;
bool g_DrawSmallQuarters   = false;
bool g_DrawOvershootAreas  = true;
bool g_DrawTrendDirection  = false;

//---- Object names for panel and buttons -----------------------------
#define PANEL_NAME       "LevelsPanel"
#define BUTTON_LARGE     "btnLargeQuarters"
#define BUTTON_SMALL     "btnSmallQuarters"
#define BUTTON_OVERSHOOT "btnOvershoot"
#define BUTTON_TREND     "btnTrendDirection"
#define TREND_LABEL      "TrendDirectionLabel"

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Create panel background and buttons
   CreatePanel();
   CreateButtons();
// Draw quarter lines initially
   DrawQuarterLines();
// If trend commentary is toggled on, update it
   if(g_DrawTrendDirection)
      UpdateTrendComment();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Delete panel, buttons, quarter lines, and trend commentary
   ObjectDelete(0, PANEL_NAME);
   ObjectDelete(0, BUTTON_LARGE);
   ObjectDelete(0, BUTTON_SMALL);
   ObjectDelete(0, BUTTON_OVERSHOOT);
   ObjectDelete(0, BUTTON_TREND);
   DeleteQuarterLines();
   DeleteTrendComment();
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Redraw quarter lines on every tick
   DrawQuarterLines();
// Update trend commentary if enabled
   if(g_DrawTrendDirection)
      UpdateTrendComment();
  }
//+------------------------------------------------------------------+
//| Chart event function to catch button clicks                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam == BUTTON_LARGE)
        {
         g_DrawLargeQuarters = !g_DrawLargeQuarters;
         UpdateButtonColors();
         DrawQuarterLines();
        }
      else
         if(sparam == BUTTON_SMALL)
           {
            g_DrawSmallQuarters = !g_DrawSmallQuarters;
            UpdateButtonColors();
            DrawQuarterLines();
           }
         else
            if(sparam == BUTTON_OVERSHOOT)
              {
               g_DrawOvershootAreas = !g_DrawOvershootAreas;
               UpdateButtonColors();
               DrawQuarterLines();
              }
            else
               if(sparam == BUTTON_TREND)
                 {
                  g_DrawTrendDirection = !g_DrawTrendDirection;
                  UpdateButtonColors();
                  if(g_DrawTrendDirection)
                     UpdateTrendComment();
                  else
                     DeleteTrendComment();
                 }
     }
  }
//+------------------------------------------------------------------+
//| Create panel background                                          |
//+------------------------------------------------------------------+
void CreatePanel()
  {
   if(ObjectCreate(0, PANEL_NAME, OBJ_RECTANGLE_LABEL, 0, 0, 0))
     {
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_XDISTANCE, PanelX);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_YDISTANCE, PanelY);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_COLOR, clrDarkGray);
      // Simulate a larger panel using newlines in the text.
      string panelText = "\n\n\n\n";
      ObjectSetString(0, PANEL_NAME, OBJPROP_TEXT, panelText);
      ObjectSetInteger(0, PANEL_NAME, OBJPROP_BORDER_TYPE, BORDER_RAISED);
     }
  }
//+------------------------------------------------------------------+
//| Create buttons on the panel                                      |
//+------------------------------------------------------------------+
void CreateButtons()
  {
   int x = PanelX + 10;
   int y = PanelY + 10;
   int btnWidth = PanelWidth - 20;
// Button for Large Quarters
   if(!ObjectCreate(0, BUTTON_LARGE, OBJ_BUTTON, 0, 0, 0))
      Print("Failed to create button ", BUTTON_LARGE);
   else
     {
      ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XDISTANCE, x);
      ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YDISTANCE, y);
      ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_XSIZE, btnWidth);
      ObjectSetInteger(0, BUTTON_LARGE, OBJPROP_YSIZE, ButtonHeight);
      ObjectSetString(0, BUTTON_LARGE, OBJPROP_TEXT, "Large Quarters");
     }
// Button for Smaller Quarters
   y += ButtonHeight + ButtonSpacing;
   if(!ObjectCreate(0, BUTTON_SMALL, OBJ_BUTTON, 0, 0, 0))
      Print("Failed to create button ", BUTTON_SMALL);
   else
     {
      ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XDISTANCE, x);
      ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YDISTANCE, y);
      ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_XSIZE, btnWidth);
      ObjectSetInteger(0, BUTTON_SMALL, OBJPROP_YSIZE, ButtonHeight);
      ObjectSetString(0, BUTTON_SMALL, OBJPROP_TEXT, "Smaller Quarters");
     }
// Button for Overshoot/Undershoot
   y += ButtonHeight + ButtonSpacing;
   if(!ObjectCreate(0, BUTTON_OVERSHOOT, OBJ_BUTTON, 0, 0, 0))
      Print("Failed to create button ", BUTTON_OVERSHOOT);
   else
     {
      ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XDISTANCE, x);
      ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YDISTANCE, y);
      ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_XSIZE, btnWidth);
      ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_YSIZE, ButtonHeight);
      ObjectSetString(0, BUTTON_OVERSHOOT, OBJPROP_TEXT, "Overshoot/Undershoot");
     }
// Button for Trend Direction
   y += ButtonHeight + ButtonSpacing;
   if(!ObjectCreate(0, BUTTON_TREND, OBJ_BUTTON, 0, 0, 0))
      Print("Failed to create button ", BUTTON_TREND);
   else
     {
      ObjectSetInteger(0, BUTTON_TREND, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XDISTANCE, x);
      ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YDISTANCE, y);
      ObjectSetInteger(0, BUTTON_TREND, OBJPROP_XSIZE, btnWidth);
      ObjectSetInteger(0, BUTTON_TREND, OBJPROP_YSIZE, ButtonHeight);
      ObjectSetString(0, BUTTON_TREND, OBJPROP_TEXT, "Trend Direction");
     }
   UpdateButtonColors();
  }
//+------------------------------------------------------------------+
//| Update button colors based on toggle state                       |
//+------------------------------------------------------------------+
void UpdateButtonColors()
  {
   color onColor  = clrGreen;
   color offColor = clrRed;
   ObjectSetInteger(0, BUTTON_LARGE,     OBJPROP_COLOR, g_DrawLargeQuarters  ? onColor : offColor);
   ObjectSetInteger(0, BUTTON_SMALL,     OBJPROP_COLOR, g_DrawSmallQuarters  ? onColor : offColor);
   ObjectSetInteger(0, BUTTON_OVERSHOOT, OBJPROP_COLOR, g_DrawOvershootAreas ? onColor : offColor);
   ObjectSetInteger(0, BUTTON_TREND,     OBJPROP_COLOR, g_DrawTrendDirection ? onColor : offColor);
  }
//+------------------------------------------------------------------+
//| Delete quarter lines                                             |
//+------------------------------------------------------------------+
void DeleteQuarterLines()
  {
   ObjectDelete(0, "MajorLower");
   ObjectDelete(0, "MajorUpper");
   for(int i = 1; i < 4; i++)
     {
      ObjectDelete(0, "LargeQuarter_" + IntegerToString(i));
      ObjectDelete(0, "Overshoot_" + IntegerToString(i) + "_up");
      ObjectDelete(0, "Undershoot_" + IntegerToString(i) + "_down");
     }
   for(int seg = 0; seg < 10; seg++)
     {
      for(int j = 1; j < 4; j++)
        {
         ObjectDelete(0, "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j));
        }
     }
  }
//+------------------------------------------------------------------+
//| Delete trend commentary                                          |
//+------------------------------------------------------------------+
void DeleteTrendComment()
  {
   ObjectDelete(0, TREND_LABEL);
  }
//+------------------------------------------------------------------+
//| Update trend commentary                                          |
//+------------------------------------------------------------------+
void UpdateTrendComment()
  {
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   if(currentPrice == 0)
      return;
   double smaValue = 0.0;
   double buffer[];
   int handle = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE);
   if(handle != INVALID_HANDLE)
     {
      if(CopyBuffer(handle, 0, 1, 1, buffer) > 0)
         smaValue = buffer[0];
      IndicatorRelease(handle);
     }
   string trendComment;
   if(currentPrice > smaValue)
      trendComment = "Uptrend";
   else
      if(currentPrice < smaValue)
         trendComment = "Downtrend";
      else
         trendComment = "Sideways";

// Calculate the position for the commentary label below the Trend Direction button
   int trendButtonY = PanelY + 10 + 3 * (ButtonHeight + ButtonSpacing);
   int trendLabelY = trendButtonY + ButtonHeight + ButtonSpacing;
   int trendLabelX = PanelX + 10;

   if(ObjectFind(0, TREND_LABEL) == -1)
     {
      ObjectCreate(0, TREND_LABEL, OBJ_LABEL, 0, 0, 0);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_CORNER, CORNER_LEFT_UPPER);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_XDISTANCE, trendLabelX);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_YDISTANCE, trendLabelY);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_COLOR, clrWhite);
      ObjectSetInteger(0, TREND_LABEL, OBJPROP_FONTSIZE, 14);
     }
   string txt = "Trend Direction: " + trendComment;
   ObjectSetString(0, TREND_LABEL, OBJPROP_TEXT, txt);
  }
//+------------------------------------------------------------------+
//| Draw horizontal line utility                                     |
//+------------------------------------------------------------------+
void DrawHorizontalLine(string name, double price, color lineColor, int width, ENUM_LINE_STYLE style)
  {
   if(ObjectFind(0, name) != -1)
      ObjectDelete(0, name);
   if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price))
     {
      Print("Failed to create line: ", name);
      return;
     }
   ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor);
   ObjectSetInteger(0, name, OBJPROP_STYLE, style);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
   ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);
  }
//+------------------------------------------------------------------+
//| Draw quarter lines based on toggle settings                      |
//+------------------------------------------------------------------+
void DrawQuarterLines()
  {
   DeleteQuarterLines();
   double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   if(currentPrice == 0)
      return;
   double lowerMajor = MathFloor(currentPrice / MajorStep) * MajorStep;
   double upperMajor = lowerMajor + MajorStep;
   DrawHorizontalLine("MajorLower", lowerMajor, MajorColor, MajorLineWidth, MajorLineStyle);
   DrawHorizontalLine("MajorUpper", upperMajor, MajorColor, MajorLineWidth, MajorLineStyle);
   if(g_DrawLargeQuarters)
     {
      double LQIncrement = MajorStep / 4.0;
      for(int i = 1; i < 4; i++)
        {
         double level = lowerMajor + i * LQIncrement;
         string objName = "LargeQuarter_" + IntegerToString(i);
         DrawHorizontalLine(objName, level, LargeQuarterColor, LargeQuarterLineWidth, LargeQuarterLineStyle);
         if(g_DrawOvershootAreas)
           {
            double smallQuarter = MajorStep / 40.0;
            DrawHorizontalLine("Overshoot_" + IntegerToString(i) + "_up", level + smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle);
            DrawHorizontalLine("Undershoot_" + IntegerToString(i) + "_down", level - smallQuarter, OvershootColor, OvershootLineWidth, OvershootLineStyle);
           }
        }
     }
   if(g_DrawSmallQuarters)
     {
      double segStep = MajorStep / 10.0;
      double smallQuarter = segStep / 4.0;
      for(int seg = 0; seg < 10; seg++)
        {
         double segStart = lowerMajor + seg * segStep;
         for(int j = 1; j < 4; j++)
           {
            double level = segStart + j * smallQuarter;
            string objName = "SmallQuarter_" + IntegerToString(seg) + "_" + IntegerToString(j);
            DrawHorizontalLine(objName, level, SmallQuarterColor, SmallQuarterLineWidth, SmallQuarterLineStyle);
           }
        }
     }
  }
//+------------------------------------------------------------------+


Ergebnisse

In diesem Abschnitt untersuchen wir die Ergebnisse und die Leistung unseres EA. Nachfolgend finden Sie ein GIF-Chart, das das Verhalten des Systems veranschaulicht. Wenn Sie den EA auf ein EURUSD-Chart ziehen, erscheint ein Panel mit Schaltflächen. Die Schaltflächen „Larger Quarters“ und „Overshoot/Undershoot“ sind zunächst in grüner Schrift dargestellt und somit deaktiviert. Im Gegensatz dazu zeigen die Schaltflächen „Smaller Quarters“ und „Trend Direction“ roten Text, was bedeutet, dass diese Ebenen aktiv sind. Wenn die einzelnen Tasten gedrückt werden, erscheinen die entsprechenden Ebenen im Chart, wenn sie aktiviert sind, oder sie werden entfernt, wenn sie deaktiviert sind. Nachdem Sie die Schaltfläche Trendrichtung aktiviert haben, wird der Trendkommentar aktualisiert und zeigt „Uptrend“, welches die aktuellen Marktbedingungen des Charts korrekt wiedergibt.

Quarters Board

Nachfolgend finden Sie ein Chart, das die Ergebnisse des Tests unseres EA deutlich macht. Es ist zu erkennen, dass die durch blaue durchgezogene Linien dargestellten großen Viertelswerte und die durch rote gestrichelte Linien dargestellten Über- bzw. Unterschreitungswerte aktiv sind, was sowohl an den Chartlinien als auch an der Farbe des Schaltflächentexts zu erkennen ist. Außerdem ist die Trendrichtung aktiv, wie der sichtbare Kommentar auf dem Chart zeigt. Im Gegensatz dazu erscheint die Schaltfläche der kleinen Viertel in Rot und zeigt damit an, dass diese Ebenen nicht aktiv sind.



Schlussfolgerung

Nachdem wir diesen Artikel mit dem Ziel eingeführt haben, ein Panel mit Schaltflächen zu erstellen, das die gewünschten Ebenen auf dem Chart mit einem einzigen Druck umschaltet und sie entweder initialisiert oder deinitialisiert, haben wir dieses Ziel erfolgreich erreicht. Dies ist ein weiterer Schritt nach vorn bei der Handhabung von Viertelstufen entsprechend den Anforderungen der Händler. Die Erweiterung bietet eine nutzerfreundliche Schnittstelle: Manchmal möchten Sie sich nur auf große Quartiere konzentrieren, ohne dass andere Ebenen stören, während Sie zu anderen Zeiten vielleicht lieber alle Ebenen anzeigen möchten. Darüber hinaus bietet dieses Tool Trendrichtungsanalysen, die Ihnen helfen zu verstehen, was wirklich auf dem Markt vor sich geht, basierend auf dem aktuellen Preis.

Datum Name des Werkzeugs  Beschreibung Version  Aktualisierungen  Hinweis
01/10/24 Chart Projector Skript zur Überlagerung der Kursentwicklung des Vortages mit Geistereffekt. 1.0 Erste Veröffentlichung Toolkit Nummer 1
18/11/24 Analytical Comment Er liefert Informationen zum Vortag in Tabellenform und nimmt die zukünftige Marktentwicklung vorweg. 1.0 Erste Veröffentlichung Toolkit Nummer 2
27/11/24 Analytics Master Reguläre Aktualisierung der Marktmetriken alle zwei Stunden.  1.01 Zweite Veröffentlichung Toolkit Nummer 3
02/12/24 Analytics Forecaster  Reguläre Aktualisierung der Marktmetriken alle zwei Stunden mit Telegram-Integration. 1.1 Dritte Auflage Toolkit Nummer 4
09/12/24 Volatility Navigator Der EA analysiert die Marktbedingungen anhand der Indikatoren Bollinger Bands, RSI und ATR. 1.0 Erste Veröffentlichung Toolkit Nummer 5
19/12/24 Mean Reversion Signal Reaper Analysiert den Markt anhand der Strategie „Umkehr zur Mitte“ und liefert Signale.  1.0  Erste Veröffentlichung  Toolkit Nummer 6 
9/01/25  Signal Pulse  Analysator für mehrere Zeitrahmen. 1.0  Erste Veröffentlichung  Toolkit Nummer 7 
17/01/25  Metrics Board  Bedienfeld mit Taste für die Analyse.  1.0  Erste Veröffentlichung Toolkit Nummer 8 
21/01/25 External Flow Analytik durch externe Bibliotheken. 1.0  Erste Veröffentlichung Toolkit Nummer 9 
27/01/25 VWAP Volumengewichteter Durchschnittspreis   1.3  Erste Veröffentlichung  Toolkit Nummer 10 
02/02/25  Heikin Ashi  Trendglättung und Identifizierung von Umkehrsignalen  1.0  Erste Veröffentlichung  Toolkit Nummer 11
04/02/25  FibVWAP  Signalerzeugung durch Python-Analyse  1.0  Erste Veröffentlichung  Toolkit Nummer 12
14/02/25  RSI DIVERGENCE  Kursentwicklung versus RSI-Divergenzen  1.0  Erste Veröffentlichung  Toolkit Nummer 13 
17/02/25  Parabolic Stop and Reverse (PSAR)  Automatisierung der PSAR-Strategie 1.0 Erste Veröffentlichung  Toolkit Nummer 14
20/02/25  Quarters Drawer Script Einzeichnen der Ebenen der Viertel auf dem Chart  1.0  Erste Veröffentlichung  Toolkit Nummer 15 
27/02/25  Intrusion Detector Erkennen und warnen, wenn der Preis ein Viertel-Niveau erreicht 1.0   Erste Veröffentlichung Toolkit Nummer 16 
27/02/25  TrendLoom Tool  Analysepanel für mehrere Zeitrahmen 1.0 Erste Veröffentlichung Toolkit Nummer 17
11/03/25  Quarters Board  Bedienfeld mit Tasten zum Aktivieren oder Deaktivieren der Viertel-Ebenen  1.0  Erste Veröffentlichung Werkzeug Nummer 18

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

Beigefügte Dateien |
Quarters_Board.mq5 (14.84 KB)
Erweiterte Speicherverwaltung und Optimierungstechniken in MQL5 Erweiterte Speicherverwaltung und Optimierungstechniken in MQL5
Entdecken Sie praktische Techniken zur Optimierung der Speichernutzung in MQL5-Handelssystemen. Lernen Sie, effiziente, stabile und schnell arbeitende Expert Advisors und Indikatoren zu erstellen. Wir werden untersuchen, wie der Speicher in MQL5 wirklich funktioniert, die häufigsten Fallen, die Ihre Systeme verlangsamen oder zum Ausfall führen, und - was am wichtigsten ist - wie man sie beheben kann.
MQL5 Handels-Toolkit (Teil 8): Implementierung und Verwendung der EX5-Bibliothek History Manager in Ihrer Codebasis MQL5 Handels-Toolkit (Teil 8): Implementierung und Verwendung der EX5-Bibliothek History Manager in Ihrer Codebasis
Im letzten Artikel dieser Serie erfahren Sie, wie Sie die EX5-Bibliothek History Manager mühelos in Ihren MQL5-Quellcode importieren und nutzen können, um Handelshistorien in Ihrem MetaTrader 5-Konto zu verarbeiten. Mit einfachen einzeiligen Funktionsaufrufen in MQL5 können Sie Ihre Handelsdaten effizient verwalten und analysieren. Darüber hinaus werden Sie lernen, wie Sie verschiedene Skripte zur Analyse der Handelshistorie erstellen und einen preisbasierten Expert Advisor als praktisches Anwendungsbeispiel entwickeln können. Der Beispiel-EA nutzt Kursdaten und die EX5-Bibliothek History Manager, um fundierte Handelsentscheidungen zu treffen, Handelsvolumina anzupassen und Wiederherstellungsstrategien auf der Grundlage zuvor abgeschlossener Handelsgeschäfte zu implementieren.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Eine Einführung in die Kurven von Receiver Operating Characteristic Eine Einführung in die Kurven von Receiver Operating Characteristic
ROC-Kurven sind grafische Darstellungen, die zur Bewertung der Leistung von Klassifikatoren verwendet werden. Obwohl ROC-Diagramme relativ einfach zu handhaben sind, gibt es bei ihrer Verwendung in der Praxis häufig Missverständnisse und Fallstricke. Dieser Artikel bietet eine Einführung in ROC-Diagramme als Hilfsmittel für Praktiker, die die Leistungsbewertung von Klassifikatoren verstehen wollen.