Issue with Indicator on MetaTrader - Objects with Future Dates

 

Hello everyone,

I am facing an issue on MetaTrader where my indicator is not counting objects that have dates later than the current server time. Below is the code for reference. Can someone help me resolve this?

Thanks in advance for the help!
//+------------------------------------------------------------------+
//|                                                    TrendCount.mq5|
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com|
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Yellow
#property indicator_width1  30  // Ajuste aqui a largura do histograma
#property indicator_label1  "TrendCount"

//--- Declaração de variáveis e objetos
datetime DataInicioPerido, DataFimPerido;

//--- indicator buffers
double TrendCountBuffer[];

input int DiasRetroativos = 0;
input int DiasPosteriores = 1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- indicator buffers mapping
   SetIndexBuffer(0, TrendCountBuffer, INDICATOR_DATA);
   //--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME, "Trend Line Count");
   //--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);

   DataInicioPerido = (TimeCurrent() / 86400) * 86400 - 86400 * DiasRetroativos;
   DataFimPerido = (TimeCurrent() / 86400) * 86400 + 86400 * DiasPosteriores - 1;

   Print("DataInicioPerido: ", DataInicioPerido, " DataFimPerido: ", DataFimPerido);

   //--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   //--- check for rates total
    if(rates_total == 0)
       return(0);

   //--- set buffer as series
   ArraySetAsSeries(TrendCountBuffer, true);

   //--- reset buffer
   ArrayInitialize(TrendCountBuffer, 0);
   
   //--- count trend lines
    int total_objects = ObjectsTotal(0, 0, OBJ_TREND);
   //Print("Total de objetos no gráfico: ", total_objects);

   for(int i = 0; i < total_objects; i++)
     {
      string name = ObjectName(0, i, 0, OBJ_TREND);
      if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_TREND)
        {
         datetime DateInicio = ObjectGetInteger(0, name, OBJPROP_TIME, 1);

         if (StringFind(name, "HD-NoticiaValor-D", 0) > 0)
          {
            int multiplier = 0;
            if (StringFind(name, "*1D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*2D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*3D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*4D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*5D", 0) >= 0) multiplier = 1;
                
            if (multiplier != 0)
            {
               int bar_index = iBarShift(NULL, 0, DateInicio, true);

               if (bar_index == -1) // Se não encontrou a barra, tenta a mais próxima
               {
                  bar_index = iBarShift(NULL, 0, DateInicio, true);
                  Print("Barra exata não encontrada, usando barra mais próxima para: ", DateInicio, " com índice: ", bar_index);
               }

               if (bar_index >= 0 && bar_index < rates_total)
               {
                  TrendCountBuffer[bar_index] += multiplier;
                 // Print("Encontrada linha de tendência: ", name, " no índice da barra: ", bar_index, " com multiplicador: ", multiplier);
               }
               else
               {
                 // Print("Erro: Índice de barra inválido para ", name, " com bar_index: ", bar_index);
               }
            }
          }
        }
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+







 
         if (StringFind(name, "HD-NoticiaValor-D", 0) > 0)
  1. You haven't shown any code that creates objects.
              Be precise and informative about your problem

  2. Do you ever expect any objects created, to contain that string after, not starting with?
 
Hello,

I am facing an issue on MetaTrader where my indicator is not counting objects that have dates later than the current server time. Below is the code I am using, where I simulate the creation of trend objects throughout the day. Despite creating objects with future dates, the indicator does not reflect these in the histogram. Could someone help me resolve this?

Thanks in advance for the help!
//+------------------------------------------------------------------+
//|                                                    TrendCount.mq5|
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com|
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Yellow
#property indicator_width1  1  
#property indicator_label1  "TrendCount"

//--- indicator buffers
double TrendCountBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   
    ObjectsDeleteAll(0, "PHD", -1, -1);
   
   //--- call the function to create trend objects
   CreateTrendObjects();
   
   //--- indicator buffers mapping
   SetIndexBuffer(0, TrendCountBuffer, INDICATOR_DATA);
   //--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME, "Trend Line Count");
   //--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);

   //--- list all objects for debugging
   ListAllObjects();

   //--- initialization done
   Print("OnInit completed");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, "PHD", -1, -1);
}



//+------------------------------------------------------------------+
//| 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[])
{
   //--- set buffer as series
   ArraySetAsSeries(TrendCountBuffer, true);

   //--- reset buffer
   ArrayInitialize(TrendCountBuffer, 0);
    
   for (int i = ObjectsTotal(0, 0, OBJ_TREND) - 1; i >= 0; i--)
   {
       string name = ObjectName(0, i, 0, OBJ_TREND);
       datetime DateInicio = ObjectGetInteger(0, name, OBJPROP_TIME, 0);
        
       int multiplier = 0;
       if (StringFind(name, "PHD-NoticiaValor*1D-", 0) >= 0) multiplier = 5;
       else if (StringFind(name, "PHD-NoticiaValor*2D-", 0) >= 0) multiplier = 2;
       else if (StringFind(name, "PHD-NoticiaValor*3D-", 0) >= 0) multiplier = 3;
       else if (StringFind(name, "PHD-NoticiaValor*4D-", 0) >= 0) multiplier = 4;
       else if (StringFind(name, "PHD-NoticiaValor*5D-", 0) >= 0) multiplier = 5;
                
       if (multiplier != 0)
       {   
           TrendCountBuffer[i] += multiplier; 
       }
   }

   return(rates_total);
}

//+------------------------------------------------------------------+
//| Function to create trend objects for testing                     |
//+------------------------------------------------------------------+
void CreateTrendObjects()
{
   datetime current_time = TimeCurrent();
   datetime start_time = StringToTime(TimeToString(current_time, TIME_DATE) + " 00:00:00"); // Start of the current day
   datetime end_of_day = StringToTime(TimeToString(current_time, TIME_DATE) + " 23:59:59"); // End of the current day

   int object_count = 0;
   double last_price = 2330.00; // Initial value

   for(datetime time_iter = start_time; time_iter <= end_of_day; time_iter += 30 * 60) // Increment by 30 minutes
   {
      // Object name with suffix "Hour-Number"
      string name = "PHD-NoticiaValor*1D-" + TimeToString(time_iter, TIME_MINUTES) + "-" + IntegerToString(object_count);

      datetime time1 = time_iter; // Initial time for the object
      datetime time2 = time1 + (60 * 60); // 1 hour after time1
      double price1, price2;

      // Check if the date is in the future
      if (time1 > current_time)
      {
         price1 = last_price; // Use the last available price for future dates
         price2 = price1 + 0.01;
      }
      else
      {
         price1 = 2330.00 + (object_count * 0.01); // Initial price for the trend line
         price2 = price1 + 0.01; // Final price for the trend line
         last_price = price1; // Update the last available price
      }

      ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clrYellow);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

      // Print to confirm object creation
      Print("Object created: ", name, " with initial time: ", TimeToString(time1), " and initial price: ", price1);

      object_count++;
   }
}

//+------------------------------------------------------------------+
//| Function to list all objects on the chart                        |
//+------------------------------------------------------------------+
void ListAllObjects()
{
   int total_objects = ObjectsTotal(0, 0); // Correct use of ObjectsTotal
   Print("Total objects on the chart: ", total_objects);
   for(int i = 0; i < total_objects; i++)
   {
      string name = ObjectName(0, i, 0); // Correct use of ObjectName
      int type = ObjectGetInteger(0, name, OBJPROP_TYPE);
      Print("Object: ", name, ", Type: ", type);
   }
}

//+------------------------------------------------------------------+

 

This is what I get in output... Looks like it is counting. 

Files:
 
Your screenshot is correct, but please pay attention to the date and time of the object. The histogram, for some reason, is unable to work with dates in the future relative to the current period and thus converts them to a previous period.
 

Hello William, Yashar, and everyone,

Thank you for the responses and feedback so far. I would like to provide more details about the issue I am facing with my indicator in MetaTrader.

The problem is that the indicator is not correctly counting objects with dates later than the current server time. Even though I am creating objects with future dates, they do not appear correctly in the histogram. Below is the complete code for the indicator, which includes the creation of trend objects throughout the day for testing purposes.

