Very Accurate Zig Zag Trend Line


Very Accurate Zig Zag Trend Line
Very Accurate Zig Zag Trend Line



//www.aflcode.com
swingDays = 0;
swingVol = 0;
ordVol = 0;
upswingSignal = 0;
downswingSignal = 0;
accumulatedVolume = 0;
accumulatedDays = 0; 
arrayHasSignal = 0;
zigPercentage = Param("ZigZag Percent", 10, 2, 50);
trendZig = Zig(C, zigPercentage); 
action = Status("action");
midPointY = 0;
midPointValue = 0;
peakVolumeExtremeDetectionDays = Param("Peak Vol. Days", 6, 1, 20); //3 days before and 3 days after a peak
daysBeforeAndAfterForPeakVolume = round(peakVolumeExtremeDetectionDays/2);
peakVolume = 0;
colorOrdVolume = ParamColor("Ord Vol. Info.", colorGrey50);
colorZig = ParamColor("ZigZag", colorGold);
colorPeakUp = ParamColor("Support Info.", colorGreen);
colorPeakDown = ParamColor("Resistance Info.", colorRed);
scalingFactor = 0.1;


function volumeInMillions(inVolume)
{
 volInM = inVolume/1000000;
 return NumToStr(volInM, 1.2, False) + " m";
}

function getPeakVolume(daysToCheck, nowDay)
{
 returnPeakVolume = V[nowDay];
 dayNumberBefore = (nowDay) - daysToCheck;
 dayNumberAfter = (nowDay) + daysToCheck;
 //find Max swing Volume
 if( dayNumberBefore > 0 AND dayNumberAfter < BarCount )
 {
  returnPeakVolume = V[dayNumberBefore];
  //_TRACE("Start returnPeakVolume = " + returnPeakVolume);
  for( j = dayNumberBefore; j < dayNumberAfter; j++ )
  {
   if(returnPeakVolume < V[j])
   {
    returnPeakVolume = V[j];
   } 
   //_TRACE("returnPeakVolume = " + returnPeakVolume);
  }
 }
 else if( dayNumberBefore > 0 AND dayNumberAfter >= BarCount )
 {
  returnPeakVolume = V[dayNumberBefore];
  //_TRACE("Start returnPeakVolume = " + returnPeakVolume); 
  for( j = dayNumberBefore; j < BarCount; j++ )
  {
   if(returnPeakVolume < V[j])
   {
    returnPeakVolume = V[j];
   }
   //_TRACE("returnPeakVolume = " + returnPeakVolume);   
  }
 }
 else 
 {
  peakVolume = V[i-1];
 }
 
 return returnPeakVolume;
}

for( i = 3; i < BarCount; i++)
{
//initialize parameters
 arrayHasSignal[i] = 0;

//Then we check which way the price goes

 swingVol = swingVol + V[i-1];//Don't add today since price may have changed direction
 swingDays = swingDays + 1;

 if( (trendZig[i] < trendZig[i-1]) AND (trendZig[i-1] > trendZig[i-2]) AND i > 10 )//Changes from up swing to down swing
 {
  /*_TRACE("Changes from up swing to down swing, i = " + i);
  _TRACE("trendZig[i-2] = " + trendZig[i-2]);
  _TRACE("trendZig[i-1] = " + trendZig[i-1]);
  _TRACE("trendZig[i] = " + trendZig[i]);*/
  downswingSignal[i-1] = 0;
  upswingSignal[i-1] = 1;
  ordVol[i-1] = swingVol/swingDays; 
  accumulatedVolume[i-1] = swingVol;
  accumulatedDays[i-1] = swingDays; 
  arrayHasSignal[i-1] = 1;
  if(action == actionIndicator)
  {
   midPointValue = i - round(swingDays/2) - 1;
   midPointY = trendZig[midPointValue];
   peakVolume = getPeakVolume(daysBeforeAndAfterForPeakVolume, i - 1);
   PlotText("(" + volumeInMillions(ordVol[i-1]) + ")", midPointValue, midPointY, colorOrdVolume);
   PlotText(NumToStr(H[i-1], 1.1, False) + " (" + volumeInMillions(peakVolume) + ")", i-4, trendZig[i-1] * 1.02, colorPeakUp);
  }
  swingVol = 0;
  swingDays = 0;
 }

 if( (trendZig[i] > trendZig[i-1]) AND (trendZig[i-1] < trendZig[i-2]) AND i > 10 )//Changes from down swing to up swing
 {
  downswingSignal[i-1] = 1;
  upswingSignal[i-1] = 0;
  ordVol[i-1] = swingVol/swingDays;
  accumulatedVolume[i-1] = swingVol;
  accumulatedDays[i-1] = swingDays; 
  arrayHasSignal[i-1] = 1;
  if(action == actionIndicator)
  {
   midPointValue = i - round(swingDays/2) - 1;
   midPointY = trendZig[midPointValue];
   peakVolume = getPeakVolume(daysBeforeAndAfterForPeakVolume, i - 1);
   PlotText("(" + volumeInMillions(ordVol[i-1]) + ")", midPointValue, midPointY, colorOrdVolume);
   PlotText(NumToStr(L[i-1], 1.1, False) + " (" + volumeInMillions(peakVolume) + ")", i-4, trendZig[i-1] * 0.95, colorPeakDown);
  } 
  swingVol = 0;
  swingDays = 0;
 }
 if( i == BarCount - 1)//add last signal too
 {
  swingVol = swingVol + V[i];//Remember to add today also
  swingDays = swingDays + 1;

  if(trendZig[i] < trendZig[i-1])//is down swing
  {
   downswingSignal[i] = 1;
   upswingSignal[i] = 0;
   ordVol[i] = swingVol/swingDays; 
   accumulatedVolume[i] = swingVol;
   accumulatedDays[i] = swingDays; 
   arrayHasSignal[i] = 1;
  }

  if(trendZig[i] > trendZig[i-1])//is up swing
  {
   downswingSignal[i] = 0;
   upswingSignal[i] = 1;
   ordVol[i] = swingVol/swingDays;
   accumulatedVolume[i] = swingVol;
   accumulatedDays[i] = swingDays; 
   arrayHasSignal[i] = 1;
  }
  
  if(action == actionIndicator)
  {
   midPointValue = i - round(swingDays/2) - 1;
   midPointY = trendZig[midPointValue]; 
   PlotText("(" + volumeInMillions(ordVol[i]) + ")", midPointValue, midPointY, colorOrdVolume);
  }

 }
}
if(action == actionExplore)
{
 //Filter = 1;
 Filter = arrayHasSignal;
 //AddColumn(trendZig , "trendZig ", 1.2);
 AddColumn(C, "Swing Up", 1.2, colorDefault, IIf(upswingSignal, colorPeakUp, colorDefault));
 AddColumn(C, "Swing Down", 1.2, colorDefault, IIf(downswingSignal, colorPeakDown, colorDefault));
 AddColumn(ordVol, "Ord Vol.", 1.0);
 AddColumn(accumulatedDays, "Swing Days", 1.0);
 AddColumn(accumulatedVolume, "Tot. Swing Vol.", 1.0);
}
else if(action == actionIndicator)
{
 Plot(trendZig, "Ord Vol ZigZag", colorZig);
 //Scale the axis so we can read the numbers
 Plot(trendZig + (trendZig * scalingFactor), "", colorRed, styleNoDraw);
 Plot(trendZig - (trendZig * scalingFactor), "", colorBlue, styleNoDraw);
}
Previous
Next Post »