Reference to Indicator - Make SL = S/R Levels

Created at 15 Apr 2019, 19:48
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!
RY

ryanoia@gmail.com

Joined 09.03.2018

Reference to Indicator - Make SL = S/R Levels
15 Apr 2019, 19:48


I have a sticking point. I have a cbot, and I want the stop loss in the cbot to be placed where the S/R levels in the chart are.

So the S/R level code I'm referring to is this:

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
 
namespace cAlgo
{
    [Indicator("Support and Resistance At Price", IsOverlay = true, AccessRights = AccessRights.None)]
    public class SRAtPrice : Indicator
    {
        private double extremeHigh = 0;
        private double extremeLow = 0;
        private double dayHi = 0;
        private double dayLo = 0;
        private SortedList<double, int> prices = new SortedList<double, int>();
        private IList<Zone> zones = new List<Zone>();
 
        private const string ExtremeHighName = "ExtremeHigh";
        private const string ExtremeLowName = "ExtremeLow";
        private const string DayHighName = "DayHigh";
        private const string DayLowName = "DayLow";
 
        [Parameter("Periods", DefaultValue = 100)]
        public int Periods { get; set; }
 
        [Parameter("Show Extreme H/L", DefaultValue = true)]
        public bool ShowExtremeHL { get; set; }
 
        [Parameter("Show Day H/L", DefaultValue = true)]
        public bool ShowDayHL { get; set; }
 
        [Parameter("Required Hits", DefaultValue = 5)]
        public int RequiredHits { get; set; }
 
        [Parameter("Zone Size", DefaultValue = 10)]
        public int ZoneSize { get; set; }
 
        [Parameter("Max Lines In Zone", DefaultValue = 3)]
        public int MaxLinesInZone { get; set; }
 
