cannot load custom indicator 'B' [4002]

 

I am working on an indicator A that is supposed to operate on the values computed by another indicator B. I have implemented B with 6 buffers 5 of which are plotted. B works great when I attach it to any chart. It takes 8 parameters. The first 3 parameters are as for a moving average and then it takes 5 colors for plotting the 5 buffers accordingly.

In order to let A access the values it needs to load B as a custom indicator callling the function iCustom() in A's OnInit(). I thought everything is allright but when loading A to my chart I receive runtime error 4002 which the docs describe by Wrong parameter in the inner call of the client terminal function. The call to iCustom() is 

Bhandle=iCustom(NULL,0,"B",InpPeriod,InpShift,InpMethod,InpColor1,InpColor2,InpColor3,InpColor4);

but whereever I search I always end up confirming that I am passing a parameter of the expected type. I am following many Exempels by using the values NULL and 0 for symbol and period. Of course, B.ex5 is present in my indicator directory. Could anybody tell me how to figure out which Parameter MT5 complains about?

Thanks in advance!

Thomas 

 

Check your parameters type and position.

Show the B parameters and the relevant A code (parameters declaration and error checking) if you need help.

 
Alain Verleyen:

Check your parameters type and position.

Show the B parameters and the relevant A code (parameters declaration and error checking) if you need help.

Like I said the parameter types match. B has these parameters:

input string         _1 = "B parameters";

input int            InpPeriod=20;   // Period

input int            InpShift=0;     // Shift

input ENUM_MA_METHOD InpMethod=MODE_SMA; // Method

input string         _2 = "Color settings";

input color          InpColor1 = clrYellow;

input color          InpColor2 = clrRed;

input color          InpColor3 = clrGreen;

input color          InpColor4 = clrOrange;

A calls

handle=iCustom(NULL,0,"B",ExtPeriod,ExtShift,ExtMethod,

        ExtColor1,ExtColor2,ExtColor3,ExtColor4);

in its OnInit() handler after setting the desired values of the variables

int ExtPeriod;

int ExtShift;

ENUM_MA_METHOD ExtMethod;

color ExtColor1;

color ExtColor2;

color ExtColor3;

color ExtColor4; 

which are declared on the global  scope of A (as is int handle).

Now it seems to me the error could only be due to the "complex" data type ENUM_MA_METHOD. I will try changing it to int tomorrow but this seems inconvenient to me. Enumerations were introduced to ensure that only valid values can be passed and I would like to use this feature.

  1. Does anybody know if this could be the reason for my error?
  2. If so, why can't I use the enumeration?

 
Thomas Schwabhäuser:

Like I said the parameter types match. B has these parameters:

input string         _1 = "B parameters";

input int            InpPeriod=20;   // Period

input int            InpShift=0;     // Shift

input ENUM_MA_METHOD InpMethod=MODE_SMA; // Method

input string         _2 = "Color settings";

input color          InpColor1 = clrYellow;

input color          InpColor2 = clrRed;

input color          InpColor3 = clrGreen;

input color          InpColor4 = clrOrange;

A calls

handle=iCustom(NULL,0,"B",ExtPeriod,ExtShift,ExtMethod,

        ExtColor1,ExtColor2,ExtColor3,ExtColor4);


No your parameters don't match. Why are you thinking you can remove the string parameters ?

handle=iCustom(NULL,0,"B","",ExtPeriod,ExtShift,ExtMethod,"",ExtColor1,ExtColor2,ExtColor3,ExtColor4);
 
Alain Verleyen:

No your parameters don't match. Why are you thinking you can remove the string parameters ?

Because they are not actual parameters but only categorising the actual parameters. Of course, MT5 does not know of this difference. 

I'm not even sure if I should be angry at myself for not having thought of the simple answer. I am rather happy that I received your help letting me make progress. Thank you so much! 

 
Thomas Schwabhäuser:

Because they are not actual parameters but only categorising the actual parameters. Of course, MT5 does not know of this difference. 

I'm not even sure if I should be angry at myself for not having thought of the simple answer. I am rather happy that I received your help letting me make progress. Thank you so much! 

We all have to learn. You are welcome.
 

I have same problem and did checked parameters type! 

My code is this! it calculates Weighed ATR and pass it through ADATR function!  

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
double ATRArray[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   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[])
  {
   CopyBuffer(iATR(Symbol(), Period(), 14), 0, 0, 1, ATRArray);
   
   Comment(DoubleToString(ATRArray[0]));
   return(rates_total);
  }
//+------------------------------------------------------------------+
double ADATR(ENUM_TIMEFRAMES time1, int ADATRshift)
{
   double sum=0;      
   double ADatr264 =  iATRMQL4(NULL , Period() , 264 , 1)  * 8 ;
   double ADatr132 =  iATRMQL4(NULL , Period() , 132 , 1)  * 5 ;
   double ADatr66  =  iATRMQL4(NULL , Period() , 66  , 1)  * 3 ;
   double ADatr21  =  iATRMQL4(NULL , Period() , 21  , 1)  * 2 ;
   double ADatr10  =  iATRMQL4(NULL , Period() , 10  , 1)  * 1 ;
   double ADatr5   =  iATRMQL4(NULL , Period() , 5   , 1)  * 1 ;
   sum = ((ADatr5 + ADatr10 + ADatr21 + ADatr66 + ADatr132 + ADatr264) / 20) * 1 ; 
   if (sum<=0) return(0);
   else return(sum);
}
//+------------------------------------------------------------------+
double iATRMQL4(string symbol,
                ENUM_TIMEFRAMES tf,
                int period,
                int shift)
{
   ENUM_TIMEFRAMES timeframe= tf;
   int handle=iATR(symbol,timeframe,period);
   if(handle<0)
     {
      Print("The iATR object is not created: Error",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
}
//+------------------------------------------------------------------+
double CopyBufferMQL4(int handle,int index,int shift)
  {
   double buf[];
   switch(index)
     {
      case 0: if(CopyBuffer(handle,0,shift,1,buf)>0)
         return(buf[0]); break;
      case 1: if(CopyBuffer(handle,1,shift,1,buf)>0)
         return(buf[0]); break;
      case 2: if(CopyBuffer(handle,2,shift,1,buf)>0)
         return(buf[0]); break;
      case 3: if(CopyBuffer(handle,3,shift,1,buf)>0)
         return(buf[0]); break;
      case 4: if(CopyBuffer(handle,4,shift,1,buf)>0)
         return(buf[0]); break;
      default: break;
     }
   return(EMPTY_VALUE);
  } 


I tested this code individually and it works perfectly! But when I try to use it in my main code, Error 4002 just pops up!!!

I tried all mentioned solutions and guesses mentioned in this article! but NO progress!!!

Has anyone any savior Idea?!

 

OnCalculate() runs every tick.

This bit of code, therefore, runs every tick.

CopyBuffer(iATR(Symbol(), Period(), 14), 0, 0, 1, ATRArray);

You probably don't want to open a new handle to iATR() every tick. I'd probably start there. Create a single handle in OnInit().

 
Anthony Garot:

OnCalculate() runs every tick.

This bit of code, therefore, runs every tick.

You probably don't want to open a new handle to iATR() every tick. I'd probably start there. Create a single handle in OnInit().

Thank you Anthony,

Actually, this code works and your mentioned pint has to be checked for a clear code.

But I have difficulties with my main code that these two functions ("iATRMQL4" and  " ADATR") are included.

Here is that part of Main Code which "ADATR" is calling.

if (TimeCurrent() >= AST2)

      {

      if (APR && !fulltime) ATRH4 = ATRPrice(PERIOD_H4, iClose(Symbol(),PERIOD_D1,i+1));

      else ATRH4 = ADATR(TimeFrame[5], i);
      }

that "else" has been executing and Error 4002 pops up!!!

 

hi guys...need some guidance here

how can i merge 3 indicators into a single indicator?

 
Kashti: how can i merge 3 indicators into a single indicator?
  1. Don't Hijack other threads for your off-topic post. Make a new thread.
  2. Write an indicator. Read the values from the others (iCustom). Output to your buffer(s).
Reason: