Построение индикатора на основе других индикаторов

Для построения индикатора на основе другого необходимо создать и рассчитать индикатор, на основе которого будет производиться расчет, после чего использовать его значения в собственных расчетах. Пример реализации индикатора MACD

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;
    }
}

В это примере для сторонних индикаторов(EMA,SMA) вызывались методы Calculate, которые обсчитывали эти индикаторы и возвращали значения каждого индикатора для конкретного бара.

Если используемые индикаторы должны рассчитываться на том же входном источнике, что и разрабатываемый индикатор, их можно просто добавить как "внутренние" через метод Add в конструкторе.

Ниже пример переделанного MACD индикатора, где _long и _short индикаторы добавляются как "внутренние" и значения из них получается просто путем запроса данных для конкретного бара.

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;
        }
    }

Если используемый внутренний индикатор имеет несколько датасерий, их тоже можно использовать в разрабатываемом индикаторе.

Пример получения данных у Signal датасерии индикатора MACD из другого индикатора

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;
        }
    }

Датасерии используемых индикаторов можно отображать в разрабатываемом. Для этого к коллекции датасерий текущего индикатора нужно добавить датасерии из используемых индикаторов, которые надо отобразить.

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)
        {
        }
    }

Сервис поддержки клиентов работает на платформе UserEcho