//+------------------------------------------------------------------+
//|                                 Normalized Volume Oscillator.mq4 |
//|                                                  Vadim Shumiloff |
//|                                                shumiloff@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Vadim Shumiloff"
#property link      "shumiloff@mail.ru"

/*--------------------------------------------------------------------
NVO Enhanced:

This version of the Normaized Volume Oscillator allows user to display
below average volume bars, or not.  Also, the graduations can be changed.
The previous graduations of 38.2/61.8 are changed to 33/66, but the user
can alter.  The indicator can be overlaid upon a normal Volumes window,
providing emphasis, if you do not show the below average bars.  Two
added text labels show the current bar volume and its percentage of the
average bar volume for the selected averaging period.

                                                       - Traderathome
--------------------------------------------- -----------------------*/

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 Blue       // Volumes below average
#property indicator_color2 Gold       // Volumes over average by 0% to 38.2%
#property indicator_color3 LimeGreen  // Volumes over average by 38.2% to 61.8%
#property indicator_color4 Crimson    // Volumes over average by 61.8% to 100%
#property indicator_color5 WhiteSmoke      // Volumes greater than 100% over average
#property indicator_width1 2  
#property indicator_width2 2  
#property indicator_width3 2  
#property indicator_width4 2  
#property indicator_width5 2  

//---- External Inputs
extern int    VolumePeriod                    = 10;
extern bool   ShowBelowAvgVolumes             = true;
extern string Need_2_numbers_dividing_range   = "0-100 into 3 parts (33&66, 25&50 etc)";
extern double Enter_Number_1                  = 33;
extern double Enter_Number_2                  = 66;
extern bool   Display_volume_text_labels?     = true;
extern color  VolumeCountTextColor            = Magenta;
extern color  BelowAverageTextColor_0         = DodgerBlue;
extern color  AboveAverageTextColor_1         = Yellow;
extern color  AboveAverageTextColor_2         = LimeGreen;
extern color  AboveAverageTextColor_3         = Red;
extern color  AboveAverageTextColor_4         = WhiteSmoke;
extern int    Text_in_window_0123             = 1;
extern int    __Text_Horizontal_Indent        = 5;
extern int    __Text_Vertical_Indent          = 4;
extern int    FontStyle_Normal_Bold_12        = 1;
extern bool   Automatic_Full_to_Brief_mode?   = false;
extern int    Brief_mode_WindowBarsPerChart   = 150;
extern bool   Manually_pick_brief_text?       = false;

//---- Buffers & Other Inputs
double VolBufferH1[];
double VolBufferH2[];
double VolBufferH3[];
double VolBufferH4[];
double VolBufferH5[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
   {
   string short_name;

   IndicatorBuffers(5);
   
   SetIndexBuffer(1, VolBufferH1);
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexBuffer(0, VolBufferH1);
   SetIndexDrawBegin(0, VolBufferH1);

   SetIndexBuffer(2, VolBufferH2);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexBuffer(1, VolBufferH2);
   SetIndexDrawBegin(1, VolBufferH2);
  
   SetIndexBuffer(3, VolBufferH3);
   SetIndexStyle(2, DRAW_HISTOGRAM);
   SetIndexBuffer(2, VolBufferH3);
   SetIndexDrawBegin(2, VolBufferH3);

   SetIndexBuffer(4, VolBufferH4);
   SetIndexStyle(3, DRAW_HISTOGRAM);
   SetIndexBuffer(3, VolBufferH4);
   SetIndexDrawBegin(3, VolBufferH4);

   SetIndexBuffer(5, VolBufferH5);
   SetIndexStyle(4, DRAW_HISTOGRAM);
   SetIndexBuffer(4, VolBufferH5);
   SetIndexDrawBegin(4, VolBufferH5);

   short_name="NVO Enhanced  (" + VolumePeriod + ")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,  NULL);
   SetIndexLabel(1,  NULL); 
   SetIndexLabel(2,  NULL);
   SetIndexLabel(3,  NULL);
   SetIndexLabel(4,  NULL);
   SetIndexLabel(5,  NULL);
   SetIndexLabel(6,  NULL);
   SetIndexLabel(7,  NULL);

   return(0);
   }
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
   {
   int obj_total= ObjectsTotal();  
   for (int i= obj_total; i>=0; i--) 
      {
      string name= ObjectName(i);    
          if (StringSubstr(name,0,6)=="voltxt")
          {
          ObjectDelete(name);
          }
      }        
   return(0);
   }

//+-------------------------------------------------------------------+
//| Calculations body of program                                      |                                                        
//+-------------------------------------------------------------------+
int start()
   {
   int counted_bars = IndicatorCounted(); int i; 
   double nv,nvo,nvo2; string Nvo = ""; string Vol = ""; string Font = "Arial";
   if (FontStyle_Normal_Bold_12 == 2){Font = "Arial Bold";}
   
   for(i = Bars-1-IndicatorCounted(); i >= 0; i--) 
      {
      VolBufferH1[i] = 0;
      VolBufferH2[i] = 0;
      VolBufferH3[i] = 0;
      VolBufferH4[i] = 0;
      VolBufferH5[i] = 0;

      Vol = DoubleToStr(Volume[i], Digits-4);
      if(StringLen(Vol)==1){Vol = "         "+Vol;}
      if(StringLen(Vol)==2){Vol = "       "+Vol;}
      if(StringLen(Vol)==3){Vol = "     "+Vol;} 
      if(StringLen(Vol)==4){Vol = "    "+Vol;}   
      if(StringLen(Vol)==5){Vol = "  "+Vol;}  
      
      if(Display_volume_text_labels?){Label4("Bar Vol Ct:    "+Vol, VolumeCountTextColor, 10, Font);}
      if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart() < Brief_mode_WindowBarsPerChart){Label4(Vol,VolumeCountTextColor,9,Font);}
      if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?){Label4(Vol,VolumeCountTextColor,9,Font);}
                       
      nv = NormalizedVolume(i);                               
      nvo = Volume[i]/nv*100 - 100;
      nvo2 = (Volume[i] /nv)*100-100;
                                    
      if (nvo<0) {Nvo = DoubleToStr(100-(nvo-(nvo*2)), Digits-4);}  //negative % changed to positive for text label      
      else {Nvo = DoubleToStr(nvo, Digits-4);}                      //the % already in positive form
      if (nvo>=0) Nvo = DoubleToStr(nvo+100, Digits-4);             //convert from normalized percent to real percent
      if(StringLen(Nvo)<2){Nvo = "    "+Nvo;}
      if(StringLen(Nvo)<3){Nvo = "  "+Nvo;}
      if (nvo<0)
         {
         VolBufferH1[i] = 0.25; if(ShowBelowAvgVolumes) {VolBufferH1[i] =nvo2;}        
         if(Display_volume_text_labels?)
            {
            Label("% Avg Bar:      "+Nvo+"%",BelowAverageTextColor_0,10,Font);
            if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart()<Brief_mode_WindowBarsPerChart) {Label(Nvo+" %",BelowAverageTextColor_0,9,Font);}
            if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);}
            }
         }
         
      else 
         {
         if (nvo<Enter_Number_1)
            {
            VolBufferH2[i]=nvo2;
            if(Display_volume_text_labels?)
               {
               Label("% Avg Bar:      "+Nvo+"%",AboveAverageTextColor_1,10,Font);
               if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart()<Brief_mode_WindowBarsPerChart) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);} 
               if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);}        
               }
             }
                
      else 
         {
         if (nvo<Enter_Number_2)
            {
            VolBufferH3[i]=nvo2;
            if(Display_volume_text_labels?)
               {
               Label("% Avg Bar:      "+Nvo+"%",AboveAverageTextColor_2,10,Font);
               if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart()<Brief_mode_WindowBarsPerChart) {Label(Nvo+" %",AboveAverageTextColor_2,9,Font);}
               if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);}
               }
            }
            
      else 
         {
         if (nvo<100)
            {
            VolBufferH4[i]=nvo2;
            if(Display_volume_text_labels?)
               {
               Label("% Avg Bar:      "+Nvo+"%",AboveAverageTextColor_3,10,Font);
               if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart()<Brief_mode_WindowBarsPerChart) {Label(Nvo+" %",AboveAverageTextColor_3,9,Font);}
               if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);}
               }
            }
             
      else
         {
         VolBufferH5[i]=nvo2;
         if(Display_volume_text_labels?)
            {
            Label("% Avg Bar:      "+Nvo+"%",AboveAverageTextColor_4,10,Font);
            if(Automatic_Full_to_Brief_mode? && WindowBarsPerChart()<Brief_mode_WindowBarsPerChart) {Label(Nvo+" %",AboveAverageTextColor_4,9,Font);}
            if(Automatic_Full_to_Brief_mode? == false && Manually_pick_brief_text?) {Label(Nvo+" %",AboveAverageTextColor_1,9,Font);}
            }                
          }        
         }
        }
       }
         
      }
   return(0);   
   }     
        
//+-------------------------------------------------------------------+
//| Subroutine to draw volume count text label                        |                                                        
//+-------------------------------------------------------------------+
void Label4 (string text, color Color, int fontsize, string fontstyle)  
      {
      ObjectDelete("voltxt4");
      ObjectCreate("voltxt4", OBJ_LABEL, Text_in_window_0123, 0, 0);
      ObjectSet("voltxt4", OBJPROP_CORNER, 3);
      ObjectSet("voltxt4", OBJPROP_XDISTANCE, __Text_Horizontal_Indent);
      ObjectSet("voltxt4", OBJPROP_YDISTANCE,  __Text_Vertical_Indent+15);
      ObjectSet("voltxt4", OBJPROP_COLOR, Color);
      ObjectSetText("voltxt4", text, fontsize, fontstyle);    
      }
    
//+-------------------------------------------------------------------+
//| Subroutine to draw volume bar percentage text label               |                                                        
//+-------------------------------------------------------------------+
void Label(string text, color Color, int fontsize, string fontstyle)    
      {
      ObjectDelete("voltxt");
      ObjectCreate("voltxt", OBJ_LABEL, Text_in_window_0123, 0, 0);
      ObjectSet("voltxt", OBJPROP_CORNER, 3);
      ObjectSet("voltxt", OBJPROP_XDISTANCE, __Text_Horizontal_Indent);
      ObjectSet("voltxt", OBJPROP_YDISTANCE,  __Text_Vertical_Indent+0);
      ObjectSet("voltxt", OBJPROP_COLOR, Color);
      ObjectSetText("voltxt", text, fontsize, fontstyle);    
      }
   
//+-------------------------------------------------------------------+
//| Subroutine to compute normalized volume                           |                                                        
//+-------------------------------------------------------------------+
double NormalizedVolume(int i)
   {
   double nv = 0;
   for (int j = i; j < (i+VolumePeriod); j++) nv = nv + Volume[j];
   nv = nv / VolumePeriod;
   //return (Volume[i] / nv);
   return (nv);
   }
      
//+-------------------------------------------------------------------+
//| End of program                                                    |                                                        
//+-------------------------------------------------------------------+
   