Построение индикатора на основе других индикаторов
Для построения индикатора на основе другого необходимо создать и рассчитать индикатор, на основе которого будет производиться расчет, после чего использовать его значения в собственных расчетах. Пример реализации индикатора 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