get vertical line index

Created at 23 Jul 2021, 07:17
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!
IR

IRCtrader

Joined 17.06.2021

get vertical line index
23 Jul 2021, 07:17


i try to draw rectable that start from vertical line. but i found vertical line give us time not candle index.

i want to draw rectangle that start from vertical line and long for period that user input .

so for other point i need to + or - user input to vertical line. 


@IRCtrader
Replies

amusleh
23 Jul 2021, 08:14

You can change the vertical line time to bar index by using Bars.OpenTimes.GetIndexByTime:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        protected override void OnStart()
        {
            var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.LastValue, Color.Red);

            // It only works if the vertical line is drawn on the past, if its drawn on future where there is no bar then it will not work
            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);
        }
    }
}

 


@amusleh

IRCtrader
23 Jul 2021, 09:24

RE:

amusleh said:

You can change the vertical line time to bar index by using Bars.OpenTimes.GetIndexByTime:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        protected override void OnStart()
        {
            var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.LastValue, Color.Red);

            // It only works if the vertical line is drawn on the past, if its drawn on future where there is no bar then it will not work
            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);
        }
    }
}

 

thanks

why in below code rectangle period calculate period from the last bat not in my period that start from vertical line..

 


            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(vl.Time);


            var rectangle = Chart.DrawRectangle("rectangle_sample", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            rectangle.IsFilled = true;
            rectangle.IsInteractive = true;
            rectangle.IsFilled = false;
            rectangle.Thickness = 3;

 


@IRCtrader

amusleh
23 Jul 2021, 10:19

Hi,

It's really hard to understand what you are after, the code works fine on my system:

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Test : Indicator
    {
        [Parameter(DefaultValue = 10)]
        public int Period { get; set; }

        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.Last(Period), Color.Red);

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);

            var rectangle = Chart.DrawRectangle("rectangle", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            rectangle.IsFilled = true;
            //rectangle.IsInteractive = true;
            rectangle.IsFilled = false;
            rectangle.Thickness = 3;
        }

        public override void Calculate(int index)
        {
        }
    }
}

 


@amusleh

IRCtrader
24 Jul 2021, 16:04

RE:

amusleh said:

Hi,

It's really hard to understand what you are after, the code works fine on my system:

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Test : Indicator
    {
        [Parameter(DefaultValue = 10)]
        public int Period { get; set; }

        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.Last(Period), Color.Red);

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);

            var rectangle = Chart.DrawRectangle("rectangle", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            rectangle.IsFilled = true;
            //rectangle.IsInteractive = true;
            rectangle.IsFilled = false;
            rectangle.Thickness = 3;
        }

        public override void Calculate(int index)
        {
        }
    }
}

 

 

thats my code . i want move box by vertical line. when i moved vertical line, box moved .

 

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWBoxOffline : Indicator
    {

        ChartVerticalLine vl;

        ChartRectangle box1;


        [Parameter("Period", DefaultValue = 26, MinValue = 1)]
        public int Period { get; set; }


        [Parameter("Line Color", DefaultValue = "Red", Group = "Line")]
        public string LineColor { get; set; }
        [Parameter("LineStyle", DefaultValue = LineStyle.LinesDots, Group = "Line")]
        public LineStyle ls { get; set; }
        [Parameter("Thickness", DefaultValue = 2, Group = "Line")]
        public int Thickness { get; set; }


        protected override void Initialize()
        {

            vl = Chart.DrawVerticalLine("scrollLine", Chart.LastVisibleBarIndex, Color.FromName(LineColor), Thickness, ls);
            vl.IsInteractive = true;





        }

        public override void Calculate(int index)
        {

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(vl.Time);


            var rectangle = Chart.DrawRectangle("rectangle_sample", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            rectangle.IsFilled = true;
            rectangle.IsInteractive = false;
            rectangle.IsFilled = false;
            rectangle.Thickness = 3;
        }






    }
}

 


@IRCtrader

amusleh
24 Jul 2021, 16:21

Hi,

Your code is not correct at all! you should use instead Chart ObjectsUpdated event:

using cAlgo.API;
using System.Linq;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWBoxOffline : Indicator
    {
        private ChartVerticalLine _vl;

        private ChartRectangle _box;

        [Parameter("Period", DefaultValue = 26, MinValue = 1)]
        public int Period { get; set; }

        [Parameter("Line Color", DefaultValue = "Red", Group = "Line")]
        public string LineColor { get; set; }

        [Parameter("LineStyle", DefaultValue = LineStyle.LinesDots, Group = "Line")]
        public LineStyle ls { get; set; }

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

        protected override void Initialize()
        {
            _vl = Chart.DrawVerticalLine("scrollLine", Chart.LastVisibleBarIndex, Color.FromName(LineColor), Thickness, ls);
            _vl.IsInteractive = true;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box = Chart.DrawRectangle("rectangle_sample", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            _box.IsFilled = true;
            _box.IsInteractive = false;
            _box.IsFilled = false;
            _box.Thickness = 3;

            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
        }

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj)
        {
            if (!obj.ChartObjects.Contains(_vl)) return;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box.Time1 = Bars.OpenTimes[verticalLineBarIndex];
            _box.Time2 = Bars.OpenTimes[verticalLineBarIndex - Period];
        }

        public override void Calculate(int index)
        {
        }
    }
}

The above code only works for past bars, not future, the best way is to use Time instead of Bars index.

 


@amusleh

IRCtrader
24 Jul 2021, 21:05 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

Your code is not correct at all! you should use instead Chart ObjectsUpdated event:

using cAlgo.API;
using System.Linq;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWBoxOffline : Indicator
    {
        private ChartVerticalLine _vl;

        private ChartRectangle _box;

        [Parameter("Period", DefaultValue = 26, MinValue = 1)]
        public int Period { get; set; }

        [Parameter("Line Color", DefaultValue = "Red", Group = "Line")]
        public string LineColor { get; set; }

        [Parameter("LineStyle", DefaultValue = LineStyle.LinesDots, Group = "Line")]
        public LineStyle ls { get; set; }

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

        protected override void Initialize()
        {
            _vl = Chart.DrawVerticalLine("scrollLine", Chart.LastVisibleBarIndex, Color.FromName(LineColor), Thickness, ls);
            _vl.IsInteractive = true;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box = Chart.DrawRectangle("rectangle_sample", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            _box.IsFilled = true;
            _box.IsInteractive = false;
            _box.IsFilled = false;
            _box.Thickness = 3;

            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
        }

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj)
        {
            if (!obj.ChartObjects.Contains(_vl)) return;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box.Time1 = Bars.OpenTimes[verticalLineBarIndex];
            _box.Time2 = Bars.OpenTimes[verticalLineBarIndex - Period];
        }

        public override void Calculate(int index)
        {
        }
    }
}

The above code only works for past bars, not future, the best way is to use Time instead of Bars index.

 

thanks for your help. it's has one problem in high and low box.

it calculate for end of chart not from the current priod that end to vertical line..


@IRCtrader

amusleh
26 Jul 2021, 08:41

Hi,

Try this:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AWBoxOffline : Indicator
    {
        private ChartVerticalLine _vl;

        private ChartRectangle _box;

        [Parameter("Period", DefaultValue = 26, MinValue = 1)]
        public int Period { get; set; }

        [Parameter("Line Color", DefaultValue = "Red", Group = "Line")]
        public string LineColor { get; set; }

        [Parameter("LineStyle", DefaultValue = LineStyle.LinesDots, Group = "Line")]
        public LineStyle ls { get; set; }

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

        protected override void Initialize()
        {
            _vl = Chart.DrawVerticalLine("scrollLine", Chart.LastVisibleBarIndex, Color.FromName(LineColor), Thickness, ls);
            _vl.IsInteractive = true;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box = Chart.DrawRectangle("rectangle_sample", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
            _box.IsFilled = true;
            _box.IsInteractive = false;
            _box.IsFilled = false;
            _box.Thickness = 3;

            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
        }

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj)
        {
            if (!obj.ChartObjects.Contains(_vl)) return;

            var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(_vl.Time);

            _box.Time1 = Bars.OpenTimes[verticalLineBarIndex];
            _box.Time2 = Bars.OpenTimes[verticalLineBarIndex - Period];

            _box.Y1 = GetMinimum(Bars.LowPrices, verticalLineBarIndex, Period);
            _box.Y2 = GetMaximum(Bars.HighPrices, verticalLineBarIndex, Period);
        }

        private double GetMinimum(DataSeries source, int index, int periods)
        {
            double min = double.MaxValue;

            var lastBarIndex = index - periods;

            for (int i = index; i > lastBarIndex; i--)
            {
                min = Math.Min(min, source[i]);
            }

            return min;
        }

        private double GetMaximum(DataSeries source, int index, int periods)
        {
            double max = double.MinValue;

            var lastBarIndex = index - periods;

            for (int i = index; i > lastBarIndex; i--)
            {
                max = Math.Max(max, source[i]);
            }

            return max;
        }

        public override void Calculate(int index)
        {
        }
    }
}

 


@amusleh