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
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.
Comments
Log in to add a comment.
Thanks for sharing, it seems to be very useful. Thank you