How can I get all the indexes of a lower time frame that correspond, or are within a time range, to an index in a higher time frame?

Created at 22 Apr 2021, 08:47
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!
FI

firemyst

Joined 26.03.2019

How can I get all the indexes of a lower time frame that correspond, or are within a time range, to an index in a higher time frame?
22 Apr 2021, 08:47


How can I get all the indexes of a lower time frame that correspond, or are within a time range, to an index in a higher time frame?

For example, I have the first 5 indexes of a 2 minute time frame on a 1 minute chart.

They are 1, 2, 3, 4, 5 obviously.

I want to draw a symbol on the chart (1 minute) that corresponds to index 3 in the 2 minute time frame.

This would be indexes 5 & 6 on the 1 minute chart.

       Index #
M2: 1    2    3    4    5
M1: 1,2  3,4  5,6  7,8  9,10

Now suppose I want to draw a symbol on the chart (1 minute) that corresponds to index 4 in the 15 minute time frame.

How can I programmatically determine/obtain all the indexes on the 1 minute chart to draw the symbol that corresponds to index 4 in the M15 time frame?

 


@firemyst
Replies

amusleh
22 Apr 2021, 09:23

Hi,

Indices are not fixed, they can change, instead use bar open times.

If you want to get index of a bar on a different time frame you can use GetIndexByTime method of Bars.OpenTimes, check this sample indicator code:

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

namespace cAlgo
{
    [Cloud("Top", "Bottom", Opacity = 0.2)]
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BollingerBandsMTFCloudSample : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Source", DefaultValue = DataSeriesType.Close)]
        public DataSeriesType DataSeriesType { get; set; }

        [Parameter("Periods", DefaultValue = 14, MinValue = 0)]
        public int Periods { get; set; }

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

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

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

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

        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;
                default:

                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

 


@amusleh

firemyst
22 Apr 2021, 09:42 ( Updated at: 22 Apr 2021, 09:44 )

RE:

amusleh said:

Hi,

Indices are not fixed, they can change, instead use bar open times.

If you want to get index of a bar on a different time frame you can use GetIndexByTime method of Bars.OpenTimes, check this sample indicator code:

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

namespace cAlgo
{
    [Cloud("Top", "Bottom", Opacity = 0.2)]
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BollingerBandsMTFCloudSample : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Source", DefaultValue = DataSeriesType.Close)]
        public DataSeriesType DataSeriesType { get; set; }

        [Parameter("Periods", DefaultValue = 14, MinValue = 0)]
        public int Periods { get; set; }

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

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

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

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

        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;
                default:

                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

 

 

Thank you, but this doesn't help and doesn't work for what I need.

 

What your code is doing is getting the indexes of the bars in the faster time frame and mapping that to a single index to the bars in the slower time frame.

With your method, it's going from "many" to "one".

I need the opposite. I have 1 index in a higher time frame and need to map it to all the related indexes in the faster time frame.

I have "one" and need to map it to "many".

If you try doing the opposite:

Bars.OpenTimes.GetIndexByTime(_baseBars.OpenTimes[index]);

simply won't work because it will not return all the indexes related. That is, if _baseBars is M15, and the chart is M1, Bars.OpenTimes.GetindexByTime will only return 1 index, not the corresponding 15 indexes I need.

 


@firemyst

amusleh
22 Apr 2021, 10:04

Hi,

You can call Bars.OpenTimes.GetindexByTime two times with two indices, for example you call it first with index 5 and then 6, and it returns 10 for the first call and 20 for the second call, then you know from 10 to 20 belongs to first index.


@amusleh

firemyst
22 Apr 2021, 10:16 ( Updated at: 24 May 2022, 03:29 )

RE:

amusleh said:

Hi,

You can call Bars.OpenTimes.GetindexByTime two times with two indices, for example you call it first with index 5 and then 6, and it returns 10 for the first call and 20 for the second call, then you know from 10 to 20 belongs to first index.

Thank you!

That makes perfect sense!!

I appreciate your help!!


@firemyst