//+------------------------------------------------------------------+
//|                                                    TrendCount.mq5|
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com|
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Yellow
#property indicator_width1  1  
#property indicator_label1  "TrendCount"

//--- indicator buffers
double TrendCountBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    ObjectsDeleteAll(0, "PHD", -1, -1);
   
    //--- call the function to create trend objects
    CreateTrendObjects();
   
    //--- indicator buffers mapping
    SetIndexBuffer(0, TrendCountBuffer, INDICATOR_DATA);
    //--- name for DataWindow and indicator subwindow label
    IndicatorSetString(INDICATOR_SHORTNAME, "Trend Line Count");
    //--- sets first bar from what index will be drawn
    PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);

    //--- list all objects for debugging
    ListAllObjects();

    //--- initialization done
    Print("OnInit completed");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, "PHD", -1, -1);
}

//+------------------------------------------------------------------+
//| 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[])
{
    //--- set buffer as series
    ArraySetAsSeries(TrendCountBuffer, true);

    //--- reset buffer
    ArrayInitialize(TrendCountBuffer, 0);
    
    for (int i = ObjectsTotal(0, 0, OBJ_TREND) - 1; i >= 0; i--)
    {
        string name = ObjectName(0, i, 0, OBJ_TREND);
        datetime DateInicio = ObjectGetInteger(0, name, OBJPROP_TIME, 0);
        
        int multiplier = 0;
        if (StringFind(name, "PHD-NoticiaValor*1D-", 0) >= 0) multiplier = 5;
        else if (StringFind(name, "PHD-NoticiaValor*2D-", 0) >= 0) multiplier = 2;
        else if (StringFind(name, "PHD-NoticiaValor*3D-", 0) >= 0) multiplier = 3;
        else if (StringFind(name, "PHD-NoticiaValor*4D-", 0) >= 0) multiplier = 4;
        else if (StringFind(name, "PHD-NoticiaValor*5D-", 0) >= 0) multiplier = 5;
                
        if (multiplier != 0)
        {   
            TrendCountBuffer[i] += multiplier; 
        }
    }

    return(rates_total);
}

//+------------------------------------------------------------------+
//| Function to create trend objects for testing                     |
//+------------------------------------------------------------------+
void CreateTrendObjects()
{
    datetime current_time = TimeCurrent();
    datetime start_time = StringToTime(TimeToString(current_time, TIME_DATE) + " 00:00:00"); // Start of the current day
    datetime end_of_day = StringToTime(TimeToString(current_time, TIME_DATE) + " 23:59:59"); // End of the current day

    int object_count = 0;
    double last_price = 2330.00; // Initial value

    for(datetime time_iter = start_time; time_iter <= end_of_day; time_iter += 30 * 60) // Increment by 30 minutes
    {
        // Object name with suffix "Hour-Number"
        string name = "PHD-NoticiaValor*1D-" + TimeToString(time_iter, TIME_MINUTES) + "-" + IntegerToString(object_count);

        datetime time1 = time_iter; // Initial time for the object
        datetime time2 = time1 + (60 * 60); // 1 hour after time1
        double price1, price2;

        // Check if the date is in the future
        if (time1 > current_time)
        {
            price1 = last_price; // Use the last available price for future dates
            price2 = price1 + 0.01;
        }
        else
        {
            price1 = 2330.00 + (object_count * 0.01); // Initial price for the trend line
            price2 = price1 + 0.01; // Final price for the trend line
            last_price = price1; // Update the last available price
        }

        ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);
        ObjectSetInteger(0, name, OBJPROP_COLOR, clrYellow);
        ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

        // Print to confirm object creation
        Print("Object created: ", name, " with initial time: ", TimeToString(time1), " and initial price: ", price1);

        object_count++;
    }
}

//+------------------------------------------------------------------+
//| Function to list all objects on the chart                        |
//+------------------------------------------------------------------+
void ListAllObjects()
{
    int total_objects = ObjectsTotal(0, 0); // Correct use of ObjectsTotal
    Print("Total objects on the chart: ", total_objects);
    for(int i = 0; i < total_objects; i++)
    {
        string name = ObjectName(0, i, 0); // Correct use of ObjectName
        int type = ObjectGetInteger(0, name, OBJPROP_TYPE);
        Print("Object: ", name, ", Type: ", type);
    }
}

