How code indicator to count number of crossings of Moving Average with Open

 

I need help on coding an indicator to count number of crossings of Moving Average with Open. I attempted coding it but when I attached to a chart there was no value. The indicator should count when MA1 crosses above Open while MA2 is under.

//+------------------------------------------------------------------+
//|                                          CountMACrossingOpen.mq4 |
//|                                          Copyright 2005-2014, RB |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright   "RisaldeB"

#property description "CountMACrossingOpen"
#property strict

//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1  DodgerBlue
//--- input parameter
input int InpAtrPeriod=14; // ATR Period
input int InpSMA=1;
int count=0;
//--- buffers
double ExtATRBuffer[];
double ExtTRBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
//--- 1 additional buffer used for counting.
   IndicatorBuffers(2);
   IndicatorDigits(Digits);
//--- indicator line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtATRBuffer);
   SetIndexBuffer(1,ExtTRBuffer);
//--- name for DataWindow and indicator subwindow label
   short_name="MACrossOpen("+IntegerToString(InpAtrPeriod)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);
//--- check for input parameter
   if(InpAtrPeriod<=0)
     {
      Print("Wrong input parameter ATR Period=",InpAtrPeriod);
      return(INIT_FAILED);
     }
//---
   SetIndexDrawBegin(0,InpAtrPeriod);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Average True Range                                               |
//+------------------------------------------------------------------+
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 i,limit;
//--- check for bars count and input parameter
   if(rates_total<=InpAtrPeriod || InpAtrPeriod<=0)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtATRBuffer,false);
   ArraySetAsSeries(ExtTRBuffer,false);
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(close,false);
//--- preliminary calculations
   if(prev_calculated==0)
     {
     
               
     
     
      ExtTRBuffer[0]=0.0;
      ExtATRBuffer[0]=0.0;
      //--- filling out the array of True Range values for each period
      for(i=1; i<rates_total; i++)
              {
               if(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) && Open[i]>iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1))count++;
              }
         ExtTRBuffer[i]=(count);
      //--- first AtrPeriod values of the indicator are not calculated
      double firstValue=0.0;
      for(i=1; i<=InpAtrPeriod; i++)
        {
         ExtATRBuffer[i]=0.0;
         firstValue+=ExtTRBuffer[i];
        }
      //--- calculating the first value of the indicator
      firstValue/=InpAtrPeriod;
      ExtATRBuffer[InpAtrPeriod]=firstValue;
      limit=InpAtrPeriod+1;
     }
   else
   
   
   
      limit=prev_calculated-1;
//--- the main loop of calculations
   for(i=limit; i<rates_total; i++)
              {
               if(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) && Open[i]>iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1))count++;
              }
   
     {
      ExtTRBuffer[i]=(count);
      ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) && Open[i]>iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1))count++;

 
A topic for WHRoeder...please be patient, he arrives.
 
Zaldy: indicator to count number of crossings of Moving Average with Open. I attempted coding it but when I attached to a chart there was no value.
  1.    IndicatorBuffers(2);
       IndicatorDigits(Digits);
    //--- indicator line
       SetIndexStyle(0,DRAW_LINE);
       SetIndexBuffer(0,ExtATRBuffer);
       SetIndexBuffer(1,ExtTRBuffer);
    
    You put count in ExtTRBuffer but aren't displaying it.
  2. if(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) && Open[i] > iMA(NULL, 0, InpSMA, 0, MODE_SMA, PRICE_CLOSE, 1)) count++;
    Don't write long, unreadable lines. Books aren't 2 foot wide one column for a reason - 6 in wide or multiple columns. Code to 80 characters max.
  3. if(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) 
    && Open[i]>iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1))count++; 
    You only check if the MA moved from below to above. A cross is both ways.
    bool wasAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1),
          isAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0),
         crossed  = wasAbove != isAbove;
    if( crossed )count++; 
  4. You're incrementing a counter for all bars. It can only cross once.
    ExtTRBuffer[i] = ExtTRBuffer[i+1];
    if(crossed) ExtTRBuffer[i]++;
  5. You loop up instead of down, calculate all bars, instead of what changed, access beyond end of the array because of the look back ima(..., 1) and don't calculate bar zero.
    #define LOOKBACK 1 // iMA(... 1)
    int indicator_counted = prev_calculated;
    if(indicator_counted < LOOKBACK) indicator_counted = LOOKBACK;
    for(i = rates_total - 1 - indicator_counted; i>=0 i--)
    For the above to work, you need to change the return
    // return(rates_total);
       return(rates_total-1); // Recalculate bar zero next tick.
    I know what the new docs say. If you do it their way you'll have to test prev_calculated for non-zero and adjust rates_total - prev_calculated down one. That is going back to decrement indicator_counted confusion.
  6. ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod;
    Not sure what you mean here. A EMA of TRbuffer would be
    double alpha = 2./(InpAtrPeriod+1);
    ExtATRBuffer[i]=ExtATRBuffer[i+1]
                   +(ExtTRBuffer[i]-ExtATRBuffer[i+1])*alpha;
    Older values are i+1 (series arrays and buffers) If you really meant ExtTRBuffer[i+InpAtrPeriod] then int LOOKBACK = InpAtrPeriod;
  7. angevoyageur: A topic for WHRoeder...please be patient, he arrives.
    Why me?!

 
WHRoeder:
  1. You put count in ExtTRBuffer but aren't displaying it.
  2. You only check if the MA moved from below to above. A cross is both ways.
  3. You're incrementing a counter for all bars. It can only cross once.
  4. You loop up instead of down, calculate all bars, instead of what changed, access beyond end of the array because of the look back ima(..., 1) and don't calculate bar zero.
    For the above to work, you need to change the return
  5. ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod;
    Not sure what you mean here. A EMA of TRbuffer would be Older values are i+1 (series arrays and buffers)
  6. angevoyageur: A topic for WHRoeder...please be patient, he arrives.
    Why me?!


I know you like to answer to that kind of question. Not ? And you are very good at this.
 
angevoyageur:
I know you like to answer to that kind of question. Not ? And you are very good at this.

WHRoeder:
  1. You put count in ExtTRBuffer but aren't displaying it.
  2. if(Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0) && Open[i] > iMA(NULL, 0, InpSMA, 0, MODE_SMA, PRICE_CLOSE, 1)) count++;
    Don't write long, unreadable lines. Books aren't 2 foot wide one column for a reason - 6 in wide or multiple columns. Code to 80 characters max.
  3. You only check if the MA moved from below to above. A cross is both ways.
  4. You're incrementing a counter for all bars. It can only cross once.
  5. You loop up instead of down, calculate all bars, instead of what changed, access beyond end of the array because of the look back ima(..., 1) and don't calculate bar zero. For the above to work, you need to change the return I know what the new docs say. If you do it their way you'll have to test prev_calculated for non-zero and adjust rates_total - prev_calculated down one. That is going back to decrement indicator_counted confusion.
  6. ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod;
    Not sure what you mean here. A EMA of TRbuffer would be Older values are i+1 (series arrays and buffers) If you really meant ExtTRBuffer[i+InpAtrPeriod] then int LOOKBACK = InpAtrPeriod;
  7. angevoyageur: A topic for WHRoeder...please be patient, he arrives.
    Why me?!



Hi WHRoeder, Thank you for taking your time in answering my call for help. I re-wrote the indicator code to reflect your input and also to make my self clear of my intention. I attached here the new code. However it is still not displaying the indicator when I attach on the chart. I hope you can help me complete this indicator. Again thank you so much.

#property indicator_separate_window
//--- input parameter
input int InpMACOPeriod=14; //  Period
input int InpSMA=1;
int count=0;
//--- buffers
double ExtMACOBuffer[];//Tell the computer that this is an array.


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  string short_name;
//--- indicator buffers mapping
  SetIndexBuffer(0,ExtMACOBuffer);  
  SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1,Red);
  SetIndexDrawBegin(0,InpMACOPeriod);
//--- name for DataWindow and indicator subwindow label
   short_name="MACO("+IntegerToString(InpMACOPeriod)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);  
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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 &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int uncountedbars=Bars-counted_bars;
//---

for (int i=0;i<uncountedbars; i++)
{
bool wasAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1),
      isAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0),
     crossed  = wasAbove != isAbove;
if( crossed )count++; 
ExtMACOBuffer[i] = ExtMACOBuffer[i+1];
if(crossed) ExtMACOBuffer[i]++;


}   
   
   
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
I'm lost I really need help on this please anyone......
 

can u please explain what r u trying to do

what do u mean by "to count number of crossings of Moving Average with Open" ? how many times in the chart ? or per bar or what ?

is it somthing like this ?

#property indicator_separate_window
//--- input parameter
input int InpMACOPeriod=14; //  Period
input int InpSMA=1;
int count=0;
//--- buffers
double ExtMACOBuffer[];//Tell the computer that this is an array.


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  string short_name;
//--- indicator buffers mapping
  SetIndexBuffer(0,ExtMACOBuffer);  
  SetIndexStyle(0,DRAW_HISTOGRAM, STYLE_SOLID, 2,Red);
  SetIndexDrawBegin(0,InpMACOPeriod);
//--- name for DataWindow and indicator subwindow label
   short_name="MACO("+IntegerToString(InpMACOPeriod)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);  
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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 &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int uncountedbars=Bars-counted_bars;
//---

for (int i=0;i<uncountedbars; i++)
{
bool wasAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,1),
      isAbove = Open[i]<iMA(NULL,0,InpSMA,0,MODE_SMA,PRICE_CLOSE,0),
     crossed  = wasAbove != isAbove;
if( crossed )count++; 
ExtMACOBuffer[i] = ExtMACOBuffer[i+1];
if(crossed) ExtMACOBuffer[i] = 1.0;


}   
   
   
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
qjol:

can u please explain what r u trying to do

what do u mean by "to count number of crossings of Moving Average with Open" ? how many times in the chart ? or per bar or what ?

is it somthing like this ?


I need an indicator that when the current price which is the Bid cross above or below the Bars Opening price it will count the number crossing per bar. For example Open price is 5 then the price moves higher but then reverses back below Open> that's count 1. Then the price went back higher than Open that's count 2 then so on and on but when the current bar is finish the number of counts will be stored in the array say if the total count is 10 then that will be plotted into the chart. When the new bar starts the counting is reset back to zero then a new counting process begins again. Then all those counted stored in the array per bar will be divided by the Period say 14 and the result will be recorded in the latest bar. I Thought the best to do it is by using the moving average iMA to cross with the Open price.

I modified the codes I attached here it finally display the indicator lines however I noticed 2 problems which I think if corrected will be perfect for my needs. First it counted every tick rather than the cross overs. Second it continuously counting to infinity without resetting every bar. Now if you can figure it out please show me where I make mistakes. Thanks.

//--- input parameter
input int InpMACOPeriod=14; //  Period
input int MA_Period=1;

int count=0;
//--- buffers
double ExtMACOBuffer[];//Tell the computer that this is an array.

// PROBLEM WITH THIS INDICATOR. 1. IT COUNTED THE TICKS NOT THE CROSSINGS.2. IT KEEP COUNTING CONTINUOUSLY. 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  string short_name;
//--- indicator buffers mapping
  SetIndexBuffer(0,ExtMACOBuffer);  
  SetIndexStyle(0,DRAW_LINE, STYLE_SOLID, 1,Red);
  SetIndexDrawBegin(0,InpMACOPeriod);
//--- name for DataWindow and indicator subwindow label
   short_name="MACO("+IntegerToString(InpMACOPeriod)+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);  
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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 &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
  
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int uncountedbars=Bars-counted_bars;
//---

for (int i=0;i<uncountedbars; i++)
{
 
   bool check;
   check = crossed();
   
  
   
if(check==true) count++;
ExtMACOBuffer[i] = count/InpMACOPeriod;



}   
   
   
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
bool crossed()
{
int i=0;
double MA0= iMA(NULL, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 0);
double MA1= iMA(NULL, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 1);

if ((Open[0]>MA1 && Open[0]<MA0) || (Open[0]<MA1 && Open[0]>MA0))
return(true);

else
return(EMPTY_VALUE);
}

I hope I am clear if not please let me know. :Big thanks.

 
Zaldy:

I Thought the best to do it is by using the moving average iMA to cross with the Open price.

how come r u familiar how does MA been calculated at all ?
Zaldy:


Second it continuously counting to infinity without resetting every bar.


reset the counter every bar

if (rates_total != prev_calculated) count = 0;

some code u didn't noticed

1) no need to use IndicatorCounted() it's build in in the OnCalculate function

2) unnecessary code & typing for nothing

 bool check;
   check = crossed();
   
  
   
if(check==true) count++;

instead of

if (crossed()) count++;
 
qjol:

how come r u familiar how does MA been calculated at all ?

reset the counter every bar

some code u didn't noticed

1) no need to use IndicatorCounted() it's build in in the OnCalculate function

2) unnecessary code & typing for nothing

instead of



Hi qjol, Thanks once again! I inserted what you suggested, it reset back to zero on the new bar however the lines of the indicator also went back to zero like a half sine wave, How can I code so that the lines will connect between the counts per bar without it going back to zero?

Also the indicator counting is not the crossings that I intended but rather the indicator is counting the per ticks, so it end up counting more than hundreds per bar rather than the usual less than 20 counts. Please help how I can resolve this. Do you think its the iMA? I tried to use other method like below but was also counting the ticks rather than the Open[i]==Bid.

bool crossed()
{
int i=0;
if (Open[i]==Bid)
return(true);

else
return(EMPTY_VALUE);
}
if (rates_total != prev_calculated) count = 0;
 
Zaldy:


Hi qjol, Thanks once again! I inserted what you suggested, it reset back to zero on the new bar however the data in the array of previous bars was also reset back to zero. i need the previous bars count data intact in the array. How can I code that?

read this code & u will get the idea

Zaldy:


Also the indicator counting is not the crossings that I intended but rather the indicator is counting the per ticks, so it end up counting more than hundreds per bar rather than the usual less than 20 counts. Please help how I can resolve this. Do you think its the iMA? I tried to use other method like below but was also counting the ticks rather than the Open[i]==Bid. I'm getting confused.

int Cnt;
bool Up, Down;

int Crosses()
   {
   if(NewBar())
      {
      if (MarketInfo(Symbol(), MODE_BID) < Open[0])
         {
         Up = false;
         Down = true;
         }
      else if (MarketInfo(Symbol(), MODE_BID) > Open[0])
         {
         Up = true;
         Down = false;
         }
      }

   if (Up)
      {
      if (MarketInfo(Symbol(), MODE_BID) < Open[0])
         {
         Up = false;
         Down = true;
         Cnt++;
         }
      }
   if (Down)
      {
      if (MarketInfo(Symbol(), MODE_BID) > Open[0])
         {
         Up = true;
         Down = false;
         Cnt++;
         }
      }
   return(Cnt);
   }

bool NewBar ()
   {
   static datetime LastTime = 0;

   if (Time[0] != LastTime) 
      {
      LastTime = Time[0];     
      return (true);
      }
   else
      {
      return (false);
      }
   }
   
Reason: