Price density

Author: Copyright © 2019, Vladimir Karputov
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Price density
ÿþ//+------------------------------------------------------------------+

//|                                                Price density.mq5 |

//|                              Copyright © 2019, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2019, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.000"

#property indicator_chart_window

#property indicator_buffers 0

#property indicator_plots 0

//--- input parameters

input int      InpZone              = 9;     // Zone

//---

datetime m_prev_bars                = 0;     // "0" -> D'1970.01.01 00:00';

int      m_chart_visible_bars       = 0;     //

int      m_prev_chart_visible_bars  = 0;     //

string   m_prefix                   = "PD "; //

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//---

   if(InpZone<1)

     {

      string err_text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                      "0@0<5B@ \"Zone\" =5 <>65B 1KBL <5=LH5 \"1\"!":

                      "The parameter \"Zone\" cannot be less than \"1\"!";

      //--- when testing, we will only output to the log about incorrect input parameters

      if(MQLInfoInteger(MQL_TESTER))

        {

         Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         return(INIT_FAILED);

        }

      else // if the Custom indicator is run on the chart, tell the user about the error

        {

         Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         return(INIT_PARAMETERS_INCORRECT);

        }

     }

//---

   return(INIT_SUCCEEDED);

  }

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

//| Indicator deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   ObjectsDeleteAll(0,m_prefix,0,OBJ_HLINE);

   ObjectsDeleteAll(0,m_prefix,0,OBJ_LABEL);

  }

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

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

  {

//--- there were no changes

   if(m_prev_bars==time[rates_total-1] && m_prev_chart_visible_bars==m_chart_visible_bars)

      return(rates_total);

//--- bar opening time has changed

   if(m_prev_bars!=time[rates_total-1])

      m_prev_bars=time[rates_total-1];

//--- the number of bars in the window has changed

   if(m_prev_chart_visible_bars!=m_chart_visible_bars)

      m_prev_chart_visible_bars=m_chart_visible_bars;

   if(m_prev_chart_visible_bars==0)

      return(rates_total);

//---

   double chart_price_min=ChartPriceMin(0,0);

   double chart_price_max=ChartPriceMax(0,0);

   if(chart_price_min==EMPTY_VALUE || chart_price_max==EMPTY_VALUE)

      return(rates_total);

   double size=(chart_price_max-chart_price_min)/InpZone;

//---

   double zones[][2]; // [min][max]

   int    count[];

   int    all=0;

   double density[];

//ArrayFree(zones);

   ArrayResize(zones,InpZone);

   ArrayResize(count,InpZone);

   ArrayInitialize(count,0);

   ArrayResize(density,InpZone);

   for(int i=0; i<InpZone; i++)

     {

      //--- we go from the minimum price to the maximum

      if(InpZone==1)

        {

         zones[i][0]=chart_price_min;

         zones[i][1]=chart_price_max;

         HLineCreate(0,m_prefix+"line#0",0,zones[i][0]);

         HLineCreate(0,m_prefix+"line#1",0,zones[i][1]);

         break;

        }

      if(i==0)

        {

         zones[i][0]=chart_price_min;

         zones[i][1]=zones[i][0]+size;

         HLineCreate(0,m_prefix+"line#0",0,zones[i][0]);

         HLineCreate(0,m_prefix+"line#1",0,zones[i][1]);

         continue;

        }

      zones[i][0]=zones[i-1][1];

      zones[i][1]=zones[i][0]+size;

      HLineCreate(0,m_prefix+"line#"+IntegerToString(i+1),0,zones[i][1]);

     }

//---

   for(int i=rates_total-m_prev_chart_visible_bars; i<rates_total; i++)

     {

      for(int j=0; j<InpZone; j++)

         if((zones[j][0]<=high[i] && zones[j][1]>=high[i]) || (zones[j][0]<=low[i] && zones[j][1]>=low[i]))

           {

            all++;

            count[j]++;

           }

     }

//---

   int x=ChartWidthInPixels(0);

   if(x==-1)

      return(rates_total);

   x/=2;



   for(int i=0; i<InpZone; i++)

     {

      density[i]=count[i]*100.0/(double)all;

      int x_,y;

      if(!ChartTimePriceToXY(0,0,time[rates_total-1],(zones[i][0]+zones[i][1])/2.0,x_,y))

         return(rates_total);

      LabelCreate(0,m_prefix+"label#"+IntegerToString(i),0,x,y,0,DoubleToString(density[i],1)+"%");

     }

//--- return value of prev_calculated for next call

   return(rates_total);

  }

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

//| ChartEvent function                                              |

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

void OnChartEvent(const int id,

                  const long &lparam,

                  const double &dparam,

                  const string &sparam)

  {

//---

   int chart_visible_bars=ChartVisibleBars(0);

   if(chart_visible_bars==-1)

      return;

   m_chart_visible_bars=chart_visible_bars;

  }

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

//| Gets the number of bars that are displayed (visible) in chart window |

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

int ChartVisibleBars(const long chart_ID=0)

  {

//--- prepare the variable to get the property value

   long result=-1;

//--- reset the error value

   ResetLastError();

//--- receive the property value

   if(!ChartGetInteger(chart_ID,CHART_VISIBLE_BARS,0,result))

     {

      //--- display the error message in Experts journal

      Print(__FUNCTION__+", Error Code = ",GetLastError());

     }

//--- return the value of the chart property

   return((int)result);

  }

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

//| Gets the value of chart minimum in the main window or in a subwindow |

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

double ChartPriceMin(const long chart_ID=0,const int sub_window=0)

  {

//--- prepare the variable to get the result

   double result=EMPTY_VALUE;

//--- reset the error value

   ResetLastError();

//--- receive the property value

   if(!ChartGetDouble(chart_ID,CHART_PRICE_MIN,sub_window,result))

     {

      //--- display the error message in Experts journal

      Print(__FUNCTION__+", Error Code = ",GetLastError());

     }

//--- return the value of the chart property

   return(result);

  }

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

//| Gets the value of chart maximum in the main window or in a subwindow |

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

double ChartPriceMax(const long chart_ID=0,const int sub_window=0)

  {

//--- prepare the variable to get the result

   double result=EMPTY_VALUE;

//--- reset the error value

   ResetLastError();

//--- receive the property value

   if(!ChartGetDouble(chart_ID,CHART_PRICE_MAX,sub_window,result))

     {

      //--- display the error message in Experts journal

      Print(__FUNCTION__+", Error Code = ",GetLastError());

     }

//--- return the value of the chart property

   return(result);

  }

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

//| Create the horizontal line                                       |

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

bool HLineCreate(const long            chart_ID=0,        // chart's ID

                 const string          name="HLine",      // line name

                 const int             sub_window=0,      // subwindow index

                 double                price=0,           // line price

                 const color           clr=clrLime,       // line color

                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style

                 const int             width=1,           // line width

                 const bool            back=false,        // in the background

                 const bool            selection=false,   // highlight to move

                 const bool            hidden=true,       // hidden in the object list

                 const long            z_order=0)         // priority for mouse click

  {

   if(ObjectFind(chart_ID,name)>=0)

      return(HLineMove(chart_ID,name,price));

//--- if the price is not set, set it at the current Bid price level

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value

   ResetLastError();

//--- create a horizontal line

   if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price))

     {

      Print(__FUNCTION__,

            ": failed to create a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- set line color

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set line display style

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set line width

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true)

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the line by mouse

//--- when creating a graphical object using ObjectCreate function, the object cannot be

//--- highlighted and moved by default. Inside this method, selection parameter

//--- is true by default making it possible to highlight and move the object

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution

   return(true);

  }

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

//| Move horizontal line                                             |

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

bool HLineMove(const long   chart_ID=0,   // chart's ID

               const string name="HLine", // line name

               double       price=0)      // line price

  {

//--- if the line price is not set, move it to the current Bid price level

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value

   ResetLastError();

//--- move a horizontal line

   if(!ObjectMove(chart_ID,name,0,0,price))

     {

      Print(__FUNCTION__,

            ": failed to move the horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution

   return(true);

  }

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

//| Gets the width of chart (in pixels)                              |

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

int ChartWidthInPixels(const long chart_ID=0)

  {

//--- prepare the variable to get the property value

   long result=-1;

//--- reset the error value

   ResetLastError();

//--- receive the property value

   if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,0,result))

     {

      //--- display the error message in Experts journal

      Print(__FUNCTION__+", Error Code = ",GetLastError());

     }

//--- return the value of the chart property

   return((int)result);

  }

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

//| Create a text label                                              |

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

bool LabelCreate(const long              chart_ID=0,               // chart's ID

                 const string            name="Label",             // label name

                 const int               sub_window=0,             // subwindow index

                 const int               x=0,                      // X coordinate

                 const int               y=0,                      // Y coordinate

                 const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // chart corner for anchoring

                 const string            text="Label",             // text

                 const string            font="Lucida Console",    // font

                 const int               font_size=10,             // font size

                 const color             clr=clrLime,              // color

                 const double            angle=0.0,                // text slope

                 const ENUM_ANCHOR_POINT anchor=ANCHOR_CENTER,     // anchor type

                 const bool              back=false,               // in the background

                 const bool              selection=false,          // highlight to move

                 const bool              hidden=true,              // hidden in the object list

                 const long              z_order=0)                // priority for mouse click

  {

   if(ObjectFind(chart_ID,name)>=0)

     {

      LabelMove(chart_ID,name,x,y);

      LabelTextChange(chart_ID,name,text);

      return(true);

     }

//--- reset the error value

   ResetLastError();

//--- create a text label

   if(!ObjectCreate(chart_ID,name,OBJ_LABEL,sub_window,0,0))

     {

      Print(__FUNCTION__,

            ": failed to create text label! Error code = ",GetLastError());

      return(false);

     }

//--- set label coordinates

   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);

   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);

//--- set the chart's corner, relative to which point coordinates are defined

   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);

//--- set the text

   ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);

//--- set text font

   ObjectSetString(chart_ID,name,OBJPROP_FONT,font);

//--- set font size

   ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);

//--- set the slope angle of the text

   ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);

//--- set anchor type

   ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);

//--- set color

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- display in the foreground (false) or background (true)

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the label by mouse

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution

   return(true);

  }

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

//| Move the text label                                              |

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

bool LabelMove(const long   chart_ID=0,   // chart's ID

               const string name="Label", // label name

               const int    x=0,          // X coordinate

               const int    y=0)          // Y coordinate

  {

//--- reset the error value

   ResetLastError();

//--- move the text label

   if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))

     {

      Print(__FUNCTION__,

            ": failed to move X coordinate of the label! Error code = ",GetLastError());

      return(false);

     }

   if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))

     {

      Print(__FUNCTION__,

            ": failed to move Y coordinate of the label! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution

   return(true);

  }

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

//| Change the label text                                            |

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

bool LabelTextChange(const long   chart_ID=0,   // chart's ID

                     const string name="Label", // object name

                     const string text="Text")  // text

  {

//--- reset the error value

   ResetLastError();

//--- change object text

   if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))

     {

      Print(__FUNCTION__,

            ": failed to change the text! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution

   return(true);

  }

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

Comments