        [Output("Extreme H/L Style", Color = Colors.Red, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries ExtremeHLStyle { get; set; }
 
        [Output("Day H/L Style", Color = Colors.Blue, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries DayHLStyle { get; set; }
 
        [Output("S/R Style", Color = Colors.Orange, LineStyle = LineStyle.DotsVeryRare)]
        public IndicatorDataSeries SRStyle { get; set; }
 
        public override void Calculate(int index)
        {
            if (this.IsLastBar)
            {
                var currentOpenDate = this.MarketSeries.OpenTime[index].Date;
                var earliest = index - this.Periods;
                for (var i = index; i >= earliest; i--)
                {
                    if (i >= 0)
                    {
                        var high = this.MarketSeries.High[i];
                        var nextHigh = this.MarketSeries.High[i + 1];
                        var low = this.MarketSeries.Low[i];
                        var nextLow = this.MarketSeries.Low[i + 1];
                        this.extremeHigh = Math.Max(high, this.extremeHigh);
                        this.extremeLow = this.extremeLow == 0 ? low : Math.Min(low, this.extremeLow);
 
                        if (this.TimeFrame < TimeFrame.Daily)
                        {
                            if (this.MarketSeries.OpenTime[i].Date == currentOpenDate)
                            {
                                this.dayHi = Math.Max(high, this.dayHi);
                                this.dayLo = this.dayLo == 0 ? low : Math.Min(low, this.dayLo);
                            }
                        }
 
                        if (nextHigh <= high)
                        {
                            this.AddOrUpdatePrice(high);
                        }
 
                        if (nextLow >= low)
                        {
                            this.AddOrUpdatePrice(low);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
 
                this.zones.Clear();
                var rangePipSize = (this.Symbol.PipSize * (double)this.ZoneSize);
                for (var i = this.extremeLow + rangePipSize; i < this.extremeHigh - rangePipSize; i += rangePipSize + this.Symbol.PipSize)
                {
                    this.zones.Add(new Zone 
                    {
                        Start = i,
                        End = i + rangePipSize,
                        LinesRendered = 0
                    });
                }
 
                this.ChartObjects.RemoveAllObjects();
 
                foreach (var price in this.prices.Keys)
                {
                    this.RenderSRIfRequred(price, this.prices[price]);
                }
 
                if (this.ShowExtremeHL)
                {
                    this.DrawExtremeHigh();
                    this.DrawExtremeLow();
                }
 
                if (this.TimeFrame < TimeFrame.Daily && this.ShowDayHL)
                {
                    this.DrawDayHigh();
                    this.DrawDayLow();
                }
            }
        }
 
        private void RenderSRIfRequred(double price, int count)
        {
            if (count < this.RequiredHits)
            {
                return;
            }
 
            foreach (var range in this.zones)
            {
                if (price >= range.Start && price <= range.End)
                {
                    if (range.LinesRendered != this.MaxLinesInZone)
                    {
                        range.LinesRendered++;
                        this.DrawSR(price);
                    }
                    return;
                }
            }
        }
 
        private void AddOrUpdatePrice(double priceValue)
        {
            if (this.prices.ContainsKey(priceValue))
            {
                this.prices[priceValue]++;
            }
            else
            {
                this.prices.Add(priceValue, 1);
            }
        }
 
        private void DrawExtremeHigh()
        {
            this.DrawExtreme(ExtremeHighName, this.extremeHigh);
        }
 
        private void DrawExtremeLow()
        {
            this.DrawExtreme(ExtremeLowName, this.extremeLow);
        }
 
        private void DrawDayHigh()
        {
            this.DrawDay(DayHighName, this.dayHi);
        }
 
        private void DrawDayLow()
        {
            this.DrawDay(DayLowName, this.dayLo);
        }
 
        private void DrawExtreme(string name, double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("ExtremeHLStyle");
            this.ChartObjects.DrawHorizontalLine(name, level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }
 
        private void DrawDay(string name, double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("DayHLStyle");
            this.ChartObjects.DrawHorizontalLine(name, level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }
 
        private void DrawSR(double level)
        {
            var attribute = this.GetAttributeFrom<OutputAttribute>("SRStyle");
            this.ChartObjects.DrawHorizontalLine(string.Format("SR {0}", level), level, attribute.Color, attribute.Thickness, attribute.LineStyle);
        }
 
        private T GetAttributeFrom<T>(string propertyName)
        {
            var attrType = typeof(T);
            var property = this.GetType().GetProperty(propertyName);
            return (T)property.GetCustomAttributes(attrType, false).GetValue(0);
        }
 
        private class Price
        {
            internal double Value { get; set; }
            internal int Count { get; set; }
        }
 
        private class Zone
        {
            internal double Start { get; set; }
            internal double End { get; set; }
            internal int LinesRendered { get; set; }
        }
    }
}

I got this code from this thread, posted by user forum member testpossessed, who was kind enough to provide the source code thereof. 

How can I do it so that the stop loss of my positions automatically correspondends to the price where the S/R levels are located according to the S/R price indicator above? Is that even possible? If not, then maybe a code wherein if position is at an S/R level and at negative xx pips, then bot automatically closes the position. 

I would appreciate help on this issue. 

Thanks.


@ryanoia@gmail.com
Replies

ryanoia@gmail.com
18 Apr 2019, 10:33

Possible?

I just need to know if this is possible or not so that I know if I am wasting time trying to do this or not. The code is simple, instead of take profit or stop loss in the executemarketorder, I want to change it to the price levels indicated in the price S/R indicator. 


@ryanoia@gmail.com

PanagiotisCharalampous
18 Apr 2019, 22:02

Hi ryanoia@gmail.com,

I don't think this is possible with the existing indicator since the S/R levels are not accessilbe. You will need to make considerable changes to achieve this.

Best Regards,

Panagiotis


@PanagiotisCharalampous

ryanoia@gmail.com
22 Apr 2019, 03:08

Considerable changes - does that mean almost changing the code from scratch or a major overhaul? Would appreciate your assessment on this. Thanks.


@ryanoia@gmail.com

ryanoia@gmail.com
22 Apr 2019, 03:10

How about making reference to this pivot point indicator:

 

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
 
namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)]
    public class AllPivots : Indicator
    {
        private DateTime _previousPeriodStartTime;
        private int _previousPeriodStartIndex;
        private TimeFrame PivotTimeFrame;
        private VerticalAlignment vAlignment = VerticalAlignment.Top;
        private HorizontalAlignment hAlignment = HorizontalAlignment.Right;
 
        public string PP;
 
        Colors pivotColor = Colors.Magenta;
        Colors supportColor = Colors.Red;
        Colors resistanceColor = Colors.DodgerBlue;
        Colors pmedioColor = Colors.Green;
 
        [Parameter("Show Labels", DefaultValue = true)]
        public bool ShowLabels { get; set; }
 
        [Parameter("Pivot Color", DefaultValue = "Magenta")]
        public string PivotColor { get; set; }
        [Parameter("Support Color", DefaultValue = "Red")]
        public string SupportColor { get; set; }
        [Parameter("Resistance Color", DefaultValue = "DodgerBlue")]
        public string ResistanceColor { get; set; }
        [Parameter("PMedio Color", DefaultValue = "Green")]
        public string PmedioColor { get; set; }
 
        [Parameter("Espessura Pivot", DefaultValue = 1)]
        public int Espessura { get; set; }
 
        [Parameter("Espessura Pivot Medio", DefaultValue = 1)]
        public int Espessura2 { get; set; }
 
 
        protected override void Initialize()
        {
 
            PivotTimeFrame = TimeFrame.Daily;
            PP = "P Daily";
 
                        /*            if (TimeFrame < TimeFrame.Hour4)
            {
                PivotTimeFrame = TimeFrame.Daily;
                PP = "P Daily";
            }
 
 
            if ((TimeFrame >= TimeFrame.Hour4) && (TimeFrame < TimeFrame.Weekly))
            {
                PivotTimeFrame = TimeFrame.Weekly;
                PP = "P Weekly";
            }
 
 
            if (TimeFrame >= TimeFrame.Weekly)
            {
                PivotTimeFrame = TimeFrame.Monthly;
                PP = "P Monthly";
            }
*/
Enum.TryParse(PivotColor, out pivotColor);
            Enum.TryParse(SupportColor, out supportColor);
            Enum.TryParse(ResistanceColor, out resistanceColor);
            Enum.TryParse(PmedioColor, out pmedioColor);
 
        }
 
        private DateTime GetStartOfPeriod(DateTime dateTime)
        {
            return CutToOpenByNewYork(dateTime, PivotTimeFrame);
        }
 
        private DateTime GetEndOfPeriod(DateTime dateTime)
        {
            if (PivotTimeFrame == TimeFrame.Monthly)
            {
                return new DateTime(dateTime.Year, dateTime.Month, 1).AddMonths(1);
            }
 
            return AddPeriod(CutToOpenByNewYork(dateTime, PivotTimeFrame), PivotTimeFrame);
        }
 
        public override void Calculate(int index)
        {
            var currentPeriodStartTime = GetStartOfPeriod(MarketSeries.OpenTime[index]);
            if (currentPeriodStartTime == _previousPeriodStartTime)
                return;
 
            if (index > 0)
                CalculatePivots(_previousPeriodStartTime, _previousPeriodStartIndex, currentPeriodStartTime, index);
 
            _previousPeriodStartTime = currentPeriodStartTime;
            _previousPeriodStartIndex = index;
        }
 
        private void CalculatePivots(DateTime startTime, int startIndex, DateTime startTimeOfNextPeriod, int index)
        {
            var high = MarketSeries.High[startIndex];
            var low = MarketSeries.Low[startIndex];
            var close = MarketSeries.Close[startIndex];
            var i = startIndex + 1;
 
            while (GetStartOfPeriod(MarketSeries.OpenTime[i]) == startTime && i < MarketSeries.Close.Count)
            {
                high = Math.Max(high, MarketSeries.High[i]);
                low = Math.Min(low, MarketSeries.Low[i]);
                close = MarketSeries.Close[i];
 
                i++;
            }
 
            var pivotStartTime = startTimeOfNextPeriod;
            var pivotEndTime = GetEndOfPeriod(startTimeOfNextPeriod);
 
            var pivot = (high + low + close) / 3;
 
            var r1 = 2 * pivot - low;
            var s1 = 2 * pivot - high;
 
            var r2 = pivot + high - low;
            var s2 = pivot - high + low;
 
            var r3 = high + 2 * (pivot - low);
            var s3 = low - 2 * (high - pivot);
 
            var r4 = r3 + pivot - low;
            var s4 = s3 + pivot - high;
 
 
            var m0 = (s4 + s3) / 2;
            var m1 = (s3 + s2) / 2;
            var m2 = (s2 + s1) / 2;
            var m3 = (s1 + pivot) / 2;
            var m4 = (pivot + r1) / 2;
            var m5 = (r1 + r2) / 2;
            var m6 = (r2 + r3) / 2;
            var m7 = (r3 + r4) / 2;
 
 
            ChartObjects.DrawLine("pivot " + startIndex, pivotStartTime, pivot, pivotEndTime, pivot, pivotColor, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("r1 " + startIndex, pivotStartTime, r1, pivotEndTime, r1, resistanceColor, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("r2 " + startIndex, pivotStartTime, r2, pivotEndTime, r2, resistanceColor, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("r3 " + startIndex, pivotStartTime, r3, pivotEndTime, r3, Colors.Aqua, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("r4 " + startIndex, pivotStartTime, r4, pivotEndTime, r4, Colors.SlateBlue, Espessura, LineStyle.Solid);
 
            ChartObjects.DrawLine("s1 " + startIndex, pivotStartTime, s1, pivotEndTime, s1, supportColor, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("s2 " + startIndex, pivotStartTime, s2, pivotEndTime, s2, supportColor, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("s3 " + startIndex, pivotStartTime, s3, pivotEndTime, s3, Colors.Yellow, Espessura, LineStyle.Solid);
            ChartObjects.DrawLine("s4 " + startIndex, pivotStartTime, s4, pivotEndTime, s4, Colors.Orange, Espessura, LineStyle.Solid);
 
 
            ChartObjects.DrawLine("m0 " + startIndex, pivotStartTime, m0, pivotEndTime, m0, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m1 " + startIndex, pivotStartTime, m1, pivotEndTime, m1, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m2 " + startIndex, pivotStartTime, m2, pivotEndTime, m2, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m3 " + startIndex, pivotStartTime, m3, pivotEndTime, m3, pmedioColor, Espessura2, LineStyle.DotsRare);
 
            ChartObjects.DrawLine("m4 " + startIndex, pivotStartTime, m4, pivotEndTime, m4, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m5 " + startIndex, pivotStartTime, m5, pivotEndTime, m5, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m6 " + startIndex, pivotStartTime, m6, pivotEndTime, m6, pmedioColor, Espessura2, LineStyle.DotsRare);
            ChartObjects.DrawLine("m7 " + startIndex, pivotStartTime, m7, pivotEndTime, m7, pmedioColor, Espessura2, LineStyle.DotsRare);
 
            if (!ShowLabels)
                return;
 
            ChartObjects.DrawText("Lpivot " + startIndex, PP + "=" + pivot.ToString("0.00000"), index, pivot, vAlignment, hAlignment, Colors.White);
            ChartObjects.DrawText("Lr1 " + startIndex, "R1=" + r1.ToString("0.00000"), index, r1, vAlignment, hAlignment, resistanceColor);
            ChartObjects.DrawText("Lr2 " + startIndex, "R2=" + r2.ToString("0.00000"), index, r2, vAlignment, hAlignment, resistanceColor);
            ChartObjects.DrawText("Lr3 " + startIndex, "R3=" + r3.ToString("0.00000"), index, r3, vAlignment, hAlignment, Colors.Aqua);
            ChartObjects.DrawText("Lr4 " + startIndex, "R4=" + r4.ToString("0.00000"), index, r4, vAlignment, hAlignment, Colors.SlateBlue);
 
            ChartObjects.DrawText("Ls1 " + startIndex, "S1=" + s1.ToString("0.00000"), index, s1, vAlignment, hAlignment, supportColor);
            ChartObjects.DrawText("Ls2 " + startIndex, "S2=" + s2.ToString("0.00000"), index, s2, vAlignment, hAlignment, supportColor);
            ChartObjects.DrawText("Ls3 " + startIndex, "S3=" + s3.ToString("0.00000"), index, s3, vAlignment, hAlignment, Colors.Yellow);
            ChartObjects.DrawText("Ls4 " + startIndex, "S4=" + s4.ToString("0.00000"), index, s4, vAlignment, hAlignment, Colors.Orange);
 
 
        }
 
 
        private static DateTime CutToOpenByNewYork(DateTime date, TimeFrame timeFrame)
        {
            if (timeFrame == TimeFrame.Daily)
            {
                var hourShift = (date.Hour + 24 - 17) % 24;
                return new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0, DateTimeKind.Unspecified).AddHours(-hourShift);
            }
 
            if (timeFrame == TimeFrame.Weekly)
                return GetStartOfTheWeek(date);
 
            if (timeFrame == TimeFrame.Monthly)
            {
                return new DateTime(date.Year, date.Month, 1, 0, 0, 0, DateTimeKind.Unspecified);
            }
 
            throw new ArgumentException(string.Format("Unknown timeframe: {0}", timeFrame), "timeFrame");
        }
 
        private static DateTime GetStartOfTheWeek(DateTime dateTime)
        {
            return dateTime.Date.AddDays((double)DayOfWeek.Sunday - (double)dateTime.Date.DayOfWeek).AddHours(-7);
        }
 
 
        public DateTime AddPeriod(DateTime dateTime, TimeFrame timeFrame)
        {
            if (timeFrame == TimeFrame.Daily)
            {
                return dateTime.AddDays(1);
            }
            if (timeFrame == TimeFrame.Weekly)
            {
                return dateTime.AddDays(7);
            }
            if (timeFrame == TimeFrame.Monthly)
                return dateTime.AddMonths(1);
 
            throw new ArgumentException(string.Format("Unknown timeframe: {0}", timeFrame), "timeFrame");
        }
 
    }
 
}

 


@ryanoia@gmail.com

PanagiotisCharalampous
22 Apr 2019, 10:35

Hi ryanoia@gmail.com,

You will need to add functionality to access the support and resistance levels from a cBot.

Best Regards,

Panagiotis


@PanagiotisCharalampous

ryanoia@gmail.com
22 Apr 2019, 10:50

Ok. So are you saying that with the second indicator, it is possible, it's just that I have to add functionality in the pivot point cBot code for the cBot to access the support and resistance levels in the indicator? 


@ryanoia@gmail.com

ryanoia@gmail.com
22 Apr 2019, 10:51

I mean, pivot point support and resistance levels


@ryanoia@gmail.com

PanagiotisCharalampous
23 Apr 2019, 16:22

Hi ryanoia@gmail.com,

Ok. So are you saying that with the second indicator, it is possible, it's just that I have to add functionality in the pivot point cBot code for the cBot to access the support and resistance levels in the indicator? 

Yes this is what I mean.

Best Regards,

Panagiotis 


@PanagiotisCharalampous