I have an Expert Advisor code that was incorrectly converted to an indicator code

 

I converted Expert Advisor Code to Indicator code in MQL5 

Expert Advisor Code :-

void OnTick()
  {
   static bool isNewBar = false;
   int currBars = iBars(Symbol(), _Period);
   static int prevBars = currBars;

   if(prevBars == currBars)
     {
      isNewBar = false;
     }
   else
      if(prevBars != currBars)
        {
         isNewBar = true;
         prevBars = currBars;
        }

   const int length = 20;
   const int limit = 20;

   int right_index, left_index;
   bool isSwingHigh = true, isSwingLow = true;
   static double swing_H = -1.0, swing_L = -1.0;
   int curr_bar = limit;

   if(isNewBar)
     {
      for(int j = 1; j <= length; j++)
        {
         right_index = curr_bar - j;
         left_index = curr_bar + j;

         if((high(curr_bar) <= high(right_index)) || (high(curr_bar) < high(left_index)))
           {
            isSwingHigh = false;
           }
         if((low(curr_bar) >= low(right_index)) || (low(curr_bar) > low(left_index)))
           {
            isSwingLow = false;
           }
        }

   

      if(isSwingHigh)
        {
         swing_H = high(curr_bar);
         // Print("UP BAR INDEX ", curr_bar, " of High = ", high(curr_bar));
         drawSwingPoint(TimeToString(time(curr_bar)), time(curr_bar), high(curr_bar), 77, clrBlue, -1);
        }

      if(isSwingLow)
        {
         swing_L = low(curr_bar);
         //Print("DOWN @ BAR INDEX ", curr_bar, " of Low: ", low(curr_bar));
         drawSwingPoint(TimeToString(time(curr_bar)), time(curr_bar), low(curr_bar), 77, clrRed, 1);
        }
     }


   double Ask = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_ASK), _Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_BID), _Digits);

   if(swing_H > 0 && Bid > swing_H && close(1) > swing_H)
     {
      
      Print("BREAK UP NOW");
      int swing_H_index = 0;
      for(int i = 0; i <= length * 2 + 1000; i++)
        {
         double high_sel = high(i);
         if(high_sel == swing_H)
           {
            swing_H_index = i;
            Print("BREAK HIGH @ BAR ", swing_H_index);
            break;
           }
        }
      
      drawBreakLevel(TimeToString(time(0)), time(swing_H_index), high(swing_H_index),
                     time(0 + 1), high(swing_H_index), clrBlue, -1);

      if(swing_H_index != 0)
        {
         Print("Up Trend");
        }

      swing_H = -1.0;

  
      return;
     }
   else
      if(swing_L > 0 && Ask < swing_L && close(1) < swing_L)
        {
         
         Print("BREAK DOWN NOW");
         int swing_L_index = 0;
         for(int i = 0; i <= length * 2 + 1000; i++)
           {
            double low_sel = low(i);
            if(low_sel == swing_L)
              {
               swing_L_index = i;
               Print("BREAK LOW @ BAR ", swing_L_index);
               break;
              }
           }
           
         drawBreakLevel(TimeToString(time(0)), time(swing_L_index), low(swing_L_index),
                        time(0 + 1), low(swing_L_index), clrRed, 1);

         if(swing_L_index != 0)
           {
            Print("Down Trend");
           }

         swing_L = -1.0;

     
         return;
        }


  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double high(int index)
  {
   return (iHigh(Symbol(), _Period, index));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double low(int index)
  {
   return (iLow(Symbol(), _Period, index));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double close(int index)
  {
   return (iClose(Symbol(), _Period, index));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime time(int index)
  {
   return (iTime(Symbol(), _Period, index));
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void drawSwingPoint(string objName, datetime time, double price, int arrCode,
                    color clr, int direction)
  {

   if(ObjectFind(0, objName) < 0)
     {
      ObjectCreate(0, objName, OBJ_ARROW, 0, time, price);
      ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, arrCode);
      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, 10);
      if(direction > 0)
         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_TOP);
      if(direction < 0)
         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);

      string txt = " BoS";
      string objNameDescr = objName + txt;
      ObjectCreate(0, objNameDescr, OBJ_TEXT, 0, time, price);
      ObjectSetInteger(0, objNameDescr, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, objNameDescr, OBJPROP_FONTSIZE, 10);

      if(direction > 0)
        {
         ObjectSetInteger(0, objNameDescr, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
         ObjectSetString(0, objNameDescr, OBJPROP_TEXT, " " + txt);
        }
      if(direction < 0)
        {
         ObjectSetInteger(0, objNameDescr, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
         ObjectSetString(0, objNameDescr, OBJPROP_TEXT, " " + txt);
        }
     }
   ChartRedraw(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void drawBreakLevel(string objName, datetime time1, double price1,
                    datetime time2, double price2, color clr, int direction)
  {
   if(ObjectFind(0, objName) < 0)
     {
      ObjectCreate(0, objName, OBJ_ARROWED_LINE, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, objName, OBJPROP_TIME, 0, time1);
      ObjectSetDouble(0, objName, OBJPROP_PRICE, 0, price1);
      ObjectSetInteger(0, objName, OBJPROP_TIME, 1, time2);
      ObjectSetDouble(0, objName, OBJPROP_PRICE, 1, price2);
      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, objName, OBJPROP_WIDTH, 2);

      string txt = " Break   ";
      string objNameDescr = objName + txt;
      ObjectCreate(0, objNameDescr, OBJ_TEXT, 0, time2, price2);
      ObjectSetInteger(0, objNameDescr, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, objNameDescr, OBJPROP_FONTSIZE, 10);
      if(direction > 0)
        {
         ObjectSetInteger(0, objNameDescr, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
         ObjectSetString(0, objNameDescr, OBJPROP_TEXT, " " + txt);
        }
      if(direction < 0)
        {
         ObjectSetInteger(0, objNameDescr, OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER);
         ObjectSetString(0, objNameDescr, OBJPROP_TEXT, " " + txt);
        }
     }
   ChartRedraw(0);
  }
//+------------------------------------------------------------------+


Indicator Code :-

#property strict

#property indicator_plots 0



//+------------------------------------------------------------------+

//| Main Calculation 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[])

  {

// Ensure series are reversed

   ArraySetAsSeries(time, true);

   ArraySetAsSeries(open, true);

   ArraySetAsSeries(high, true);

   ArraySetAsSeries(low, true);

   ArraySetAsSeries(close, true);



   const int length = 20;          // Swing length

   const int forward_bars = 100;   // Future bars to check for breakout



// Start scanning from the rightmost valid bar

   for(int curr_bar = rates_total - length - forward_bars - 1; curr_bar >= length; curr_bar--)

     {

      bool isSwingHigh = true;

      bool isSwingLow = true;



      for(int j = 1; j <= length; j++)

        {

         if(high[curr_bar] <= high[curr_bar - j] || high[curr_bar] < high[curr_bar + j])

            isSwingHigh = false;



         if(low[curr_bar] >= low[curr_bar - j] || low[curr_bar] > low[curr_bar + j])

            isSwingLow = false;

        }



      if(isSwingHigh)

        {

         double swing_H = high[curr_bar];

         drawSwingPoint(TimeToString(time[curr_bar]), time[curr_bar], swing_H, 217, clrBlue, -1);



         // Check future bars for Break Up

         for(int i = curr_bar - 1; i >= MathMax(0, curr_bar - forward_bars); i--)

           {

            if(close[i] > swing_H)

              {

               drawBreakLevel("BreakUp" + IntegerToString(curr_bar),

                              time[curr_bar], swing_H,

                              time[i], swing_H, clrBlue, -1);

               break;

              }

           }

        }



      if(isSwingLow)

        {

         double swing_L = low[curr_bar];

         drawSwingPoint(TimeToString(time[curr_bar]), time[curr_bar], swing_L, 218, clrRed, 1);



         // Check future bars for Break Down

         for(int i = curr_bar - 1; i >= MathMax(0, curr_bar - forward_bars); i--)

           {

            if(close[i] < swing_L)

              {

               drawBreakLevel("BreakDown_" + IntegerToString(curr_bar),

                              time[curr_bar], swing_L,

                              time[i], swing_L, clrRed, 1);

               break;

              }

           }

        }

     }



   return rates_total;

  }



//+------------------------------------------------------------------+

//| Draw Swing Point Arrow and Label                                 |

//+------------------------------------------------------------------+

void drawSwingPoint(string objName, datetime time, double price, int arrowCode,

                    color clr, int direction)

  {

   if(ObjectFind(0, objName) < 0)

     {

      ObjectCreate(0, objName, OBJ_ARROW, 0, time, price);

      ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, arrowCode);

      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);

      ObjectSetInteger(0, objName, OBJPROP_WIDTH, 1);



      string txt = " BoS";

      string labelName = objName + "_label";

      ObjectCreate(0, labelName, OBJ_TEXT, 0, time, price);

      ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr);

      ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10);



      if(direction > 0)

        {

         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_TOP);

         ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);

         ObjectSetString(0, labelName, OBJPROP_TEXT, "↓" + txt);

        }

      else

        {

         ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);

         ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);

         ObjectSetString(0, labelName, OBJPROP_TEXT, "↑" + txt);

        }

     }

  }



//+------------------------------------------------------------------+

//| Draw Break Line and Label                                        |

//+------------------------------------------------------------------+

void drawBreakLevel(string objName, datetime time1, double price1,

                    datetime time2, double price2, color clr, int direction)

  {

   if(ObjectFind(0, objName) < 0)

     {

      ObjectCreate(0, objName, OBJ_ARROWED_LINE, 0, time1, price1, time2, price2);

      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);

      ObjectSetInteger(0, objName, OBJPROP_WIDTH, 2);



      string labelName = objName + "_label";

      ObjectCreate(0, labelName, OBJ_TEXT, 0, time2, price2);

      ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr);

      ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10);



      if(direction > 0)

        {

         ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);

         ObjectSetString(0, labelName, OBJPROP_TEXT, "↓ Break");

        }

      else

        {

         ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER);

         ObjectSetString(0, labelName, OBJPROP_TEXT, "↑ Break");

        }

     }

  }

//+------------------------------------------------------------------+


Is this correct code ?

 

What do you mean incorrectly converted? Did you use a tool to attempt to convert it or did you ask a freelancer to convert it?

The code isn't wrong, but you have no initializer or object cleanup. I fixed it.

Edit: I added the traditional zigzag as a dynamic buffer so it draws with the objects in the strategy tester

 
Conor Mcnamara #:

What do you mean incorrectly converted? Did you use a tool to attempt to convert it or did you ask a freelancer to convert it?

The code isn't wrong, but you have no initializer or object cleanup. I fixed it

Sorry sir, I have some wrong indicator code but I converted EA code to Indicator code.


Thank you for fixed it...👍

I don't use zigzag Indicator but I wanted detect this BOS .

I need detect this history/Previous/shift bar .

 
Conor Mcnamara #:

What do you mean incorrectly converted? Did you use a tool to attempt to convert it or did you ask a freelancer to convert it?

The code isn't wrong, but you have no initializer or object cleanup. I fixed it.

Edit: I added the traditional zigzag as a dynamic buffer so it draws with the objects in the strategy tester

You edited the message, and I downloaded both mq5 files. Thank you for fixing it! 👍👍

 
I didn't mind as it was easy to make it work. It's true that the zigzag indicator wasn't needed for this logic, but it always complements market structure logic (visually)
 
Conor Mcnamara #:
I didn't mind as it was easy to make it work. It's true that the zigzag indicator wasn't needed for this logic, but it always complements market structure logic (visually)

You optimized the 'for' loop.

No need ZigZag Indicator....


I added this "shiftOffset" code 👇

if(close[i] < swing_L && close[i + shiftOffset] < swing_L)

Because I wanted to detect this BOS after closed candle..


It worked very well..

Thank you 👍