Code problem!

 

I have a problem that I don't know how to solve. I have code for an indicator, one of its functions is to show what the price is at a specific point - in this case, the value at the last closed bar.

The problem is that the indicator recognizes the start and end trend-line coordinates as the same and the message is "Undefined".

// Дефиниране на константите за тренд линии, ако не са дефинирани
#ifndef OBJPROP_TIME1
   #define OBJPROP_TIME1 16
#endif
#ifndef OBJPROP_PRICE1
   #define OBJPROP_PRICE1 17
#endif
#ifndef OBJPROP_TIME2
   #define OBJPROP_TIME2 18
#endif
#ifndef OBJPROP_PRICE2
   #define OBJPROP_PRICE2 19
#endif
#ifndef OBJPROP_TYPE
   #define OBJPROP_TYPE 0
#endif

//+------------------------------------------------------------------+
//|                                                     EMA50.mq5    |
//| Индикатор, който показва стойността на EMA50 и избрани тренд линии|
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

//--- Input параметри за EMA
input int               InpMAPeriod     = 50;                // Период на EMA
input int               InpMAShift      = 0;                 // Изместване (0 за последния затворен бар)
input int               InpMAMethod     = MODE_EMA;          // Метод за изчисляване – MODE_EMA (стойност 1)
input int               InpAppliedPrice = PRICE_CLOSE;       // Вид цена (PRICE_CLOSE)
input color             InpTextColor    = clrWhite;          // Цвят на текста
input int               InpFontSize     = 12;                // Размер на шрифта
input int               InpCorner       = CORNER_LEFT_UPPER; // Ъгъл на екрана за показване на текста

//--- Input параметър за имената на тренд линиите (разделени с точка и запетая)
input string            InpTrendLineNames = "TrendLine1;TrendLine2"; // Пример: "TrendLine1;TrendLine2"

//--- Глобални променливи
int    ma_handle = INVALID_HANDLE; // Ръкохватка към EMA
string objName   = "EMAIndicator";  // Име на текстовия обект

//+------------------------------------------------------------------+
//| Функция за инициализация на индикатора                           |
//+------------------------------------------------------------------+
int OnInit()
{
   // Създаване на ръкохватката за EMA с избраните параметри
   ma_handle = iMA(_Symbol, _Period, InpMAPeriod, InpMAShift, (ENUM_MA_METHOD)InpMAMethod, InpAppliedPrice);
   if(ma_handle == INVALID_HANDLE)
   {
      Print("Грешка: Неуспех при създаването на MA handle");
      return(INIT_FAILED);
   }

   // Създаване на текстов обект за показване на EMA и тренд линиите
   if(!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0))
   {
      Print("Грешка: Неуспех при създаването на текстовия обект");
      return(INIT_FAILED);
   }
   
   // Настройки на текстовия обект
   ObjectSetInteger(0, objName, OBJPROP_CORNER, InpCorner);
   ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, InpFontSize);
   ObjectSetInteger(0, objName, OBJPROP_COLOR, InpTextColor);
   ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, 10);
   ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, 30);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Функция за деинициализация на индикатора                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, objName);
   
   if(ma_handle != INVALID_HANDLE)
      IndicatorRelease(ma_handle);
}

//+------------------------------------------------------------------+
//| Функция за изчисление на индикатора                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
   // Вземаме стойността от последния затворен бар (индекс 1) на EMA
   double maBuffer[1];
   if(CopyBuffer(ma_handle, 0, 1, 1, maBuffer) <= 0)
   {
      Print("Грешка: Неуспех при копиране на буфера на EMA");
      return(rates_total);
   }
   double ma_value = maBuffer[0];

   // Подготвяме текста за показване
   string text = StringFormat("EMA50: %.5f", ma_value);

   // Вземаме времето на последния затворен бар
   datetime currentTime = iTime(_Symbol, _Period, 1);

   // Разделяме входния стринг с имената на тренд линиите по разделителя ";"
   string trendNames[];
   int count = StringSplit(InpTrendLineNames, ';', trendNames);

   // Отладъчен код, който ще се изпълни само веднъж
   static bool debugPrinted = false;

   for(int i = 0; i < count; i++)
   {
      // Вземаме името и премахваме водещите и крайните интервали
      string trendName = trendNames[i];
      StringTrimLeft(trendName);
      StringTrimRight(trendName);

      if(StringLen(trendName) > 0)
      {
         // Отпечатваме отладъчни данни само при първото извикване
         if(!debugPrinted)
         {
            int objType = (int)ObjectGetInteger(0, trendName, OBJPROP_TYPE, 0);
            Print("Тип на обекта: ", objType, " (трябва да е 4 за OBJ_TREND)");
            
            datetime t1 = (datetime)ObjectGetInteger(0, trendName, (ENUM_OBJECT_PROPERTY_INTEGER)OBJPROP_TIME1, 0);
            datetime t2 = (datetime)ObjectGetInteger(0, trendName, (ENUM_OBJECT_PROPERTY_INTEGER)OBJPROP_TIME2, 0);
            Print("Обект: ", trendName,
                  " time1=", t1, " (", TimeToString(t1), ") ",
                  " time2=", t2, " (", TimeToString(t2), ")");
         }

         // Проверяваме дали обектът с даденото име съществува
         if(ObjectFind(0, trendName) == -1)
         {
            text += "\n" + trendName + ": Not found";
         }
         else
         {
            datetime time1 = (datetime)ObjectGetInteger(0, trendName, (ENUM_OBJECT_PROPERTY_INTEGER)OBJPROP_TIME1, 0);
            datetime time2 = (datetime)ObjectGetInteger(0, trendName, (ENUM_OBJECT_PROPERTY_INTEGER)OBJPROP_TIME2, 0);
            double price1  = ObjectGetDouble(0, trendName, (ENUM_OBJECT_PROPERTY_DOUBLE)OBJPROP_PRICE1, 0);
            double price2  = ObjectGetDouble(0, trendName, (ENUM_OBJECT_PROPERTY_DOUBLE)OBJPROP_PRICE2, 0);

            // Ако двата времеви параметъра са равни, не можем да пресметнем линията
            if(time2 == time1)
            {
               text += "\n" + trendName + ": Undefined";
            }
            else
            {
               // Изчисляваме наклона и стойността на линията при currentTime
               double slope = (price2 - price1) / ((double)(time2 - time1));
               double lineValue = price1 + slope * (currentTime - time1);
               text += "\n" + StringFormat("%s: %.5f", trendName, lineValue);
            }
         }
      }
   }
   // Задаваме, че отладъчният код вече е изпълнен
   debugPrinted = true;

   // Актуализираме текстовия обект с получения текст
   ObjectSetString(0, objName, OBJPROP_TEXT, text);

   return(rates_total);
}
 

Use the correct property modifier instead of the non existent OBJPROP_TIME1 or OBJPROP_TIME2 in MQL5.

Example:

      ObjectSetInteger(0, name, OBJPROP_TIME, 0, time1);
      ObjectSetDouble(0, name, OBJPROP_PRICE, 0, price1);
      ObjectSetInteger(0, name, OBJPROP_TIME, 1, time2);
      ObjectSetDouble(0, name, OBJPROP_PRICE, 1, price2);
 
Amine Largou #: Use the correct property modifier instead of the non existent OBJPROP_TIME1 or OBJPROP_TIME2 in MQL5.

It turned out perfectly. Thank you very much!👍👍👍👏❤❤❤

⚠️  Post edited by moderator. On the English forum, please write in English. 

 
Ivaylo Melkov #:

It turned out perfectly. Thank you very much!👍👍👍👏❤❤❤

⚠️  Post edited by moderator. On the English forum, please write in English. 

You're welcome 👍