How to call custom indicator correctly in MT5 ?

 

Hi,

I try to create custom indicator that give arrow signal if the conditions are met. Using MA and Stochastic. If I run the indicator independently there is no problem, but when I try to call the indicator from EA the values is not the same with what the indicator show.

My indicator code as below:

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//Property Up Arrow
#property indicator_label1  "BuyArrow"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrAqua
#property indicator_width1  2
#property indicator_label2  "SellArrow"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_width2  2


//Include Indicators
#include <Indicators\Trend.mqh>
#include <Indicators\Oscilators.mqh>
//Built-in Indicators That Will Be Used
CiMA           ma4;
CiStochastic   stoch;
CiMA           ma20;
//indicator buffer
double up[],dn[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,up,INDICATOR_DATA);
   PlotIndexSetString(0,PLOT_LABEL,"BuyArrow");
   PlotIndexSetInteger(0,PLOT_ARROW,233);
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,5);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);  
   ArraySetAsSeries(up,true);
   
   SetIndexBuffer(1,dn,INDICATOR_DATA);
   PlotIndexSetString(1,PLOT_LABEL,"SellArrow");
   PlotIndexSetInteger(1,PLOT_ARROW,234);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,5);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
   ArraySetAsSeries(dn,true);

//---Initiate All Indicators
   if(!CreateHandles())
      //--- the indicator is stopped early
      return(INIT_FAILED);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CreateHandles()
  {
//--- create handles of the indicator
   if(!ma4.Create(Symbol(),PERIOD_CURRENT,4,0,MODE_EMA,PRICE_CLOSE))
     {
      //--- if the handle is not created
      Print(__FUNCTION__,
            ": failed to create handle of iMA indicator for symbol ",Symbol());
      return(false);
     }
   if(!ma20.Create(Symbol(),PERIOD_CURRENT,20,0,MODE_EMA,PRICE_CLOSE))
     {
      //--- if the handle is not created
      Print(__FUNCTION__,
            ": failed to create handle of iMA indicator for symbol ",Symbol());
      return(false);
     }

   if(!stoch.Create(Symbol(),PERIOD_CURRENT,13,5,5,MODE_EMA,STO_LOWHIGH))
     {
      //--- if the handle is not created
      Print(__FUNCTION__,
            ": failed to create handle of iMA indicator for symbol ",Symbol());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//Minimum bars on chart for indicator to run
   if(rates_total<19)
      return(0);
//sort close,high,and low values from the end to the beginning
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(open,true);
//Last indicator to draw
   int limit;
   limit = rates_total;
//Initiate indicator for the first time
   if(prev_calculated>0)
      limit = rates_total - prev_calculated;
   ma4.Refresh();
   ma20.Refresh();
   stoch.Refresh();
//Condition to draw indicator
   for(int i=0; i<limit; i++)
     {
      if(stoch.Main(i)>stoch.Signal(i) && stoch.Main(i)<30 && close[i]>ma4.Main(i) && open[i]<ma4.Main(i) && close[i]<ma20.Main(i)) //
        {
         up[i]=low[i];
         dn[i]=0;
        }
      else
         if(stoch.Main(i)<stoch.Signal(i) && stoch.Main(i)>70 && close[i]<ma4.Main(i) && open[i]>ma4.Main(i) && close[i]>ma20.Main(i)) //
           {
            dn[i]=high[i];
            up[i]=0;
           }
         else
           {
            up[i]=0;
            dn[i]=0;
           }
     }
   return(rates_total);
  }

And my EA code as below:

int handle[1];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---GU,EJ,EC,EU,NU,AC
   SymbolSelect("GBPUSD",true);
   handle[0]=iCustom("GBPUSD",PERIOD_CURRENT,"McBreak");
   if(handle[0]==INVALID_HANDLE)
     {
      Print("The Indicator is not created: Error",GetLastError());
      return(-1);
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   static double closePrice=0;
   static int trade=0;

   if(closePrice!=iClose(NULL,PERIOD_CURRENT,1))
     {
      trade=1;
      closePrice=iClose(NULL,PERIOD_CURRENT,1);
     }
   double GUUp[],GUDn[];

   if(CopyBuffer(handle[0],0,1,100,GUUp)<=0)
      return;
   if(CopyBuffer(handle[0],1,1,100,GUDn)<=0)
      return;

   
   if(GUUp[0]>0||GUDn[0]>0)
      Print("GUUp : ",GUUp[0]," GUDn : ",GUDn[0]);
}

Thank you for any input.

 
Christopher :

Hi,

I try to  create custom indicator  that give arrow signal if the conditions are met. Using MA and Stochastic. If I run the indicator independently there is no problem, but when I try to call the indicator from EA the values is not the same with what the indicator show.

My indicator code as below:

And my EA code as below:

Thank you for any input.

Apply

   ***
   ArraySetAsSeries(GUUp,true);
   ArraySetAsSeries(GUDn,true);

   if(CopyBuffer(handle[0],0,1,100,GUUp)<=0)
      return;
   if(CopyBuffer(handle[0],1,1,100,GUDn)<=0)
      return;
 
Vladimir Karputov:

Apply

Thank you Vladimir, I have tried your suggestion. The result as below:

The EA only once get the value from the indicator, while actually the indicator give a lot of signal, for example from Oct 2020 till now as below:

Both use the same TF 4hr. I don't know what's the problem. 

And the history quality is 99%. So, I don't think there is a problem with the history data.

Maybe you have another solution Vladimir ?

Thank you.

 
There are many errors in the indicator. The zero bar can never be calculated. Don't use CIndicators classes, work with pure iMA and iStochastic ...
 
Vladimir Karputov:
There are many errors in the indicator. The zero bar can never be calculated. Don't use CIndicators classes, work with pure iMA and iStochastic ...

Thank you Vladimir... will do that...

 
Just to let you know Vladimir after I coded iMA & iStoch manually into my indicator, the EA works just fine. Thank you once again for your guidance.
 
Comments that do not relate to this topic, have been moved to "Off Topic Posts".
 
Christopher :


I wrote an example on the iMA and iStochastic indicators: Two MA one Stochastic

Two MA one Stochastic

Reason: