Sincronización de gráficos para facilitar el análisis técnico
Uno de los retos habituales a los que se enfrentan los operadores durante el análisis técnico es la falta de coherencia de las anotaciones en los gráficos entre los distintos marcos temporales. Aunque la mayoría de las plataformas de negociación permiten que los objetos gráficos, como las líneas de tendencia o las zonas, aparezcan en todos los marcos temporales a medida que el operador navega entre ellos, analizar varios marcos temporales en paralelo puede seguir resultando poco eficiente. Los traders (operadores) suelen abrir varias ventanas de gráficos para un mismo valor, cada una con un intervalo de tiempo diferente, con el fin de obtener una perspectiva técnica más amplia. Sin embargo, sin sincronización, cada gráfico funciona de forma independiente. Esto significa que acciones como desplazarse por el gráfico, ampliarlo o cambiar de símbolo deben repetirse en cada gráfico por separado, lo que da lugar a un análisis fragmentado, una mayor carga de trabajo y un mayor riesgo de pasar por alto confluencias clave.
La sincronización de gráficos resuelve este problema vinculando varias ventanas de gráficos del mismo valor en diferentes marcos temporales. Acciones como el desplazamiento, el zoom o los cambios de símbolos se reflejan en todos los gráficos sincronizados, lo que permite a los operadores visualizar y comparar sin problemas el mismo contexto de evolución de los precios en varios marcos temporales. Esta interacción unificada agiliza el flujo de trabajo analítico, reduce el esfuerzo manual y garantiza un análisis en múltiples marcos temporales más coherente y preciso, lo que, en última instancia, permite tomar decisiones de negociación más rápidas y fundamentadas.
Planificación y lógica del indicador de sincronización de gráficos
Objetivo principal
Crear un sistema de sincronización de gráficos entre distintos intervalos de tiempo, de modo que los objetos dibujados en los intervalos de tiempo superiores aparezcan automáticamente en los inferiores con la jerarquía y el estilo adecuados.
1. Requisito funcional clave:
- Selección del marco temporal de referencia: el usuario selecciona su marco temporal de referencia preferido mediante un parámetro de entrada; el resto de gráficos se sincronizan con este símbolo, pero con marcos temporales diferentes.
- Jerarquía temporal:
PERIOD_H1 (Superior) ↓ PERIOD_M30 ↓ PERIOD_M15 ↓ PERIOD_M5 (Inferior)
- Reglas de propagación de objetos: los objetos creados en cualquier marco temporal aparecen en todos los marcos temporales inferiores (propagación automática hacia abajo); por ejemplo, un objeto de H1 es visible en M30, M15 y M5.
- Función de restablecimiento: borra los objetos de todos los gráficos sincronizados (se conserva el gráfico de precios).
2. Arquitectura del sistema:

3. Lógica del flujo de trabajo:

4. Lógica de propagación:

5. Proceso de desarrollo:
- Inicialización del gráfico: Establecer el gráfico base en el intervalo de tiempo seleccionado por el usuario. Asigna otros gráficos a los demás intervalos de tiempo (H1/M30/M15/M5) y guarda los identificadores de los gráficos para el grupo de sincronización.
- Seguimiento de objetos: Etiqueta los objetos con metadatos del periodo de tiempo de origen y genera identificadores de clon [NombreOriginal]_clone_[IDDelGráfico].
- Gestión de la jerarquía: mantener una lista de prioridades de los marcos temporales.
const ENUM_TIMEFRAMES timeframes[4] = {PERIOD_H1, PERIOD_M30, PERIOD_M15, PERIOD_M5};
- Restablecer sistema: Elimina todos los objetos, excepto los elementos del gráfico de precios y el propio botón de restablecimiento.
Primeros pasos
//+------------------------------------------------------------------+ //| 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;
Empezamos definiendo los parámetros de entrada configurables por el usuario para un indicador de sincronización de gráficos. El campo «BaseTimeframe» permite al usuario seleccionar un marco temporal principal (por ejemplo, H1) a partir del cual se sincronizarán los objetos gráficos con otros gráficos. El parámetro booleano `SyncAllTimeframes` determina si los objetos deben sincronizarse con todos los marcos temporales o solo con los seleccionados. Las propiedades visuales de los objetos, como su color (DefaultObjColor), el estilo de línea (DefaultObjStyle) y el grosor de línea (DefaultObjWidth), se pueden personalizar para lograr una visualización clara y coherente. El parámetro `DefaultObjBack` determina si los objetos deben aparecer en el fondo del gráfico.
El parámetro `SyncUnlockedObjects` especifica si también deben sincronizarse los objetos no seleccionables, lo que permite controlar los elementos editables. Por último, ResetButtonX y ResetButtonY determinan la posición en pantalla de un botón de reinicio que se utiliza para borrar los dibujos sincronizados.
#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};A continuación, definimos algunas constantes y variables básicas que se utilizan en un sistema de sincronización de gráficos. Las directivas #define crean dos constantes de cadena: OBJ_ORIGIN_TF_, que utilizamos como prefijo para identificar los objetos según su intervalo de tiempo de origen, y resetBtn, que representa el botón de reinicio que aparece en pantalla. La variable `baseChartID` almacena el ID del gráfico principal (o gráfico base) que sirve como punto de referencia para la sincronización. El símbolo base indica el símbolo bursátil de ese gráfico. La variable «timeframesAssigned» es una matriz dinámica de cadenas destinada a almacenar los identificadores de los gráficos que participan en la sincronización. Por último, `availableTFs` es una matriz fija que enumera cuatro intervalos de tiempo concretos: H1, M30, M15 y 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; }
Cuando se carga el indicador, lo primero que hace es registrar el ID del gráfico actual (baseChartID) y el símbolo financiero (baseSymbol). A continuación, comprueba si el intervalo de tiempo del gráfico actual coincide con el BaseTimeframe definido por el usuario. De lo contrario, cambia automáticamente el gráfico al intervalo de tiempo base especificado mediante la función ChartSetSymbolPeriod(). Tras asegurarse de que se ha establecido el intervalo de tiempo correcto, llama a dos funciones auxiliares: `AssignTimeframesToCharts()`, para asignar o realizar un seguimiento de los gráficos y los intervalos de tiempo que formarán parte del proceso de sincronización, y `CreateResetButtons()`, para dibujar un botón de la interfaz de usuario en el gráfico que permita a los usuarios restablecer o actualizar los objetos sincronizados.
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); } }
La función «Asignar intervalos de tiempo al gráfico» se encarga de preparar y asignar diferentes intervalos de tiempo del gráfico (excluyendo el intervalo de tiempo base) para su sincronización. En primer lugar, se crea una matriz temporal «timeframes» para almacenar los marcos temporales no básicos de la lista predefinida «availableTFs». Recorre los TF disponibles y añade cualquier intervalo de tiempo que no coincida con el `BaseTimeframe` seleccionado por el usuario a la matriz `timeframes`. De este modo se garantiza que solo los marcos temporales alternativos (por ejemplo, M30, M15 y M5, si H1 es el marco base) se asignen a ventanas de gráficos independientes para su sincronización.
A continuación, la función recorre todas las ventanas de gráficos abiertas utilizando las funciones ChartFirst() y ChartNext() para encontrar los gráficos candidatos a la sincronización. Omite el gráfico base (utilizando baseChartID) y asigna uno de los intervalos de tiempo filtrados a cada gráfico disponible mediante ChartSetSymbolPeriod(). Dado que a cada gráfico se le asigna un intervalo de tiempo, su ID se convierte en una cadena y se almacena en el array `timeframesAssigned`, que registra qué gráficos participan en la sincronización. El bucle se detiene una vez que se han asignado todos los marcos temporales no básicos o cuando ya no hay más gráficos disponibles.
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; } }
La función OnChartEvent() gestiona las interacciones del usuario con los objetos del gráfico y responde en consecuencia para mantener la sincronización. Cuando se crea o se desplaza un objeto (OBJECT_CREATE u OBJECT_DRAG), se invoca la función PropagateObject() para replicar o actualizar dicho objeto en todos los gráficos sincronizados en función del intervalo de tiempo actual. Si se elimina un objeto (OBJECT_DELETE), la función DeleteSyncedInstances() elimina todas sus copias sincronizadas de los demás gráficos. Además, si el usuario hace clic en el botón de restablecimiento (OBJECT_CLICK y sparam == RESET_BUTTON), se activa la función DeleteAllSyncedObjects() para borrar todos los objetos gráficos sincronizados en todos los marcos temporales. Esta lógica basada en eventos garantiza que cualquier modificación que se realice en los objetos del gráfico se refleje o se gestione al instante en toda la configuración de múltiples marcos temporales.
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); } } }
La función PropagateObject() se encarga de sincronizar objetos gráficos, como líneas de tendencia o figuras, entre los distintos intervalos de tiempo de los gráficos. En primer lugar, descarta cualquier objeto que ya sea un clon (identificado por la secuencia «_clone_» en su nombre) para evitar la propagación recursiva de copias. A continuación, comprueba si el objeto es seleccionable; si el parámetro «SyncUnlockedObjects» es «false» y el objeto no es seleccionable, la función se detiene prematuramente, lo que garantiza que solo se propaguen los objetos seleccionables. Esto evita la sincronización accidental de objetos no interactivos que quizá no estén destinados a la replicación.
El núcleo de la función recorre todos los gráficos asignados almacenados en el array «timeframesAssigned». Para cada gráfico de destino, evalúa si el objeto debe propagarse según las reglas de sincronización actuales. Si la opción «SyncAllTimeframes» está activada, el objeto se clona en todos los gráficos, independientemente del marco temporal de origen o de destino. En caso contrario, se aplica una regla lógica: si el objeto procede del marco temporal base, se propaga a todos los demás marcos temporales; si procede de un marco temporal superior (por ejemplo, H1) y el de destino es inferior (por ejemplo, M15), también se propaga. Una vez cumplidas estas condiciones, se llama a la función CloneObject() para replicar el objeto del gráfico de origen al gráfico de destino, manteniendo la coherencia visual entre los distintos marcos temporales.
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); } } }
La función CloneObject() se encarga de replicar un objeto gráfico desde un gráfico de origen (srcChart) a un gráfico de destino (targetChart). En primer lugar, se recupera el tipo de objeto (como una línea de tendencia, un rectángulo o un Fibo) y se genera un nuevo nombre único añadiendo «_clone_» y el ID del gráfico de destino al nombre original. Si no es posible crear el objeto en el gráfico de destino mediante ObjectCreate(), la función finaliza prematuramente. A continuación, copia la primera coordenada (hora y precio) del objeto de origen y la asigna a la misma posición en el objeto clonado del gráfico de destino. Si existe una segunda coordenada (como suele ocurrir con las líneas de tendencia o los canales), también se transfiere en consecuencia.
A continuación, la función aplica propiedades visuales al objeto clonado para mantener su aspecto. Entre ellas se incluyen el color, el estilo (por ejemplo, continuo o discontinuo), el ancho y la capa de fondo (OBJPROP_BACK). El objeto clonado se configura como no seleccionable (OBJPROP_SELECTABLE = false) y se oculta de la lista de objetos (OBJPROP_HIDDEN = true) para evitar modificaciones accidentales y reducir el desorden. Además, se añade una etiqueta de información sobre herramientas mediante OBJPROP_TOOLTIP, que identifica el objeto con el intervalo de tiempo original a modo de referencia. Esto ayuda a los operadores a identificar de dónde procede el objeto, sobre todo cuando se trabaja con varios gráficos sincronizados.
Por último, la función gestiona tipos de objetos especiales. Si el objeto es una etiqueta de texto o una etiqueta simple, transfiere el contenido de texto que se muestra al clon. Si se trata de un objeto de Fibonacci (OBJ_FIBO), la función copia el número de niveles y sus respectivos niveles de precio, garantizando que la estructura de Fibonacci se mantenga precisa en el gráfico de destino. Al duplicar íntegramente tanto las coordenadas como las propiedades visuales y estructurales, CloneObject() garantiza que los objetos sincronizados se mantengan fieles a sus originales, lo que permite realizar un análisis técnico coherente en todos los intervalos de tiempo seleccionados.
//+------------------------------------------------------------------+ //| 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); }
El indicador no se basa en OnCalculate() para su lógica principal, ya que funciona íntegramente a través de eventos del gráfico y la manipulación de objetos. Sin embargo, la función OnCalculate() sigue siendo obligatoria en todos los indicadores personalizados; si se omite, se produce un error de compilación. Para cumplir este requisito, se incluye un stub mínimo que simplemente devuelve «rates_total» sin realizar ningún cálculo.
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); } }
La función DeleteSyncedInstances() garantiza que, cuando se elimina un objeto gráfico de un gráfico, también se eliminen todas sus contrapartes sincronizadas en los demás gráficos. En primer lugar, determina si el objeto eliminado es un clon (comprobando si su nombre contiene _clone_) y, en función de ello, extrae el nombre base original. A continuación, la función elimina el objeto del gráfico actual y recorre todos los gráficos que figuran en «timeframesAssigned», eliminando tanto el objeto base como cualquier clon asociado que haga referencia al gráfico actual.
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); } } }
La función DeleteAllSyncedObjects() elimina todos los objetos gráficos de todos los gráficos sincronizados, excepto el propio botón de restablecimiento. En primer lugar, crea una matriz, «chartIDs», que contiene el ID del gráfico base y todos los ID de los gráficos de la lista «timeframesAssigned». A continuación, para cada uno de estos gráficos, recorre todos los objetos existentes en orden inverso y los elimina, salvo que el nombre del objeto contenga «RESET_BUTTON», lo que garantiza que la interfaz de reinicio permanezca intacta. Esta función permite eliminar rápidamente del espacio de trabajo todos los objetos gráficos sincronizados.
void CreateResetButtons() { CreateResetButtonOnChart(baseChartID); for(int i=0; i<ArraySize(timeframesAssigned); i++) CreateResetButtonOnChart((long)StringToInteger(timeframesAssigned[i])); }La función CreateResetButtons() añade un botón de restablecimiento al gráfico principal y a todos los gráficos sincronizados. Recorre cada gráfico asignado y llama a la función CreateResetButtonOnChart(), lo que permite a los usuarios borrar todos los objetos sincronizados del gráfico base con un solo clic.
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); }
La función CreateResetButtonOnChart() crea un botón «Restablecer todo» en un gráfico específico (cid). Primero comprueba si ya existe un botón con el mismo nombre y, en caso afirmativo, lo elimina para evitar duplicados. A continuación, crea un nuevo botón (OBJ_BUTTON) y establece su posición mediante ResetButtonX y ResetButtonY, además de definir unas dimensiones fijas y el estilo del color de fondo, el color del texto y la etiqueta. El botón se configura como no seleccionable pero visible (HIDDEN = false) para que los usuarios puedan interactuar con él.
void OnDeinit(const int reason) { DeleteAllSyncedObjects(); }Por último, la función OnDeinit() se ejecuta cuando se elimina el indicador o se cierra el gráfico. Activa la función DeleteAllSyncedObjects() para eliminar todos los elementos gráficos sincronizados, garantizando que no queden objetos residuales.
Demostración:

Conclusión
En resumen, hemos desarrollado un indicador de sincronización de gráficos en varios intervalos de tiempo que mejora el análisis técnico al replicar automáticamente objetos gráficos —como líneas de tendencia, rectángulos y niveles de Fibonacci— en los intervalos de tiempo seleccionados. Empezamos por configurar entradas personalizables para controlar los estilos de los objetos, el comportamiento de la sincronización y los componentes de la interfaz de usuario, como el botón de restablecimiento. Se implementaron funciones clave para asignar intervalos de tiempo a las ventanas de gráficos, detectar y propagar eventos de objetos (creación, movimiento, eliminación) y mantener una sincronización óptima mediante la clonación y una nomenclatura coherente de los objetos. Otras funciones auxiliares se encargaban de la creación del botón de reinicio y de la eliminación completa de los objetos tras la desinicialización o mediante un comando del usuario.
En conclusión, este indicador ofrece a los operadores una herramienta potente y eficaz para el análisis en múltiples marcos temporales, ya que elimina la necesidad de volver a trazar o gestionar manualmente los objetos en los distintos gráficos. Garantiza la coherencia y la claridad al trabajar con múltiples perspectivas del mismo símbolo, lo que agiliza los flujos de trabajo y reduce la carga cognitiva. Gracias a la visibilidad sincronizada de los objetos y a la interacción fluida entre los marcos temporales, los operadores pueden detectar mejor las confluencias, realizar un seguimiento de los niveles clave y tomar decisiones más fundamentadas.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/18937
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Pipelines en MQL5
Automatización de estrategias de trading en MQL5 (Parte 32): Creación de un sistema para el patrón armónico 5 Drives basado en Price Action
Desarrollo de un indicador personalizado de matriz de rendimiento de cuenta
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 40): Pasaporte de ADN del mercado
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso