Indicator not drawing rectangle - no error given

 

This indicator keeps track of the time remaining before the 4hr candle opens. The time can be specified by the user in intervals of 15 minutes such that the total time does not exceed 4 hours (i.e. 240 minutes). The indicator is supposed to draw a rectangle once the countdown to the remaining time before the 4hr candle opens. The rectangle will start from when the countdown begins, and will end when the countdown ends. The countdown ends when the same amount of time specified has elapsed after the 4hr candle has closed. The indicator does not keep an active count down timer but only checks if the time remaining for the 4hr candle to open is equal to (or less than) the specified time.

The indicator works well by notifying when there’s X amount of time before a 4hr candle closes, but the problem is, the indicator does not draw any rectangle, and there are no errors to why it is not drawing rectangles. I went through the logic several times but still cannot figure out why the rectangles are not being drawn. Can you please help me figure out the error or give me some pointers, your help will be greatly appreciated.

The indicator code is below:

//+------------------------------------------------------------------+
//|                                                     GameTime.mq5 |
//|                        Copyright 2024, User                      |
//|                                                                  |
//+------------------------------------------------------------------+
#property strict

// Define indicator properties
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrBlue

// Input parameters
input int GameTime = 45;  // Game Time (can be 45min, 60min, 75min, 90min or 115min)
input bool UseGameTimeFeature = true;  // Use Game Time Feature (Yes or No)
input bool NotifyBeforeGameTime = true;  // Notify before “Game Time” (Yes or No)
input int GMT = 2;  // GMT offset to align local time to broker time

// Global variables
datetime Next4HourCandleTime;  // Time of the next 4-hour candle
bool IsGameTime = false;  // Flag for checking if it's game time
int RectangleID = 0;  // ID for rectangles
bool NotificationSent = false;  // Flag to control notifications

// Define a dummy buffer to avoid warnings
double DummyBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  // Set the dummy buffer
  SetIndexBuffer(0, DummyBuffer);

  // Initialization
  CalculateNext4HourCandleTime();
  return(INIT_SUCCEEDED);
}

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

//+------------------------------------------------------------------+
//| 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[])
{
  if (!UseGameTimeFeature)
    return(rates_total);

  datetime currentTime = TimeCurrent() + GMT * 3600;  // Adjust for GMT offset

  // Check if it's time to notify before Game Time
  if (NotifyBeforeGameTime && (Next4HourCandleTime - currentTime) <= GameTime * 60 && !NotificationSent)
  {
    // Send notification
    Alert("Game Time is in ", GameTime, " minutes!");
    SendNotification("Game Time is in " + IntegerToString(GameTime) + " minutes!");
    NotificationSent = true;
  }

  // Check if it's Game Time
  if ((currentTime >= (Next4HourCandleTime - GameTime * 60)) && (currentTime <= (Next4HourCandleTime + GameTime * 60)))
  {
    IsGameTime = true;

    // Draw rectangle
    string rectangleName = "GameTimeRectangle_" + IntegerToString(RectangleID);
    if (!ObjectFind(0, rectangleName))
    {
      datetime startTime = Next4HourCandleTime - GameTime * 60;
      datetime endTime = Next4HourCandleTime + GameTime * 60;
      double highPrice = iHigh(NULL, 0, iBarShift(NULL, 0, startTime));
      double lowPrice = iLow(NULL, 0, iBarShift(NULL, 0, endTime));
      DrawRectangle(rectangleName, startTime, endTime, highPrice, lowPrice);
      RectangleID++;
    }
  }
  else
  {
    IsGameTime = false;
    NotificationSent = false;  // Reset notification flag after Game Time period
  }

  // If the 4-hour candle has opened and GameTime has passed, calculate the next 4-hour candle time
  if (currentTime > (Next4HourCandleTime + GameTime * 60))
  {
    CalculateNext4HourCandleTime();
  }

  return(rates_total);
}

//+------------------------------------------------------------------+
//| Function to calculate the next 4-hour candle time                |
//+------------------------------------------------------------------+
void CalculateNext4HourCandleTime()
{
  datetime currentTime = TimeCurrent() + GMT * 3600;  // Adjust for GMT offset
  datetime currentCandleTime = iTime(NULL, PERIOD_H4, 0) + GMT * 3600;  // Adjust for GMT offset

  if (currentTime >= currentCandleTime + 4 * 60 * 60)
    Next4HourCandleTime = currentCandleTime + 8 * 60 * 60;
  else
    Next4HourCandleTime = currentCandleTime + 4 * 60 * 60;
}

//+------------------------------------------------------------------+
//| Function to draw a rectangle                                     |
//+------------------------------------------------------------------+
void DrawRectangle(string name, datetime startTime, datetime endTime, double highPrice, double lowPrice)
{
  if (!ObjectCreate(0, name, OBJ_RECTANGLE, 0, startTime, highPrice, endTime, lowPrice))
  {
    Print("Failed to create rectangle: ", name);
    return;
  }

  // Set rectangle properties
  ObjectSetInteger(0, name, OBJPROP_COLOR, clrYellow);  // Set color to yellow
  ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);  // Set style
  ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);  // Set width
  ObjectSetInteger(0, name, OBJPROP_BACK, true);  // Draw in the background
  ObjectSetInteger(0, name, OBJPROP_FILL, clrYellow & 0x7FFFFFFF);  // Set transparent fill color
}
 
ITM7:
if (!ObjectFind(0, rectangleName))

https://www.mql5.com/en/docs/objects/objectfind

If the object is not found, the function returns a negative number.


void OnStart()
  {
   Print(!-1);
  }
 
Vladislav Boyko #:

Oh, thank you very very much, I would not have figured that out. After trying it out, it now draws rectangles, although appearing a bit weird. I will continue from here and try and fix what I can. 

Do you know of a better logic alternative to get the rectangles to be drawn other than what I used below:

if (ObjectFind(0, rectangleName) < 0)
 

ITM7 #:
Do you know of a better logic alternative to get the rectangles to be drawn other than what I used below:

if (ObjectFind(0, rectangleName) < 0)

Now the check of the return value of ObjectFind looks correct.

ITM7 #:
although appearing a bit weird

Sorry, but I don't have time to study your code in detail right now. I showed you your most obvious mistake, which immediately caught my eye.

 
Vladislav Boyko #:

Now the check of the return value of ObjectFind looks correct.

Sorry, but I don't have time to study your code in detail right now. I showed you your most obvious mistake, which immediately caught my eye.

No problem, thank you once again for taking time out of your busy schedule to assist.