Индикатор с несколькими вычислениями
using System.Collections.Generic;
using System.ComponentModel;
using TSLab.Script.Handlers;
using TSLab.Script.Helpers;
namespace MyLib
{
[HandlerCategory("MyLib")]
[HandlerName("MyBollinger")]
[Description("Рассчитывает верхнюю, нижнюю линию или ширину боллинжера")]
[InputsCount(1)]
[Input(0, TemplateTypes.DOUBLE)]
[OutputsCount(1)]
[OutputType(TemplateTypes.DOUBLE)]
public class MyBollinger : IStreamHandler, IContextUses, INeedVariableParentNames
{
public enum MyBollingerType
{
Top,
Bottom,
Width
}
[HandlerParameter(true, "20", Min = "1", Max = "100", Step = "1")]
public int Period { get; set; }
[HandlerParameter(true, "2", Min = "1", Max = "4", Step = "0.1")]
public double Coef { get; set; }
[HandlerParameter(true, nameof(MyBollingerType.Top))]
public MyBollingerType Type { get; set; }
public IContext Context { get; set; }
/// <summary>
/// Тут будет список наименований родительских блоков с параметрами. В виде строки.
/// Нужно для правильного кеширования индикаторов SMA и StDev.
/// </summary>
public string VariableParentNames { get; set; }
public IList<double> Execute(IList<double> values)
{
// Получить скользящую среднюю (SMA)
var sma = Context.GetData("SMA", new[] { VariableParentNames, Period.ToString() },
() => GetSma(Context, values, Period));
// Получить стандартное отклонение (StDev)
var stdev = Context.GetData("StDev", new[] { VariableParentNames, Period.ToString() },
() => GetStDev(Context, values, Period));
var array = Context.GetArray<double>(values.Count);
switch (Type)
{
case MyBollingerType.Top:
// Если считаем верхнюю линию боллинжера, то складываем: SMA + StDev * Coef.
for (int i = 0; i < values.Count; i++)
array[i] = sma[i] + stdev[i] * Coef;
break;
case MyBollingerType.Bottom:
// Если считаем нижнюю линию боллинжера, то вычитаем: SMA - StDev * Coef.
for (int i = 0; i < values.Count; i++)
array[i] = sma[i] - stdev[i] * Coef;
break;
case MyBollingerType.Width:
// Если считаем ширину канала, то из верхней линии боллинжера вычитаем нижнюю.
for (int i = 0; i < values.Count; i++)
array[i] = (sma[i] + stdev[i] * Coef) - (sma[i] - stdev[i] * Coef);
break;
}
return array;
}
public static IList<double> GetSma(IContext ctx, IList<double> values, int period)
{
// Выводим в лог сколько раз вызвался этот метод при расчете скрипта.
// Для одного боллинжера с одинаковыми параметрами будет только одни запуск этого метода.
// Это только для демонстрации, в 'боевых' индикаторах вывод в лог не обязателен.
ctx.Log($"Get sma", toMessageWindow: true);
return Series.SMA(values, period, ctx);
}
public static IList<double> GetStDev(IContext ctx, IList<double> values, int period)
{
// Выводим в лог сколько раз вызвался этот метод при расчете скрипта.
// Для одного боллинжера с одинаковыми параметрами будет только одни запуск этого метода.
// Это только для демонстрации, в 'боевых' индикаторах вывод в лог не обязателен.
ctx.Log($"Get stdev", toMessageWindow: true);
return Series.StDev(values, period, ctx);
}
}
}


Last updated
Was this helpful?