iCustom - Return Value 0 when it is calculated from indicator

 

Hi All,

I am new in programming and hope to get some help.

I've create a simple indicator and uses iCustom in EA, and it works.

 Indicator for testing purposes

//---- input parameters
extern int ADXPeriod=28;
//---- buffers
double abc[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- 3 additional buffers are used for counting.
   IndicatorBuffers(1);
//---- indicator buffers
   SetIndexBuffer(0,abc);

  

//----
   return(0);
  }

int start(){

   abc[0] = 123.4;
   Comment( abc[0]);

   return(abc[0]);
  }

EA

#property copyright "ADX"


int start() {
double i;

   i = iCustom (NULL, 0, "ADX.ex4", 0, 6, 0);

   Print("Custom :", i);





   return(0);
}


It works, which is great. So, I uses the same method for my ADX indicator as per below but it return 0.


//+------------------------------------------------------------------+
//|                                                          ADX.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 LightSeaGreen
#property indicator_color2 YellowGreen
#property indicator_color3 Wheat
//---- input parameters
extern int ADXPeriod=28;
//---- buffers
double ADXBuffer[];
double PlusDiBuffer[];
double MinusDiBuffer[];
double PlusSdiBuffer[];
double MinusSdiBuffer[];
double TempBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- 3 additional buffers are used for counting.
   IndicatorBuffers(6);
//---- indicator buffers
   SetIndexBuffer(0,ADXBuffer);
   SetIndexBuffer(1,PlusDiBuffer);
   SetIndexBuffer(2,MinusDiBuffer);
   SetIndexBuffer(3,PlusSdiBuffer);
   SetIndexBuffer(4,MinusSdiBuffer);
   SetIndexBuffer(5,TempBuffer);

  
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("ADX("+ADXPeriod+")");
   SetIndexLabel(0,"ADX");
   SetIndexLabel(1,"+DI");
   SetIndexLabel(2,"-DI");
//----
   SetIndexDrawBegin(0,ADXPeriod);
   SetIndexDrawBegin(1,ADXPeriod);
   SetIndexDrawBegin(2,ADXPeriod);
  
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Average Directional Movement Index                               |
//+------------------------------------------------------------------+
int start()
  {
   double pdm,mdm,tr;
   double price_high,price_low;
   int    starti,i,counted_bars=IndicatorCounted();
//----
   i=Bars-2;
   PlusSdiBuffer[i+1]=0;
   MinusSdiBuffer[i+1]=0;
   if(counted_bars>=i) i=Bars-counted_bars-1;
   starti=i;
//----
   while(i>=0)
     {
      price_low=Low[i];
      price_high=High[i];
      //----
      pdm=price_high-High[i+1];
      mdm=Low[i+1]-price_low;
      if(pdm<0) pdm=0;  // +DM
      if(mdm<0) mdm=0;  // -DM
      if(pdm==mdm) { pdm=0; mdm=0; }
      else if(pdm<mdm) pdm=0;
           else if(mdm<pdm) mdm=0;
      //---- âû÷èñëÿåì èñòèííûé èíòåðâàë
      double num1=MathAbs(price_high-price_low);
      double num2=MathAbs(price_high-Close[i+1]);
      double num3=MathAbs(price_low-Close[i+1]);
      tr=MathMax(num1,num2);
      tr=MathMax(tr,num3);
      //---- counting plus/minus direction
      if(tr==0) { PlusSdiBuffer[i]=0; MinusSdiBuffer[i]=0; }
      else      { PlusSdiBuffer[i]=100.0*pdm/tr; MinusSdiBuffer[i]=100.0*mdm/tr; }
      //----
      i--;
     }
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
//---- apply EMA to +DI
   for(i=0; i<=limit; i++)
      PlusDiBuffer[i]=iMAOnArray(PlusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
//---- apply EMA to -DI
   for(i=0; i<=limit; i++)
      MinusDiBuffer[i]=iMAOnArray(MinusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
//---- Directional Movement (DX)
   i=Bars-2;
   TempBuffer[i+1]=0;
   i=starti;
   while(i>=0)
     {
      double div=MathAbs(PlusDiBuffer[i]+MinusDiBuffer[i]);
      if(div==0.00) TempBuffer[i]=0;
      else TempBuffer[i]=100*(MathAbs(PlusDiBuffer[i]-MinusDiBuffer[i])/div);
      i--;
     }
//---- ADX is exponential moving average on DX
   for(i=0; i<limit; i++)
  
      ADXBuffer[i]=iMAOnArray(TempBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
      
    

//----
   return(ADXBuffer[0]);
  }
//+------------------------------------------------------------------+--------------+


I am trying to get the value of ADXBuffer[0]. But, when the value transfer to EA via iCustom, it return 0.


Any advice is appreciated. I think i might miss out something but i keep on searching and debugging with no luck. Please help 


Many Thanks,

Jeannie
 

 

Hi Again,

I found the output of my array - ADXBuffer[0]. I am not good in array and still trying to learn it. 

It gave me two value, one is 0 and the other is the value I want 21.2366.

It seems that it pass the value to iCustom and not the other value.

Is there a way to remove the 0 or to pass it to iCustom?

Any help is appreciated. 

 
  1. Start checking the error messages - probably they have told you a lot faster your problem! (The debugger (F5 in the editor) is perfect for this if you place _LastError at the very top!!)
  2. Start reading editor's help (F1) about iCustom - the example there (double val=iCustom(NULL,0,"SampleInd",13,1,0);) would have told you (again a lot faster) as well what is your problem.
  3. iCustom needs only the name not the extension so instead of iCustom (NULL, 0, "ADX.ex4", 0, 6, 0); this should work: Custom (NULL, 0, "ADX", 0, 6, 0); (if it is in the correct folder).
(Remark: despite you are free about naming your variable i is mainly used for (integer) indices).
 
Carl Schreiber:
  1. Start checking the error messages - probably they have told you a lot faster your problem! (The debugger (F5 in the editor) is perfect for this if you place _LastError at the very top!!)
  2. Start reading editor's help (F1) about iCustom - the example there (double val=iCustom(NULL,0,"SampleInd",13,1,0);) would have told you (again a lot faster) as well what is your problem.
  3. iCustom needs only the name not the extension so instead of Custom (NULL, 0, "ADX.ex4", 0, 6, 0); this should work: Custom (NULL, 0, "ADX", 0, 6, 0); (if it is in the correct folder).
(Remark: despite you are free about naming your variable i is mainly used for (integer) indices).

Thank you Carl for the tips 1. I managed to found the errors and it's array out of range. Haven't look into 2 & 3, it seems the problem lies on the indicator.

What surprise me thou is it works fine when displaying the indicator on the chart. No error but when I press F5, only it shows me the array out of range.

here is the code that I managed to drilldown  that cause the issue.

 

//---- apply EMA to +DI


   for(i=0; i<=limit; i++)
      PlusDiBuffer[i]=iMAOnArray(PlusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);
     //Alert(ArraySize(PlusDiBuffer));
     //Alert(i);

//---- apply EMA to -DI
  for(i=0; i<=limit; i++)
     MinusDiBuffer[i]=iMAOnArray(MinusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i);

I checked the array size is 3512 by using ArraySize function. Does that means anything above 3512, it will throw this error message?

I tried to use ArrayResize but not luck. By any chances, do you know how to fix the the array out of range? Any advice is appreciated.

 

Many Thanks,

Jeannie 

 

Jeannie,

1) you probably would have already solved your problem if you have followed 2) and 3). Just compare you call of iCustom(..) and my call of iCustom(..).

2) Start reading about array (editor => F1 => Serach-Tab => "array"). Learn the difference about dynamic and non-dynamic arrays, arrays as indicator buffers, ....

MQL4 is a bit different to C.

 
Carl Schreiber:

Jeannie,

1) you probably would have already solved your problem if you have followed 2) and 3). Just compare you call of iCustom(..) and my call of iCustom(..).

2) Start reading about array (editor => F1 => Serach-Tab => "array"). Learn the difference about dynamic and non-dynamic arrays, arrays as indicator buffers, ....

MQL4 is a bit different to C.

Thank you Carl. I managed to get the value I want. 

I think I over complicate stuff. Thank you for your help again :) 

 
jeannie: I found the output of my array - ADXBuffer[0].
The indicator contains one extern and 6 buffers.
extern int ADXPeriod=28;

   SetIndexBuffer(0,ADXBuffer);
   SetIndexBuffer(1,PlusDiBuffer);
   SetIndexBuffer(2,MinusDiBuffer);
   SetIndexBuffer(3,PlusSdiBuffer);
   SetIndexBuffer(4,MinusSdiBuffer);
   SetIndexBuffer(5,TempBuffer);
But the call sets the ADXperiod to zero and tries to get a value from TempBuffer.
You should write a self documenting function instead of calling iCustom directly, see Detailed explanation of iCustom - MQL4 forum
 Carl Schreiber: Custom (NULL, 0, "ADX", 0, 6, 0); (if it is in the correct folder).