MqlRates: Spread[] Problem!! How to handle it properly?

 

I'm trying to write a spread oscillator, but for some reason it doesn't works.
I don't know what is happening... That's the way i saw in the iIndicators examples. But for "MqlRates" it doesn't works.

MqlRates must be handled in a different way? or..?


My full code is below.
Thank you!!


#property copyright ""
#property link      ""
#property version   ""
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1

input int  period=14;
double  Signal[];



int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0,Signal,INDICATOR_DATA);   
//---
   return(INIT_SUCCEEDED);
}



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[])
  {
//---      
      
      if(rates_total<period)
         return(0);
      
      if(prev_calculated<period)
         pos=period;      
      else
         pos=prev_calculated-1;


      
      for(int i=pos; i<rates_total && !IsStopped();i++)
      {                  
            double sum  =  0;      
            double average = 0;
            

            for(int j=i-1; j>i-period && j>=0; j--)
            {
               sum += spread[j];
            }
            average = sum/period;              
            

            Signal[i] = spread[i] - average; //this fails
      }
      
      
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
karp wak:I'm trying to write a spread oscillator, but for some reason it doesn't works. I don't know what is happening... That's the way i saw in the iIndicators examples. But for "MqlRates" it doesn't works.

MqlRates must be handled in a different way? or..?

First, a word of note! Nowhere in your posted sample code are you using "MqlRates". What you are using is the data provided by OnCalculate() event handler. Don't mix the two concepts.

However, with that issue aside, the spread is a (long) datatype and in points and not in price difference, so you will have to typecast the value. You will also have to typecast the period to prevent integer division.

long sum = 0;      
double average = 0;

for(int j=i-1; j>i-period && j>=0; j--)
   sum += spread[j];

average = (double) sum / (double) period;              
Signal[i] = (double) spread[i] - average;

EDIT: I've opted to do the summing with a long instead of a double, and only doing the typecast at the end of the summing loop, because it will be faster than having to typecast on every iteration.

EDIT2: Please note the the spread value is not always available on certain symbols and/or brokers and it is also not available on MT4.

 
Fernando Carreiro:

First, a word of note! No where in your posted sample code are you using "MqlRates". What you are using is the data provided by OnCalculate() event handler. Don't mix the two concepts.

However, with that issue aside, the spread is in points and not in price difference, so you will have to multiple with the point size as follows:


I'm sorry, i was confused about it...
Thank you so much for your help Fernando!!

 
karp wak: I'm sorry, i was confused about it... Thank you so much for your help Fernando!!

Here is a fixed version with some other things cleaned up.

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "Spread Osc"
#property indicator_color1  clrMagenta
#property indicator_type1   DRAW_LINE
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int period=14;
double  Signal[];

int OnInit()
{
   SetIndexBuffer(0,Signal,INDICATOR_DATA);   
   return(INIT_SUCCEEDED);
}

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[] ) 
{
   for( int i = prev_calculated < 1 ? 0 : prev_calculated - 1; !IsStopped() && ( i < rates_total ); i++ )
   {
      if( i >= period )
      {
         long sum = 0;
         for( int j = i - period; !IsStopped() && ( j < i ); j++ )
            sum += spread[ j ];
            
         double average = (double) sum / (double) period;
         Signal[ i ] = (double) spread[ i ] - average;
      }
      else
         Signal[ i ] = EMPTY_VALUE;
   };
      
   return(rates_total);
}
 
Fernando Carreiro:

Here is a fixed version with some other things cleaned up.

It is wonderful!! :-) Thank you so much Fernando!!