Indicator that plots arrows on the highest high and lowest low between every two successive moving average crossovers

 

This is my first time trying to code an indicator, I can't seem to get my indicator to show on the chart. Seems like I'm getting some of the logic wrong, can anyone help to see through my code and tell me what I'm doing wrong. I know my calculations are most likely off.

The indicator is supposed to plot arrows on the highest high and low

//--- input parameters
input bool     UseEMA=true;
input bool     UseSMA=false;
input int      FastMAPeriod=10;
input int      SlowMAPeriod=20;
//--- indicator buffers
double         HighBuffer[];
double         LowBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorBuffers(2);
   SetIndexBuffer(0,HighBuffer);
   SetIndexBuffer(1,LowBuffer);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,159);
   PlotIndexSetInteger(1,PLOT_ARROW,159);
   IndicatorShortName("CNVRSN High Low");
   
//---
   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[])
  {
//---
   if(rates_total<SlowMAPeriod-1) return(0);
   
   int first;
   double FastMA[];
   double SlowMA[];
   int UpCross = 0;
   int DownCross = 0;
   
   if (prev_calculated==0) first = SlowMAPeriod-1;
   if (prev_calculated>0) first = prev_calculated-1;
   
//--- Main loop
   for (int cnt=first; cnt<rates_total; cnt++)
   {
      if(UseEMA)
      {
         FastMA[cnt] = iMA(NULL,0,FastMAPeriod,0,MODE_EMA,PRICE_CLOSE,cnt);
         SlowMA[cnt] = iMA(NULL,0,SlowMAPeriod,0,MODE_EMA,PRICE_CLOSE,cnt);
      }
      if (UseSMA)
      {
         FastMA[cnt] = iMA(NULL,0,FastMAPeriod,0,MODE_SMA,PRICE_CLOSE,cnt);
         SlowMA[cnt] = iMA(NULL,0,SlowMAPeriod,0,MODE_SMA,PRICE_CLOSE,cnt);
      }
//--- Store the index of the bar where a cross happened
      if (FastMA[cnt] > SlowMA[cnt] && FastMA[cnt+1] < SlowMA[cnt+1])
      {
         UpCross = iBarShift(NULL,0,Time[cnt],false);
      }
      if (SlowMA[cnt] > FastMA[cnt] && SlowMA[cnt+1] < FastMA[cnt+1])
      {
         DownCross = iBarShift(NULL,0,Time[cnt],false);
      }
//--- Get the Highest high between an upcross and a downcross
//--- and the Lowest low between a downcross and an upcross
      if (DownCross > UpCross)
      {
         HighBuffer[cnt] = iHighest(NULL,0,MODE_HIGH,(DownCross-UpCross),cnt);
         LowBuffer[cnt] = iLowest(NULL,0,MODE_LOW,(DownCross-UpCross),cnt);
      }
      if (UpCross>DownCross)
      {
         HighBuffer[cnt] = iHighest(NULL,0,MODE_HIGH,(UpCross-DownCross),cnt);
         LowBuffer[cnt] = iLowest(NULL,0,MODE_LOW,(UpCross-DownCross),cnt);
      }
   } 
//--- return value of prev_calculated for next call
   return(rates_total);
  }


est low between every two successive moving average crossovers.

 
Topics concerning MT4 and MQL4 have their own section.
In future please post in the correct section.
I will move your topic to the MQL4 and Metatrader 4 section.
 
Keith Watford:
Topics concerning MT4 and MQL4 have their own section.
In future please post in the correct section.
I will move your topic to the MQL4 and Metatrader 4 section.
Oh.
 
Aseweje David:

This is my first time trying to code an indicator, I can't seem to get my indicator to show on the chart. Seems like I'm getting some of the logic wrong, can anyone help to see through my code and tell me what I'm doing wrong. I know my calculations are most likely off.

The indicator is supposed to plot arrows on the highest high and low


est low between every two successive moving average crossovers.

If you compile, you have an error;

no indicator window property is defined, indicator_chart_window is applied              0       0

You have to choose indicator_chart_window, or indicator_separate window

This is because the #property are missing :

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 MistyRose
#property indicator_width1 3
#property indicator_width2 3

This is not for MT4 I think, but for MT5

   PlotIndexSetInteger(0,PLOT_ARROW,159);
   PlotIndexSetInteger(1,PLOT_ARROW,159);

   SetIndexStyle(0, DRAW_ARROW); // MT4
   SetIndexArrow(0, 233);  
 
Aseweje David:

This is my first time trying to code an indicator, I can't seem to get my indicator to show on the chart. Seems like I'm getting some of the logic wrong, can anyone help to see through my code and tell me what I'm doing wrong. I know my calculations are most likely off.

The indicator is supposed to plot arrows on the highest high and low


est low between every two successive moving average crossovers.

for the rest, it should be something like that :

// Global declaration 
// so you will have 4 buffers declaration, with color and witdh, instead of 2
// so ma buffers will be see on the chart

   double FastMA[];
   double SlowMA[];

   int UpCross = 0;
   int DownCross = 0;

//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(rates_total<SlowMAPeriod-1) return(0);
   
   int first;
   if (prev_calculated==0) first = SlowMAPeriod-1;
   if (prev_calculated>0) first = prev_calculated-1;
   
//--- Main loop
   for (int cnt=first; cnt<rates_total; cnt++) //  this loop is false I think
   {
      if(UseEMA)
      {
         FastMA[cnt] = iMA(NULL,0,FastMAPeriod,0,MODE_EMA,PRICE_CLOSE,cnt);
         SlowMA[cnt] = iMA(NULL,0,SlowMAPeriod,0,MODE_EMA,PRICE_CLOSE,cnt);
      }
      if (UseSMA)
      {
         FastMA[cnt] = iMA(NULL,0,FastMAPeriod,0,MODE_SMA,PRICE_CLOSE,cnt);
         SlowMA[cnt] = iMA(NULL,0,SlowMAPeriod,0,MODE_SMA,PRICE_CLOSE,cnt);
      }
//--- Store the index of the bar where a cross happened
      if (FastMA[cnt] > SlowMA[cnt] && FastMA[cnt+1] < SlowMA[cnt+1])
      {
        // UpCross = iBarShift(NULL,0,Time[cnt],false);// this maybe work
         UpCross = cnt+1;                               
      }
      if (SlowMA[cnt] > FastMA[cnt] && SlowMA[cnt+1] < FastMA[cnt+1])
      {
        // DownCross = iBarShift(NULL,0,Time[cnt],false);
         DownCross = cnt+1;  
      }
//--- Get the Highest high between an upcross and a downcross
//--- and the Lowest low between a downcross and an upcross
     // here it need more comments
      if (DownCross > UpCross) 
      {
         HighBuffer[cnt] = iHighest(NULL,0,MODE_HIGH,(DownCross-UpCross),cnt);
         LowBuffer[cnt] = iLowest(NULL,0,MODE_LOW,(DownCross-UpCross),cnt);
      }
      if (UpCross>DownCross)
      {
         HighBuffer[cnt] = iHighest(NULL,0,MODE_HIGH,(UpCross-DownCross),cnt);
         LowBuffer[cnt] = iLowest(NULL,0,MODE_LOW,(UpCross-DownCross),cnt);
      }
   } 
//--- return value of prev_calculated for next call
   return(rates_total);
  }
Reason: