Fractal Lines Indicator

Created at 30 Jul 2023, 08:21
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
WM

wmclennan77

Joined 29.06.2021

Fractal Lines Indicator
30 Jul 2023, 08:21


I'm trying to modify a fractal indicator to draw lines if the previous up fractal is lower than the current up fractal and if the previous down fractal is higher than the current down fractal, but having problems getting the indicator to draw the lines.

The goal:

The code:

using cAlgo.API;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class FractalLines : Indicator
    {
        [Parameter(DefaultValue = 5, MinValue = 1)]
        public int Period { get; set; }

        [Output("Up Fractal", LineColor = "Red", PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries UpFractal { get; set; }

        [Output("Down Fractal", LineColor = "Lime", PlotType = PlotType.Points, Thickness = 5)]
        public IndicatorDataSeries DownFractal { get; set; }

        private double? CurrentUpFractalValue = null;
        private double? PreviousUpFractalValue = null;
        private double? CurrentDownFractalValue = null;
        private double? PreviousDownFractalValue = null;
        
        string ObjUp, ObjDown;

        public override void Calculate(int index)
        {
            if (index < Period)
                return;

            DrawUpFractal(index);
            DrawDownFractal(index);
        }

        private void DrawUpFractal(int index)
        {
            int period = Period % 2 == 0 ? Period - 1 : Period;
            int middleIndex = index - period / 2;
            double middleValue = Bars.HighPrices[middleIndex];

            bool up = true;

            for (int i = 0; i < period; i++)
            {
                if (middleValue < Bars.HighPrices[index - i])
                {
                    up = false;
                    break;
                }
            }
            if (up)
            {
                UpFractal[middleIndex] = middleValue;

                ObjUp = string.Format("UpTrendLine");
                if (CurrentUpFractalValue.HasValue)
                {
                    PreviousUpFractalValue = CurrentUpFractalValue.Value;
                    CurrentUpFractalValue = middleValue;

                    if (CurrentUpFractalValue > PreviousUpFractalValue)
                    {
                        Chart.DrawTrendLine(ObjUp, Bars.OpenTimes[index - period], PreviousUpFractalValue.Value, Bars.OpenTimes[middleIndex], CurrentUpFractalValue.Value, Color.Red, 1);
                    }
                }
                else
                {
                    CurrentUpFractalValue = middleValue;
                }
            }
            
            if (!up)
            {
                Chart.RemoveObject(ObjUp);
            }
        }

        private void DrawDownFractal(int index)
        {
            int period = Period % 2 == 0 ? Period - 1 : Period;
            int middleIndex = index - period / 2;
            double middleValue = Bars.LowPrices[middleIndex];
            bool down = true;

            for (int i = 0; i < period; i++)
            {
                if (middleValue > Bars.LowPrices[index - i])
                {
                    down = false;
                    break;
                }
            }
            if (down)
            {
                DownFractal[middleIndex] = middleValue;

                ObjDown = string.Format("DownTrendLine");
                if (CurrentDownFractalValue.HasValue)
                {
                    PreviousDownFractalValue = CurrentDownFractalValue.Value;
                    CurrentDownFractalValue = middleValue;

                    if (CurrentDownFractalValue < PreviousDownFractalValue)
                    {
                        Chart.DrawTrendLine(ObjDown, Bars.OpenTimes[index - period], PreviousDownFractalValue.Value, Bars.OpenTimes[middleIndex], CurrentDownFractalValue.Value, Color.Lime, 1);
                    }
                }
                else
                {
                    CurrentDownFractalValue = middleValue;
                }
            }
            
            if (!down)
            {
                Chart.RemoveObject(ObjDown);
            }
        }
    }
}

Any advice would be appreciated, thanks.


@wmclennan77
Replies

firemyst
30 Jul 2023, 08:45

One issue you'll have is the trendlines are overwriting each other because you're giving them the same names.

 

Change the line:

ObjUp = string.Format("UpTrendLine");

to be this instead:

ObjUp = string.Format("UpTrendLine") + index.toString();

 

Do the same for the down trend line. This way, every up obj and down obj will have unique names so they won't overwrite each other.


@firemyst

wmclennan77
30 Jul 2023, 18:15 ( Updated at: 21 Dec 2023, 09:23 )

RE: Fractal Lines Indicator

firemyst said: 

One issue you'll have is the trendlines are overwriting each other because you're giving them the same names.

 

Change the line:

ObjUp = string.Format("UpTrendLine");

to be this instead:

ObjUp = string.Format("UpTrendLine") + index.toString();

 

Do the same for the down trend line. This way, every up obj and down obj will have unique names so they won't overwrite each other.

Hi, 

Thanks for the response.

I made the changes you suggested and did get the indicator to start drawing lines, but noticed that there is only one line at a random spot on the chart:

Any advice on why it's drawing incorrectly and only in one spot?


@wmclennan77