Help explaning the result of CopyBuffer

 

Dear friends, im trying to use a indicator signal in my EA but i have no idea why CopyBuffer just give me ordered numbers, let me show the code:

 

#property copyright "Copyright © 2011-2016, EarnForex"
#property link      "http://www.earnforex.com/metatrader-indicators/Pinbar-Detector/"
#property version   "1.01" 

#property description "Pinbar Detector - detects Pinbars on charts."
#property description "Has two sets of predefined settings: common and strict."
#property description "Fully modifiable parameters of Pinbar pattern."
#property description "Usage instructions:"
#property description "http://www.earnforex.com/forex-strategy/pinbar-trading-system/"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_ARROW
#property indicator_color1  clrLime, clrRed
#property indicator_width1  2

input int  CountBars = 0; // CountBars - number of bars to count on, 0 = all.
input bool UseAlerts = true; // Use Alerts
input bool UseEmailAlerts = false; // Use Email Alerts (configure SMTP parameters in Tools->Options->Emails)
input bool UseCustomSettings = false; // Use Custom Settings - if true = use below parameters:
input double CustomMaxNoseBodySize = 0.33; // Max. Body / Candle length ratio of the Nose Bar
input double CustomNoseBodyPosition = 0.4; // Body position in Nose Bar (e.g. top/bottom 40%)
input bool   CustomLeftEyeOppositeDirection = true; // true = Direction of Left Eye Bar should be opposite to pattern (bearish bar for bullish Pinbar pattern and vice versa)
input bool   CustomNoseSameDirection = false; // true = Direction of Nose Bar should be the same as of pattern (bullish bar for bullish Pinbar pattern and vice versa)
input bool   CustomNoseBodyInsideLeftEyeBody = false; // true = Nose Body should be contained inside Left Eye Body
input double CustomLeftEyeMinBodySize = 0.1; // Min. Body / Candle length ratio of the Left Eye Bar
input double CustomNoseProtruding = 0.5; // Minmum protrusion of Nose Bar compared to Nose Bar length
input double CustomNoseBodyToLeftEyeBody = 1; // Maximum relative size of the Nose Bar Body to Left Eye Bar Body
input double CustomNoseLengthToLeftEyeLength = 0; // Minimum relative size of the Nose Bar Length to Left Eye Bar Length
input double CustomLeftEyeDepth = 0.1; // Minimum relative depth of the Left Eye to its length; depth is difference with Nose's back
 
// Indicator buffers
double UpDown[];
double Color[];

// Global variables
int LastBars = 0;
double MaxNoseBodySize = 0.33;
double NoseBodyPosition = 0.4;
bool   LeftEyeOppositeDirection = true;
bool   NoseSameDirection = false;
bool   NoseBodyInsideLeftEyeBody = false;
double LeftEyeMinBodySize = 0.1;
double NoseProtruding = 0.5;
double NoseBodyToLeftEyeBody = 1;
double NoseLengthToLeftEyeLength = 0;
double LeftEyeDepth = 0.1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
//---- indicator buffers mapping  
   SetIndexBuffer(0, UpDown, INDICATOR_DATA);
   SetIndexBuffer(1, Color, INDICATOR_COLOR_INDEX);
   ArraySetAsSeries(UpDown, true);
   ArraySetAsSeries(Color, true);
//---- drawing settings
   PlotIndexSetInteger(0, PLOT_ARROW, 74);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetString(0, PLOT_LABEL, "Pinbar");
//----
   if (UseCustomSettings)
   {
      MaxNoseBodySize = CustomMaxNoseBodySize;
      NoseBodyPosition = CustomNoseBodyPosition;
      LeftEyeOppositeDirection = CustomLeftEyeOppositeDirection;
      NoseSameDirection = CustomNoseSameDirection;
      LeftEyeMinBodySize = CustomLeftEyeMinBodySize;
      NoseProtruding = CustomNoseProtruding;
      NoseBodyToLeftEyeBody = CustomNoseBodyToLeftEyeBody;
      NoseLengthToLeftEyeLength = CustomNoseLengthToLeftEyeLength;
      LeftEyeDepth = CustomLeftEyeDepth;
   }
}

//+------------------------------------------------------------------+
//| 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 &tickvolume[],
                const long &volume[],
                const int &spread[])
{
   int NeedBarsCounted;
   double NoseLength, NoseBody, LeftEyeBody, LeftEyeLength;

   ArraySetAsSeries(Open, true);
   ArraySetAsSeries(High, true);
   ArraySetAsSeries(Low, true);
   ArraySetAsSeries(Close, true);
   
   if (LastBars == rates_total) return(rates_total);
   NeedBarsCounted = rates_total - LastBars;
   if ((CountBars > 0) && (NeedBarsCounted > CountBars)) NeedBarsCounted = CountBars;
   LastBars = rates_total;
   if (NeedBarsCounted == rates_total) NeedBarsCounted--;

   
UpDown[0] = EMPTY_VALUE;
   
   for (int i = NeedBarsCounted; i >= 1; i--)
   {
      // Prevents bogus indicator arrows from appearing (looks like PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); is not enough.)
      UpDown[i] = EMPTY_VALUE;
      
      // Won't have Left Eye for the left-most bar
      if (i == rates_total - 1) continue;
      
      // Left Eye and Nose bars's paramaters
      NoseLength = High[i] - Low[i];
      if (NoseLength == 0) NoseLength = _Point;
      LeftEyeLength = High[i + 1] - Low[i + 1];
      if (LeftEyeLength == 0) LeftEyeLength = _Point;
      NoseBody = MathAbs(Open[i] - Close[i]);
      if (NoseBody == 0) NoseBody = _Point;
      LeftEyeBody = MathAbs(Open[i + 1] - Close[i + 1]);
      if (LeftEyeBody == 0) LeftEyeBody = _Point;

      // Bearish Pinbar
      if (High[i] - High[i + 1] >= NoseLength * NoseProtruding) // Nose protrusion
      {
         if (NoseBody / NoseLength <= MaxNoseBodySize) // Nose body to candle length ratio
         {
            if (1 - (High[i] - MathMax(Open[i], Close[i])) / NoseLength < NoseBodyPosition) // Nose body position in bottom part of the bar
            {
               if ((!LeftEyeOppositeDirection) || (Close[i + 1] > Open[i + 1])) // Left Eye bullish if required
               {
                  if ((!NoseSameDirection) || (Close[i] < Open[i])) // Nose bearish if required
                  {
                     if (LeftEyeBody / LeftEyeLength  >= LeftEyeMinBodySize) // Left eye body to candle length ratio
                     {
                        if ((MathMax(Open[i], Close[i]) <= High[i + 1]) && (MathMin(Open[i], Close[i]) >= Low[i + 1])) // Nose body inside Left Eye bar
                        {
                           if (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) // Nose body to Left Eye body ratio
                           {
                              if (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) // Nose length to Left Eye length ratio
                              {
                                 if (Low[i] - Low[i + 1] >= LeftEyeLength * LeftEyeDepth)  // Left Eye low is low enough
                                 {
                                    if ((!NoseBodyInsideLeftEyeBody) || ((MathMax(Open[i], Close[i]) <= MathMax(Open[i + 1], Close[i + 1])) && (MathMin(Open[i], Close[i]) >= MathMin(Open[i + 1], Close[i + 1])))) // Nose body inside Left Eye body if required
                                    {
                                       UpDown[i] = High[i] + 5 * _Point + NoseLength / 5;
                                       Color[i] = 1;
                                       if (i == 1) SendAlert("Bearish"); // Send alerts only for the latest fully formed bar
                                    }
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
      
      // Bullish Pinbar
      if (Low[i + 1] - Low[i] >= NoseLength * NoseProtruding) // Nose protrusion
      {
         if (NoseBody / NoseLength <= MaxNoseBodySize) // Nose body to candle length ratio
         {
            if (1 - (MathMin(Open[i], Close[i]) - Low[i]) / NoseLength < NoseBodyPosition) // Nose body position in top part of the bar
            {
               if ((!LeftEyeOppositeDirection) || (Close[i + 1] < Open[i + 1])) // Left Eye bearish if required
               {
                  if ((!NoseSameDirection) || (Close[i] > Open[i])) // Nose bullish if required
                  {
                     if (LeftEyeBody / LeftEyeLength >= LeftEyeMinBodySize) // Left eye body to candle length ratio
                     {
                        if ((MathMax(Open[i], Close[i]) <= High[i + 1]) && (MathMin(Open[i], Close[i]) >= Low[i + 1])) // Nose body inside Left Eye bar
                        {
                           if (NoseBody / LeftEyeBody <= NoseBodyToLeftEyeBody) // Nose body to Left Eye body ratio
                           {
                              if (NoseLength / LeftEyeLength >= NoseLengthToLeftEyeLength) // Nose length to Left Eye length ratio
                              {
                                 if (High[i + 1] - High[i] >= LeftEyeLength * LeftEyeDepth) // Left Eye high is high enough
                                 {
                                    if ((!NoseBodyInsideLeftEyeBody) || ((MathMax(Open[i], Close[i]) <= MathMax(Open[i + 1], Close[i + 1])) && (MathMin(Open[i], Close[i]) >= MathMin(Open[i + 1], Close[i + 1])))) // Nose body inside Left Eye body if required
                                    {
                                       UpDown[i] = Low[i] - 5 * _Point - NoseLength / 5;
                                       Color[i] = 0;
                                       if (i == 1) SendAlert("Bullish"); // Send alerts only for the latest fully formed bar
                                    }
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
   return(rates_total);
}

string TimeframeToString(int P)
{
   switch(P)
   {
      case PERIOD_M1:  return("M1");
      case PERIOD_M2:  return("M2");
      case PERIOD_M3:  return("M3");
      case PERIOD_M4:  return("M4");
      case PERIOD_M5:  return("M5");
      case PERIOD_M6:  return("M6");
      case PERIOD_M10: return("M10");
      case PERIOD_M12: return("M12");
      case PERIOD_M15: return("M15");
      case PERIOD_M20: return("M20");
      case PERIOD_M30: return("M30");
      case PERIOD_H1:  return("H1");
      case PERIOD_H2:  return("H2");
      case PERIOD_H3:  return("H3");
      case PERIOD_H4:  return("H4");
      case PERIOD_H6:  return("H6");
      case PERIOD_H8:  return("H8");
      case PERIOD_H12: return("H12");
      case PERIOD_D1:  return("D1");
      case PERIOD_W1:  return("W1");
      case PERIOD_MN1: return("MN1");
      default:         return(IntegerToString(P));
   }
}

void SendAlert(string dir)
{
   string per = TimeframeToString(_Period);
   if (UseAlerts)
   {
      Alert(dir + " Pinbar on ", _Symbol, " @ ", per);
      PlaySound("alert.wav");
   }
   if (UseEmailAlerts)
      SendMail(_Symbol + " @ " + per + " - " + dir + " Pinbar", dir + " Pinbar on " + _Symbol + " @ " + per + " as of " + TimeToString(TimeCurrent()));
}

 

Then, in my EA:

 

   int      getcolor;
   int      getupdown;
   double   pinbarup[], pinbarcolor [];

int pinbarup = iCustom(NULL,0,"Pinbar",0,true,false,false,0.33,0.4,true,false,false,0.1,0.5,1,0,0.1);
int pinbarcolor = iCustom(NULL,0,"Pinbar",0,true,false,false,0.33,0.4,true,false,false,0.1,0.5,1,0,0.1);

     ArraySetAsSeries(pinbarup, true);
     ArraySetAsSeries(pinbarcolor, true);

     CopyBuffer(getupdown, 0, 0, 5, pinbarup);
     Print("Updown =",getupdown);

     CopyBuffer(getcolor, 1, 0, 5, pinbarcolor);
     Print("Color =",getcolor);

 

Here is my problem, i need to know the direction of the pinbar to place the buy or sell order, but the only result that i receive from copybuffer is:

Updown = 10

Color =  11

Updown = 12

Color =  13

Updown = 14

Color =  15

... 

I dont know why im receiving ordered numbers from 2 different buffers and how can i use this data to place the orders

 

Thanks in advice guys. 

 

Hi!


You are mixing the array and the buffer handler.

Alternatively you don't neet two calls to iCustom(). I changed the Print statement so it shows the current bar's values. Like this:


   int      pinbar_handle;
   double   pinbarup[], pinbarcolor [];

     int pinbar_handle= iCustom(NULL,0,"Pinbar",0,true,false,false,0.33,0.4,true,false,false,0.1,0.5,1,0,0.1);

     ArraySetAsSeries(pinbarup, true);
     ArraySetAsSeries(pinbarcolor, true);

     CopyBuffer(pinbar_handle, 0, 0, 5, pinbarup);
     Print("Updown =",pinbarup[4]);

     CopyBuffer(pinbar_handle, 1, 0, 5, pinbarcolor);
     Print("Color =",pinbarcolor[4]);
 

And in addition, you must always check the return value of CopyBuffer(). Otherwise you'll get an array out of range some day.


     if(CopyBuffer(pinbar_handle, 0, 0, 5, pinbarup)<0)
     {
         Print("Error copying buffer");
     {
     else
     {
         Print("Updown =",pinbarup[4]);
     }

 
And finally, if your EA is calculating every tick, use the previous candle value instead pinbarup[3]. Indicator may return values that change every tick for the current bar.
 
Fred Metraux:
And finally, if your EA is calculating every tick, use the previous candle value instead pinbarup[3]. Indicator may return values that change every tick for the current bar.

Dear Fred, thanks a lot for your help.

 

I still cant understand why i dont see any change in  pinbarcolor[] , i put the 5 buffers(0,1,2,3 and 4) to print but all of them just give me the result  Color =0.0

 

 In the indicator, there is a moment where Color becomes 0 or 1 , i want to see this change to pass it as a buy or sell condition  

if ((!NoseBodyInsideLeftEyeBody) || ((MathMax(Open[i], Close[i]) <= MathMax(Open[i + 1], Close[i + 1])) && (MathMin(Open[i], Close[i]) >= MathMin(Open[i + 1], Close[i + 1])))) // Nose body inside Left Eye body if required
                                    {
                                       UpDown[i] = Low[i] - 5 * _Point - NoseLength / 5;

                                       Color[i] = 0;  // This is the moment that i want to capture!!!

 

This is how im trying to capture

 

  static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar=false;

// copying the last bar time to the element New_Time[0]
   int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(copied>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
        // ArraySetAsSeries(pinbarup, true);
         ArraySetAsSeries(pinbarcolor, true);
         
         //CopyBuffer(pinbar_handle, 0, 0, 5, pinbarup);
         //Print("Updown =",pinbarup[0]);

         CopyBuffer(pinbar_handle, 1, 0, 5, pinbarcolor);
         Print("Color =",pinbarcolor[4]);
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }

 



 

You have an error either in initializing the indicator or when copying the buffer. change the code in order to get the errors be printed. iCustom() and CopyBuffer() alone is a bad idea.


for instance:

      AbsStrng_Handle2 = iCustom(CorrCurrenciesMatching[i].symbol,0,"absolutestrengthmarket_v1",TimeFrame,MathMode,Price,Length2,PreSmooth2,Smooth2,Signal,MA_Mode,IndicatorValue,ArrowCode,AlertMode2,ShowName,ShowTimeFrame,FontName,FontSize,TextColor,UniqueName);     
      if(AbsStrng_Handle2==INVALID_HANDLE)
      {
         Alert(" Íå óäàëîñü ïîëó÷èòü õåíäë èíäèêàòîðà AbsStrng_Handle2 "+GetLastError()); 
         return;     
      } 

and:

      if(CopyBuffer(ThreePairsInd_Handle,0,0,4,ThreePairsSignal)<0)
      {
         Alert("Error copying ThreePairs indicator Buffers - Error: "+GetLastError());
         return;
      } 

You can't call these functions without checking if they went well or not. I often get an error with iCustom because its name must be exactly the same as the file name. Another error is when the parameters are not good. This must be checked in your code.

Reason: