Description
- The ZigZag indicator shows trend lines filtering out changes below a defined level.
- The Indicator was converted from NinjaTrader script to cAlgo.
Updates
- 31/01/2016
- Released.
- 08/03/2016
- Added channels.
- Updates on tick.
Inputs
- High source - The source of High DataSeries.
- Low source - The source of Low DataSeries.
- Deviation - Value of deviation.
Screenshot
Make a Donation
- If you like my work and effort then please consider to make a kind donation thru PayPal or any Credit Card at the top right corner.

//+-------------------------------------------------------------------------------------+
//| The ZigZag indicator shows trend lines filtering out changes below a defined level. |
//+-------------------------------------------------------------------------------------+
#region Using declarations
using System;
using cAlgo.API;
#endregion
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AutoRescale = true, AccessRights = AccessRights.None)]
public class ZigZag : Indicator
{
#region Properties
[Parameter()]
public DataSeries High { get; set; }
[Parameter()]
public DataSeries Low { get; set; }
[Parameter("Deviation", DefaultValue = 5, MinValue = 1)]
public int deviationValue { get; set; }
[Output("ZigZag", Color = Colors.Gray, Thickness = 2, PlotType = PlotType.Line)]
public IndicatorDataSeries Value { get; set; }
[Output("Swing High", Color = Colors.Gray, Thickness = 1, PlotType = PlotType.Line, LineStyle = LineStyle.Lines)]
public IndicatorDataSeries SwingHigh { get; set; }
[Output("Swing Low", Color = Colors.Gray, Thickness = 1, PlotType = PlotType.Line, LineStyle = LineStyle.Lines)]
public IndicatorDataSeries SwingLow { get; set; }
#endregion
#region Variables
private double currentZigZagHigh = 0;
private double currentZigZagLow = 0;
private int lastSwingIndex = -1;
private double lastSwingPrice = 0.0;
private int trendDir = 0;
private int CurrentBar;
private double tickSize;
private IndicatorDataSeries zigZagHighZigZags, zigZagLowZigZags;
#endregion
protected override void Initialize()
{
zigZagHighZigZags = CreateDataSeries();
zigZagLowZigZags = CreateDataSeries();
tickSize = Symbol.TickSize;
}
public override void Calculate(int index)
{
CurrentBar = High.Count;
if (CurrentBar < 2)
{
zigZagHighZigZags[index] = 0;
zigZagLowZigZags[index] = 0;
return;
}
if (lastSwingPrice == 0.0)
lastSwingPrice = Low[index] + (High[index] - Low[index]) / 2;
bool isSwingHigh = High[index] >= High[index] - double.Epsilon && High[index] >= High[index - 1] - double.Epsilon;
bool isSwingLow = Low[index] <= Low[index] + double.Epsilon && Low[index] <= Low[index - 1] + double.Epsilon;
bool isOverHighDeviation = IsPriceGreater(High[index], (lastSwingPrice * (1.0 + deviationValue * 0.0001)));
bool isOverLowDeviation = IsPriceGreater(lastSwingPrice * (1.0 - deviationValue * 0.0001), Low[index]);
double saveValue = 0.0;
bool addHigh = false;
bool addLow = false;
bool updateHigh = false;
bool updateLow = false;
zigZagHighZigZags[index] = 0;
zigZagLowZigZags[index] = 0;
if (!isSwingHigh && !isSwingLow)
{
return;
}
if (trendDir <= 0 && isSwingHigh && isOverHighDeviation)
{
saveValue = High[index];
addHigh = true;
trendDir = 1;
}
else if (trendDir >= 0 && isSwingLow && isOverLowDeviation)
{
saveValue = Low[index];
addLow = true;
trendDir = -1;
}
else if (trendDir == 1 && isSwingHigh && IsPriceGreater(High[index], lastSwingPrice))
{
saveValue = High[index];
updateHigh = true;
}
else if (trendDir == -1 && isSwingLow && IsPriceGreater(lastSwingPrice, Low[index]))
{
saveValue = Low[index];
updateLow = true;
}
if (addHigh || addLow || updateHigh || updateLow)
{
if (updateHigh && lastSwingIndex >= 0)
{
zigZagHighZigZags[lastSwingIndex] = 0;
SwingHigh[lastSwingIndex] = double.NaN;
Value[lastSwingIndex] = double.NaN;
}
else if (updateLow && lastSwingIndex >= 0)
{
zigZagLowZigZags[lastSwingIndex] = 0;
SwingLow[lastSwingIndex] = double.NaN;
Value[lastSwingIndex] = double.NaN;
}
if (addHigh || updateHigh)
{
zigZagHighZigZags[index] = saveValue;
zigZagHighZigZags[index] = 0;
currentZigZagHigh = saveValue;
SwingHigh[index] = currentZigZagHigh;
Value[index] = currentZigZagHigh;
}
else if (addLow || updateLow)
{
zigZagLowZigZags[index] = saveValue;
zigZagLowZigZags[index] = 0;
currentZigZagLow = saveValue;
SwingLow[index] = currentZigZagLow;
Value[index] = currentZigZagLow;
}
lastSwingIndex = CurrentBar - 1;
lastSwingPrice = saveValue;
}
}
private bool IsPriceGreater(double a, double b)
{
if (a > b && a - b > tickSize / 2)
return true;
else
return false;
}
}
}
Jiri
Joined on 31.08.2015
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: ZigZag.algo
- Rating: 4.29
- Installs: 4086
- Modified: 13/10/2021 09:55
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Nice, I'll try it