From my tests, the objects are being created correctly, but the histogram does not count objects with future dates. It seems that the indicator does not properly recognize these objects with future dates.

William, to answer your question, yes, I expect the objects to contain the string "PHD-NoticiaValor1D-", "PHD-NoticiaValor2D-", etc., and the counting logic should take this into account based on the date.

Yashar, I appreciate the confirmation that the objects are being counted, but could you help me understand why objects with future dates are not appearing in the histogram? Is there a way to ensure that these objects are included in the count, even if their dates are later than the current server time?

Thank you all for your help!

Best regards, LuisOrtin

 

LuisOrtin 2024.06.07 13:59 PT

Hello everyone,

I am facing an issue on MetaTrader where my indicator is not counting objects that have dates later than the current server time. Below is the code for reference. Can someone help me resolve this?

Thanks in advance for the help!

//+------------------------------------------------------------------+
//|                                                    TrendCount.mq5|
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com|
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  Yellow
#property indicator_width1  30  // Adjust histogram width here
#property indicator_label1  "TrendCount"

//--- Variable and object declarations
datetime DataInicioPerido, DataFimPerido;

//--- indicator buffers
double TrendCountBuffer[];

input int DiasRetroativos = 0;
input int DiasPosteriores = 1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- indicator buffers mapping
   SetIndexBuffer(0, TrendCountBuffer, INDICATOR_DATA);
   //--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME, "Trend Line Count");
   //--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);

   DataInicioPerido = (TimeCurrent() / 86400) * 86400 - 86400 * DiasRetroativos;
   DataFimPerido = (TimeCurrent() / 86400) * 86400 + 86400 * DiasPosteriores - 1;

   Print("DataInicioPerido: ", DataInicioPerido, " DataFimPerido: ", DataFimPerido);

   //--- initialization done
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
   //--- check for rates total
    if(rates_total == 0)
       return(0);

   //--- set buffer as series
   ArraySetAsSeries(TrendCountBuffer, true);

   //--- reset buffer
   ArrayInitialize(TrendCountBuffer, 0);
   
   //--- count trend lines
    int total_objects = ObjectsTotal(0, 0, OBJ_TREND);

   for(int i = 0; i < total_objects; i++)
     {
      string name = ObjectName(0, i, 0, OBJ_TREND);
      if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_TREND)
        {
         datetime DateInicio = ObjectGetInteger(0, name, OBJPROP_TIME, 1);

         if (StringFind(name, "HD-NoticiaValor-D", 0) > 0)
          {
            int multiplier = 0;
            if (StringFind(name, "*1D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*2D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*3D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*4D", 0) >= 0) multiplier = 1;
            else if (StringFind(name, "*5D", 0) >= 0) multiplier = 1;
                
            if (multiplier != 0)
            {
               int bar_index = iBarShift(NULL, 0, DateInicio, true);

               if (bar_index == -1) // If no exact bar found, use the nearest bar
               {
                  bar_index = iBarShift(NULL, 0, DateInicio, true);
                  Print("Exact bar not found, using nearest bar for: ", DateInicio, " with index: ", bar_index);
               }

               if (bar_index >= 0 && bar_index < rates_total)
               {
                  TrendCountBuffer[bar_index] += multiplier;
                 // Print("Trend line found: ", name, " at bar index: ", bar_index, " with multiplier: ", multiplier);
               }
               else
               {
                 // Print("Error: Invalid bar index for ", name, " with bar_index: ", bar_index);
               }
            }
          }
        }
     }

   return(rates_total);
}
How do I make a function that counts bars from the opening time of a position until the current time? How to delete visible object only on current timeframe? Help with Indicator for finding objects in the Chart of another indicator.
 
              int bar_index = iBarShift(NULL, 0, DateInicio, true);

               if (bar_index == -1) // If no exact bar found, use the nearest bar
               {
                  bar_index = iBarShift(NULL, 0, DateInicio, true);
                  Print("Exact bar not found, using nearest bar for: ", DateInicio, " with index: ", bar_index);
               }
If bar_index is -1, you search again with the same call. Do you expect a different result?