Visibilidad de los objetos en el contexto de marcos temporales

Los usuarios de MetaTrader 5 conocen la pestaña Mostrar del cuadro de diálogo de propiedades del objeto, donde puede utilizar los interruptores (switches) para seleccionar en qué marcos temporales se mostrará el objeto y en cuáles estará oculto. En concreto, puede ocultar temporalmente el objeto por completo en todos los marcos temporales.

MQL5 tiene una propiedad de programa similar, OBJPROP_TIMEFRAMES, que controla la visibilidad del objeto en un marco temporal. El valor de esta propiedad puede ser cualquier combinación de banderas de enteros especiales: cada bandera (constante) contiene un bit correspondiente a un marco temporal (véase la tabla). Para establecer/obtener la propiedad OBJPROP_TIMEFRAMES, utilice las funciones ObjectSetInteger/ObjectGetInteger.

Constante

Valor

Visibilidad en marcos temporales

OBJ_NO_PERIODS

0

El objeto está oculto en todos los marcos temporales

OBJ_PERIOD_M1

0x00000001

M1

OBJ_PERIOD_M2

0x00000002

M2

OBJ_PERIOD_M3

0x00000004

M3

OBJ_PERIOD_M4

0x00000008

M4

OBJ_PERIOD_M5

0x00000010

M5

OBJ_PERIOD_M6

0x00000020

M6

OBJ_PERIOD_M10

0x00000040

M10

OBJ_PERIOD_M12

0x00000080

M12

OBJ_PERIOD_M15

0x00000100

M15

OBJ_PERIOD_M20

0x00000200

M20

OBJ_PERIOD_M30

0x00000400

M30

OBJ_PERIOD_H1

0x00000800

H1

OBJ_PERIOD_H2

0x00001000

H2

OBJ_PERIOD_H3

0x00002000

H3

OBJ_PERIOD_H4

0x00004000

H4

OBJ_PERIOD_H6

0x00008000

H6

OBJ_PERIOD_H8

0x00010000

H8

OBJ_PERIOD_H12

0x00020000

H12

OBJ_PERIOD_D1

0x00040000

D1

OBJ_PERIOD_W1

0x00080000

W1

OBJ_PERIOD_MN1

0x00100000

MN1

OBJ_ALL_PERIODS

0x001fffff

Todos los marcos temporales

Las banderas pueden combinarse utilizando el operador OR («|»), por ejemplo, la superposición de las banderas OBJ_PERIOD_M15 | OBJ_PERIOD_H4 significa que el objeto será visible en los marcos temporales de 15 minutos y 4 horas.

Obsérvese que cada bandera puede obtenerse desplazando en 1 a la izquierda el número de bits igual al número de la constante en la tabla. Esto facilita la generación dinámica de banderas cuando el algoritmo opera en múltiples marcos temporales en lugar de en uno concreto.

Utilizaremos esta función en el script de prueba ObjectTimeframes.mq5. Su tarea consiste en crear un montón de grandes etiquetas de texto en el gráfico con los nombres de los marcos temporales, y cada título debe mostrarse sólo en el marco temporal correspondiente. Por ejemplo, una etiqueta grande «D1» sólo será visible en el gráfico diario, y al cambiar a H4, veremos «H4».

Para obtener el nombre abreviado del marco temporal, sin el prefijo «PERIOD_», se implementa una sencilla función auxiliar.

string GetPeriodName(const int tf)
{
   const static int PERIOD_ = StringLen("PERIOD_");
   return StringSubstr(EnumToString((ENUM_TIMEFRAMES)tf), PERIOD_);
}

Para obtener la lista de todos los marcos temporales a partir de la enumeración ENUM_TIMEFRAMES, utilizaremos la función EnumToArray que se presentó en la sección sobre conversión de Enumeraciones.

#include "ObjectPrefix.mqh"
#include <MQL5Book/EnumToArray.mqh>
 
void OnStart()
{
   ENUM_TIMEFRAMES tf = 0;
   int values[];
   const int n = EnumToArray(tfvalues0USHORT_MAX);
   ...

Todas las etiquetas se mostrarán en el centro de la ventana en el momento en que se inicie el script. Si se cambia el tamaño de la ventana una vez finalizado el script, los subtítulos creados dejarán de estar centrados. Esto es consecuencia del hecho de que MQL5 sólo admite el anclaje en las esquinas de la ventana, pero no en el centro. Si desea mantener automáticamente la posición de los objetos debe implementar un algoritmo similar en el indicador y responder a eventos de cambio de tamaño de ventana. Como alternativa, podríamos mostrar las etiquetas en una esquina; por ejemplo, la inferior derecha.

   const int centerX = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS) / 2;
   const int centerY = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELS) / 2;
   ...

En el ciclo a través de los marcos temporales, creamos un objeto OBJ_LABEL para cada uno de ellos, y lo colocamos en el centro de la ventana anclada en el centro del objeto.

   for(int i = 1i < n; ++i)
   {
      // create and setup text label for each timeframe
      const string name = ObjNamePrefix + (string)i;
      ObjectCreate(0nameOBJ_LABEL000);
      ObjectSetInteger(0nameOBJPROP_XDISTANCEcenterX);
      ObjectSetInteger(0nameOBJPROP_YDISTANCEcenterY);
      ObjectSetInteger(0nameOBJPROP_ANCHORANCHOR_CENTER);
      ...

A continuación, establecemos el texto (nombre del marco temporal), el tamaño de fuente grande, el color gris y la propiedad de visualización en segundo plano.

      ObjectSetString(0nameOBJPROP_TEXTGetPeriodName(values[i]));
      ObjectSetInteger(0nameOBJPROP_FONTSIZEfmin(centerYcenterX));
      ObjectSetInteger(0nameOBJPROP_COLORclrLightGray);
      ObjectSetInteger(0nameOBJPROP_BACKtrue);
      ...

Por último, generamos la bandera de visibilidad correcta para el marco temporal iésimo y la escribimos en la propiedad OBJPROP_TIMEFRAMES.

      const int flag = 1 << (i - 1);
      ObjectSetInteger(0nameOBJPROP_TIMEFRAMESflag);
   }

Vea lo que ha ocurrido en el gráfico al cambiar de marco temporal.

Etiquetas con nombres de marcos temporales

Etiquetas con nombres de marcos temporales

Si abre el cuadro de diálogo Object List y activa All objetos en la lista, es fácil asegurarse de que haya etiquetas generadas para todos los marcos temporales y comprobar sus banderas de visibilidad.

Para eliminar objetos, puede ejecutar el script ObjectCleanup1.mq5.