vdm_with_lines

Author: Vitaliy Samara
Miscellaneous
Implements a curve of type %1
1 Views
0 Downloads
0 Favorites
vdm_with_lines
//+------------------------------------------------------------------+
//|                                    Volume Divergence Markers.mq4 |
//|                                                   Vitaliy Samara |
//|                          https://www.mql5.com/en/users/samaridze |
//+------------------------------------------------------------------+
#property copyright "Vitaliy Samara"
#property link      "https://www.mql5.com/en/users/samaridze"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
//------
enum mode
  {
   Convergence = 0,
   Divergence  = 1,
  };
//------
input bool     ThisBar        = 0;              //Is current bar counted?
input mode     Mode           = 0;              //Marker display mode
extern int     VolGlobal      = 2;              //Continuous change in volume (in bars)
extern int     SizeGlobal     = 2;              //Continuous change in barsize (in bars)
input color    main=clrRoyalBlue;               //Marker colour
//------
double BufferMarker[];
datetime datetime1=0,datetime2=0;
double price1,price2;
//------
int OnInit()
  {
   SetIndexBuffer(0,BufferMarker);
//------
   SetIndexStyle(0,DRAW_ARROW,EMPTY,4,main);
//------
   SetIndexArrow(0,119);
//------
   SetIndexEmptyValue(0,0);
//------
   IndicatorShortName("VDM "+(string)VolGlobal+","+(string)SizeGlobal);
//------ Values above 4 are pointless because it never happens on a market
   if(VolGlobal>4) VolGlobal=4;
   if(SizeGlobal>4) SizeGlobal=4;
   return(INIT_SUCCEEDED);
  }
//------ Not leaving any junk on the graph after indicator is removed
void OnDeinit(const int reason)
  {
   for(int i=0; i<Bars; i++)
     {
      ObjectDelete(ChartID(),"VDM Line "+IntegerToString(i));
     }
  }
//------   
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[])
  {
//------ Reversing timeseries to make Series[0] the earliest
   ArraySetAsSeries(BufferMarker,false);
   ArraySetAsSeries(High,false);
   ArraySetAsSeries(Low,false);
   ArraySetAsSeries(Open,false);
   ArraySetAsSeries(Close,false);
   ArraySetAsSeries(Volume,false);
   ArraySetAsSeries(Time,false);
//------ Initializing variables 
   int bar;
   int vol,barsize;
   bool dir;
   vol=barsize=dir=0;
//------ Checking for sufficient bars in history
   if(rates_total<MathMax(VolGlobal*2,SizeGlobal*2))
     {
      return (0);
     }
//------ Setting the starting bar to calculate from     
   if(prev_calculated==0)
      bar=MathMax(VolGlobal*2,SizeGlobal*2);
   else
      bar=prev_calculated-1;
//------ Main program cycle for each bar
   while(bar<rates_total-!ThisBar)
     {
      BarSizeDynamics(bar,dir,barsize);
      if(barsize>=SizeGlobal && VolumeDynamics(bar,dir)==true)    // Every time a marker is created
        {
         datetime1 = datetime2;                                   // datetime1 takes the value of a previous marker
         datetime2 = Time[bar];                                   // datetime2 takes the value of a current one
         price1 = price2;                                         // Same applies to price values
         price2 = BufferMarker[bar] = Close[bar];                 // Based on these coordinates,
         TrendLine(bar);                                          // a line is drawn betwwen two markers
        }
      bar++;
     }
//------
   return(rates_total);
  }
//------ Function that counts continuous increase or decrease of barsize (in bars)
//------ Need to return two values, so variables are passed by reference
void BarSizeDynamics(int bar,bool &dir,int &barsize)
  {
   int i=bar;
   int up=0,down=0;
//------ Counting continuous increase in barsize
   while(MathAbs(Open[i]-Close[i])>MathAbs(Open[i-1]-Close[i-1]))
     {
      up++;
      i--;
     }
//------ Counting continuous decrease in barsize
   i=bar;
   while(MathAbs(Open[i]-Close[i])<MathAbs(Open[i-1]-Close[i-1]))
     {
      down++;
      i--;
     }
//------ Selecting the correct movement and setting the value of direction variable (0 = increase, 1 = decrease)
   barsize=MathMax(up,down);
   if(up==0)
      dir=Mode;
   else
      dir=!Mode;
  }
//------ Function that counts continuous increase or decrease of volume (in bars)
bool VolumeDynamics(int bar,bool dir)
  {
   int i=bar;
   int counter=0;
//------
   if(dir==0)
      while(Volume[i]<Volume[i-1])
        {
         counter++;
         i--;
        }
   else
   while(Volume[i]>Volume[i-1])
     {
      counter++;
      i--;
     }
//------ Both variables (barsize, vol) derived from these functions have to match user input globals         
//------ Returning values as a boolean (to draw a marker or not) because no further calculations are required
   if(counter==VolGlobal)
      return true;
   else
      return false;
  }
//------ Function that creates lines between markers
void TrendLine(int i)
  {
   string objname= "VDM Line "+IntegerToString(i);
   if(datetime1!=0) // A simple check if all data needed for a line exist
     {
      ObjectCreate(ChartID(),objname,OBJ_TREND,0,datetime1,price1,datetime2,price2);
      ObjectSet(objname,10,false); // Ray property off
      ObjectSet(objname,8,2);      // Line Thickness
      ObjectSet(objname,6,main);   // Line color
     }
  }
//+------------------------------------------------------------------+

Comments