Actualización o reinicio de un indicador

 
Saludos colegas, espero que se encuentren bien.

Acabo de crear un indicador que muestras líneas en los niveles comerciales de la última hora en cualquier activo financiero, pero tengo un problema a medida que pasan las horas y es que cuando inicia la siguiente hora el indicador no actualiza las líneas que se deben marcar en los nuevos precios obtenidos a menos que cambie de temporalidad. ¿Alguien tiene alguna idea de que podría hacer para que las líneas en los precios obtenidos cada hora se actualicen automáticamente sin necesidad de cambiar de temporalidad o cargarlo de nuevo?

Acá les dejo el código en caso de que necesiten echarle un vistazo:

//+------------------------------------------------------------------+
//|                                                      OHLC_H1.mq5 |
//|                                      Copyright 2024, Saul Lopez. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Saul Lopez."
#property link      ""
#property version   "1.02"
#property indicator_chart_window
#property indicator_plots 0 // Evita la advertencia de "no indicator plot defined"

// Parámetros para mostrar/ocultar líneas
sinput group                                  "*** Niveles comerciales - 0 para oculatar ***"
input int showOpenLine = 1;                   // Open
input int showHighLine = 1;                   // High
input int showLowLine = 1;                    // Low
input int showCloseLine = 1;                  // Close
input int showVerticalLine = 0;               // Separador de intervalos

// Parámetros de entrada
sinput group                                  "*** Personalización NC ***"
input int widthLines = 1;                    // Grosor de las líneas
input ENUM_LINE_STYLE lineStyle = STYLE_DOT;  // Estilo de las líneas
sinput group                                  "*** Colores ***"
input color colorOpenLine = clrYellow;        // Color de la línea de Open
input color colorHighLine = clrTeal;          // Color de la línea de High
input color colorLowLine = clrSteelBlue;      // Color de la línea de Low
input color colorCloseLine = clrDarkBlue;     // Color de la línea de Close
input color colorVerticalLine = clrGray;      // Color separador de intervalos
sinput group                                  "*** Intervalos de actualización ***"
input int updateInterval = 3600;              // Intervalo de actualización en segundos (3600s = 1 hora)

datetime lastUpdate = 0; // Tiempo de la última actualización

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Configurar temporizador para actualizar cada hora
   EventSetTimer(updateInterval);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Eliminar temporizador
   EventKillTimer();

   // Eliminar las líneas del gráfico
   ObjectDelete(0, "OpenLine");
   ObjectDelete(0, "HighLine");
   ObjectDelete(0, "LowLine");
   ObjectDelete(0, "CloseLine");
   ObjectDelete(0, "VerticalLine");
   ObjectDelete(0, "TradeRecommendation"); // Eliminar el label de recomendación
}

//+------------------------------------------------------------------+
//| Custom indicator iteration 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[])
{
   datetime currentTime = TimeCurrent();

   // Verificar si ya se actualizó en la última hora
   if (currentTime - lastUpdate < updateInterval)
      return prev_calculated;

   // Reiniciar el indicador eliminando las líneas antes de la nueva actualización
   OnDeinit(0);

   // Obtener el inicio y fin de la hora anterior
   datetime startTime = iTime(NULL, PERIOD_H1, 1);
   datetime endTime = startTime + 3600; // Fin de la hora anterior

   // Escanear velas M1 para la hora anterior
   datetime firstM1Time = 0, lastM1Time = 0;
   double highestPrice = -DBL_MAX, lowestPrice = DBL_MAX;
   datetime highestTime = 0, lowestTime = 0;

   // Iterar sobre las velas M1 de la hora anterior
   for (int i = 0; i < iBars(NULL, PERIOD_M1); i++)
   {
      datetime m1Time = iTime(NULL, PERIOD_M1, i);

      if (m1Time >= startTime && m1Time < endTime)
      {
         // Encontrar la primera vela M1
         if (firstM1Time == 0)
            firstM1Time = m1Time;

         // Encontrar la última vela M1
         lastM1Time = m1Time;

         // Encontrar el high más alto
         double m1High = iHigh(NULL, PERIOD_M1, i);
         if (m1High > highestPrice)
         {
            highestPrice = m1High;
            highestTime = m1Time;
         }

         // Encontrar el low más bajo
         double m1Low = iLow(NULL, PERIOD_M1, i);
         if (m1Low < lowestPrice)
         {
            lowestPrice = m1Low;
            lowestTime = m1Time;
         }
      }
   }

   // Obtener el precio de apertura de la primera vela de M1 y el precio de cierre de la última
   double openPrice = iOpen(NULL, PERIOD_M1, iBarShift(NULL, PERIOD_M1, firstM1Time));
   double closePrice = iClose(NULL, PERIOD_M1, iBarShift(NULL, PERIOD_M1, lastM1Time));

   // Crear líneas para los niveles comerciales con los respectivos anclajes
   if (showOpenLine == 1)
      DrawLine("OpenLine", firstM1Time, openPrice, endTime, openPrice, colorOpenLine, widthLines, lineStyle); // Apertura
   if (showHighLine == 1)
      DrawLine("HighLine", highestTime, highestPrice, endTime, highestPrice, colorHighLine, widthLines, lineStyle); // High
   if (showLowLine == 1)
      DrawLine("LowLine", lowestTime, lowestPrice, endTime, lowestPrice, colorLowLine, widthLines, lineStyle); // Low
   if (showCloseLine == 1)
      DrawLine("CloseLine", lastM1Time, closePrice, endTime, closePrice, colorCloseLine, widthLines, lineStyle); // Cierre

   // Dibujar línea vertical en la primera vela de M1 (apertura) si está en las temporalidades de 1M o 5M
   if (showVerticalLine == 1 && (Period() == PERIOD_M1 || Period() == PERIOD_M5))
      DrawVerticalLine("VerticalLine", firstM1Time, colorVerticalLine, widthLines, lineStyle);

   // Evaluar precios y mostrar recomendación
   string recommendation = "";
   color commentColor = clrWhite; // Inicializar el color del comentario

   if (openPrice > closePrice)
   {
      recommendation = "Compras";
      commentColor = clrForestGreen; // Color si Open es mayor que Close
   }
   else if (openPrice < closePrice)
   {
      recommendation = "Ventas";
      commentColor = clrRed; // Color si Open es menor que Close
   }

   // Dibujar el label de recomendación
   if (recommendation != "")
      DrawLabel("TradeRecommendation", recommendation, firstM1Time, high[0] + 10 * _Point, commentColor, 10); // Ajusta la posición según sea necesario

   // Actualizar el tiempo de la última actualización
   lastUpdate = currentTime;

   return rates_total; // Retornar el total de tasas para la siguiente llamada
}

//+------------------------------------------------------------------+
//| Function to draw a line at a given time and price               |
//+------------------------------------------------------------------+
void DrawLine(string name, datetime time1, double price1, datetime time2, double price2, color lineColor, int lineWidth, ENUM_LINE_STYLE style)
{
   // Si la línea ya existe, la eliminamos antes de crearla de nuevo
   if (ObjectFind(0, name) != -1)
      ObjectDelete(0, name);

   // Crear la línea
   if (!ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2))
   {
      Print("Error al crear la línea: ", name);
      return;
   }

   // Configurar las propiedades de la línea
   ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, lineWidth);
   ObjectSetInteger(0, name, OBJPROP_STYLE, style);
   ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);  // Extender la línea a la derecha
   ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false);  // No extender la línea a la izquierda
}

//+------------------------------------------------------------------+
//| Function to draw a vertical line                                 |
//+------------------------------------------------------------------+
void DrawVerticalLine(string name, datetime time, color lineColor, int lineWidth, ENUM_LINE_STYLE style)
{
   // Si la línea ya existe, la eliminamos antes de crearla de nuevo
   if (ObjectFind(0, name) != -1)
      ObjectDelete(0, name);

   // Crear la línea vertical
   if (!ObjectCreate(0, name, OBJ_VLINE, 0, time, 0))
   {
      Print("Error al crear la línea vertical: ", name);
      return;
   }

   // Configurar las propiedades de la línea
   ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, lineWidth);
   ObjectSetInteger(0, name, OBJPROP_STYLE, style);
}

//+------------------------------------------------------------------+
//| Function to draw a label at a given time and price               |
//+------------------------------------------------------------------+
void DrawLabel(string name, string text, datetime time, double price, color textColor, int fontSize)
{
   // Si el label ya existe, lo eliminamos antes de crearlo de nuevo
   if (ObjectFind(0, name) != -1)
      ObjectDelete(0, name);

   // Crear el label
   if (!ObjectCreate(0, name, OBJ_LABEL, 0, time, price))
   {
      Print("Error al crear el label: ", name);
      return;
   }

   // Configurar las propiedades del label
   ObjectSetInteger(0, name, OBJPROP_COLOR, textColor);
   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontSize);
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, 7);   // Distancia desde el borde derecho en píxeles
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 25);  // Distancia desde el borde superior en píxeles
   ObjectSetString(0, name, OBJPROP_TEXT, text);
   ObjectSetInteger(0, name, OBJPROP_XSIZE, 100); // Ajustar el tamaño de la etiqueta
   ObjectSetInteger(0, name, OBJPROP_YSIZE, 20); // Ajustar el tamaño de la etiqueta
}
 
Elimina líneas al marcar para que se actualicen y estés feliz :)))