Building an indicator on the basis of other indicators

In order to build an indicator on the basis of another one, it is necessary to develop and calculate the indicator, on the basis of which a calculation would be carried out, after which its value will be used in its own calculations. Example of realization of the MACD indicator:

public class MACD : Indicator
{
    private readonly EMA _long = new EMA();
    private readonly EMA _short = new EMA();
    private readonly SMA _sma = new SMA();
    public int LongPeriod
    {
        get { return _long.Period; }
        set
        {
            if (value <= 0)
                return;
            _long.Period = value;
            RecalculateValues();
        }
    }
    public int ShortPeriod
    {
        get { return _short.Period; }
        set
        {
            if (value <= 0)
                return;
            _short.Period = value;
            RecalculateValues();
        }
    }
    public int SignalPeriod
    {
        get { return _sma.Period; }
        set
        {
            if (value <= 0)
                return;
            _sma.Period = value;
            RecalculateValues();
        }
    }
    public MACD()
    {
        Panel = IndicatorDataProvider.NewPanel;
        ((ValueDataSeries)DataSeries[0]).VisualType = VisualMode.Histogram;
        ((ValueDataSeries)DataSeries[0]).Color = Colors.CadetBlue;
        DataSeries.Add(new ValueDataSeries("Signal")
        {
            VisualType = VisualMode.Line,
            LineDashStyle = LineDashStyle.Dash
        });
        LongPeriod = 26;
        ShortPeriod = 12;
        SignalPeriod = 9;
    }
    protected override void OnCalculate(int bar, decimal value)
    {
        var macd =_short.Calculate(bar, value) - _long.Calculate(bar, value);
        var signal = _sma.Calculate(bar, macd);
        this[bar] = macd;
        DataSeries[1][bar] = signal;
    }
}

The Calculate methods, which calculated these indicators and returned values of each indicator for a specific bar, were called in this example for third-party indicators (EMA, SMA, etc.).

If the used indicators should be calculated at the same incoming source as the developed indicator, they could be just added as ‘internal ones’ through the Add method in the constructor.

Below is an example of the altered MACD indicator where the _long and _short indicators are added as ‘internal ones’ and their values are received just through the data request for a specific bar.

.

public class MACD : Indicator
    {
        private readonly EMA _long = new EMA();
        private readonly EMA _short = new EMA();
        private readonly SMA _sma = new SMA();

        public MACD()
        {
            Panel = IndicatorDataProvider.NewPanel;

            ((ValueDataSeries)DataSeries[0]).VisualType = VisualMode.Histogram;
            ((ValueDataSeries)DataSeries[0]).Color = Colors.CadetBlue;

            DataSeries.Add(new ValueDataSeries("Signal")
            {
                VisualType = VisualMode.Line,
                LineDashStyle = LineDashStyle.Dash
            });

            LongPeriod = 26;
            ShortPeriod = 12;
            SignalPeriod = 9;

            Add(_short);
            Add(_long);
        }

        protected override void OnCalculate(int bar, decimal value)
        {
            var macd = _short[bar] - _long[bar];
            var signal = _sma.Calculate(bar, macd);

            this[bar] = macd;
            DataSeries[1][bar] = signal;
        }
    }

If a used internal indicator has several DataSeries, they also could be used in the developed indicator.

Example of receiving the data from the Signal DataSeries of the MACD indicator from another indicator:

public class SampleIndicator : Indicator
    {
        private readonly MACD _macd=new MACD();

        public SampleIndicator()
        {
            Add(_macd);
        }

        protected override void OnCalculate(int bar, decimal value)
        {
            var macdSignalSeries = (ValueDataSeries)_macd.DataSeries[1];
            var macdSignal = macdSignalSeries[bar];

            this[bar] = macdSignal * 2;
        }
    }

DataSeries of the used indicators could be displayed in the developed indicator. For this, the DataSeries from the used indicators, which should be displayed, should be added to the collection of DataSeries of the current indicator.

public class SampleIndicator : Indicator
    {
        private readonly MACD _macd=new MACD();

        public SampleIndicator()
        {
            Add(_macd);
            DataSeries.Add(_macd.DataSeries[1]);
        }

        protected override void OnCalculate(int bar, decimal value)
        {
        }
    }

This article was helpful for 1 person. Is this article helpful for you?