Initialization Problem in MQL5!

 

Hello friends,

I was converting a simple indicator that I have from MQL4 to MQL5 but I meet a strange problem in the initialization function OnInit().

To simplify the problem I wrote the next code then I complied it in mql4 & mql5.

When I add several copies from the same indicator to a chart, I got different results in mt5 than what I got from mt4.

In mt4 the initialization happens for all the copies of the indicator loaded on the chart, but in MT5 it happens for the first copy only!

My question is why did MT5 OnInit() run for the first time only then stopped for the next copies!

I think that there is an error in OnInit() function because it is supposed to work for all indicators on the chart, not just the first one ... Or I might be missing something and some friend here can correct me.

MT4 OnInit


MT5 OnInit


//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                       Copyright © 2022, Muhammad Al Bermaui,CMT. |
//|                         https://www.mql5.com/en/users/bermaui314 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Muhammad Al Bermaui,CMT."
#property link      "https://www.mql5.com/en/users/bermaui314"
#property version   "3.00"
#property indicator_separate_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
Print("Initialization Window No: "+(string)ChartWindowFind());

//---
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[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Files:
 

You must write your indicator correctly: add an input parameter to the indicator. When adding an indicator, set a different value for the input parameter for each indicator.

I took the indicator:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 0
#property indicator_plots   0
//--- input parameters
input int      Input1=9;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Print("Input1: ",IntegerToString(Input1),", Initialization Window No: "+IntegerToString(ChartWindowFind()));
//---
   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[])
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

and set its own parameter value for each indicator (each value is unique).

Result: three subwindows appeared


and this printout:

Test (GBPUSD,M1)        Input1: 9 , Initialization Window No: 1 
Test (GBPUSD,M1)        Input1: 1 , Initialization Window No: 2 
Test (GBPUSD,M1)        Input1: 3 , Initialization Window No: 3
Files:
Test.mq5  4 kb
 

Thanks, Vladimir for your answer.

I appreciate your answer because it solves a part of the problem but:

  1. What if the indicator does not have any parameters.
  2. Why OnInit() function in mql5 does not give the same results as in mql4.


I added your code to mt4 and plot the indicator on the chart three times without changing the default parameter and it printed three messages which means that initialization is done for the three copies of the indicator.

The same Vladimir code on MT4

 
Muhammad Elbermawi # :

Thanks, Vladimir for your answer.

I appreciate your answer because it solves a part of the problem but:

  1. What if the indicator does not have any parameters.
  2. Why OnInit() function in mql5 does not give the same results as in mql4.


I added your code to mt4 and plot the indicator on the chart three times without changing the default parameter and it printed three messages which means that initialization is done for the three copies of the indicator.


Please read the advice above: YOU MUST MAKE DIFFERENT INPUT PARAMETERS!

Tip number 2: remove and replace the old terminal ("old terminal" - is MetaTrader 4!!!) from your computer.

Delete the old terminal permanently ("the old terminal is MetaTrader 4!!!") and never return to the old terminal again.

 
Vladimir Karputov #:

Please read the advice above: YOU MUST MAKE DIFFERENT INPUT PARAMETERS!

Tip number 2: remove and replace the old terminal ("old terminal" - is MetaTrader 4!!!) from your computer.

Delete the old terminal permanently ("the old terminal is MetaTrader 4!!!") and never return to the old terminal again.

I tested the same problem on another PC which have MT5 only installed on it but the same issue still exists.
 
Muhammad Elbermawi # :
I tested the same problem on another PC which have MT5 only installed on it but the same issue still exists.

There are no problems in the MetaTrade 5 terminal. You have a small problem: you are still sitting on the old terminal ("the old terminal" is MetaTrade 4!!).

What needs to be done:

Step one: You must permanently delete the old terminal ("the old terminal" is MetaTrade 4!!) and never think about it again

Step two: remember that MetaTrader 5 effectively manages indicator handles and does not allow you to create two absolutely identical indicators on the same chart. This is an axiom, a law. It has always been like this, it's just that you started using MetaTrader 5 very late and still know very little.

I recommend that you put more effort into learning MetaTrader 5 - and you will succeed!

 

An example that demonstrates how to work with indicator handles.

Indicator code:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.001"
#property indicator_separate_window
#property indicator_buffers 0
#property indicator_plots   0
//--- input parameters
input int      Input1=9;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Print("Input1: ",IntegerToString(Input1));
//---
   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[])
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Advisor code:

//+------------------------------------------------------------------+
//|                                                       TestEA.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
//--- input parameters
input int      Input_1  = 1;
input int      Input_2  = 3;
input int      Input_3  = 3;
//---
int      handle_iCustom_1;                      // variable for storing the handle of the iCustom indicator
int      handle_iCustom_2;                      // variable for storing the handle of the iCustom indicator
int      handle_iCustom_3;                      // variable for storing the handle of the iCustom indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create Input_1
   handle_iCustom_1=iCustom(Symbol(),Period(),"TestIndicator",Input_1);
//--- if the handle is not created
   if(handle_iCustom_1==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iCustom indicator ('Input_1' %d) for the symbol %s/%s, error code %d",
                  Input_1,
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_SUCCEEDED);
     }
   else
     {
      Print("'Input_1' ",IntegerToString(Input_1),", handle "+IntegerToString(handle_iCustom_1));
     }
//--- create Input_2
   handle_iCustom_2=iCustom(Symbol(),Period(),"TestIndicator",Input_2);
//--- if the handle is not created
   if(handle_iCustom_2==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iCustom indicator ('Input_2' %d) for the symbol %s/%s, error code %d",
                  Input_2,
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_SUCCEEDED);
     }
   else
     {
      Print("'Input_2' ",IntegerToString(Input_2),", handle "+IntegerToString(handle_iCustom_2));
     }
//--- create Input_3
   handle_iCustom_3=iCustom(Symbol(),Period(),"TestIndicator",Input_3);
//--- if the handle is not created
   if(handle_iCustom_3==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iCustom indicator ('Input_3' %d) for the symbol %s/%s, error code %d",
                  Input_3,
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_SUCCEEDED);
     }
   else
     {
      Print("'Input_3' ",IntegerToString(Input_3),", handle "+IntegerToString(handle_iCustom_3));
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  }
//+------------------------------------------------------------------+

The result of running the adviser online - I just attached the adviser to the chart.

TestEA (EURUSD,H1)      'Input_1' 1, handle 10
TestEA (EURUSD,H1)      'Input_2' 3, handle 11
TestEA (EURUSD,H1)      'Input_3' 3, handle 11

You can see that I tried to create indicator #3 with parameters similar to indicator #2 - as a result, indicator #3 was not created, indicator #2's handle was returned instead.

Files:
Test.mq5  4 kb
TestEA.mq5  8 kb
 
Thanks for your great efforts with me, Vladimir.
 
Muhammad Elbermawi # :
Thanks for your great efforts with me, Vladimir.

Always happy to help. If possible, I try to demonstrate the MQL5 code :)

Reason: