Category Trend  Published on 29/11/2021

Pivot Super Trend

Description

This is a modifed version of the super trend indicator based on pivot points (fractals). The idear comes form an indicator found in tradingview with a slight modification for the calculation of the center line (any exponetial moving average period insted of a fixed 1/3). Trigger arrows are genereted on trend continuation when price goes above the center line and then drops back below it in down trends or when price drops below the center line and then goes back above it in up trends.

Can be usfull for short- and long-term trading depending on the settings.


using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Cloud("Center Line", "Trend Line", Opacity = 0.2, FirstColor = "FF7CFC00", SecondColor = "Red")]
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class PivotSuperTrend : Indicator
    {
        [Parameter("Fractal Length", DefaultValue = 2)]
        public int fractalLength { get; set; }

        [Parameter("Center Line Smoothing", DefaultValue = 5)]
        public int centerSmoothing { get; set; }

        [Parameter("ATR Period", DefaultValue = 10)]
        public int atrPeriod { get; set; }

        [Parameter("Atr Multiplier", DefaultValue = 3)]
        public double atrMulti { get; set; }

        [Parameter("Show Trigger", DefaultValue = false)]
        public bool ShowTrigger { get; set; }

        [Parameter("Show Pivot Points", DefaultValue = false)]
        public bool ShowPP { get; set; }



        [Output("Trend Line", LineColor = "Transparent", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries TrendLine { get; set; }

        [Output("Center Line", LineColor = "LightBlue", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries CenterLine { get; set; }

        [Output("Fractals", LineColor = "Yellow", Thickness = 6, PlotType = PlotType.Points)]
        public IndicatorDataSeries Fractals { get; set; }



        private IndicatorDataSeries Direction;
        private AverageTrueRange atr;
        private double k;



        protected override void Initialize()
        {
            Direction = CreateDataSeries();

            atr = Indicators.AverageTrueRange(atrPeriod, MovingAverageType.WilderSmoothing);

            k = 2.0 / (centerSmoothing + 1.0);
        }

        public override void Calculate(int index)
        {
            double close, range, up, down;

            close = Bars.ClosePrices[index];

            range = atr.Result[index] * atrMulti;

            CenterLine[index] = CenterLine[index - 1];

            int? bullFractalIndex = FindLastBullFractal(Bars.HighPrices, index, fractalLength, fractalLength);
            double bullFractal = double.NaN;

            if (bullFractalIndex != null)
            {
                bullFractal = Bars.HighPrices[(int)bullFractalIndex];
                if (ShowPP)
                {
                    Fractals[(int)bullFractalIndex] = bullFractal;
                }

                // calculate the Center line using pivot points
                if (double.IsNaN(CenterLine[index - 1]))
                {
                    CenterLine[index] = bullFractal;
                }
                else
                {
                    //weighted calculation
                    CenterLine[index] = CenterLine[index - 1] * (1.0 - k) + k * bullFractal;
                }
            }

            int? bearFractalIndex = FindLastBearFractal(Bars.LowPrices, index, fractalLength, fractalLength);
            double bearFractal = double.NaN;

            if (bearFractalIndex != null)
            {
                bearFractal = Bars.LowPrices[(int)bearFractalIndex];
                if (ShowPP)
                {
                    Fractals[(int)bearFractalIndex] = bearFractal;
                }

                // calculate the Center line using pivot points
                if (double.IsNaN(CenterLine[index - 1]))
                {
                    CenterLine[index] = bearFractal;
                }
                else
                {
                    //weighted calculation
                    CenterLine[index] = CenterLine[index - 1] * (1.0 - k) + k * bearFractal;
                }
            }

            up = CenterLine[index] - range;
            down = CenterLine[index] + range;

            if (index < atrPeriod && Bars.ClosePrices[index] >= Bars.OpenPrices[index])
            {
                Direction[index] = 1;
                TrendLine[index] = up;
            }
            else if (index < atrPeriod && Bars.ClosePrices[index] < Bars.OpenPrices[index])
            {
                Direction[index] = -1;
                TrendLine[index] = down;
            }

//********************************* Trend Changed to Bull **************************************
            if (Direction[index - 1] == 1)
            {
                if (close < TrendLine[index - 1])
                {
                    TrendLine[index] = down;
                    Direction[index] = -1;
                }
                else
                {
                    Direction[index] = Direction[index - 1];
                }
            }
//********************************* Trend Changed to Bear **************************************
            else if (Direction[index - 1] == -1)
            {
                if (close > TrendLine[index - 1])
                {
                    TrendLine[index] = up;
                    Direction[index] = 1;
                }
                else
                {
                    Direction[index] = Direction[index - 1];
                }
            }

//********************************* Bull Trend Continuation **************************************
            if (Direction[index] == 1 && Direction[index - 1] == 1)
            {
                TrendLine[index] = !double.IsNaN(TrendLine[index - 1]) ? Math.Max(TrendLine[index - 1], up) : up;
            }
//********************************* Bear Trend Continuation **************************************
            else if (Direction[index] == -1 && Direction[index - 1] == -1)
            {
                TrendLine[index] = !double.IsNaN(TrendLine[index - 1]) ? Math.Min(TrendLine[index - 1], down) : down;
            }

            if (Bars.LowPrices[index] < TrendLine[index] && TrendLine[index] < close)
                Chart.SetBarColor(index, Color.Cyan);

            if (Bars.HighPrices[index] > TrendLine[index] && TrendLine[index] > close)
                Chart.SetBarColor(index, Color.HotPink);

            if (ShowTrigger)
            {
                if (Bars.LowPrices.HasCrossedAbove(CenterLine, 0) && Bars.ClosePrices[index] < down && Bars.ClosePrices[index] > CenterLine[index] && TrendLine[index] < close)
                {
                    Chart.DrawIcon("Up" + index, ChartIconType.UpArrow, index, Bars.LowPrices[index] - 10 * Symbol.PipSize, Color.LimeGreen);
                }

                if (Bars.HighPrices.HasCrossedBelow(CenterLine, 0) && Bars.ClosePrices[index] > up && Bars.ClosePrices[index] < CenterLine[index] && TrendLine[index] > close)
                {
                    Chart.DrawIcon("Down" + index, ChartIconType.DownArrow, index, Bars.HighPrices[index] + 10 * Symbol.PipSize, Color.Pink);
                }
            }
        }

        private int? FindLastBullFractal(DataSeries source, int index, int leftBars, int rightBars)
        {
            var found = true;
            for (int j = 0; j < rightBars; j++)
            {
                if (source[index - j] > source[index - rightBars])
                {
                    found = false;
                    break;
                }
            }
            if (found)
            {
                for (int j = 0; j < leftBars; j++)
                {
                    if (source[index + j - (rightBars + leftBars)] > source[index - rightBars])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return index - rightBars;
                }
            }

            return null;
        }

        private int? FindLastBearFractal(DataSeries source, int index, int leftBars, int rightBars)
        {
            var found = true;
            for (int j = 0; j < rightBars; j++)
            {
                if (source[index - j] < source[index - rightBars])
                {
                    found = false;
                    break;
                }
            }
            if (found)
            {
                for (int j = 0; j < leftBars; j++)
                {
                    if (source[index + j - (rightBars + leftBars)] < source[index - rightBars])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    return index - rightBars;
                }
            }

            return null;
        }
    }
}


CW
cW22Trader

Joined on 16.03.2021

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: Pivot Super Trend.algo
  • Rating: 5
  • Installs: 3024
  • Modified: 28/11/2021 22:52
Comments
Log in to add a comment.
davidf7's avatar
davidf7 · 3 months ago

Thanks for sharing, it seems to be very useful. Thank you