Category Trend  Published on 09/05/2016

ZigZag

Description

DonateDescription

  • 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's avatar
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
Comments
Log in to add a comment.
MA
malukuan · 8 years ago

Nice, I'll try it

Jiri's avatar
Jiri · 8 years ago

It repaints if there is new swing of last direction, but once there's Zig-Zag it won't repaint. :)

EL
ellcz · 8 years ago

I guess its repainter, right? No fixes whatsoever :D