MTF indicator only showing correct value in matching timeframe

Created at 10 May 2020, 17:07
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!
2bnnp's avatar

2bnnp

Joined 12.02.2019

MTF indicator only showing correct value in matching timeframe
10 May 2020, 17:07


I am trying to create an indicator which will check for other the hull slope of other timeframes and print them like on the screenshot below. The output is correct if the chart timeframe matches with the selected timeframe in the indicator.

If i choose another timeframe, it either shows nothing or just a green line.
 

here is the code i am currently working on:

 

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

namespace cAlgo.Indicators
{
    [Indicator(AccessRights = AccessRights.None)]
    public class HullTrendMtf : Indicator
    {
        [Parameter("Timeframe #1", DefaultValue = "Hour")]
        public TimeFrame TimeFrameOne { get; set; }

        [Parameter("Timeframe #2", DefaultValue = "Hour4")]
        public TimeFrame TimeFrameTwo { get; set; }

        [Parameter("Timeframe #3", DefaultValue = "Daily")]
        public TimeFrame TimeFrameThree { get; set; }

        [Parameter("HULL #1 Period", DefaultValue = 21)]
        public int HullPeriodFast { get; set; }

        [Parameter("HULL #2 Period", DefaultValue = 55)]
        public int HullPeriodSlow { get; set; }

        #region outputs

        //outputs up

        [Output("Hull #1 Tf #1 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfOneUp { get; set; }

        [Output("Hull #1 Tf #2 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfTwoUp { get; set; }

        [Output("Hull #1 Tf #3 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfThreeUp { get; set; }

        [Output("Hull #2 Tf #1 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfOneUp { get; set; }

        [Output("Hull #2 Tf #2 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfTwoUp { get; set; }

        [Output("Hull #2 Tf #3 Up", Color = Colors.Lime, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfThreeUp { get; set; }

        //outputs down

        [Output("Hull #1 Tf #1 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfOneDown { get; set; }

        [Output("Hull #1 Tf #2 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfTwoDown { get; set; }

        [Output("Hull #1 Tf #3 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullOneTfThreeDown { get; set; }

        [Output("Hull #2 Tf #1 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfOneDown { get; set; }

        [Output("Hull #2 Tf #2 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfTwoDown { get; set; }

        [Output("Hull #2 Tf #3 Down", Color = Colors.Red, Thickness = 5, PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries HullTwoTfThreeDown { get; set; }

        #endregion outputs

        private HullMovingAverage _hullFastTimeFrameOne;
        private HullMovingAverage _hullFastTimeFrameTwo;
        private HullMovingAverage _hullFastTimeFrameThree;
        private HullMovingAverage _hullSlowTimeFrameOne;
        private HullMovingAverage _hullSlowTimeFrameTwo;
        private HullMovingAverage _hullSlowTimeFrameThree;

        private Bars SeriesTimeFrameOne;
        private Bars SeriesTimeFrameTwo;
        private Bars SeriesTimeFrameThree;

        private IndicatorDataSeries series5;

        protected override void Initialize()
        {
            series5 = CreateDataSeries();

            SeriesTimeFrameOne = MarketData.GetBars(TimeFrameOne);
            SeriesTimeFrameTwo = MarketData.GetBars(TimeFrameTwo);
            SeriesTimeFrameThree = MarketData.GetBars(TimeFrameThree);

            _hullFastTimeFrameOne = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameOne.ClosePrices, HullPeriodFast);
            _hullFastTimeFrameTwo = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameTwo.ClosePrices, HullPeriodFast);
            _hullFastTimeFrameThree = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameThree.ClosePrices, HullPeriodFast);

            _hullSlowTimeFrameOne = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameOne.ClosePrices, HullPeriodSlow);
            _hullSlowTimeFrameTwo = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameTwo.ClosePrices, HullPeriodSlow);
            _hullSlowTimeFrameThree = Indicators.GetIndicator<HullMovingAverage>(SeriesTimeFrameThree.ClosePrices, HullPeriodSlow);
        }

        public override void Calculate(int index)
        {
            var index5 = GetIndexByDate(SeriesTimeFrameOne, Bars.OpenTimes[index]);
            if (index5 != -1)
            {
                series5[index] = 5;

                if (_hullFastTimeFrameOne.Result.IsFalling())
                {
                    HullOneTfOneDown[index - 1] = series5[index5];
                    HullOneTfOneDown[index] = series5[index5];
                    HullOneTfOneUp[index] = double.NaN;
                }
                else if (_hullFastTimeFrameOne.Result.IsRising())
                {
                    HullOneTfOneUp[index - 1] = series5[index5];
                    HullOneTfOneUp[index] = series5[index5];
                    HullOneTfOneDown[index] = double.NaN;
                }
            }
        }

        private int GetIndexByDate(Bars series, DateTime time)
        {
            for (int i = series.ClosePrices.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTimes[i])
                    return i;
            }
            return -1;
        }
    }
}

 


@2bnnp
Replies

PanagiotisCharalampous
11 May 2020, 08:40

Hi 2bnnp,

When you get bars from other timeframes on indicator initialization, then the complete data until the current moment is loaded. So when you feed this data to an indicator, the indicator contains values up to the last candlestick. Therefore IsFalling()  and IsRising() will always display the same value since indicator series data does not change. To fix this you should replace the IsFalling() and IsRising() with an actual comparison of the two previous values of the indicator at the current index.

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

2bnnp
11 May 2020, 11:46

yes thanks. just after thinking about it like you explained it actually does make more sense.

heres the code i changed for anyone else wondering:


            var index5 = SeriesTimeFrameOne.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            if (index5 != -1)
            {
                if (_hullFastTimeFrameOne.Result[index5] < _hullFastTimeFrameOne.Result[index5 - 1])
                {
                    FastTimeFrameOneDown[index - 1] = 5;
                    FastTimeFrameOneDown[index] = 5;
                    FastTimeFrameOneUp[index] = double.NaN;
                }
                else if (_hullFastTimeFrameOne.Result[index5] > _hullFastTimeFrameOne.Result[index5 - 1])
                {
                    FastTimeFrameOneUp[index - 1] = 5;
                    FastTimeFrameOneUp[index] = 5;
                    FastTimeFrameOneDown[index] = double.NaN;
                }
            }

 


@2bnnp