Author: Copyright � 2004, MetaQuotes Software Corp. Modified RonT
VSAdiv
Price Data Components
Series array that contains close prices for each barSeries array that contains tick volumes of each bar
Indicators Used
MACD Histogram
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
VSAdiv
//+------------------------------------------------------------------+
//|                            Volume with Custom Moving Average.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp. Modified RonT"
#property link      "http://www.metaquotes.net/"
//----
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 White
#property indicator_color4 White
#property indicator_color5 Green
#property indicator_color6 Red


// User input
extern string  Note1 = "****** Volume Settings ******";
extern string  MAMethods0 = "*** 0 = SMA, 1 = EMA ***";
extern string  MAMethods2 = "*** 2 = SMMA, 3 = LWMA ***";
extern int     MA_Period=13;
extern int     MA_Shift=0;
extern string  Note2 = "****** Filter Level ******";
extern bool    ShowFilterLevel = true;
extern int     LevelAvgDays = 100;        // Set to number of days back to calculate the level on
extern double  LevelPercentage = 90.0;    // sets the indicator level to a % of the MA of the volume average buffer
extern string separator1 = "*** MACD Settings ***";
extern int    fastEMA = 12;
extern int    slowEMA = 26;
extern int    signalSMA = 9;
extern string separator2 = "*** Indicator Settings ***";
extern bool   drawPriceTrendLines = true;


// Buffers
double VolBuffer1[];  // value down
double VolBuffer2[];  // value up
double VolBuffer3[];  // moving average
double P3Buffer[];
double bullishDivergence[];
double bearishDivergence[];
double macd[];
double signal[];
//----

double P1;
double P2;
int ExtCountedBars=0;
int lastcolor=0;
int MA_Method=0;
static string   indicatorName;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int    draw_begin;

   // indicator buffers mapping, drawing settings and Shift
   // Histogram downArrow Red
   SetIndexBuffer(0,VolBuffer1);
   SetIndexStyle(0,DRAW_HISTOGRAM,0,2);
   SetIndexShift(0,MA_Shift);
   // Histogram upArrow Green
   SetIndexBuffer(1,VolBuffer2);
   SetIndexStyle(1,DRAW_HISTOGRAM,0,2);
   SetIndexShift(1,MA_Shift);
   // Moving average line white
   SetIndexBuffer(2,VolBuffer3);
   SetIndexStyle(2,DRAW_LINE,0,2);
   SetIndexShift(2,MA_Shift);
   
   SetIndexBuffer(3, P3Buffer);   
   SetIndexStyle(3, DRAW_HISTOGRAM, STYLE_SOLID, 2);
   
   
   SetIndexBuffer(4, bullishDivergence);
   SetIndexBuffer(5, bearishDivergence);
   SetIndexBuffer(6, macd);
   SetIndexStyle(6,DRAW_NONE,0,0);
   SetIndexBuffer(7, signal); 
   SetIndexStyle(7,DRAW_NONE,0,0); 
   
   
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//----
   if(MA_Period<2) MA_Period=2;
   draw_begin=MA_Period-1;
//----
  
   indicatorName = "VSA";
   SetIndexDrawBegin(3, signalSMA);
   IndicatorDigits(Digits + 2);
   IndicatorShortName(indicatorName);

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   for(int i = ObjectsTotal() - 1; i >= 0; i--)
     {
       string label = ObjectName(i);
       if(StringSubstr(label, 0, 19) != "MACD_DivergenceLine")
           continue;
       ObjectDelete(label);   
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Main                                                             |
//+------------------------------------------------------------------+
int start()
  {
   if (ShowFilterLevel) VolumeFilterLevel();
   TickVolumeDiff();
   
   int countedBars = IndicatorCounted();
   if(countedBars < 0)
   countedBars = 0;
   CalculateIndicator(countedBars);
   
   if(Bars<=MA_Period) return(0);
   ExtCountedBars=IndicatorCounted();
   // check for possible errors
   if (ExtCountedBars<0) return(-1);
   // last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   switch(MA_Method)
     {
      case 0 : sma();  
     }
   return(0);
  }

//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
void sma()
  {
   double sum=0;
   int    i,pos=Bars-ExtCountedBars-1;
   // initial accumulation
   if(pos<MA_Period) pos=MA_Period;
   for(i=1;i<MA_Period;i++,pos--)
      sum+=Volume[pos];
   while(pos>=0)
     {
      sum+=Volume[pos];
      VolBuffer3[pos]=sum/MA_Period;
      sum-=Volume[pos+MA_Period-1];
      Vcolor(pos);
      pos--;
     }
   // zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<MA_Period;i++) VolBuffer1[Bars-i]=0;
  }

//+------------------------------------------------------------------+
//|Color depends on gain or loss and previous volume                 |             
// 1 - histo down red                                                |
// 2 - histo up green                                                |
// 3 - line white                                                    |
//+------------------------------------------------------------------+

void Vcolor(int p)
  {
   if (Volume[p+1]>Volume[p])
     {
      VolBuffer1[p]=Volume[p];
      VolBuffer2[p]=0;
      lastcolor=Red;
     }
   if (Volume[p+1]<Volume[p])
     {
      VolBuffer1[p]=0;
      VolBuffer2[p]=Volume[p];
      lastcolor=Green;
     }
   if (Volume[p+1]==Volume[p])
     {
      if(lastcolor==Red )
        {
         VolBuffer1[p]=Volume[p];
         VolBuffer2[p]=0;
        }
      if(lastcolor==Green )
        {
         VolBuffer1[p]=0;
         VolBuffer2[p]=Volume[p];
        }
     }
  }

//+------------------------------------------------------------------+
//| VolumeFilterLevel()                                              |
//+------------------------------------------------------------------+
void VolumeFilterLevel()
{
   int LevelMAPeriod;
   string short_name;

   if (LevelAvgDays == (-1)) LevelMAPeriod = Bars;
   else
   {
      switch(Period())
      {
         case 1:        LevelMAPeriod = LevelAvgDays*(1440); break;
         case 5:        LevelMAPeriod = LevelAvgDays*(1440/5); break;
         case 15:       LevelMAPeriod = LevelAvgDays*(1440/15); break;
         case 30:       LevelMAPeriod = LevelAvgDays*(1440/30); break;
         case 60:       LevelMAPeriod = LevelAvgDays*(1440/60); break;
         case 240:      LevelMAPeriod = LevelAvgDays*(1440/240); break;
         case 1440:     LevelMAPeriod = LevelAvgDays; break;
         default :      LevelMAPeriod = Bars;
      }
   }
   double MyBuffer[];
   int BufSize = ArraySize(VolBuffer3);
   ArrayResize(MyBuffer,BufSize);
   ArrayCopy(MyBuffer,VolBuffer3);
   SetLevelValue(0,0);
   SetLevelStyle(0,0,CLR_NONE);
   ObjectDelete("MAofVolLev");
   double LevValue = 0;
   LevValue = MathRound(VolBuffer3[0]) * (LevelPercentage/100);              
   SetLevelValue(0,LevValue);
   SetLevelStyle(2,1,Gray);
   int IntLevelValue = LevValue;
   ObjectCreate("MAofVolLev", OBJ_LABEL, WindowFind("VSA"), 0, 0);
   ObjectSetText("MAofVolLev","VSA & VolDiv (FOREXflash 2009)",8, "Arial", Gray);
   ObjectSet("MAofVolLev", OBJPROP_CORNER, 1);
   ObjectSet("MAofVolLev", OBJPROP_XDISTANCE, 5);
   ObjectSet("MAofVolLev", OBJPROP_YDISTANCE, 5);
}
//+------------------------------------------------------------------+   
void TickVolumeDiff()
  {

   int i,ii;
   static int pii=-1;
   
   for(i = 0; i <iBars(Symbol(),PERIOD_M1) ; i++)
     {
       ii = iBarShift(Symbol(), Period(), iTime(Symbol(),PERIOD_M1,i), true);
       //----
       if (pii!=ii)
       {
         P1=0;
         P2=0;
         P3Buffer[ii]=0;
       }
       
       if (ii != -1)
       {
         if (iClose(Symbol(),PERIOD_M1,i)>iClose(Symbol(),PERIOD_M1,i+1))
         {
           P1 = P1+(iVolume(Symbol(),PERIOD_M1,i));
         }
         if (iClose(Symbol(),PERIOD_M1,i)<iClose(Symbol(),PERIOD_M1,i+1))
         {
           P2 = P2-(iVolume(Symbol(),PERIOD_M1,i));
         }
         if (iClose(Symbol(),PERIOD_M1,i)==iClose(Symbol(),PERIOD_M1,i+1))
         {
           P1 = P1+(iVolume(Symbol(),PERIOD_M1,i)/2);
           P2 = P2-(iVolume(Symbol(),PERIOD_M1,i)/2);
         }
       }

       P3Buffer[ii]=(P1+P2)/2; 

       pii=ii;
    }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateIndicator(int countedBars)
  {
   for(int i = Bars - countedBars; i >= 0; i--)
     {
       CalculateMACD(i);
       CatchBullishDivergence(i + 2);
       CatchBearishDivergence(i + 2);
     }              
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateMACD(int i)
  {
   macd[i] = iMACD(NULL, 0, fastEMA, slowEMA, signalSMA, 
                   PRICE_CLOSE, MODE_MAIN, i);
   
   signal[i] = Volume[i];         
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift)
  {
   if(IsIndicatorTrough(shift) == false)
       return;  
   int currentTrough = shift;
   int lastTrough = GetIndicatorLastTrough(shift);
//----   
   if(macd[currentTrough] > macd[lastTrough] && 
      Low[currentTrough] < Low[lastTrough])
     {

       //----
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                             Low[lastTrough], Green, STYLE_SOLID);
     }
//----   
   if(macd[currentTrough] < macd[lastTrough] && 
      Low[currentTrough] > Low[lastTrough])
     {

       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                              Low[lastTrough], Green, STYLE_DOT);
     }      
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift)
  {
   if(IsIndicatorPeak(shift) == false)
       return;
   int currentPeak = shift;
   int lastPeak = GetIndicatorLastPeak(shift);
//----   
   if(macd[currentPeak] < macd[lastPeak] && 
      High[currentPeak] > High[lastPeak])
     {

      
       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], Red, STYLE_SOLID);

     }
   if(macd[currentPeak] > macd[lastPeak] && 
      High[currentPeak] < High[lastPeak])
     {

       if(drawPriceTrendLines == true)
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], Red, STYLE_DOT);
     }   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift)
  {
   if(macd[shift] >= macd[shift+1] && macd[shift] > macd[shift+2] && 
      macd[shift] > macd[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift)
  {
   if(macd[shift] <= macd[shift+1] && macd[shift] < macd[shift+2] && 
      macd[shift] < macd[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift)
  {
   for(int i = shift + 5; i < Bars; i++)
     {
       if(signal[i] >= signal[i+1] && signal[i] >= signal[i+2] &&
          signal[i] >= signal[i-1] && signal[i] >= signal[i-2])
         {
           for(int j = i; j < Bars; j++)
             {
               if(macd[j] >= macd[j+1] && macd[j] > macd[j+2] &&
                  macd[j] >= macd[j-1] && macd[j] > macd[j-2])
                   return(j);
             }
         }
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift)
  {
    for(int i = shift + 5; i < Bars; i++)
      {
        if(signal[i] <= signal[i+1] && signal[i] <= signal[i+2] &&
           signal[i] <= signal[i-1] && signal[i] <= signal[i-2])
          {
            for (int j = i; j < Bars; j++)
              {
                if(macd[j] <= macd[j+1] && macd[j] < macd[j+2] &&
                   macd[j] <= macd[j-1] && macd[j] < macd[j-2])
                    return(j);
              }
          }
      }
    return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1, 
                        double y2, color lineColor, double style)
  {
   string label = "MACD_DivergenceLine_v1.0# " + DoubleToStr(x1, 0);
   ObjectDelete(label);
   ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
   ObjectSet(label, OBJPROP_RAY, 0);
   ObjectSet(label, OBJPROP_COLOR, lineColor);
   ObjectSet(label, OBJPROP_STYLE, style);
  }

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

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 ---