Problem with creation custom indicator.

 

Hello,

I have tried for some weeks now to learn mql-coding.

I would like to create a custom indicator where i want the difference between the opening and the close, the difference between the high and the low and the quote of above values.

So far so good, but when I try to calculate an average of the quote something strange happens. the indicator are giving me values both above 1 and below 0. Maybe I have become stupid or

been out of school for too long but as I see it a value divided with a greater value should result in another value somewhere between 0 and 1.

could someone please have mercy and look through my code for what kind of error I have made.

//--------------------------------------------------------------------
// Aver_det2.mq4
//--------------------------------------------------------------------
#property indicator_separate_window // Drawing in a separate window
#property indicator_buffers 1 // Number of buffers
#property indicator_color1 Blue // Color of the 1st line

extern int Aver_Bars=5; // Amount of bars for calculation

double Buf_0[]; // Declaring an indicator array
//--------------------------------------------------------------------
int init() // Special function init()
{
SetIndexBuffer(0,Buf_0); // Assigning an array to a buffer
SetIndexStyle (0,DRAW_LINE,STYLE_SOLID,1);// line style
return; // Exit the special funct. init()
}
//--------------------------------------------------------------------
int start() // Special function start()
{
int i, // Bar index
n, // Formal parameter
Counted_bars; // Number of counted bars
double
Diff_OC, // Sum of the difference between open and close for period
Diff_HL; // Sum of the difference between high and low for period
//--------------------------------------------------------------------

Counted_bars=IndicatorCounted(); // Number of counted bars
i=Bars-Counted_bars-1; // Index of the first uncounted

while(i>=0) // Loop for uncounted bars
{
Diff_OC=0;
Diff_HL=0; // Nulling at loop beginning

for(n=i;n<=i+Aver_Bars-1;n++) // Loop of summing values
{
Diff_OC=Diff_OC + (Open[n]-Close[n]); // Accumulating difference between open and close sum
Diff_HL=Diff_HL + (High[n]-Low[n]); // Accumulating difference between high and low sum

Diff_OC=MathAbs(Diff_OC); //Making Diff_OC positive
}
Buf_0[i]=(Diff_OC/Diff_HL)/Aver_Bars; // Value of 0 buffer on i bar
i--; // Calculating index of the next bar
}
//--------------------------------------------------------------------
return; // Exit the special funct. start()
}
//--------------------------------------------------------------------

thank you ever so much,

 
radpajo:

Hello,

I have tried for some weeks now to learn mql-coding.

I would like to create a custom indicator where i want the difference between the opening and the close, the difference between the high and the low and the quote of above values.

So far so good, but when I try to calculate an average of the quote something strange happens. the indicator are giving me values both above 1 and below 0.

I think you are mistaken . . . . I think your code is incorrect but that is another matter. I think you are seeing the lower value of the Y axis scale going -ve and you assume you have -values . . . look at the Data window and check your values for all the bars on the chart when you see a -ve value on the y axis . . . do you have any -ve values ? i don't think you will . . .

As for your code being wrong . . . I think you need to do this . . . maybe, if I understand what you are trying to do.

{ 
Diff_OC=Diff_OC + (Open[n]-Close[n]); // Accumulating difference between open and close sum 
Diff_HL=Diff_HL + (High[n]-Low[n]); // Accumulating difference between high and low sum 

Diff_OC=MathAbs(Diff_OC); //Making Diff_OC positive 
} 

change to

{ 
Diff_OC=Diff_OC + (Open[n]-Close[n]); // Accumulating difference between open and close sum 
Diff_HL=Diff_HL + (High[n]-Low[n]); // Accumulating difference between high and low sum 
}

Diff_OC=MathAbs(Diff_OC); //Making Diff_OC positive   <---- outside of the braces.
 
 
RaptorUK:

I think you are mistaken . . . . I think your code is incorrect but that is another matter. I think you are seeing the lower value of the Y axis scale going -ve and you assume you have -values . . . look at the Data window and check your values for all the bars on the chart when you see a -ve value on the y axis . . . do you have any -ve values ? i don't think you will . . .

As for your code being wrong . . . I think you need to do this . . . maybe, if I understand what you are trying to do.


Thank you for the help, this seem to get all the values positive. There is however still something very wrong with the code. The values are still not reasonable and the indicatorline

is jagged, not smoothe like one would expect from a line that shows an average.

The information I would like from the indicator is the relationship between the candles body and the full size of the candle. My theory is that a high value, when the body is relatively large,

indicates a market with more determination and a low value indicates a more confused market.

Files:
aver_det2.mq4  3 kb
 
  1. Of course the line will be jagged. Supposed you have one up bar of 10 pips followed by one down bar of 10 pips. Sum of OC will be zero but Sum of HL will be 20. You may want to sum MathAbs(O-C). If you're trying to do something like an RSI you may want to sum and average just (O-C)/(H-L)

  2. for(n=i;n<=i+Aver_Bars-1;n++) // Loop of summing values 
    Your summing i through i+Aver for a total of Aver+1.
  3. // Diff_OC=Diff_OC + ... // Simplify where possible
       Diff_OC += ...        // Less typing/less typos

 
WHRoeder:
  1. Of course the line will be jagged. Supposed you have one up bar of 10 pips followed by one down bar of 10 pips. Sum of OC will be zero but Sum of HL will be 20. You may want to sum MathAbs(O-C). If you're trying to do something like an RSI you may want to sum and average just (O-C)/(H-L)I

  2. Your summing i through i+Aver for a total of Aver+1.


Thank You for Your insights WHRoeder, I have changed the code to make it simpler, that was a good tip, it did nothing to make the line smoother though.

My intention is to divide the size of the body with the size of the whole bar, MathAbs should here make Diff_OC always positive so it would make no difference

if the bar is up or down, it would always have a positive size. Because of this the sum of one up bar of 10 pips and one down bar of 10 pips would not be zero but 20.

As for the loop, well I´m not sure how you mean, I´ve actually "borrowed" the whole code from one of the examples in the mql4 book on this site. I have then changed

the calculations and the variables to fit my purpouses, the loops and the averaging method I have left as they were.

The code now looks like this and it is still not working as I wish.

//--------------------------------------------------------------------
// Aver_det2.mq4 
//--------------------------------------------------------------------
#property indicator_separate_window // Drawing in a separate window
#property indicator_buffers 1       // Number of buffers
#property indicator_color1 Blue     // Color of the 1st line

extern int Aver_Bars=5;             // Amount of bars for calculation 

double Buf_0[];                     // Declaring an indicator array
//--------------------------------------------------------------------
int init()                          // Special function init()  
   {   
   SetIndexBuffer(0,Buf_0);         // Assigning an array to a buffer   
   SetIndexStyle (0,DRAW_LINE,STYLE_SOLID,1);// line style   
   return;                          // Exit the special funct. init()  
   }
//--------------------------------------------------------------------
int start()                         // Special function start()  
   {   
   int i,                           // Bar index
   n,                               // Formal parameter   
   Counted_bars;                    // Number of counted bars   
   double   
         Diff_OC,                   // Sum of the difference between open and close for period   
         Diff_HL;                   // Sum of the difference between high and low for period
//--------------------------------------------------------------------   

   Counted_bars=IndicatorCounted(); // Number of counted bars   
   i=Bars-Counted_bars-1;           // Index of the first uncounted   
           
   while(i>=0)                        // Loop for uncounted bars     
      {      
                 Diff_OC=0;
                 Diff_HL=0;   // Nulling at loop beginning      
      
      for(n=i;n<=i+Aver_Bars-1;n++)   // Loop of summing values         
         {           
          Diff_OC+=MathAbs(Open[n]-Close[n]);     // Accumulating difference between open and close sum and making Diff_OC positive      
          Diff_HL+=(High[n]-Low[n]);       // Accumulating difference between high and low sum      
          }    
                          
      Buf_0[i]=(Diff_OC/Diff_HL)/Aver_Bars;         // Value of 0 buffer on i bar      
      i--;                                          // Calculating index of the next bar     
      }
//--------------------------------------------------------------------   
   return;                          // Exit the special funct. start()  
   }
//--------------------------------------------------------------------
 
radpajo:


Thank You for Your insights WHRoeder, I have changed the code to make it simpler, that was a good tip, it did nothing to make the line smoother though.

My intention is to divide the size of the body with the size of the whole bar, MathAbs should here make Diff_OC always positive so it would make no difference

Diff_OC/Diff_HL gives a ratio of bar body to bar length . . . as I'm sure you are aware. The question is what do you want to show ? do you want to show this averaged over 5 bars or do you want to show the aggregate of 5 bars ?

Currently you are showing the aggregate.

Take an example, 5 bars, 1 very big bar with no wicks (100 pips), 4 very small bars with no bodies (DOJIs, 10 pips), the average of the ratios will result in a value of 0.2, the bodies summed/candles summed = (100 /140)/5 = 0.143

These produce different values . . . what are you looking for ?

 
RaptorUK:

Diff_OC/Diff_HL gives a ratio of bar body to bar length . . . as I'm sure you are aware. The question is what do you want to show ? do you want to show this averaged over 5 bars or do you want to show the aggregate of 5 bars ?

Currently you are showing the aggregate.

Take an example, 5 bars, 1 very big bar with no wicks (100 pips), 4 very small bars with no bodies (DOJIs, 10 pips), the average of the ratios will result in a value of 0.2, the bodies summed/candles summed = (100 /140)/5 = 0.143

These produce different values . . . what are you looking for ?


This forum is just full of AHA-experiences, I am interested in the average, this seem to be the fundamental mistake in my code. It makes perfect sense, all I need to do now is to figure out how to change my code.

Thank´s a lot Raptor

 
radpajo:


This forum is just full of AHA-experiences, I am interested in the average, this seem to be the fundamental mistake in my code. It makes perfect sense, all I need to do now is to figure out how to change my code.

Thank´s a lot Raptor


Thought this would do the trick, it didn´t, now I see nothing...

int start()                         // Special function start()  
   {   
   int i,                           // Bar index
   n,                               // Formal parameter   
   Counted_bars;                    // Number of counted bars   
   double   
         Ratio_BC;
         //Diff_OC,                   // Sum of the difference between open and close for period   
         //Diff_HL;                   // Sum of the difference between high and low for period
//--------------------------------------------------------------------   

   Counted_bars=IndicatorCounted(); // Number of counted bars   
   i=Bars-Counted_bars-1;           // Index of the first uncounted   
           
   while(i>=0)                        // Loop for uncounted bars     
      {      
                 Ratio_BC=0;          // Nulling at loop beginning      
      
      for(n=i;n<=i+Aver_Bars-1;n++)   // Loop of summing values         
         {           
          Ratio_BC+=(MathAbs(Open[n]-Close[n]))/(High[n]-Low[n]);    
          }    
                          
      Buf_0[i]=Ratio_BC/Aver_Bars;         // Value of 0 buffer on i bar      
      i--;                                          // Calculating index of the next bar     
      }
//--------------------------------------------------------------------   
   return;                          // Exit the special funct. start()  
   }
 
radpajo:


Thought this would do the trick, it didn´t, now I see nothing...

Your code looks OK to me . . . what is the problem you are getting ?
 
RaptorUK:
Your code looks OK to me . . . what is the problem you are getting ?

The problem is that it does not draw anything at all, the indicatorwindow is empty.
 
radpajo:

The problem is that it does not draw anything at all, the indicatorwindow is empty.

Look at your Experts tab to see what is going on when you add the Indicator to your chart . . . .

Add this . . .

          if (( High[n]-Low[n]) != 0)        //  <----  add this line
             Ratio_BC+=( MathAbs( Open[n]-Close[n] )  / ( High[n]-Low[n]) );
              
Reason: