Chart-Synchronisation für eine einfachere technische Analyse
Eine der häufigsten Herausforderungen, mit denen Händler bei der technischen Analyse konfrontiert werden, ist die Inkonsistenz der Chart-Kommentare über verschiedene Zeitrahmen hinweg. Die meisten Handelsplattformen erlauben es zwar, dass grafische Objekte wie Trendlinien oder Zonen über mehrere Zeitrahmen hinweg angezeigt werden, wenn der Händler zwischen ihnen navigiert, aber die Analyse mehrerer Zeitrahmen nebeneinander kann dennoch ineffizient sein. Händler öffnen oft mehrere Chart-Fenster für dasselbe Symbol, die jeweils auf einen anderen Zeitrahmen eingestellt sind, um eine breitere technische Perspektive zu erhalten. Ohne Synchronisierung funktioniert jedoch jedes Chart unabhängig. Das bedeutet, dass Änderungen wie Scrollen, Zoomen oder das Wechseln von Symbolen in jedem einzelnen Chart wiederholt werden müssen, was zu einer fragmentierten Analyse, einer erhöhten Arbeitsbelastung und einer höheren Wahrscheinlichkeit führt, dass wichtige Zusammenhänge übersehen werden.
Die Chart-Synchronisation löst dieses Problem, indem sie mehrere Chart-Fenster desselben Symbols über verschiedene Zeitrahmen hinweg miteinander verbindet. Aktionen wie Schwenken, Zoomen oder Symbolwechsel werden in allen synchronisierten Charts gespiegelt, sodass Händler nahtlos denselben Preisaktionskontext in mehreren Zeitrahmen anzeigen und vergleichen können. Diese einheitliche Interaktion strafft den Analyse-Workflow, reduziert den manuellen Aufwand und gewährleistet eine konsistentere und genauere Multi-Timeframe-Analyse, die letztlich schnellere und fundiertere Handelsentscheidungen ermöglicht.
Planung und Logik für Chart-Synchronisationskennzeichen
Kernziel
Erstellen Sie ein System zur Synchronisierung von Charts mit mehreren Zeitrahmen, bei dem Objekte, die auf höheren Zeitrahmen gezeichnet werden, automatisch auf niedrigeren Zeitrahmen mit der richtigen Hierarchie und dem richtigen Styling erscheinen.
1. Anforderung an die Schlüsselfunktionalität:
- Auswahl des Basiszeitrahmens: Der Nutzer wählt seinen bevorzugten Basiszeitrahmen über einen Eingabeparameter aus, alle anderen Charts synchronisieren sich mit diesem Symbol, aber mit anderen Zeitrahmen.
- Hierarchie der Zeitrahmen:
PERIOD_H1 (Highest) ↓ PERIOD_M30 ↓ PERIOD_M15 ↓ PERIOD_M5 (Lowest)
- Regeln für die Weitergabe von Objekten: Objekte, die auf einem beliebigen Zeitrahmen erstellt werden, erscheinen auf allen niedrigeren Zeitrahmen (automatische Ausbreitung nach unten), Beispiel: H1-Objekt sichtbar auf M30, M15 und M5.
- Reset-Funktionalität: Löscht alle synchronisierten Charts (Preis-Chart bleibt erhalten).
2. Systemarchitektur:

3. Workflow-Logik:

4. Ausbreitungslogik:

5. Entwicklungsprozess:
- Initialisierung des Charts: Setzen Sie das Basis-Chart auf den vom Nutzer gewählten Zeitrahmen. Weisen Sie den verbleibenden Zeitrahmen (H1/M30/M15/M5) andere Charts zu und speichern Sie Chart-IDs für die Synchronisationsgruppe.
- Objektverfolgung: Kennzeichnen Sie Objekte mit Metadaten des Ursprungszeitraums und erzeugen Sie Klon-IDs [OriginalName]_Klon_[ChartID].
- Verwaltung von Hierarchien: Pflege der Prioritätenliste für den Zeitrahmen.
const ENUM_TIMEFRAMES timeframes[4] = {PERIOD_H1, PERIOD_M30, PERIOD_M15, PERIOD_M5};
- System zurücksetzen: Löscht alle Objekte mit Ausnahme der Preiselemente vom Chart und der Schaltfläche „Zurücksetzen“ selbst.
Erste Schritte
//+------------------------------------------------------------------+ //| ChartSyncIndicator.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "GIT under MetaQuotes Ltd." #property version "1.01" #property indicator_chart_window #property indicator_plots 0 input ENUM_TIMEFRAMES BaseTimeframe = PERIOD_H1; // Base timeframe for objects input bool SyncAllTimeframes = false; input color DefaultObjColor = clrDodgerBlue; input ENUM_LINE_STYLE DefaultObjStyle = STYLE_SOLID; input int DefaultObjWidth = 2; input bool DefaultObjBack = true; input bool SyncUnlockedObjects = false; input int ResetButtonX = 10; input int ResetButtonY = 20;
Wir beginnen mit der Definition von nutzerkonfigurierbaren Eingabeparametern für einen Indikator zur Chart-Synchronisation. Die Eingabe BaseTimeFrame ermöglicht es dem Nutzer, einen primären Zeitrahmen (z.B. H1) auszuwählen, von dem aus grafische Objekte mit anderen Charts synchronisiert werden sollen. Der Boolesche Wert „SyncAllTimeFrames“ legt fest, ob Objekte mit allen Zeitrahmen oder nur mit ausgewählten Zeitrahmen synchronisiert werden sollen. Die visuellen Eigenschaften der Objekte, wie ihre Farbe (DefaultObjColor), der Linienstil (DefaultObjStyle) und die Linienbreite (DefaultObjWidth), sind für eine klare und konsistente Darstellung anpassbar. Der Parameter „DefaultObjBack“ entscheidet, ob die Objekte im Hintergrund des Charts erscheinen sollen.
Der Eingang „SyncUnlockedObjects“ gibt an, ob nur nicht gesperrte Objekte synchronisiert werden sollen, wodurch die Kontrolle über bearbeitbare Elemente ermöglicht wird. Schließlich bestimmen ResetButtonX und ResetButtomY die Position einer Reset-Taste auf dem Bildschirm, die zum Löschen synchronisierter Zeichnungen verwendet wird.
#define OBJ_ORIGIN_TF "OBJ_ORIGIN_TF_" #define RESET_BUTTON "resetBtn" long baseChartID; string baseSymbol; string timeframesAssigned[]; ENUM_TIMEFRAMES availableTFs[4] = {PERIOD_H1, PERIOD_M30, PERIOD_M15, PERIOD_M5};Hier richten wir einige grundlegende Konstanten und Variablen ein, die in einem Chart-Synchronisationssystem verwendet werden. Die #define-Direktiven erzeugen zwei String-Konstanten OBJ_ORIGIN_TF_, die wir als Präfix verwenden, um Objekte mit ihrem Ursprungszeitrahmen zu kennzeichnen, und resetBtn, das die Reset-Taste auf dem Bildschirm darstellt. Die Variable „baseChartID“ speichert die ID des Hauptdiagramms (oder Basisdiagramms), das als Bezugspunkt für die Synchronisierung dient. Das Basissymbol enthält das Handelssymbol dieses Charts. TimeframesAssigned ist ein dynamisches String-Array, das dazu dient, die vom Nutzer für die Synchronisierung ausgewählten Zeitrahmen zu speichern. Schließlich ist „availableTFs“ ein festes Array, das vier spezifische Zeitrahmen auflistet: H1, M30, M15 und M5.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { baseChartID = ChartID(); baseSymbol = Symbol(); // Set this chart to user-selected base timeframe if(Period() != BaseTimeframe) { ChartSetSymbolPeriod(baseChartID, baseSymbol, BaseTimeframe); } AssignTimeframesToCharts(); CreateResetButtons(); return INIT_SUCCEEDED; }
Wenn der Indikator geladen wird, erfasst er zunächst die ID des aktuellen Charts (baseChartID) und das Handelssymbol (baseSymbol). Anschließend wird geprüft, ob der Zeitrahmen des aktuellen Charts mit dem nutzerdefinierten BaseTimeFrame übereinstimmt. Ist dies nicht der Fall, wird das Chart mit ChartSetSymbolPeriod() automatisch auf den angegebenen Basiszeitrahmen umgestellt. Nachdem sichergestellt wurde, dass der richtige Zeitrahmen eingestellt ist, werden zwei Hilfsfunktionen aufgerufen: „AssignTimeFramesToChart()“, um die Charts und Zeitrahmen, die Teil des Synchronisierungsprozesses sind, zuzuweisen oder zu verfolgen, und „CreateResetButtons()“, um eine Schaltfläche auf der Nutzeroberfläche des Charts zu zeichnen, mit der die Nutzer die synchronisierten Objekte zurücksetzen oder aktualisieren können.
void AssignTimeframesToCharts() { // Create a list of timeframes excluding the base TF ENUM_TIMEFRAMES timeframes[3]; int index = 0; for(int i = 0; i < 4; i++) { if(availableTFs[i] != BaseTimeframe) { timeframes[index] = availableTFs[i]; index++; } } int tfIndex = 0; long currChart = ChartFirst(); ArrayResize(timeframesAssigned, 0); while(currChart != -1 && tfIndex < ArraySize(timeframes)) { if(currChart != baseChartID) { ChartSetSymbolPeriod(currChart, baseSymbol, timeframes[tfIndex]); int size = ArraySize(timeframesAssigned); ArrayResize(timeframesAssigned, size + 1); timeframesAssigned[size] = (string)currChart; tfIndex++; } currChart = ChartNext(currChart); } }
Die Chart-Funktion für die Zuweisung der Zeitrahmen ist zuständig für die Vorbereitung und Zuweisung verschiedener Chart-Zeitrahmen (außer dem Basiszeitrahmen) zur Synchronisierung. Zu Beginn wird ein temporäres Array der Zeitrahmen erstellt, das die Nicht-Basiszeitrahmen aus der vordefinierten Liste availableTFs enthält. Es durchläuft die verfügbaren Zeitrahmen und fügt jeden Zeitrahmen, der nicht mit dem vom Nutzer ausgewählten „BaseTimeFrame“ übereinstimmt, in das Array „Timeframes“ ein. Dadurch wird sichergestellt, dass nur die alternativen Zeitrahmen (z. B. M30, M15, M5, wenn H1 die Basis ist) separaten Chart-Fenstern für die Synchronisierung zugewiesen werden.
Die Funktion durchläuft dann alle geöffneten Chart-Fenster mit ChartFirst() und ChartNext(), um Kandidaten für die Synchronisierung zu finden. Es überspringt das Basisdiagramm (mit baseChartID) und weist jedem verfügbaren Chart mit ChartSetSymbolPeriod() einen der gefilterten Zeitrahmen zu. Da jedem Chart ein Zeitrahmen zugewiesen wird, wird seine Chart-ID in eine Zeichenkette umgewandelt und im Array timeframesAssigend gespeichert, das verfolgt, welche Charts an der Synchronisierung teilnehmen. Die Schleife stoppt, sobald alle Zeitrahmen, die keine Basiszeitrahmen sind, zugewiesen wurden oder keine weiteren Charts verfügbar sind.
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { switch(id) { case CHARTEVENT_OBJECT_CREATE: case CHARTEVENT_OBJECT_DRAG: PropagateObject(sparam, (ENUM_TIMEFRAMES)Period()); break; case CHARTEVENT_OBJECT_DELETE: DeleteSyncedInstances(sparam); break; case CHARTEVENT_OBJECT_CLICK: if(sparam == RESET_BUTTON) { DeleteAllSyncedObjects(); } break; } }
Die Funktion OnChartEvent() verarbeitet Nutzerinteraktionen mit Chart-Objekten und reagiert entsprechend, um die Synchronisation aufrechtzuerhalten. Wenn ein Objekt erstellt oder verschoben wird (OBJECT_CREATE oder OBJECT_DRAG), wird die Funktion PropagateObject() aufgerufen, um dieses Objekt auf der Grundlage des aktuellen Zeitrahmens in allen synchronisierten Charts zu replizieren oder zu aktualisieren. Wenn ein Objekt gelöscht wird (OBJECT_DELETE), entfernt die Funktion DeleteSyncedInstances() alle seine synchronisierten Kopien aus anderen Charts. Wenn der Nutzer auf die Reset-Taste klickt (OBJECT_CLICK und sparam == RESET_BUTTON), wird außerdem DeleteAllSyncedObjects() ausgelöst, um alle synchronisierten grafischen Objekte in allen Zeitrahmen zu löschen. Diese ereignisgesteuerte Logik stellt sicher, dass jede an Chart-Objekten vorgenommene Änderung sofort im gesamten Setup aus mehreren Zeitrahmen reflektiert oder verarbeitet wird.
void PropagateObject(string objName, ENUM_TIMEFRAMES srcTF) { if(StringFind(objName, "_clone_") != -1) return; bool isLocked = ObjectGetInteger(ChartID(), objName, OBJPROP_SELECTABLE); if(!SyncUnlockedObjects && !isLocked) return; for(int i = 0; i < ArraySize(timeframesAssigned); i++) { long targetChart = (long)StringToInteger(timeframesAssigned[i]); ENUM_TIMEFRAMES targetTF = (ENUM_TIMEFRAMES)ChartPeriod(targetChart); bool shouldPropagate = false; if(SyncAllTimeframes) { shouldPropagate = true; } else { // Propagate from base timeframe to all others if(srcTF == BaseTimeframe) { shouldPropagate = true; } // Propagate from other timeframes only to lower timeframes else if(srcTF > targetTF) { shouldPropagate = true; } } if(shouldPropagate) { CloneObject(objName, ChartID(), targetChart); } } }
Die Funktion PropagateObject() ist für die Synchronisierung von grafischen Objekten wie Trendlinien oder Shapes über verschiedene Chart-Zeitrahmen hinweg zuständig. Zunächst werden alle Objekte herausgefiltert, die bereits ein Klon sind (gekennzeichnet durch „clone“ im Namen), um zu vermeiden, dass Kopien rekursiv weitergegeben werden. Anschließend wird geprüft, ob das Objekt gesperrt (auswählbar) ist. Wenn die Einstellung SyncUnlockedObjects false ist und das Objekt nicht gesperrt ist, wird die Funktion vorzeitig beendet, um sicherzustellen, dass nur vom Nutzer genehmigte oder bearbeitbare Objekte übertragen werden. Dies verhindert eine versehentliche Synchronisierung von nicht interaktiven Objekten, die möglicherweise nicht für die Replikation vorgesehen sind.
Der Kern der Funktion durchläuft alle zugewiesenen Charts, die in dem Array timeframesAssigned gespeichert sind. Für jede Zielkarte wird geprüft, ob das Objekt auf der Grundlage der aktuellen Synchronisierungsregeln übertragen werden soll. Wenn SyncAllTimeframes aktiviert ist, wird das Objekt in alle Charts geklont, unabhängig vom Quell- oder Zielzeitrahmen. Andernfalls wird eine logische Regel angewandt: Wenn das Objekt aus dem BaseTimeframe stammt, wird es auf alle anderen Zeitrahmen übertragen; wenn es aus einem höheren Timeframe stammt (z. B. H1) und das Ziel niedriger ist (z. B. M15), wird es ebenfalls übertragen. Sobald diese Bedingungen erfüllt sind, wird CloneObject() aufgerufen, um das Objekt aus dem Quell-Chart in das Ziel-Chart zu kopieren, wobei die visuelle Konsistenz über alle Zeitrahmen hinweg erhalten bleibt.
void CloneObject(string objName, long srcChart, long targetChart) { int type = (int)ObjectGetInteger(srcChart, objName, OBJPROP_TYPE); string newName = objName + "_clone_" + (string)targetChart; if(!ObjectCreate(targetChart, newName, (ENUM_OBJECT)type, 0, 0, 0)) return; datetime time1 = (datetime)ObjectGetInteger(srcChart, objName, OBJPROP_TIME, 0); double price1 = ObjectGetDouble(srcChart, objName, OBJPROP_PRICE, 0); ObjectSetInteger(targetChart, newName, OBJPROP_TIME, 0, time1); ObjectSetDouble(targetChart, newName, OBJPROP_PRICE, 0, price1); datetime time2 = (datetime)ObjectGetInteger(srcChart, objName, OBJPROP_TIME, 1); double price2 = ObjectGetDouble(srcChart, objName, OBJPROP_PRICE, 1); if(time2 > 0 || price2 > 0) { ObjectSetInteger(targetChart, newName, OBJPROP_TIME, 1, time2); ObjectSetDouble(targetChart, newName, OBJPROP_PRICE, 1, price2); } color objColor = ObjectGetInteger(srcChart, objName, OBJPROP_COLOR, 0); ENUM_LINE_STYLE objStyle = (ENUM_LINE_STYLE)ObjectGetInteger(srcChart, objName, OBJPROP_STYLE, 0); int objWidth = ObjectGetInteger(srcChart, objName, OBJPROP_WIDTH, 0); bool objBack = ObjectGetInteger(srcChart, objName, OBJPROP_BACK, 0); ObjectSetInteger(targetChart, newName, OBJPROP_COLOR, objColor != clrNONE ? objColor : DefaultObjColor); ObjectSetInteger(targetChart, newName, OBJPROP_STYLE, objStyle); ObjectSetInteger(targetChart, newName, OBJPROP_WIDTH, objWidth); ObjectSetInteger(targetChart, newName, OBJPROP_BACK, objBack); ObjectSetInteger(targetChart, newName, OBJPROP_SELECTABLE, false); ObjectSetInteger(targetChart, newName, OBJPROP_HIDDEN, true); string originTag = OBJ_ORIGIN_TF + EnumToString((ENUM_TIMEFRAMES)Period()); ObjectSetString(targetChart, newName, OBJPROP_TOOLTIP, originTag); if(type == OBJ_TEXT || type == OBJ_LABEL) { string txt = ObjectGetString(srcChart, objName, OBJPROP_TEXT); ObjectSetString(targetChart, newName, OBJPROP_TEXT, txt); } if(type == OBJ_FIBO) { int levels = (int)ObjectGetInteger(srcChart, objName, OBJPROP_LEVELS); ObjectSetInteger(targetChart, newName, OBJPROP_LEVELS, levels); for(int i = 0; i < levels; i++) { double level = ObjectGetDouble(srcChart, objName, OBJPROP_LEVELVALUE, i); ObjectSetDouble(targetChart, newName, OBJPROP_LEVELVALUE, i, level); } } }
Die Funktion CloneObject() ist für die Replikation eines grafischen Objekts von einem Quell-Chart (srcChart) zu einem Ziel-Chart (targetChart) verantwortlich. Es beginnt mit dem Abrufen des Objekttyps (z. B. Trendlinie, Rechteck oder Fibo) und der Generierung eines neuen eindeutigen Namens durch Anhängen von _clone_ und der Zielchart-ID an den ursprünglichen Namen. Wenn das Objekt nicht mit ObjectCreate() auf der Zielkarte erstellt werden kann, wird die Funktion vorzeitig beendet. Es kopiert dann die erste Koordinate (Zeit und Preis) aus dem Quellobjekt und weist sie der gleichen Position auf dem geklonten Objekt im Ziel-Chart zu. Ist eine zweite Koordinate vorhanden (wie bei Trendlinien oder Kanälen üblich), wird auch diese entsprechend übertragen.
Anschließend wendet die Funktion visuelle Eigenschaften auf das geklonte Objekt an, um sein Aussehen zu erhalten. Dazu gehören die Farbe, der Stil (z. B. durchgezogen oder gestrichelt), die Breite und die Hintergrundschichtung (OBJPROP_BACK). Das geklonte Objekt ist nicht auswählbar (OBJPROP_SELECTABLE = false) und wird aus der Objektliste ausgeblendet (OBJPROP_HIDDEN = true), um versehentliche Bearbeitungen zu vermeiden und die Übersichtlichkeit zu erhöhen. Zusätzlich wird mit OBJPROP_TOOLTIP ein Tooltip-Label hinzugefügt, das das Objekt mit dem ursprünglichen Zeitrahmen als Referenz kennzeichnet. Dies hilft den Händlern zu erkennen, woher das Objekt stammt, insbesondere wenn sie mit mehreren synchronisierten Charts arbeiten.
Und schließlich behandelt die Funktion spezielle Objekttypen. Handelt es sich bei dem Objekt um eine Textkennzeichnung oder ein einfaches Etikett, so wird der angezeigte Textinhalt auf den Klon übertragen. Handelt es sich um ein Fibonacci-Objekt (OBJ_FIBO), kopiert die Funktion die Anzahl der Ebenen und ihre jeweiligen Kursniveaus, um sicherzustellen, dass die Fibo-Struktur auf dem Ziel-Chart korrekt bleibt. Durch die gründliche Duplizierung sowohl der Koordinaten als auch der visuellen/strukturellen Eigenschaften garantiert CloneObject(), dass die synchronisierten Objekte ihren Originalen treu bleiben, was eine konsistente technische Analyse über alle ausgewählten Zeitrahmen hinweg ermöglicht.
//+------------------------------------------------------------------+ //| Required OnCalculate 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[]) { return(rates_total); }
Der Indikator verlässt sich in seiner Kernlogik nicht auf OnCalculate(), da er vollständig über Chart-Ereignisse und Objektmanipulation arbeitet. Die Funktion OnCalculate() ist jedoch nach wie vor in allen nutzerdefinierten Indikatoren erforderlich; wird sie weggelassen, führt dies zu einem Kompilierungsfehler. Um diese Anforderung zu erfüllen, ist ein kleines Codefragment enthalten, das einfach rates_total zurückgibt, ohne irgendwelche Berechnungen durchzuführen.
void DeleteSyncedInstances(string objName) { long thisChart = ChartID(); bool isClone = StringFind(objName, "_clone_") != -1; string baseName = isClone ? StringSubstr(objName, 0, StringFind(objName, "_clone_")) : objName; // Delete from all charts ObjectDelete(thisChart, objName); for(int i = 0; i < ArraySize(timeframesAssigned); i++) { long chartID = (long)StringToInteger(timeframesAssigned[i]); ObjectDelete(chartID, baseName); ObjectDelete(chartID, baseName + "_clone_" + (string)thisChart); } }
Die Funktion DeleteSyncedInstances() stellt sicher, dass beim Löschen eines grafischen Objekts aus einem Chart auch alle seine synchronisierten Gegenstücke in anderen Charts entfernt werden. Zunächst wird festgestellt, ob es sich bei dem gelöschten Objekt um einen Klon handelt (indem geprüft wird, ob sein Name _clone_ enthält) und der ursprüngliche Basisname entsprechend extrahiert. Die Funktion löscht dann das Objekt aus dem aktuellen Chart und durchläuft alle in timeframesAssigned aufgelisteten Charts, wobei sie sowohl das Basisobjekt als auch jeden zugehörigen Klon, der auf das aktuelle Chart verweist, entfernt.
void DeleteAllSyncedObjects() { long chartIDs[]; ArrayResize(chartIDs, ArraySize(timeframesAssigned) + 1); chartIDs[0] = baseChartID; for(int i = 0; i < ArraySize(timeframesAssigned); i++) chartIDs[i + 1] = (long)StringToInteger(timeframesAssigned[i]); for(int j = 0; j < ArraySize(chartIDs); j++) { int total = ObjectsTotal(chartIDs[j]); for(int i = total - 1; i >= 0; i--) { string name = ObjectName(chartIDs[j], i); if(StringFind(name, RESET_BUTTON) == -1) ObjectDelete(chartIDs[j], name); } } }
Die Funktion DeleteAllSyncedObjects() entfernt alle grafischen Objekte in allen synchronisierten Charts, mit Ausnahme der Reset-Schaltfläche selbst. Zunächst wird ein Array chartIDs erstellt, das die ID des Basisdiagramms und alle Chart-IDs aus der Liste timeframesAssigned enthält. Dann werden für jedes dieser Charts alle vorhandenen Objekte in umgekehrter Reihenfolge durchlaufen und gelöscht – es sei denn, der Name des Objekts enthält RESET_BUTTON, sodass die Reset-Schnittstelle intakt bleibt. Diese Funktion bietet eine schnelle Möglichkeit, den Arbeitsbereich von allen synchronisierten Zeichnungen zu befreien.
void CreateResetButtons() { CreateResetButtonOnChart(baseChartID); for(int i=0; i<ArraySize(timeframesAssigned); i++) CreateResetButtonOnChart((long)StringToInteger(timeframesAssigned[i])); }Die Funktion CreateResetButtons() fügt dem Basisdiagramm und allen synchronisierten Charts eine Reset-Schaltfläche hinzu. Er durchläuft jedes zugewiesene Chart in einer Schleife und ruft CreateResetButtonOnChart() auf, sodass der Nutzer mit einem einzigen Klick alle synchronisierten Objekte aus dem Basisdiagramm löschen kann.
void CreateResetButtonOnChart(long cid) { if(ObjectFind(cid, RESET_BUTTON) >= 0) ObjectDelete(cid, RESET_BUTTON); if(!ObjectCreate(cid, RESET_BUTTON, OBJ_BUTTON, 0, 0, 0)) return; ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_XDISTANCE, ResetButtonX); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_YDISTANCE, ResetButtonY); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_XSIZE, 80); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_YSIZE, 20); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_BGCOLOR, clrGray); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_COLOR, clrWhite); ObjectSetString(cid, RESET_BUTTON, OBJPROP_TEXT, "Reset All"); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_SELECTABLE, false); ObjectSetInteger(cid, RESET_BUTTON, OBJPROP_HIDDEN, false); ChartRedraw(cid); }
Die Funktion CreateResetButtonOnChart() erstellt die Schaltfläche „Reset All“ in einem bestimmten Chart (cid). Sie prüft zunächst, ob eine Schaltfläche mit demselben Namen bereits vorhanden ist, und löscht sie, um Doppelarbeit zu vermeiden. Dann wird eine neue Schaltfläche (OBJ_BUTTON) erstellt und ihre Position mit ResetButtonX und ResetButtonY festgelegt, zusammen mit festen Abmessungen und Styling für Hintergrundfarbe, Textfarbe und Beschriftung. Die Schaltfläche ist nicht auswählbar, aber sichtbar (HIDDEN = false), damit die Nutzer mit ihr interagieren können.
void OnDeinit(const int reason) { DeleteAllSyncedObjects(); }Schließlich wird die Funktion OnDeinit() aufgerufen, wenn der Indikator entfernt oder das Chart geschlossen wird. Es löst DeleteAllSyncedObjects() aus, um alle synchronisierten grafischen Elemente zu bereinigen und sicherzustellen, dass keine Restobjekte zurückbleiben.
Demonstration:

Schlussfolgerung
Zusammenfassend lässt sich sagen, dass wir einen Indikator für die Synchronisierung von Charts mit mehreren Zeitrahmen entwickelt haben, der die technische Analyse verbessert, indem er grafische Objekte wie Trendlinien, Rechtecke und Fibonacci-Levels in ausgewählten Zeitrahmen automatisch repliziert. Wir begannen mit der Einrichtung konfigurierbarer Eingänge zur Steuerung von Objektstilen, des Synchronisationsverhaltens und von Nutzeroberflächenkomponenten wie der Reset-Taste. Es wurden Schlüsselfunktionen implementiert, um Chart-Fenstern Zeitrahmen zuzuweisen, Objektereignisse (Erstellung, Verschiebung, Löschung) zu erkennen und weiterzuleiten sowie eine saubere Synchronisierung durch Klonen und konsistente Objektbenennung zu gewährleisten. Zusätzliche Utility-Funktionen sorgten für die Erstellung von Reset-Tasten und die vollständige Bereinigung von Objekten bei Deinitialisierung oder Nutzerbefehlen.
Zusammenfassend lässt sich sagen, dass dieser Indikator Händlern ein leistungsfähiges und effizientes Werkzeug für die Analyse mehrerer Zeitrahmen bietet, da er die Notwendigkeit beseitigt, Objekte in verschiedenen Charts manuell neu zu zeichnen oder zu verwalten. Es sorgt für Konsistenz und Klarheit bei der Arbeit mit mehreren Perspektiven desselben Symbols, rationalisiert Arbeitsabläufe und reduziert die kognitive Belastung. Dank der synchronisierten Sichtbarkeit der Objekte und der nahtlosen Interaktion zwischen den Zeitrahmen können Händler Zusammenstöße besser erkennen, wichtige Niveaus verfolgen und fundiertere Entscheidungen treffen.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/18937
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
MetaTrader trifft auf Google Sheets mit Pythonanywhere: Ein Leitfaden für einen sicheren Datenfluss
Automatisieren von Handelsstrategien in MQL5 (Teil 29): Erstellung eines Preisaktionssystems mit dem harmonischen Muster von Gartley
Entwicklung eines individuellen Indikators für die Marktstimmung
Statistische Arbitrage durch kointegrierte Aktien (Teil 4): Modellaktualisierung in Echtzeit
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.