my Chandelier conversion from mql4 - anyone knows what the bug can be?

 

Hi,

I am using chandelier stops indicator from these guys:

//+------------------------------------------------------------------+
//|                                           ChandelierStops_v1.mq4 |
//|                                  Copyright © 2006, Forex-TSD.com |
//|                         Written by IgorAD,igorad2003@yahoo.co.uk |   
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |                                      
//+------------------------------------------------------------------+

It is a great indicator and I decided to convert it to the mql5.


It seems to be working fine and showing all the right levels. However problems arise when I'm trying to use it in an EA. After displaying values that are returned to the EA and comparing them to the values on screen when indicator is plotted on historical data there are a lot of differences. Can anyone tell me what is wrong in my Indicator? Here is the code:

//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   2

#property indicator_label1  "Up"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

#property indicator_label2  "Dn"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//---- input parameters
input int     Length=15;
input int     ATRperiod=20;
input double  Kv=3;
input int     Shift=1;

//---- indicator buffers
double UpBuffer1[];
double DnBuffer1[];
double smin[];
double smax[];
double trend[];

int atr_handle;

//+------------------------------------------------------------------+
int OnInit() {

   SetIndexBuffer(0,UpBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,DnBuffer1,INDICATOR_DATA);
   SetIndexBuffer(2,smin,INDICATOR_DATA);
   SetIndexBuffer(3,smax,INDICATOR_DATA);
   SetIndexBuffer(4,trend,INDICATOR_DATA);
   
   atr_handle = iATR(_Symbol,0,ATRperiod);
   
   return(0);
}
//+------------------------------------------------------------------+
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[])
{  
   int pos,start;
   double buf_atr[];
   
//--- starting calculation
   if(prev_calculated > 1) 
      pos = prev_calculated-1;
   else 
      pos = 0;
      
   CopyBuffer(atr_handle,0,pos,rates_total,buf_atr);

//--- main cycle
   for(int i=pos;i<rates_total;i++)
   {
      
      if(i-Shift-Length < 0) start=0;
      else  start = i-Shift-Length;
      
      smin[i]=high[ArrayMaximum(high, start,Length)] - Kv * buf_atr[i];
      smax[i]=low[ArrayMinimum(low, start, Length)] + Kv * buf_atr[i];
      
      if(i>0)  
      {        
         trend[i]=trend[i-1];
        
         if(close[i] > smax[i-1])trend[i]= 1;         
         if(close[i] < smin[i-1])trend[i]=-1;
         
         if(trend[i] >0)
           {
            if(smin[i]<smin[i-1])smin[i]=smin[i-1];
            UpBuffer1[i]=smin[i];
            DnBuffer1[i]=EMPTY_VALUE;
           }
         if(trend[i] <0)
           {
            if(smax[i]>smax[i-1])smax[i]=smax[i-1];
            UpBuffer1[i]=EMPTY_VALUE;
            DnBuffer1[i]=smax[i];
           }
      }
   }
   return(rates_total);
}
//+------------------------------------------------------------------+


The call to this indicator to display it's values is:

void OnTick()
{  
   double buffer_ma[], buffer_chandelier_up[], buffer_chandelier_dn[];
   
   MqlRates rates[];
   ArraySetAsSeries(rates,true);   
   CopyRates(_Symbol,_Period,0,2,rates);
   
   if(rates[0].tick_volume == 1)
   {
      
      ArraySetAsSeries(buffer_chandelier_up,true);
      CopyBuffer(handle_chandelier,0,0,2,buffer_chandelier_up);
      if(buffer_chandelier_up[1] != EMPTY_VALUE) Print(rates[0].time+": up[1]: "+buffer_chandelier_up[1]);
      
      ArraySetAsSeries(buffer_chandelier_dn,true);
      CopyBuffer(handle_chandelier,1,0,2,buffer_chandelier_dn);
      if(buffer_chandelier_dn[1] != EMPTY_VALUE) Print(rates[0].time+": dn[1]: "+buffer_chandelier_dn[1]);
      
      /*
      CopyBuffer(handle_chandelier,1,0,2,buffer_chandelier_dn);
      ArraySetAsSeries(buffer_chandelier_dn,true);
      
      
      ArraySetAsSeries(buffer_ma,true);      
      CopyBuffer(handle_ma,0,0,4,buffer_ma);      
      Print(rates[0].time+": MA[0]: "+buffer_ma[0]+", MA[1]: "+buffer_ma[1]+", MA[2]: "+buffer_ma[2]+", MA[3]: "+buffer_ma[3]);
      */
   }
}
Files:
 
baq:

Hi,

I am using chandelier stops indicator from these guys:

It is a great indicator and I decided to convert it to the mql5.

It seems to be working fine and showing all the right levels. However problems arise when I'm trying to use it in an EA. After displaying values that are returned to the EA and comparing them to the values on screen when indicator is plotted on historical data there are a lot of differences. Can anyone tell me what is wrong in my Indicator? Here is the code:

The call to this indicator to display it's values is:

 

Without looking at it in detail I'm not sure if this is the only problem, but it looks like you should include the following at the top of OnCalculate for all timeseries arrays delivered by and used inside that function.

ArraySetAsSeries(close,true);
// etc
 
phampton:

 

Without looking at it in detail I'm not sure if this is the only problem, but it looks like you should include the following at the top of OnCalculate for all timeseries arrays delivered by and used inside that function.

 

If you look at the original and my version, you can see that I actually converted all the calls and indexing order in the function itself in order to work with the "non as series" indexing. I changed [i+1] to [i-1] etc. Direction of the main cycle is ascending (I took that from some other mt5 indics). Do you think this is too little ?

Another thing is that the indicator is working fine. You can copy the code, compile it and it will display chandelier stops on the chart. The only problem is when it is used within the EA. I think it is something with supplying a new bar to the indicator, somehow processing of the latest bar is wrong, but what? I'm loosing my patience here :-/

 

Ok, It's fixed now.


The problem was here:

CopyBuffer(atr_handle,0,pos,rates_total,buf_atr);

//--- main cycle
   for(int i=pos;i<rates_total;i++)
   {
      
      if(i-Shift-Length < 0) start=0;
      else  start = i-Shift-Length;
      
      smin[i]=high[ArrayMaximum(high, start,Length)] - Kv * buf_atr[i];

It should be

CopyBuffer(atr_handle,0,0,rates_total-pos,buf_atr);

//--- main cycle
   for(int i=pos;i<rates_total;i++)
   {
      
      if(i-Shift-Length < 0) start=0;
      else  start = i-Shift-Length;
      
      smin[i]=high[ArrayMaximum(high, start,Length)] - Kv * buf_atr[i-pos];


The whole listing for anyone interested:

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   2

#property indicator_label1  "Up"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

#property indicator_label2  "Dn"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//---- input parameters
input int     Length=15;
input int     ATRperiod=20;
input double  Kv=3;
input int     Shift=1;

//---- indicator buffers
double UpBuffer1[];
double DnBuffer1[];
double smin[];
double smax[];
double trend[];

int atr_handle;

//+------------------------------------------------------------------+
int OnInit() {

   SetIndexBuffer(0,UpBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,DnBuffer1,INDICATOR_DATA);
   SetIndexBuffer(2,smin,INDICATOR_DATA);
   SetIndexBuffer(3,smax,INDICATOR_DATA);
   SetIndexBuffer(4,trend,INDICATOR_DATA);
   
   atr_handle = iATR(_Symbol,0,ATRperiod);
   
   return(0);
}
//+------------------------------------------------------------------+
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[])
{  
   int pos,start;
   double buf_atr[];
   
//--- starting calculation
   if(prev_calculated > 1) 
      pos = prev_calculated-1;
   else 
      pos = 0;
   
   CopyBuffer(atr_handle,0,0,rates_total-pos,buf_atr);

//--- main cycle
   for(int i=pos;i<rates_total;i++)
   {
      
      if(i-Shift-Length < 0) start=0;
      else  start = i-Shift-Length;
      
      smin[i]=high[ArrayMaximum(high, start,Length)] - Kv * buf_atr[i-pos];
      smax[i]=low[ArrayMinimum(low, start, Length)] + Kv * buf_atr[i-pos];
      
      if(i>0)  
      {        
         trend[i]=trend[i-1];
        
         if(close[i] > smax[i-1])trend[i]= 1;         
         if(close[i] < smin[i-1])trend[i]=-1;
         
         if(trend[i] >0)
           {
            if(smin[i]<smin[i-1])smin[i]=smin[i-1];
            UpBuffer1[i]=smin[i];
            DnBuffer1[i]=EMPTY_VALUE;
           }
         if(trend[i] <0)
           {
            if(smax[i]>smax[i-1])smax[i]=smax[i-1];
            UpBuffer1[i]=EMPTY_VALUE;
            DnBuffer1[i]=smax[i];
           }
      }
      
      if(1==2 && pos == rates_total - 1)
      {
         Print("smin[i]"+smin[i]);
      }
   }
   return(rates_total);
}
//+------------------------------------------------------------------+






Reason: