Trendline Indicator

Created at 29 Oct 2023, 10:24
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!
JXTA's avatar

JXTA

Joined 23.08.2023

Trendline Indicator
29 Oct 2023, 10:24


I have found this indicator in the forum, it draw the trendline based on high and low, I have questions 

  1. why is this only drawing one trend in the entire chart? how to make it draw more in the past ? 
  2. how to make it draw and stop when it broke out down/up then start to draw a new one ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true)]
    public class TrendLines : Indicator
    {
        [Parameter(DefaultValue = 30, MinValue = 1)]
        public int Period { get; set; }    
    
        protected override void Initialize()
        {
            RedrawLines();
        }
    
        public override void Calculate(int index)
        {
            if (IsLastBar)
                RedrawLines();
        }
        
        private void RedrawLines()
        {
            int count = Bars.ClosePrices.Count;
        
            int maxIndex1 = FindNextLocalExtremum(Bars.HighPrices, count - 1, true);
            int maxIndex2 = FindNextLocalExtremum(Bars.HighPrices, maxIndex1 - Period, true);
            
            int minIndex1 = FindNextLocalExtremum(Bars.LowPrices, count - 1, false);
            int minIndex2 = FindNextLocalExtremum(Bars.LowPrices, minIndex1 - Period, false);
            
            int startIndex = Math.Min(maxIndex2, minIndex2) - 100;
            int endIndex = count + 100;
            
            DrawTrendLine("high", startIndex, endIndex, maxIndex1, Bars.HighPrices[maxIndex1], 
                maxIndex2, Bars.HighPrices[maxIndex2]);

            DrawTrendLine("low", startIndex, endIndex, minIndex1, Bars.LowPrices[minIndex1], 
                minIndex2, Bars.HighPrices[minIndex2]);
        }
        
        private void DrawTrendLine(string lineName, int startIndex, 
            int endIndex, int index1, double value1, int index2, double value2)
        {
            double gradient = (value2 - value1) / (index2 - index1);
            
            double startValue = value1 + (startIndex - index1) * gradient;
            double endValue = value1 + (endIndex - index1) * gradient;
            
            Chart.DrawTrendLine(lineName, startIndex, startValue, endIndex, endValue, Color.Gray);
            Chart.DrawTrendLine(lineName+"_red", index1, value1, index2, value2, Color.Red);
        }
        
        private int FindNextLocalExtremum(DataSeries series, int maxIndex, bool findMax)
        {
            for (int index = maxIndex; index >= 0; index --)
            {
                if (IsLocalExtremum(series, index, findMax))
                {
                    return index;
                }
            }
            return 0;
        }
        
        private bool IsLocalExtremum(DataSeries series, int index, bool findMax)
        {    
            int end = Math.Min(index + Period, series.Count - 1);
            int start = Math.Max(index - Period, 0);
            
            double value = series[index];
        
            for (int i = start; i < end; i++)
            {
                if (findMax && value < series[i])
                    return false;
                    
                if (!findMax && value > series[i])
                    return false;
            }
            return true;
        }
    }
}

@JXTA