//+------------------------------------------------------------------+
//|                                         Tick Volume Indicator v2 |
//|                                         Copyright © William Blau |
//|                           Originally coded © 2006 by Profitrader |
//|                                       Recoded © 2011 by MaryJane |
//+------------------------------------------------------------------+
#property copyright "Profitrader, 2006 && MaryJane, 2011"
//+------------------------------------------------------------------+
//---- properties
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Silver
#property indicator_width1 1
//+------------------------------------------------------------------+
//---- input parameters
extern int     r                 = 8;
extern int     s                 = 8;
extern int     u                 = 1;
extern int     BarCount          = 2000;
//+------------------------------------------------------------------+
int            Precision         = 5;
datetime       OldTime;
//+------------------------------------------------------------------+
//---- buffers
double TVI[], TVI_Raw[], Trend[];
//+------------------------------------------------------------------+
//---- extra buffers
double UpTicks[], DnTicks[];
double EMA_U[], EMA_D[], DEMA_U[], DEMA_D[];

string ShortName$;

//+------------------------------------------------------------------+
//| indicator initialization                                         |
//+------------------------------------------------------------------+
int init()
   { 
   //---- data window / tooltip precision
   IndicatorDigits(Precision);
   //---- 7 buffers used (one still free)
   IndicatorBuffers(3);
   //---- 5 buffers for drawing
   SetIndexBuffer(0, TVI);
   SetIndexStyle(0, DRAW_LINE);
   //---- 2 buffers for calculations
   SetIndexBuffer(1, TVI_Raw);
   SetIndexBuffer(2, Trend);
   //---- 6 additional buffers for calc
   ArrayResize(UpTicks, BarCount); ArraySetAsSeries(UpTicks, true);
   ArrayResize(DnTicks, BarCount); ArraySetAsSeries(DnTicks, true);
   ArrayResize(EMA_U, BarCount); ArraySetAsSeries(EMA_U, true);
   ArrayResize(EMA_D, BarCount); ArraySetAsSeries(EMA_D, true);
   ArrayResize(DEMA_U, BarCount); ArraySetAsSeries(DEMA_U, true);
   ArrayResize(DEMA_D, BarCount); ArraySetAsSeries(DEMA_D, true);
   // ---- disable data values for histo buffers
   SetIndexLabel(0, NULL); SetIndexLabel(1, NULL); SetIndexLabel(2, NULL); SetIndexLabel(3, NULL);
   // ---- enable data value for TVI
   SetIndexLabel(0, "TVI Value");
   //---- reset bar counter  
   //---- collect indi name
   ShortName$ = "TVI v2 Line(" + r + "," + s + "," + u + ") Trend is ";
   //---- end init
   return(0);
   }
//+------------------------------------------------------------------+
//| indicator code                                                   |
//+------------------------------------------------------------------+
int start()
   {
   int counted_bars = IndicatorCounted();
   if (counted_bars < 0) return (-1);
   if (counted_bars > 0) counted_bars--;
   int limit = MathMin(BarCount, Bars - counted_bars) - 1;
   //---- resize/shift extra buffers on first and every next bar
   if (Time[0] != OldTime) SyncExtraBuffers(BarCount);
   //---- calculate ticks
   for(int i = limit; i >= 0; i--)
      {
      UpTicks[i] = (Volume[i] + (Close[i] - Open[i]) / Point) / 2;
      DnTicks[i] = Volume[i] - UpTicks[i];
      }
   //---- 1st pass smoothing   
   for(i = limit; i >= 0; i--)
      {
      EMA_U[i] = iMAOnArray(UpTicks, 0, r, 0, MODE_EMA, i);
      EMA_D[i] = iMAOnArray(DnTicks, 0, r, 0, MODE_EMA, i);
      }
   //---- 2nd pass smoothing   
   for(i = limit; i >= 0; i--)
      {
      DEMA_U[i] = iMAOnArray(EMA_U, 0, s, 0, MODE_EMA, i);
      DEMA_D[i] = iMAOnArray(EMA_D, 0, s, 0, MODE_EMA, i);
      }
   //---- calculate the ratio   
   for(i = limit; i >= 0; i--)
      TVI_Raw[i] = 100.0 * (DEMA_U[i] - DEMA_D[i]) / (DEMA_U[i] + DEMA_D[i]);
   //---- final smoothing   
   for(i = limit; i >= 0; i--)
      TVI[i] = iMAOnArray(TVI_Raw, 0, u, 0, MODE_EMA, i);
   //---- end of loop
   return(0);
   }

//+------------------------------------------------------------------+
//| shift extra buffers on new bar                                   |
//+------------------------------------------------------------------+
void SyncExtraBuffers(int count)
   {
   for (int i = count - 1; i >= 0; i--)
      {
      UpTicks[i + 1] = UpTicks[i];
      DnTicks[i + 1] = DnTicks[i];
      EMA_U[i + 1] = EMA_U[i];
      EMA_D[i + 1] = EMA_D[i];
      DEMA_U[i + 1] = DEMA_U[i];
      DEMA_D[i + 1] = DEMA_D[i];
      }
   //---- reset bar counter   
   OldTime = Time[0];
   }


