Calculate Position based on high - low of specific hours

Created at 25 Apr 2021, 22:33
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!
CT

ctid892592

Joined 21.04.2021

Calculate Position based on high - low of specific hours
25 Apr 2021, 22:33


How do I retrieve the high and low of a current day, and 2 specific time points (static, form the current day) from a chart into the Bot, in order for it to use this new variable in a proceding caclculation?

 


@ctid892592
Replies

amusleh
02 May 2021, 10:23

Hi,

There are different ways to do this, one if load daily bars data and find the index of current day by using GetIndexByTime method of daily Bars.OpenTimes series and once you got the index you can query its high or low price levels via daily bars collection.

You can also do this without using the daily bars, you can set a specific time as day start time and then use a loop over your current chart bars to find the maximum high price and minimum low price, here is a complete indicator example:

using cAlgo.API;
using System;
using System.Globalization;
using System.Linq;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class DailyHighLowSample : Indicator
    {
        private readonly string _name = "Daily High Low";

        private string _chartObjectNamesSuffix;

        private int _lastBarIndex;

        private TimeSpan _dayStartTime;

        [Parameter("Use Bar Bodies", DefaultValue = false, Group = "General")]
        public bool UseBarBodies { get; set; }

        [Parameter("Day Start Time", DefaultValue = "00:00:00", Group = "General")]
        public string DayStartTime { get; set; }

        [Parameter("Days #", DefaultValue = 3, MinValue = 0, Group = "General")]
        public int DaysNumber { get; set; }

        [Parameter("Show", DefaultValue = true, Group = "Separator")]
        public bool ShowSeparatorLine { get; set; }

        [Parameter("Line Color", DefaultValue = "White", Group = "Separator")]
        public string SeparatorLineColor { get; set; }

        [Parameter("Line Style", DefaultValue = LineStyle.Dots, Group = "Separator")]
        public LineStyle SeparatorLineStyle { get; set; }

        [Parameter("Line Thickness", DefaultValue = 1, Group = "Separator")]
        public int SeparatorLineThickness { get; set; }

        [Output("High", LineColor = "Lime", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries High { get; set; }

        [Output("Low", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Low { get; set; }

        protected override void Initialize()
        {
            _chartObjectNamesSuffix = string.Format("{0}_{1}", _name, DateTime.Now.Ticks);

            if (!TimeSpan.TryParse(DayStartTime, CultureInfo.InvariantCulture, out _dayStartTime))
            {
                Print("Your provided value for 'Day Start Time' parameter is not valid");
            }

            Application.UserTimeOffsetChanged += Application_UserTimeOffsetChanged;
        }

        public override void Calculate(int index)
        {
            if (index == _lastBarIndex)
            {
                return;
            }

            _lastBarIndex = index;

            var currentBarTime = Bars.OpenTimes[index].Add(Application.UserTimeOffset);

            var dayStartTime = currentBarTime.TimeOfDay >= _dayStartTime ? currentBarTime.Date.Add(_dayStartTime) : currentBarTime.Date.AddDays(-1).Add(_dayStartTime);

            dayStartTime = dayStartTime.Add(-Application.UserTimeOffset);

            if (DaysNumber > 0)
            {
                var currentBarTimeDiffWithToday = Server.Time.Add(Application.UserTimeOffset) - dayStartTime;

                if (currentBarTimeDiffWithToday.TotalDays > DaysNumber)
                {
                    return;
                }
            }

            if (ShowSeparatorLine)
            {
                string separatorLineObjectName = string.Format("{0}_{1}", dayStartTime.ToString("o"), _chartObjectNamesSuffix);

                Chart.DrawVerticalLine(separatorLineObjectName, dayStartTime, Chart.ColorSettings.PeriodSeparatorColor, SeparatorLineThickness, SeparatorLineStyle);
            }

            var dayStartBarIndex = Bars.OpenTimes.GetIndexByTime(dayStartTime);

            var dayHigh = double.MinValue;
            var dayLow = double.MaxValue;

            for (var iBarIndex = dayStartBarIndex; iBarIndex <= index; iBarIndex++)
            {
                if (UseBarBodies)
                {
                    if (Bars[iBarIndex].Close > Bars[iBarIndex].Open)
                    {
                        dayHigh = Math.Max(Bars.ClosePrices[iBarIndex], dayHigh);
                        dayLow = Math.Min(Bars.OpenPrices[iBarIndex], dayLow);
                    }
                    else
                    {
                        dayHigh = Math.Max(Bars.OpenPrices[iBarIndex], dayHigh);
                        dayLow = Math.Min(Bars.ClosePrices[iBarIndex], dayLow);
                    }
                }
                else
                {
                    dayHigh = Math.Max(Bars.HighPrices[iBarIndex], dayHigh);
                    dayLow = Math.Min(Bars.LowPrices[iBarIndex], dayLow);
                }
            }

            High[index] = dayHigh;
            Low[index] = dayLow;
        }

        private void Application_UserTimeOffsetChanged(UserTimeOffsetChangedEventArgs obj)
        {
            if (ShowSeparatorLine)
            {
                var separatorLines = Chart.Objects.Where(iChartObject => iChartObject.Name.EndsWith(_chartObjectNamesSuffix, StringComparison.InvariantCultureIgnoreCase) && iChartObject.ObjectType == ChartObjectType.VerticalLine).ToArray();

                foreach (var separatorLine in separatorLines)
                {
                    Chart.RemoveObject(separatorLine.Name);
                }
            }

            _lastBarIndex = -1;

            for (var iBarIndex = 0; iBarIndex < Bars.Count; iBarIndex++)
            {
                High[iBarIndex] = double.NaN;
                Low[iBarIndex] = double.NaN;

                Calculate(iBarIndex);
            }
        }
    }
}

Increase the number of "Days #" parameter to show the high/low lines for more days, these two lines show the developing high/low levels of each day until the day ends.

If you check the API references you will be able to do this easily based on your needs.

If you can't do this by your self then post a job request or contact one of our consultants.


@amusleh