Nested indicator isn't giving same chart as coded nested indicator. Why?

Created at 22 Feb 2020, 10:26
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

Nested indicator isn't giving same chart as coded nested indicator. Why?
22 Feb 2020, 10:26


Hi everyone:

See below screen capture and code. As a learning exercise, I'm trying to code the OnBalanceVolume indicator to use an EMA (13) as a source.

However, the lines differ and I don't know why.

Would anyone be able to help?

Here is the code:

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

namespace cAlgo
{
    [Indicator("OBV x MA Crossover", IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class OnBalanceVolumexMACrossover : Indicator
    {
        [Parameter("MA Short Period", Group = "Moving Averages", DefaultValue = 13, MinValue = 1)]
        public int MAXOverShortPeriod { get; set; }
        [Parameter("MA SP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverShortPeriodType { get; set; }
        [Parameter("MA Long Period", Group = "Moving Averages", DefaultValue = 48, MinValue = 2)]
        public int MAXOverLongPeriod { get; set; }
        [Parameter("MA LP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverLongPeriodType { get; set; }

        [Output("MA OBV Short", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvShort { get; set; }
        [Output("MA OBV Long", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvLong { get; set; }
        [Output("OBV", LineColor = "Cyan", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries ResultObv { get; set; }

        private OnBalanceVolume _onBalanceVolume;
        private OnBalanceVolume _onBalanceVolumeMaLong;
        private OnBalanceVolume _onBalanceVolumeMaShort;
        private MovingAverage _maLong;
        private MovingAverage _maShort;

        private IndicatorDataSeries _longIDS;
        private IndicatorDataSeries _shortIDS;

        private Bars _marketSeries;

        protected override void Initialize()
        {
            // Initialize and create nested indicators
            _marketSeries = MarketData.GetBars(Bars.TimeFrame, SymbolName);
            _onBalanceVolume = Indicators.OnBalanceVolume(_marketSeries.ClosePrices);

            _longIDS = CreateDataSeries();
            _shortIDS = CreateDataSeries();
            
            //_maLong = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverLongPeriod, MAXOverLongPeriodType);
            //_maShort = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverShortPeriod, MAXOverShortPeriodType);
            _maLong = Indicators.MovingAverage(_longIDS, MAXOverLongPeriod, MAXOverLongPeriodType);
            _maShort = Indicators.MovingAverage(_shortIDS, MAXOverShortPeriod, MAXOverShortPeriodType);

            //_onBalanceVolumeMaLong = Indicators.OnBalanceVolume(_maLong.Result);
            //_onBalanceVolumeMaShort = Indicators.OnBalanceVolume(_maShort.Result);
            _onBalanceVolumeMaLong = Indicators.OnBalanceVolume(_marketSeries.ClosePrices);
            _onBalanceVolumeMaShort = Indicators.OnBalanceVolume(_marketSeries.ClosePrices);

        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            ResultObv[index] = _onBalanceVolume.Result[index];

            //_maLongIDS[index] = _maLong.Result[index];
            //_maShortIDS[index] = _maShort.Result[index];
            _longIDS[index] = _onBalanceVolumeMaLong.Result[index];
            _shortIDS[index] = _onBalanceVolumeMaShort.Result[index];

            //ResultMaObvLong[index] = _onBalanceVolumeMaLong.Result[index];
            //ResultMaObvShort[index] = _onBalanceVolumeMaShort.Result[index];
            ResultMaObvLong[index] = _maLong.Result[index];
            ResultMaObvShort[index] = _maShort.Result[index];
        }
    }
}

 

 


@firemyst
Replies

PanagiotisCharalampous
24 Feb 2020, 10:00

Hi firemyst,

I am not sure what are you trying to do with your source code but I tried the below and seems ok

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

namespace cAlgo
{
    [Indicator("OBV x MA Crossover", IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class OnBalanceVolumexMACrossover : Indicator
    {
        [Parameter("MA Short Period", Group = "Moving Averages", DefaultValue = 13, MinValue = 1)]
        public int MAXOverShortPeriod { get; set; }
        [Parameter("MA SP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverShortPeriodType { get; set; }
        [Parameter("MA Long Period", Group = "Moving Averages", DefaultValue = 48, MinValue = 2)]
        public int MAXOverLongPeriod { get; set; }
        [Parameter("MA LP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverLongPeriodType { get; set; }

        [Output("MA OBV Short", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvShort { get; set; }
        [Output("MA OBV Long", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvLong { get; set; }
        [Output("OBV", LineColor = "Cyan", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries ResultObv { get; set; }

        private OnBalanceVolume _onBalanceVolume;
        private OnBalanceVolume _onBalanceVolumeMaLong;
        private OnBalanceVolume _onBalanceVolumeMaShort;
        private MovingAverage _maLong;
        private MovingAverage _maShort;

        private IndicatorDataSeries _longIDS;
        private IndicatorDataSeries _shortIDS;

        private Bars _marketSeries;

        protected override void Initialize()
        {
            // Initialize and create nested indicators
            _marketSeries = MarketData.GetBars(Bars.TimeFrame, SymbolName);
            _maLong = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverLongPeriod, MAXOverLongPeriodType);
            _maShort = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverShortPeriod, MAXOverShortPeriodType);

            _onBalanceVolumeMaLong = Indicators.OnBalanceVolume(_maLong.Result);
            _onBalanceVolumeMaShort = Indicators.OnBalanceVolume(_maShort.Result);

        }

        public override void Calculate(int index)
        {
            ResultMaObvLong[index] = _onBalanceVolumeMaLong.Result[index];
            ResultMaObvShort[index] = _onBalanceVolumeMaShort.Result[index];
        }
    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

firemyst
24 Feb 2020, 10:27

RE:

PanagiotisCharalampous said:

Hi firemyst,

I am not sure what are you trying to do with your source code but I tried the below and seems ok

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

namespace cAlgo
{
    [Indicator("OBV x MA Crossover", IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class OnBalanceVolumexMACrossover : Indicator
    {
        [Parameter("MA Short Period", Group = "Moving Averages", DefaultValue = 13, MinValue = 1)]
        public int MAXOverShortPeriod { get; set; }
        [Parameter("MA SP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverShortPeriodType { get; set; }
        [Parameter("MA Long Period", Group = "Moving Averages", DefaultValue = 48, MinValue = 2)]
        public int MAXOverLongPeriod { get; set; }
        [Parameter("MA LP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverLongPeriodType { get; set; }

        [Output("MA OBV Short", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvShort { get; set; }
        [Output("MA OBV Long", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvLong { get; set; }
        [Output("OBV", LineColor = "Cyan", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries ResultObv { get; set; }

        private OnBalanceVolume _onBalanceVolume;
        private OnBalanceVolume _onBalanceVolumeMaLong;
        private OnBalanceVolume _onBalanceVolumeMaShort;
        private MovingAverage _maLong;
        private MovingAverage _maShort;

        private IndicatorDataSeries _longIDS;
        private IndicatorDataSeries _shortIDS;

        private Bars _marketSeries;

        protected override void Initialize()
        {
            // Initialize and create nested indicators
            _marketSeries = MarketData.GetBars(Bars.TimeFrame, SymbolName);
            _maLong = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverLongPeriod, MAXOverLongPeriodType);
            _maShort = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverShortPeriod, MAXOverShortPeriodType);

            _onBalanceVolumeMaLong = Indicators.OnBalanceVolume(_maLong.Result);
            _onBalanceVolumeMaShort = Indicators.OnBalanceVolume(_maShort.Result);

        }

        public override void Calculate(int index)
        {
            ResultMaObvLong[index] = _onBalanceVolumeMaLong.Result[index];
            ResultMaObvShort[index] = _onBalanceVolumeMaShort.Result[index];
        }
    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 

HI @Panagiotis:

I was trying to graph the OnBalanceVolume in the same indicator area with 1 or two moving averages, with:

1) one line showing the OnBalanceVolume with closing prices

2) the other two lines showing the OnBalanceVolume with the source as the selected MA types and periods from the input parameters. In this case, one OBV with a source of 13 EMA and the second OBV using a source of 48 EMA. I want to be able to set these programmatically without having to use a source parameter, because using a source parameter requires the actual MA to be placed on the chart as far as I can tell.

 

Your modified code doesn't do that.

Thank you.


@firemyst

PanagiotisCharalampous
24 Feb 2020, 11:25

Hi firemyst,

My code demonstrates how to display On Balance Volume using custom moving averages. Isn't there were your problem was? I cannot reproduce your problem.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

firemyst
24 Feb 2020, 15:09 ( Updated at: 21 Dec 2023, 09:21 )

RE:

PanagiotisCharalampous said:

Hi firemyst,

My code demonstrates how to display On Balance Volume using custom moving averages. Isn't there were your problem was? I cannot reproduce your problem.

Best Regards,

Panagiotis 

Join us on Telegram

HI @Panagiotis:

My problem appears to be I wasn't paying attention to the scale on the right of the chart, which is why the lines weren't matching up exactly.

 

DUH! I hate it when that happens.

Thank you for your assistance and patience as always. :-)


@firemyst

caputojr
05 Apr 2021, 07:06

RE:

PanagiotisCharalampous said:

Hi firemyst,

I am not sure what are you trying to do with your source code but I tried the below and seems ok

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

namespace cAlgo
{
    [Indicator("OBV x MA Crossover", IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class OnBalanceVolumexMACrossover : Indicator
    {
        [Parameter("MA Short Period", Group = "Moving Averages", DefaultValue = 13, MinValue = 1)]
        public int MAXOverShortPeriod { get; set; }
        [Parameter("MA SP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverShortPeriodType { get; set; }
        [Parameter("MA Long Period", Group = "Moving Averages", DefaultValue = 48, MinValue = 2)]
        public int MAXOverLongPeriod { get; set; }
        [Parameter("MA LP Type", Group = "Moving Averages", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAXOverLongPeriodType { get; set; }

        [Output("MA OBV Short", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvShort { get; set; }
        [Output("MA OBV Long", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
        public IndicatorDataSeries ResultMaObvLong { get; set; }
        [Output("OBV", LineColor = "Cyan", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries ResultObv { get; set; }

        private OnBalanceVolume _onBalanceVolume;
        private OnBalanceVolume _onBalanceVolumeMaLong;
        private OnBalanceVolume _onBalanceVolumeMaShort;
        private MovingAverage _maLong;
        private MovingAverage _maShort;

        private IndicatorDataSeries _longIDS;
        private IndicatorDataSeries _shortIDS;

        private Bars _marketSeries;

        protected override void Initialize()
        {
            // Initialize and create nested indicators
            _marketSeries = MarketData.GetBars(Bars.TimeFrame, SymbolName);
            _maLong = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverLongPeriod, MAXOverLongPeriodType);
            _maShort = Indicators.MovingAverage(_marketSeries.ClosePrices, MAXOverShortPeriod, MAXOverShortPeriodType);

            _onBalanceVolumeMaLong = Indicators.OnBalanceVolume(_maLong.Result);
            _onBalanceVolumeMaShort = Indicators.OnBalanceVolume(_maShort.Result);

        }

        public override void Calculate(int index)
        {
            ResultMaObvLong[index] = _onBalanceVolumeMaLong.Result[index];
            ResultMaObvShort[index] = _onBalanceVolumeMaShort.Result[index];
        }
    }
}

Best Regards,

Panagiotis 

Join us on Telegram

 

 

Hi Panagiotis,

I have tried to impement (copy and paste the code) to a new indicator and it is showing only the MAs, not the OBV. Is there somethng I can do to fix it?

 

Thank you in advance.


@caputojr

PanagiotisCharalampous
05 Apr 2021, 08:12

Hi caputojr,

I am not sure what do you mean. Can you share some screenshots?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

caputojr
21 Jun 2023, 17:42 ( Updated at: 21 Dec 2023, 09:23 )

RE:

PanagiotisCharalampous said:

Hi caputojr,

I am not sure what do you mean. Can you share some screenshots?

Best Regards,

Panagiotis 

Join us on Telegram

Hi Panagiotis,

Sorry the delay and that I was not clear on my question. I have copy and paste in a new indicator, which showed 4 warnings, but with no success on painting the OBV with the MAs, please see some screenshots I have attached.

 

 

I have double clicked the indicator scale in order to have it showed back but with no luck. 

Thank you in advance.


@caputojr