Most pragmatic code for converging/diverging indicators

Created at 13 Apr 2022, 22:25
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!
PR

Prospect

Joined 21.03.2014

Most pragmatic code for converging/diverging indicators
13 Apr 2022, 22:25


Would someone be so kind as to point me in the direction of some sample code?

I would just like to have a play with a framework to establish whether indicators are converging or diverging. For example, if the difference between EMA1 and EMA2 (or whatever) is growing or shrinking over the last n indexes.

Thanks.


@Prospect
Replies

Prospect
14 Apr 2022, 09:24

RE:

I can find lots of references for when indicators have crossed, but nothing for when they're starting to converge and therefore might cross, or conversely when they start diverging. I have no idea whether this is actually useful, but it's a decent learning exercise. 

So for example, if you have MA's for two different periods, is it as simple as creating a new data series or array to contain the differences between the MA's, then looping through the last n indexes to see if the values are progressively bigger/smaller? 

 


@Prospect

amusleh
14 Apr 2022, 09:55

Hi,

The convergence and divergence are two very broad topics and subjective.

But I will give you an example that might help you:

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

namespace cAlgo.Indicators

{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private MovingAverage _fastMa, _slowMa;

        [Parameter("Convergence", DefaultValue = 10, Group = "Thresholds (Pips)")]
        public double ConvergenceThresholds { get; set; }

        [Parameter("Divergence", DefaultValue = 20, Group = "Thresholds (Pips)")]
        public double DivergenceThresholds { get; set; }

        [Parameter("Periods", DefaultValue = 10, Group = "Fast MA")]
        public int FastMaPeriods { get; set; }

        [Parameter("Source", Group = "Fast MA")]
        public DataSeries FastMaSource { get; set; }

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

        [Parameter("Periods", DefaultValue = 20, Group = "Slow MA")]
        public int SlowMaPeriods { get; set; }

        [Parameter("Source", Group = "Slow MA")]
        public DataSeries SlowMaSource { get; set; }

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

        [Output("Convergence", LineColor = "Green", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Convergence { get; set; }

        [Output("Divergence", LineColor = "Red", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Divergence { get; set; }

        [Output("Normal", LineColor = "Yellow", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Normal { get; set; }

        protected override void Initialize()
        {
            _fastMa = Indicators.MovingAverage(FastMaSource, FastMaPeriods, FastMaType);
            _slowMa = Indicators.MovingAverage(SlowMaSource, SlowMaPeriods, SlowMaType);

            ConvergenceThresholds *= Symbol.PipSize;
            DivergenceThresholds *= Symbol.PipSize;
        }

        public override void Calculate(int index)
        {
            var distance = _fastMa.Result[index] - _slowMa.Result[index];
            var distanceAbs = Math.Abs(distance);

            Convergence[index] = double.NaN;
            Divergence[index] = double.NaN;
            Normal[index] = double.NaN;

            if (distanceAbs <= ConvergenceThresholds)
            {
                Convergence[index] = distance;
            }
            else if (distanceAbs >= DivergenceThresholds)
            {
                Divergence[index] = distance;
            }
            else
            {
                Normal[index] = distance;
            }
        }
    }
}

 


@amusleh

Prospect
14 Apr 2022, 12:42

RE:

amusleh said:

Hi,

The convergence and divergence are two very broad topics and subjective.

But I will give you an example that might help you:

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

namespace cAlgo.Indicators

{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private MovingAverage _fastMa, _slowMa;

        [Parameter("Convergence", DefaultValue = 10, Group = "Thresholds (Pips)")]
        public double ConvergenceThresholds { get; set; }

        [Parameter("Divergence", DefaultValue = 20, Group = "Thresholds (Pips)")]
        public double DivergenceThresholds { get; set; }

        [Parameter("Periods", DefaultValue = 10, Group = "Fast MA")]
        public int FastMaPeriods { get; set; }

        [Parameter("Source", Group = "Fast MA")]
        public DataSeries FastMaSource { get; set; }

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

        [Parameter("Periods", DefaultValue = 20, Group = "Slow MA")]
        public int SlowMaPeriods { get; set; }

        [Parameter("Source", Group = "Slow MA")]
        public DataSeries SlowMaSource { get; set; }

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

        [Output("Convergence", LineColor = "Green", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Convergence { get; set; }

        [Output("Divergence", LineColor = "Red", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Divergence { get; set; }

        [Output("Normal", LineColor = "Yellow", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Normal { get; set; }

        protected override void Initialize()
        {
            _fastMa = Indicators.MovingAverage(FastMaSource, FastMaPeriods, FastMaType);
            _slowMa = Indicators.MovingAverage(SlowMaSource, SlowMaPeriods, SlowMaType);

            ConvergenceThresholds *= Symbol.PipSize;
            DivergenceThresholds *= Symbol.PipSize;
        }

        public override void Calculate(int index)
        {
            var distance = _fastMa.Result[index] - _slowMa.Result[index];
            var distanceAbs = Math.Abs(distance);

            Convergence[index] = double.NaN;
            Divergence[index] = double.NaN;
            Normal[index] = double.NaN;

            if (distanceAbs <= ConvergenceThresholds)
            {
                Convergence[index] = distance;
            }
            else if (distanceAbs >= DivergenceThresholds)
            {
                Divergence[index] = distance;
            }
            else
            {
                Normal[index] = distance;
            }
        }
    }
}

 

Thanks, there's some stuff in there I can research further/work with!


@Prospect