BounceNumber_V1

Author: Copyright 2023, MetaQuotes Ltd.
Price Data Components
Series array that contains close prices for each barSeries array that contains the lowest prices of each barSeries array that contains the highest prices of each bar
Miscellaneous
It opens Message Boxes to the user
0 Views
0 Downloads
0 Favorites
BounceNumber_V1
ÿþ//+------------------------------------------------------------------+

//|                                              BounceNumber_V0.mq4 |

//|                                  Copyright 2023, MetaQuotes Ltd. |

//|                                             https://www.mql5.com |

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

#property copyright "Copyright 2023, MetaQuotes Ltd."

#property link      "https://www.mql5.com"

#property version   "1.00"

#property strict



input int maxbar = 10000;                             // Max number of lookback candles

input ENUM_TIMEFRAMES TF = PERIOD_M1;                 // Time-Frame

input int BPoints = 300;                              // Bouncing Channel Half Height (Points)

input int FontSize =10;                               // Font Size

input color ChartBG = clrBlack;                       // Chart Background Color

input color color1 = clrRed;                          // Bar Chart Color 1

input color color2 = clrBlue;                         // Bar Chart Color 2

input color countcolor = clrBlue;                     // Count Cells Color

input color BounceColor = clrDarkBlue;                // Bounce Numbers Cell color

input color barcolor = clrGold;                       // Load bar color



datetime newtime;

int freq[], i, mybars, BPoints_set;

string OBJName="";

color BGColor;

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

//| Custom indicator initialization function                         |

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

int OnInit()

{

   ChartSetInteger(ChartID(), CHART_FOREGROUND, false);

   ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, ChartBG);

   ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, ChartBG);

   ChartSetInteger(0, CHART_COLOR_CHART_LINE, ChartBG);

   ChartSetInteger(0, CHART_COLOR_CHART_DOWN, ChartBG);

   ChartSetInteger(0, CHART_COLOR_CHART_UP, ChartBG);

   ChartSetInteger(0, CHART_COLOR_ASK, ChartBG);

   ChartSetInteger(0, CHART_COLOR_BID, ChartBG);

   ChartSetInteger(0, CHART_COLOR_GRID, ChartBG);

   ChartSetInteger(0, CHART_COLOR_BACKGROUND, ChartBG);



   OBJName = "Percentage";

   ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, "0.0 %", 20, 50, 50, 20, 10, barcolor, ChartBG, ChartBG, ALIGN_LEFT, "Calibri");

   newtime=0;

   BGColor = ChartBG;



   OBJName = "Start";

   ObjectCreate(0, OBJName, OBJ_BUTTON, 0, 0, 0);

   OBJSet(OBJName, "Start", 20, 75, 100, 20, 10, barcolor, clrYellow, ChartBG, ALIGN_CENTER, "Calibri");



   OBJName = "Maxbar";

   ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, "No. of Bars", 20, 110, 100, 20, 10, barcolor, clrGray, ChartBG, ALIGN_LEFT, "Calibri");



   OBJName = "Maxbar.E";

   ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, IntegerToString(maxbar), 20, 135, 100, 20, 10, ChartBG, clrGray, clrWhite, ALIGN_LEFT, "Calibri");

   ObjectSetInteger(0, OBJName, OBJPROP_READONLY, false);



   OBJName = "BPoints";

   ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, "Channel ¼ Height", 20, 165, 100, 20, 10, barcolor, clrGray, ChartBG, ALIGN_LEFT, "Calibri");



   OBJName = "BPoints.E";

   ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, IntegerToString(BPoints), 20, 190, 100, 20, 10, ChartBG, clrGray, clrWhite, ALIGN_LEFT, "Calibri");

   ObjectSetInteger(0, OBJName, OBJPROP_READONLY, false);

   

   newtime=0;

   BGColor = ChartBG;



   OBJName = "_Symbol";

   if (ObjectFind(ChartID(), OBJName)<0) 

      ObjectCreate(ChartID(), OBJName, OBJ_EDIT, 0, 0, 0);

      OBJSet(OBJName, Symbol(), 15, 15, 150, 25, 12, ChartBG, ChartBG, clrGold, ALIGN_LEFT, "Arial");



   mybars = iBars(Symbol(), TF);

   Print("mybars: ", mybars);

   ArrayResize(freq, 1); ArrayInitialize(freq, 0);



   i=mybars;

   if(i>maxbar) i=maxbar;

   mybars=i;



   BPoints_set = BPoints;

   return(INIT_SUCCEEDED);

}

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

{

   ObjectDelete(0, "Percentage");

   ObjectsDeleteAll(0, "Header_", -1, -1);

   ObjectsDeleteAll(0, "Bar_", -1, -1);

   ObjectsDeleteAll(0, "Text_", -1, -1);

   ObjectsDeleteAll(0, "_Symbol", -1, -1);

   ObjectsDeleteAll(0, "BPoints", -1, -1);

   ObjectsDeleteAll(0, "BPoints.E", -1, -1);

   ObjectsDeleteAll(0, "Maxbar", -1, -1);

   ObjectsDeleteAll(0, "Maxbar.E", -1, -1);

}

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

//| Expert tick function                                             |

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

void OnTick()

{

   if(iTime(Symbol(), Period(), 0) == newtime)

      return;

   

   newtime = iTime(Symbol(), Period(),0);

}

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

void RunStat()

{

   while(i>0)

     {

      int index = -1;

      for(int z=i-1; z>=0; z--)                                                 // Whhich candle Price goes beyond Bounce Channel?

         if(iHigh(Symbol(), TF, z)>iClose(Symbol(), TF, i)+2*BPoints_set*Point())   // Price breacks channel up limit

           {

            index = z;

            break;

           }

         else

            if(iLow(Symbol(), TF, z)<iClose(Symbol(), TF, i)-2*BPoints_set*Point()) // Price breaks channel low limit

              {

               index = z;

               break;

              }

   

      if(index!=-1)        // Check how many times Price bounce between Channel High/Low before breaking it

        {

         int count=0, con=0;

         double LowBand = iClose(Symbol(), TF, i)-BPoints_set*Point();

         double HighBand = iClose(Symbol(), TF, i)+BPoints_set*Point();

   

         for(int z=i-1; z>=index; z--)

            if(con>=0 && iLow(Symbol(), TF, z)<LowBand)

              {

               con=-1;

               count++;

              }

            else

               if(con<=0 && iHigh(Symbol(), TF, z)>HighBand)

                 {

                  con=1;

                  count++;

                 }

         

         if (ArraySize(freq)<=count) ArrayResize(freq, count+1);

         freq[count]++;

        }

      i--;

   

      if(MathMod(i, 100) !=0)             // each 100 candle update graphical things

         continue;

   

      ObjectSetInteger(0, "Percentage", OBJPROP_XSIZE, (int)(50 + (1-((double) i/ (double)mybars)) * 300));

      ObjectSetString(0, "Percentage", OBJPROP_TEXT, DoubleToString((1-((double) i/ (double)mybars)) * 100, 1)+" %");

      UpdateStat();

      ChartRedraw();

      Sleep(1);

     }

}       

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

void UpdateStat()

  {

   int x = 100;

   int y = (int)(ChartGetInteger(ChartID(), CHART_HEIGHT_IN_PIXELS));

   int tickness = 50;



   int maxcount = freq[ArrayMaximum(freq, WHOLE_ARRAY, 0)];

   bool first = false;

   int step = 0, spoint = (int) 50;



   for(int ii=ArraySize(freq)-1+x; ii>=x+1; ii--)

     {

      if(freq[ii-x]!=0 && !first)

        {

         first=true;

         step=ii-x;

        }



      if(!first) continue;

      OBJName = "Text_" + IntegerToString(ii-x);



      if(maxcount!=0)

         if(ObjectFind(ChartID(), OBJName)<0)

           {

            ObjectCreate(ChartID(), OBJName, OBJ_EDIT, 0, 0, 0);

            TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint-26, tickness,20, BounceColor, 1, STYLE_SOLID, true, IntegerToString(ii-x));

            ObjectSetInteger(0, OBJName, OBJPROP_COLOR, clrWhite);

            ObjectSetInteger(0, OBJName, OBJPROP_BORDER_COLOR, clrDarkBlue);

            ObjectSetInteger(0, OBJName, OBJPROP_ALIGN, ALIGN_CENTER);

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }

         else

           {

            TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint-26, tickness,20, BounceColor, 1, STYLE_SOLID, true, IntegerToString(ii-x));

            ObjectSetInteger(0, OBJName, OBJPROP_COLOR, clrWhite);

            ObjectSetInteger(0, OBJName, OBJPROP_BORDER_COLOR, clrDarkBlue);

            ObjectSetInteger(0, OBJName, OBJPROP_ALIGN, ALIGN_CENTER);

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }



      if(freq[ii-x]!=0 && !first) first=true;

      if(!first) continue;

      

      OBJName = "Header_" + IntegerToString(ii-x);

      if(maxcount!=0)

         if(ObjectFind(ChartID(), OBJName)<0)

           {

            ObjectCreate(ChartID(), OBJName, OBJ_EDIT, 0, 0, 0);

            TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint-3, tickness,20, countcolor, 1, STYLE_SOLID, true, IntegerToString(freq[ii-x]));

            ObjectSetInteger(0, OBJName, OBJPROP_COLOR, clrWhite);

            ObjectSetInteger(0, OBJName, OBJPROP_BORDER_COLOR, clrBlue);

            ObjectSetInteger(0, OBJName, OBJPROP_ALIGN, ALIGN_CENTER);

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }

         else

           {

            TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint-3, tickness,20, countcolor, 1, STYLE_SOLID, true, IntegerToString(freq[ii-x]));

            ObjectSetInteger(0, OBJName, OBJPROP_COLOR, clrWhite);

            ObjectSetInteger(0, OBJName, OBJPROP_BORDER_COLOR, clrBlue);

            ObjectSetInteger(0, OBJName, OBJPROP_ALIGN, ALIGN_CENTER);

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }



      OBJName = "Bar_" + IntegerToString(ii-x);

      color mycolor = ss2rgb(ColorToString(color1, false), ColorToString(color2, false), step, ii-x);



      if(freq[ii-x]!=0)

        {

         if(ObjectFind(ChartID(), OBJName)<0)

           {

            ObjectCreate(ChartID(), OBJName, OBJ_EDIT, 0, 0, 0);

            if(maxcount!=0)

               TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint, tickness,-(y-200)*freq[ii-x]/maxcount-1, mycolor, 1, STYLE_SOLID, true, "");

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }

         else

           {

            if(maxcount!=0)

               TrendSet(OBJName, (ii-x) *(tickness+2) +ii, spoint, tickness,-(y-200)*freq[ii-x]/maxcount-1, mycolor, 1, STYLE_SOLID, true, "");

            ObjectSetInteger(0, OBJName, OBJPROP_CORNER, CORNER_LEFT_LOWER);

           }

        }

     }

  }

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

void TrendSet(string TrendName, int x0, int y0, int xsize, int ysize, color Tcolor, int Twidth, ENUM_LINE_STYLE Tstyle, int b, string text)

  {

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_XDISTANCE, x0);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_YDISTANCE, y0);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_XSIZE, xsize);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_YSIZE, ysize);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_COLOR, Tcolor);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_BGCOLOR, Tcolor);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_WIDTH, Twidth);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_STYLE, Tstyle);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_BACK, false);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_SELECTABLE, false);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_READONLY, true);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_FONTSIZE, FontSize);

   ObjectSetString(ChartID(), TrendName, OBJPROP_TEXT, text);

   ObjectSetInteger(ChartID(), TrendName, OBJPROP_TIMEFRAMES, b?OBJ_ALL_PERIODS:OBJ_NO_PERIODS);

  }

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

//| ChartEvent function                                              |

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

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

   int PH = (int) ChartGetInteger(ChartID(), CHART_HEIGHT_IN_PIXELS);

   int PW = (int) ChartGetInteger(ChartID(), CHART_WIDTH_IN_PIXELS);



   OBJName = "Bounce" + "_Frame";

   if(ObjectFind(ChartID(), OBJName)<0)

      ObjectCreate(ChartID(), OBJName, OBJ_EDIT, 0, 0, 0);

   OBJSet(OBJName, "", 0, 0, PW, PW, 1, BGColor, BGColor, BGColor, ALIGN_CENTER, "Arial");

   ObjectSetInteger(ChartID(), OBJName, OBJPROP_BACK, true);



   if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam == "Maxbar.E") 

      {

      int newmybar = (int) StringToInteger(ObjectGetString(0, "Maxbar.E", OBJPROP_TEXT));

      if (newmybar<1000) 

         {

         ObjectSetString(0, "Maxbar.E", OBJPROP_TEXT, IntegerToString(mybars));

         MessageBox("Too Low number of candles to check in history!", "Low Look-back candle", 0);

         return;

         }

      else

         {

         mybars = iBars(Symbol(), TF);

         ArrayResize(freq, 1); ArrayInitialize(freq, 0);

         if (newmybar<mybars) mybars = newmybar;

         

         i=mybars;

         mybars=i;

         ObjectSetString(0, "Maxbar.E", OBJPROP_TEXT, IntegerToString(mybars));

         }

      }

      

   if (id == CHARTEVENT_OBJECT_CLICK && sparam == "Start") 

      {

      OBJName = "Percentage";

      ObjectCreate(0, OBJName, OBJ_EDIT, 0, 0, 0);

      OBJSet(OBJName, "0.0 %", 20, 50, 50, 20, 10, barcolor, ChartBG, ChartBG, ALIGN_LEFT, "Calibri");

      

      int newmybar = (int) StringToInteger(ObjectGetString(0, "Maxbar.E", OBJPROP_TEXT));

      ArrayResize(freq, 1); ArrayInitialize(freq, 0);

      if (newmybar<mybars) mybars = newmybar;

      i=mybars;

      mybars=i;

      

      Sleep(1);

      ObjectSetInteger(0, "Start", OBJPROP_STATE, 0);

      ObjectsDeleteAll(0, "Text_", -1, -1);

      ObjectsDeleteAll(0, "Header_", -1, -1);

      ObjectsDeleteAll(0, "Bar_", -1, -1);

      RunStat();

      }

      

   if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam == "BPoints.E") 

      {

      int newmBPoint = (int) StringToInteger(ObjectGetString(0, "BPoints.E", OBJPROP_TEXT));

      if (newmBPoint<5) 

         {

         ObjectSetString(0, "BPoints.E", OBJPROP_TEXT, IntegerToString(BPoints));

         BPoints_set = BPoints;

         MessageBox("Too Low Bouncing Channel Half Height!", "Low Channel Height", 0);

         return;

         }

      else

         {

         BPoints_set = newmBPoint;

         ArrayResize(freq, 1); ArrayInitialize(freq, 0);

         }

      }

  }

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

void OBJSet(string OBJNameSet, string txt, int XDis, int YDis, int XSize, int YSize, int FSize, color Fill, color Border, color TColor, ENUM_ALIGN_MODE myAlign, string myFont)

  {

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_CORNER, CORNER_LEFT_UPPER);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_XDISTANCE, XDis);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_YDISTANCE, YDis);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_XSIZE, XSize);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_YSIZE, YSize);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_FONTSIZE, FontSize);

   ObjectSetString(ChartID(),  OBJNameSet, OBJPROP_TEXT,txt);

   ObjectSetString(ChartID(),  OBJNameSet, OBJPROP_FONT,myFont);



   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BGCOLOR, Fill);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BORDER_COLOR, Border);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_COLOR, TColor);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ALIGN, myAlign);



   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_BACK, false);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_ZORDER,5);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_HIDDEN, true);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_READONLY, true);

   ObjectSetInteger(ChartID(), OBJNameSet, OBJPROP_SELECTABLE, false);

  }

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

color ss2rgb(string colour1, string colour2, int step, int index)

  {

   int r1 = StrToInteger(StringSubstr(colour1, 0,3));

   int g1 = StrToInteger(StringSubstr(colour1, 4,3));

   int b1 = StrToInteger(StringSubstr(colour1, 8,3));



   int r2 = StrToInteger(StringSubstr(colour2, 0,3));

   int g2 = StrToInteger(StringSubstr(colour2, 4,3));

   int b2 = StrToInteger(StringSubstr(colour2, 8,3));



   int r=0, g=0, b=0;



   if(r1>r2)

     {

      r = r1+((r2-r1)/step*index);

     }

   if(r1<r2)

     {

      r = r1-((r1-r2)/step*index);

     }



   if(g1>g2)

     {

      g = g1+((g2-g1)/step*index);

     }

   if(g1<g2)

     {

      g = g1-((g1-g2)/step*index);

     }



   if(b1>b2)

     {

      b = b1+((b2-b1)/step*index);

     }

   if(b1<b2)

     {

      b = b1-((b1-b2)/step*index);

     }



   g<<=8;

   b<<=16;

   return((color) (r+g+b));



  }

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---