//+------------------------------------------------------------------+
//|                                           Volatility quality.mq4 |
//|                                                                  |
//|                                                                  |
//| Volatility quality index originaly developed by                  |
//| Thomas Stridsman (August 2002 Active Trader Magazine)            |
//|                                                                  |
//| Price pre-smoothing and filter added by raff1410                 |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_separate_window
#property indicator_buffers  8
#property indicator_color1   clrGoldenrod
#property indicator_color2   clrGold
#property indicator_color3   clrLimeGreen
#property indicator_color4   clrRed
#property indicator_color5   clrRed
#property indicator_color6   clrDodgerBlue
#property indicator_color7   clrSandyBrown
#property indicator_color8   clrDimGray
#property indicator_width3   2
#property indicator_width4   2
#property indicator_width5   2
#property indicator_style1   STYLE_DOT
#property indicator_style2   STYLE_DOT
#property indicator_style8   STYLE_DASH

//
//
//
//
//

#import "dynamicZone.dll"
   double dzBuyP(double& sourceArray[],double probabiltyValue, int lookBack, int bars, int i, double precision);
   double dzSellP(double& sourceArray[],double probabiltyValue, int lookBack, int bars, int i, double precision);
#import

//
//
//
//
//

extern ENUM_TIMEFRAMES TimeFrame                  = PERIOD_CURRENT;
extern int             PriceSmoothing             = 5;
extern ENUM_MA_METHOD  PriceSmoothingMethod       = MODE_LWMA;
extern int             MA1Period                  = 9;
extern ENUM_MA_METHOD  MA1Method                  = MODE_SMA;
extern int             MA2Period                  = 200;
extern ENUM_MA_METHOD  MA2Method                  = MODE_SMA;
extern double          FilterInPips               = 2.0;
extern int             DzLookBackBars             = 70;             // Dynamic zone look back bars
extern double          DzStartBuyProbability1     = 0.10;           // Dynamic zone buy probability 1
extern double          DzStartSellProbability1    = 0.10;           // Dynamic zone sell probability 1
extern bool            alertsOn                   = true;
extern bool            alertsOnSlope              = true;
extern bool            alertsOnVQFastCross        = true;
extern bool            alertsOnVQSlowCross        = true;
extern bool            alertsOnCurrent            = true;
extern bool            alertsMessage              = true;
extern bool            alertsNotify               = true;
extern bool            alertsSound                = false;
extern bool            alertsEmail                = false;
extern bool            ShowArrows                 = true;
extern bool            arrowsOnFirst              = true;
extern bool            arrowsOnSlope              = true;
extern bool            arrowsOnVQFastCross        = true;
extern bool            arrowsOnVQSlowCross        = true;
extern string          arrowsIdentifier           = "vq arrows1";
extern double          arrowsUpperGap             = 0.5;
extern double          arrowsLowerGap             = 0.5;
extern color           arrowsOnSlopeUpColor       = clrLimeGreen;
extern color           arrowsOnSlopeDnColor       = clrRed;
extern int             arrowsOnSlopeUpCode        = 241;
extern int             arrowsOnSlopeDnCode        = 242;
extern color           arrowsOnVQFastCrossUpColor = clrLimeGreen;
extern color           arrowsOnVQFastCrossDnColor = clrRed;
extern int             arrowsOnVQFastCrossUpCode  = 159;
extern int             arrowsOnVQFastCrossDnCode  = 159;
extern color           arrowsOnVQSlowCrossUpColor = clrLimeGreen;
extern color           arrowsOnVQSlowCrossDnColor = clrRed;
extern int             arrowsOnVQSlowCrossUpCode  = 108;
extern int             arrowsOnVQSlowCrossDnCode  = 108;
extern bool            Interpolate                = true;

//
//
//
//
//

double sumVqi[];
double sumVqida[];
double sumVqidb[];
double sumVqi1[];
double sumVqi2[];
double Vqi[];
double bl1[];
double bl2[];
double sl1[];
double sl2[];
double zl1[];
double trend[];
double trend1[];
double trend2[];
string indicatorFileName;
bool   returnBars;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   IndicatorBuffers(12);
      SetIndexBuffer(0, sumVqi1); 
      SetIndexBuffer(1, sumVqi2); 
      SetIndexBuffer(2, sumVqi); 
      SetIndexBuffer(3, sumVqida); 
      SetIndexBuffer(4, sumVqidb); 
      SetIndexBuffer(5, bl1);
      SetIndexBuffer(6, sl1);
      SetIndexBuffer(7, zl1);
      SetIndexBuffer(8, Vqi); 
      SetIndexBuffer(9, trend);
      SetIndexBuffer(10,trend1);
      SetIndexBuffer(11,trend2);
         PriceSmoothing    = MathMax(PriceSmoothing,1);
         indicatorFileName = WindowExpertName();
         returnBars        = TimeFrame==-98;
         TimeFrame         = MathMax(TimeFrame,_Period);
         IndicatorShortName(timeFrameToString(TimeFrame)+" ddz VQ Stridsman");
   return(0);
}
int deinit()
{ 
   string lookFor       = arrowsIdentifier+":";
   int    lookForLength = StringLen(lookFor);
   for (int i=ObjectsTotal()-1; i>=0; i--)
   {
      string objectName = ObjectName(i);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
   }
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         int limit = MathMin(Bars-counted_bars,Bars-1);
         if (returnBars) { sumVqi1[0] = MathMin(limit+1,Bars-1); return(0); }
         double pipMultiplier = MathPow(10,_Digits%2);
         
   //
   //
   //
   //
   //
            
   if (TimeFrame == _Period)
   {
      if (trend[limit] == -1) CleanPoint(limit,sumVqida,sumVqidb);
      for(int i=limit; i>=0; i--)
      {
         if (i==(Bars-1))
         {
            Vqi[i]    = 0;
            sumVqi[i] = 0;
            continue;
         }
      
         //
         //
         //
         //
         //
      
         double cHigh  = iMA(NULL,0,PriceSmoothing,0,PriceSmoothingMethod,PRICE_HIGH ,i);
         double cLow   = iMA(NULL,0,PriceSmoothing,0,PriceSmoothingMethod,PRICE_LOW  ,i);
         double cOpen  = iMA(NULL,0,PriceSmoothing,0,PriceSmoothingMethod,PRICE_OPEN ,i);
         double cClose = iMA(NULL,0,PriceSmoothing,0,PriceSmoothingMethod,PRICE_CLOSE,i);
         double pClose = iMA(NULL,0,PriceSmoothing,0,PriceSmoothingMethod,PRICE_CLOSE,i+1);
         
         double trueRange = MathMax(cHigh,pClose)-MathMin(cLow,pClose);
         double     range = cHigh-cLow;
      
            if (range != 0 && trueRange!=0)
               double vqi = ((cClose-pClose)/trueRange + (cClose-cOpen)/range)*0.5;
            else      vqi = Vqi[i+1];

      //
      //
      //
      //
      //
         
         Vqi[i]      = MathAbs(vqi)*(cClose-pClose+cClose-cOpen)*0.5;
         sumVqi[i]   = sumVqi[i+1]+Vqi[i];
         if (DzStartBuyProbability1  > 0) bl1[i] = dzBuyP (sumVqi, DzStartBuyProbability1,  DzLookBackBars, Bars, i, 0.0001);
         if (DzStartSellProbability1 > 0) sl1[i] = dzSellP(sumVqi, DzStartSellProbability1, DzLookBackBars, Bars, i, 0.0001);
                                          zl1[i] = dzSellP(sumVqi, 0.5                    , DzLookBackBars, Bars, i, 0.0001);
         sumVqida[i] = EMPTY_VALUE;
         sumVqidb[i] = EMPTY_VALUE;
            if (FilterInPips > 0) if (MathAbs(sumVqi[i]-sumVqi[i+1]) < FilterInPips*pipMultiplier*Point) sumVqi[i] = sumVqi[i+1];
      
      //
      //
      //
      //
      //
      
      trend[i] = trend[i+1];
         if (sumVqi[i] > sumVqi[i+1]) trend[i] =  1;
         if (sumVqi[i] < sumVqi[i+1]) trend[i] = -1;
         
         if (trend[i] == -1) PlotPoint(i,sumVqida,sumVqidb,sumVqi);
         manageArrow(i);
      }
      for(i=limit; i>=0; i--)
      {
         if (MA1Period > 1) sumVqi1[i] = iMAOnArray(sumVqi,0,MA1Period,0,MA1Method,i);
         if (MA2Period > 1) sumVqi2[i] = iMAOnArray(sumVqi,0,MA2Period,0,MA2Method,i);
         trend1[i] = trend1[i+1];
         trend2[i] = trend2[i+1];
         if (sumVqi[i]>sumVqi1[i]) trend1[i] =  1;
         if (sumVqi[i]<sumVqi1[i]) trend1[i] = -1;
         if (sumVqi[i]>sumVqi2[i]) trend2[i] =  1;
         if (sumVqi[i]<sumVqi2[i]) trend2[i] = -1;
         manageArrow(i);
      }  
      manageAlerts();     
      return(0);
   }
   
   //
   //
   //
   //
   //
   
   limit = (int)MathMax(limit,MathMin(Bars-1,iCustom(NULL,TimeFrame,indicatorFileName,-98,0,0)*TimeFrame/Period()));
   if (trend[limit] == -1) CleanPoint(limit,sumVqida,sumVqidb);
   for (i=limit; i>=0; i--)
   {
      int y = iBarShift(NULL,TimeFrame,Time[i]);
         sumVqi1[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,0,y);
         sumVqi2[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,1,y);
         sumVqi[i]  = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,2,y);
         bl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,5,y);
         sl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,6,y);
         zl1[i]     = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,7,y); 
         trend[i]   = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,PriceSmoothing,PriceSmoothingMethod,MA1Period,MA1Method,MA2Period,MA2Method,FilterInPips,DzLookBackBars,DzStartBuyProbability1,DzStartSellProbability1,
                      alertsOn,alertsOnSlope,alertsOnVQFastCross,alertsOnVQSlowCross,alertsOnCurrent,alertsMessage,alertsNotify,alertsSound,alertsEmail,ShowArrows,arrowsOnFirst,arrowsOnSlope,arrowsOnVQFastCross,arrowsOnVQSlowCross,arrowsIdentifier,arrowsUpperGap,arrowsLowerGap,
                      arrowsOnSlopeUpColor,arrowsOnSlopeDnColor,arrowsOnSlopeUpCode,arrowsOnSlopeDnCode,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossUpCode,arrowsOnVQFastCrossDnCode,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossUpCode,arrowsOnVQSlowCrossDnCode,9,y);                                   
         sumVqida[i] = EMPTY_VALUE;
         sumVqidb[i] = EMPTY_VALUE;

         //
         //
         //
         //
         //
               
         if (!Interpolate || y==iBarShift(NULL,TimeFrame,Time[i-1])) continue;
         datetime time = iTime(NULL,TimeFrame,y);
            for(int n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;	
            for(int k = 1; k < n; k++)
            {
               sumVqi1[i+k] = sumVqi1[i] + (sumVqi1[i+n] - sumVqi1[i]) * k/n;
               sumVqi2[i+k] = sumVqi2[i] + (sumVqi2[i+n] - sumVqi2[i]) * k/n;
               sumVqi[i+k]  = sumVqi[i]  + (sumVqi[i+n]  - sumVqi[i])  * k/n;
               bl1[i+k]     = bl1[i]     + (bl1[i+n]     - bl1[i])     * k/n;
  	            sl1[i+k]     = sl1[i]     + (sl1[i+n]     - sl1[i])     * k/n;
  	            zl1[i+k]     = zl1[i]     + (zl1[i+n]     - zl1[i])     * k/n;
            }               
   }
   for (i=limit; i>=0; i--) if (trend[i] == -1) PlotPoint(i,sumVqida,sumVqidb,sumVqi);
   return(0);         
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

void CleanPoint(int i,double& first[],double& second[])
{
   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
        second[i+1] = EMPTY_VALUE;
   else
      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
          first[i+1] = EMPTY_VALUE;
}
void PlotPoint(int i,double& first[],double& second[],double& from[])
{
   if (first[i+1] == EMPTY_VALUE)
         if (first[i+2] == EMPTY_VALUE) 
               {  first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
         else  {  second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
   else        {  first[i]  = from[i];                          second[i] = EMPTY_VALUE; }
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M10","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,10,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1; 

      //
      //
      //
      //
      //
            
      static datetime time1 = 0;
      static string   mess1 = "";
      if (alertsOnSlope && trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar] ==  1) doAlert(time1,mess1,whichBar,"sloping up");
         if (trend[whichBar] == -1) doAlert(time1,mess1,whichBar,"sloping down");
      }
      
      static datetime time2 = 0;
      static string   mess2 = "";
      if (alertsOnVQFastCross && trend1[whichBar]!= trend1[whichBar+1])
      {
         if (trend1[whichBar] ==  1) doAlert(time2,mess2,whichBar,"crossing fast moving average up");
         if (trend1[whichBar] == -1) doAlert(time2,mess2,whichBar,"crossing fast moving average down");
      }   
      
      static datetime time3 = 0;
      static string   mess3 = "";
      if (alertsOnVQSlowCross && trend2[whichBar]!= trend2[whichBar+1])
      {
         if (trend2[whichBar] ==  1) doAlert(time3,mess3,whichBar,"crossing slow moving average up");
         if (trend2[whichBar] == -1) doAlert(time3,mess3,whichBar,"crossing slow moving average down");
      }   
   }
}

//
//
//
//
//

void doAlert(datetime& previousTime, string& previousAlert, int forBar, string doWhat)
{
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) {
       previousAlert  = doWhat;
       previousTime   = Time[forBar];

       //
       //
       //
       //
       //

       message =  StringConcatenate(Symbol(),Period()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," VQ ",doWhat);
          if (alertsMessage) Alert(message);
          if (alertsNotify)  SendNotification(message);
          if (alertsEmail)   SendMail(StringConcatenate(Symbol()," VQ "),message);
          if (alertsSound)   PlaySound("alert2.wav");
   }
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void manageArrow(int i)
{
    if (ShowArrows)
    {
      ObjectDelete(arrowsIdentifier+":1:"+Time[i]);
      ObjectDelete(arrowsIdentifier+":2:"+Time[i]);
      ObjectDelete(arrowsIdentifier+":3:"+Time[i]);
      string lookFor = arrowsIdentifier+":"+Time[i]; ObjectDelete(lookFor);
      if (arrowsOnSlope && trend[i] != trend[i+1])
      {
         if (trend[i] == 1) drawArrow("1",0.5,i,arrowsOnSlopeUpColor,arrowsOnSlopeUpCode,false);
         if (trend[i] ==-1) drawArrow("1",0.5,i,arrowsOnSlopeDnColor,arrowsOnSlopeDnCode, true);
      } 
      if (arrowsOnVQFastCross && trend1[i] != trend1[i+1])
      {
         if (trend1[i] == 1) drawArrow("2",1,i,arrowsOnVQFastCrossUpColor,arrowsOnVQFastCrossUpCode,false);
         if (trend1[i] ==-1) drawArrow("2",1,i,arrowsOnVQFastCrossDnColor,arrowsOnVQFastCrossDnCode, true);
      } 
      if (arrowsOnVQSlowCross && trend2[i] != trend2[i+1])
      {
         if (trend2[i] == 1) drawArrow("3",1.5,i,arrowsOnVQSlowCrossUpColor,arrowsOnVQSlowCrossUpCode,false);
         if (trend2[i] ==-1) drawArrow("3",1.5,i,arrowsOnVQSlowCrossDnColor,arrowsOnVQSlowCrossDnCode, true);
      } 
    }
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------          
//
//
//
//
//

void drawArrow(string nameAdd, double gapMul, int i,color theColor,int theCode,bool up)
{
   string name = arrowsIdentifier+":"+nameAdd+":"+Time[i];
   double gap  = iATR(NULL,0,20,i)*gapMul;   
   
      //
      //
      //
      //
      //
      
      int add = 0; if (!arrowsOnFirst) add = _Period*60-1;
      ObjectCreate(name,OBJ_ARROW,0,Time[i]+add,0);
         ObjectSet(name,OBJPROP_ARROWCODE,theCode);
         ObjectSet(name,OBJPROP_COLOR,theColor);
         if (up)
               ObjectSet(name,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
         else  ObjectSet(name,OBJPROP_PRICE1,Low[i]  - arrowsLowerGap * gap);
}                                    
      