Coding help with this indicator

 

Ok so I only just passed coding 101. But its enough for me to do the basics. So I modified a donchian channel indicator so it only adjust levels when a new high or low is made. But it only works once applied to a chart. 

Could someone have a quick look at it and tell me where I went wrong. Thanks in anticipation of help.

 

 Original DC code

//+------------------------------------------------------------------+
//|                                             donchian-channel.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
//---- indicator settings
#property  indicator_chart_window
#property  indicator_buffers 2
#property  indicator_color1  Blue
#property  indicator_color2  Blue
#property  indicator_width1  2
#property  indicator_width2  2

//---- indicator parameters
extern int periods=20;

//---- indicator buffers
double     upper[];
double     lower[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   
//---- indicator buffers mapping
   SetIndexBuffer(0,upper);
   SetIndexBuffer(1,lower);
   
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("Donchian Channel("+periods+")");
   SetIndexLabel(0,"Upper");
   SetIndexLabel(1,"Lower");
   
    
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

//---- calculate values
   for(int i=0; i<limit; i++) {
      upper[i]=iHigh(Symbol(),Period(),iHighest(Symbol(),Period(),MODE_HIGH,periods,i));
      lower[i]=iLow(Symbol(),Period(),iLowest(Symbol(),Period(),MODE_LOW,periods,i));
   }
   
   return(0);
  }
//+------------------------------------------------------------------+  

 

Bobs Modified DC

//+------------------------------------------------------------------+
//|                              bobs modified donchian channels.mq4 |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
//---- indicator settings
#property  indicator_chart_window
#property  indicator_buffers 3
#property  indicator_color1  Blue
#property  indicator_color2  Blue
#property  indicator_color3  Goldenrod
#property  indicator_width1  2
#property  indicator_width2  2
#property  indicator_width3  1

//---- indicator parameters
extern int periods=20;

//---- indicator buffers
double     upper[];
double     lower[];
double     midline[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   
//---- indicator buffers mapping
   SetIndexBuffer(0,upper);
   SetIndexBuffer(1,lower);
   SetIndexBuffer(2,midline);
   
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("Bobs Modified Donchian Channel("+periods+")");
   SetIndexLabel(0,"Upper");
   SetIndexLabel(1,"Lower");
   SetIndexLabel(2,"Mid Line");
    
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

//---- calculate values
   for(int i=0; i<limit; i++)
    {
     if((iHigh(Symbol(),0,i) > upper[i+1]) || (iLow(Symbol(),0,i) < lower[i+1]))
      {
       upper[i]=iHigh(Symbol(),Period(),iHighest(Symbol(),Period(),MODE_HIGH,periods,i));
       lower[i]=iLow(Symbol(),Period(),iLowest(Symbol(),Period(),MODE_LOW,periods,i));
       midline[i]=NormalizeDouble((upper[i]+lower[i])/2,Digits);
      }
     else
      {
       upper[i] = upper[i+1];
       lower[i] = lower[i+1];
       midline[i] = midline[i+1];
      }
    }
   return(0);
  }
//+------------------------------------------------------------------+  
 
for(int i=2; i<limit; i++)

is there a reason that you changed from

for(int i=0; i<limit; i++)

 in the original code?

 
GumRai:

is there a reason that you changed from

 in the original code?


That's me bad. I was trying to work out why so I thought that since I'm introducing i+1 into the equation I needed to start back a couple. How wrong I am. It should be the same. I just forgot to change it back.
 

So here's the problem pictorially. Blue channel is the original DC code. Green channel is the modified DC code. 

Application 

As you can see when first applied, historically the two codes plot the same output.  Its only once applied the new code starts to work and we see the difference in output.

 Trending 

Since DC is trend following the modified code needs to replicate the original code and it does so nicely. Although later on the initial break it still captures the trend but also eliminates a couple of false long breaks a DC trader would of traded against the original code.  

However Ranging markets are a DC traders worst nightmare constantly being whipped into losing trades. 

Ranging 

As you can see here. The new logic detects a ranging markets and eliminates all losing trades. In this shot 15 trades over an 8 day period would of been taken, 2 winners 13 losers. That hurts a DC traders bank account. But with the modified code, the only two trades that would of been taken correspond to the two winning trades. Now that works for me. So that's why I want to make sure the code logic is correct and share this little finding

 
   for(int i=0; i<limit; i++)
    {
     if((iHigh(Symbol(),0,i) > upper[i+1]) || (iLow(Symbol(),0,i) < lower[i+1]))
      {

This if condition will be true for every historical bar when the indicator is initialised.

This is because you count up, so initially buffer[i+1] will always be EMPTY_VALUE 

   for(int i=limit-1; i>=0; i--)
    {

 

 Count down instead

 
Thanks so my bro. That worked a treat. 
Reason: