Issue reading custom indicator via iCustom in EA (MT5)

 

Hi Everyone,

I hope you are all fine. I am having an issue reading from a custom indicator I just made and for the life of me, I can't figure it out. The indicator I am trying to read from is the following.

#property copyright   ""
#property link        ""
#property description ""
#property version     "2.0"


//---- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_buffers 10

//---- plotting settings
#property indicator_plots  5
#property indicator_color1 clrGainsboro
#property indicator_color2 clrBlue 
#property indicator_color3 clrRed
#property indicator_color4 clrOrange
#property indicator_color5 clrLightGreen

//---- Width
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
#property indicator_width4 1
#property indicator_width5 1

//---- lines
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_type2   DRAW_LINE
#property indicator_type3   DRAW_LINE
#property indicator_type4   DRAW_LINE
#property indicator_type5   DRAW_LINE

//---- style
#property indicator_style3 STYLE_DASH
#property indicator_style4 STYLE_DOT

//---- constants 
//---- Definitions
#define ShortName       "PZ Open Deviation"
#define OLabel          "PZOD"
#define Shift           1
#define OP_BUY          0
#define OP_SELL         1
  

//---- indicator parameters
input string  Settings_ex  = "====== INDICATOR SETTINGS ======";
input int    Deviation     = 50; 

//---- indicator buffers
double FextMapBuffer1[];
double FextMapBuffer2[];
double FextMapBuffer3[];
double FextMapBuffer4[];
double FextMapBuffer5[];
double ValuesOHL[];
double ValuesOH[];
double ValuesOL[];
double ValuesHL[];
double ValuesCC[];


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    //--
    //-- Buffers 
    //--

    // Indicator buffers
    SetIndexBuffer(0, FextMapBuffer1); PlotIndexSetString(0, PLOT_LABEL, "HL Deviation from Open"); 
    SetIndexBuffer(1, FextMapBuffer2); PlotIndexSetString(1, PLOT_LABEL, "L Deviation from Open");                             
    SetIndexBuffer(2, FextMapBuffer3); PlotIndexSetString(2, PLOT_LABEL, "H Deviation from Open");  
    SetIndexBuffer(3, FextMapBuffer4); PlotIndexSetString(3, PLOT_LABEL, "Deviation from Bar Ranges");  
    SetIndexBuffer(4, FextMapBuffer5); PlotIndexSetString(4, PLOT_LABEL, "O Deviation from last Close");                                                         
    SetIndexBuffer(5, ValuesOHL, INDICATOR_DATA);
    SetIndexBuffer(6, ValuesOH, INDICATOR_DATA);
    SetIndexBuffer(7, ValuesOL, INDICATOR_DATA);
    SetIndexBuffer(8, ValuesHL, INDICATOR_DATA);
    SetIndexBuffer(9, ValuesCC, INDICATOR_DATA);
    
    // Buffers
    ArraySetAsSeries(FextMapBuffer1, true);
    ArraySetAsSeries(FextMapBuffer2, true);
    ArraySetAsSeries(FextMapBuffer3, true);
    ArraySetAsSeries(FextMapBuffer4, true);
    ArraySetAsSeries(FextMapBuffer5, true);
    ArraySetAsSeries(ValuesOHL, true);
    ArraySetAsSeries(ValuesOH, true);
    ArraySetAsSeries(ValuesOL, true);
    ArraySetAsSeries(ValuesHL, true);
    ArraySetAsSeries(ValuesCC, true);
    
    // Short Name
    IndicatorSetString(INDICATOR_SHORTNAME, ShortName +" ("+ IntegerToString(Deviation) +")");

    // Ok!
    return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ChartRedraw();
}
//+------------------------------------------------------------------+
//| 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[])
{
    //--
    //-- Turn data into series
    //--
    ArraySetAsSeries(close,true);
    ArraySetAsSeries(high,true);
    ArraySetAsSeries(low,true);
    ArraySetAsSeries(time,true);

    //--
    //-- Limit, Start and Rates 
    //--

    // Iteration limit
    int start = 1;    
    int limit;  
    if(prev_calculated==0)
    {
      // Set as series
      ArrayInitialize(FextMapBuffer1,  0);
      ArrayInitialize(FextMapBuffer2,  0);
      ArrayInitialize(FextMapBuffer3,  0);
      ArrayInitialize(FextMapBuffer4,  0);
      ArrayInitialize(FextMapBuffer5,  0);
      ArrayInitialize(ValuesOHL, 0);
      ArrayInitialize(ValuesOH, 0);
      ArrayInitialize(ValuesOL, 0);
      ArrayInitialize(ValuesHL, 0);
      ArrayInitialize(ValuesCC, 0);
      limit=rates_total-1;
   } else {
      limit=rates_total-prev_calculated;
   }
   
    //--
    //-- Iteration
    //--
    
    // First loop
    for(int i = limit; i >= start; i--)
    {   
      // Bars evaluated
      int eval = Bars(Symbol(), _Period) - i - 1;
      
      // Store deviations
      ValuesOHL[i] = MathAbs(Close(i)-Open(i)) / 2;
      
      // Store deviations
      ValuesOH[i] = MathAbs(High(i)-Open(i));
      ValuesOL[i] = MathAbs(Low(i)-Open(i));
      ValuesHL[i] = MathAbs(High(i)-Low(i));
      ValuesCC[i] = MathMax( 
                        MathAbs(MathMax(Open(i+1), Close(i)) - MathMin(Close(i), Open(i-1))),
                        MathAbs(MathMin(Open(i+1), Close(i)) - MathMax(Close(i), Open(i-1)))
                     );
      
      // Calculate std dev
      if(i < Bars(Symbol(), _Period) - 2)
      {
         FextMapBuffer1[i] = StdDev(ValuesOHL, MathMin(Deviation, eval), i);
         FextMapBuffer2[i] = StdDev(ValuesOH,  MathMin(Deviation, eval), i);
         FextMapBuffer3[i] = StdDev(ValuesOL,  MathMin(Deviation, eval), i);
         FextMapBuffer4[i] = StdDev(ValuesHL,  MathMin(Deviation, eval), i);
         FextMapBuffer5[i] = StdDev(ValuesCC,  MathMin(Deviation, eval), i);
      }
    }
    return(rates_total);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StdDev(double &arr[], int period, int shift)
{  
      int i;
      double sum = 0;
      double mean = 0;
      double SD = 0;
      double size = MathMin(ArraySize(arr), period);
      
      for(i = 0; i < size; i++)
      {
         sum += arr[shift+i];
         mean = sum/size;
      }
      
      for(i = 0; i < size; i++)
         SD += MathPow(arr[shift+i]-mean,2);
      
      return MathSqrt(SD/size);
}
//+------------------------------------------------------------------+
//| Migration functions
//+------------------------------------------------------------------+

datetime Time(int bar)
{
   datetime t[1] = {0};
   CopyTime(_Symbol, _Period, bar, 1, t);
   return(t[0]);
}

double High(int bar)
{
    double h[1]= {0};
    CopyHigh(_Symbol, _Period, bar, 1, h);
    return(h[0]);
}

double Low(int bar)
{
   double l[1] = {0};
   CopyLow(_Symbol, _Period, bar, 1, l);
   return(l[0]);
}

double Close(int bar)
{
    double c[1]= {0};
    CopyClose(_Symbol, _Period, bar, 1, c);
    return(c[0]);
}

double Open(int bar)
{
   double o[1] = {0};
   CopyOpen(_Symbol, _Period, bar, 1, o);
   return(o[0]);
}

The indicator runs fine, no issues.


However, when I try to read from any buffer on shift 1, it always returns zero. All the time.

input string TR_Ex                       = "======= INDICATOR SETINGS =======";
input int             DevPeriod          = 20;              // Std. Dev Period

// Handle
int devhandle;

//+------------------------------------------------------------------+
//| Custom EA initialization function
//+------------------------------------------------------------------+
int init()
{
   devhandle = iCustom(_Symbol, _Period, "PZ_DeviationFromOpen", "--", DevPeriod);
   if(devhandle == INVALID_HANDLE) 
   {
      Print("DevHandle failed");
      return(INIT_FAILED);
   }
   return(0);
}
//+------------------------------------------------------------------+
//| Custom EA start function
//+------------------------------------------------------------------+
void OnTick()
{    
   // Do not continue unless the bar is closed
   if(!IsBarClosed(Period(), true)) return;
   
   // Std dev from open prices
   double std_dev[1] = {0};
   if(!CopyBuffer(devhandle,0,1,1,std_dev))
   {
      Print("Could not read data from indicator.");
      return;
   } else {
     Print("STDDEV is "+ std_dev[0] +" for time"+ iTime(Symbol(), Period(), 1));
   }
}


/**
* Checks if the bar has closed
* @return   bool
*/
bool IsBarClosed(ENUM_TIMEFRAMES timeframe,bool reset)
{
    static datetime lastbartime;
    if(timeframe==-1)
    {
        if(reset)
            lastbartime=0;
        else
            lastbartime=iTime(NULL,timeframe,0);
        return(true);
    }
    if(iTime(NULL,timeframe,0)==lastbartime) // wait for new bar
        return(false);
    if(reset)
        lastbartime=iTime(NULL,timeframe,0);
    return(true);
}

The CopyBuffer call always stores zero, not the actual value.

I would greatly appreciate your help.

Many thanks in advance.

 

Your indicator is not working. Drop this code:

You must use the 'open', 'high', 'low', 'close' arrays from Oncalculate:

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[])
 
Arturo Lopez Perez:

However, when I try to read from any buffer on shift 1, it always returns zero. All the time.

The CopyBuffer call always stores zero, not the actual value.

You don't create the handle for the indicator.

int init()
{
   devhandle = iCustom(_Symbol, _Period, "PZ_DeviationFromOpen", "--", DevPeriod);
   if(devhandle == INVALID_HANDLE) 
   {
      Print("DevHandle failed");
      return(INIT_FAILED);
   }
   return(0);
}

This is a function that you have created and is not called anywhere.

You should use OnInit().

Reason: