Construcción de un indicador a partir de otros indicadores

Para construir un indicador a partir de otro indicador, es necesario crear y calcular un indicador a partir del cual se realizará el cálculo y, a continuación, utilizar sus valores en los cálculos propios. Ejemplo de implementación del indicador 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;
    }
}

En este ejemplo hemos llamado a métodos Calculate para indicadores de terceros (EMA, SMA) para calcular estos indicadores y devolver valores de cada indicador para una barra específica.

Si desea calcular los indicadores utilizados en la misma fuente de entrada que el indicador desarrollado, puede añadirlos como indicadores "internos" a través del método Add en el constructor.

A continuación se muestra un ejemplo de un indicador MACD rediseñado donde los indicadores _long y _short se añaden como "internos" y los valores de los mismos se obtienen simplemente consultando los datos para una barra específica.

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

Si el indicador interno utilizado tiene varias series de datos, también se pueden utilizar en el indicador desarrollado.

Ejemplo de obtención de datos de la serie de datos Signal de un indicador MACD a partir de otro indicador.

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

Las series de datos de los indicadores utilizados pueden mostrarse en un indicador desarrollado. Para ello, las series de datos de los indicadores personalizados que se van a mostrar deben añadirse a la colección de series de datos del indicador actual.

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