← 返回

Отрисовка стопов без вертикальных линий

Добрый день! Скажите пожалуйста как можно отрисовать стопы без вертикальных линий? Дело в том что когда позиция переворачивается то линия стопа переносится на противоположную сторону, и этот перенос соединяется неразрывной линией. Может в рендере нужно использовать какие то классы реализующие IChartElement или в свойство Style устанавливать какое значение?

Индикатор такой:


    public class StopLossIndicator : BaseIndicator
    {
        protected override IIndicatorValue OnProcess(IIndicatorValue input)
        {
            var value = input.GetValue<decimal>();
            IsFormed = value != 0;
            return new DecimalIndicatorValue(this, value);
        }
    }

Рендер такой:

public class StopLossPainter : BaseChartIndicatorPainter
    {
        [Display(Name = "Стоп-Лосс", Description = "Область графика для отрисовки стопа")]
        public ChartLineElement StopLossLine { get; }


        public StopLossPainter()
        {
            StopLossLine = new ChartLineElement()
            {
                Style = ChartIndicatorDrawStyles.Line, StrokeThickness = 2, Color = Colors.Red
            };
            AddChildElement(StopLossLine);
        }


        protected override bool OnDraw()
        {
            var ind = (StopLossIndicator)Indicator;
            var result = false;
            result |= DrawValues(ind, StopLossLine);

            return result;
        }
    }

Отрисовка как:


.....
StopLoss = new StopLossIndicator();
.....
private void OnCandleSeriesProcessing(CandleSeries candleSeries, Candle candle)
        {
            var chartDrawData = new ChartDrawData();
            var chartDrawDataItem = chartDrawData.Group(candle.OpenTime);
            chartDrawDataItem.Add(ChartCandleElement, candle);

            var dataStop = StopLoss.Process(StopPriсe, candle.State == CandleStates.Finished);
            chartDrawDataItem.Add(StopLossElement, dataStop);

            Chart.Draw(chartDrawData);
}

评论 (12)

登录创建账户, 登录或注册以发表评论

Support
Support

Добрый день

Вы можете использовать аннотации для этого:

var annotation = new ChartAnnotation { Type = ChartAnnotationTypes.LineAnnotation };
			Chart.AddElement(_areaComb, annotation);

			var data = new ChartDrawData.AnnotationData
			{
				X1 = new DateTimeOffset(2015, 8, 03, 5, 0, 0, TimeSpan.FromHours(3)),
				X2 = new DateTimeOffset(2015, 8, 03, 5, 30, 0, TimeSpan.FromHours(3)),
				Y1 = 2098.5m,
				Y2 = 2098.5m,
				IsVisible = true,
				IsEditable = false,
				Stroke = Brushes.Red,
				CoordinateMode = AnnotationCoordinateMode.Absolute,
			};

			var dd = new ChartDrawData();
			dd.Add(annotation, data);

			Chart.Draw(dd);

На примере SampleChart это выглядит так:

37b04f5a757a10692c5d86dce3070d09.png

Константин
Константин 作者

Если _annotation объявить как поле типа ChartAnnotation один раз, добавить его на график Chart.AddElement(_areaComb, _annotation) и добавлять на него новые данные ChartDrawData.AnnotationData, то предыдущая линия стирается и начитает прорисовываться новая. Можно ли как то рисовать не одну линию, а несколько? Неужели для каждого стопа нужно добавлять новый элемент ChartAnnotation на график?

Support
Константин
Константин 作者

Если я правильно понимаю решения в настоящее время нет. Если да то у меня сопутствующий вопрос - Планируется ли реализация данного решения в будущем?

Support
Support

Добрый день

Да, пока только через создание новых элементов. Мы обсудим возможность введение единичного элемента графика.

Константин
Константин 作者

Добрый день. Не было ли принято решение по данному вопросу?

Support
Support

Здравствуйте. Пока на стадии рассмотрения. Как будут новости мы оповестим в данном топике.

Koc
Koc

На самом деле это очень нужная опция. Так как без нее очень сложно разбираться где был выставлен и как подтягивался трейл стоп. Рисовать индикатором слегка деревянный способ.🧐

Константин
Константин 作者

Судя по всему вопрос был отклонен. В связи с этим вопрос: Как рисовать стопы на истории? Если группировка данных происходит по времени


var chartData = new ChartDrawData();
var gr =  chartData.Group(candle.OpenTime);

то следуя логике если я буду рисовать линию по 10 свечей так


if (_count < 10)
   gr.Add(_indicatorElement, longValue);
else  if (_count > 20) _count = 0;

то линия должна прерываться каждые 10 свечей. Вместо этого линия рисуется без разрывов, но пропуск 10 свечей учтен. Линия получается в два раза короче. Какой смысл в группировке по времени, если индикатор никаким образом не реагирует на это?

Sprite
Sprite

if (drawLine) gr.Add(_indicatorElement, (double)longValue); else gr.Add(_indicatorElement, double.NaN);

Идея в том, что нужно хоть что-то рисовать, чтобы значения индикатора не пропускались и из-за этого следующие значения не съезжали влево по горизонтальной оси. Еще момент - если вы так нарисуете линию только в одной свечке, а слева и справа значения будут double.NaN - то вы не увидите линию. Для этого можно использовать стиль линии Dots. Собственно так в StockSharp рисуются фракталы.

К сожалению так нельзя делать со свечками, т.е. нельзя просто так взять и нарисовать индикатором одну свечку в нужном месте. Поясню: допустим у вас рисуются свечки на оси + рисуются другие свечки индикатором на этой же оси, но другим элементом ChartCandleElement. Так вот, пропуск вторых свечек приведет к тому, что как ни группируй свечки будут рисоваться одна за другой, без пропусков. И по сути вы правы - группировка по времени при таком использовании не работает. И еще момент - свечки нельзя рисовать в кастомном рендерере (унаследовав от BaseChartIndicatorPainter), почему так сделано - для меня загадка.

Константин
Константин
Константин 作者

sprite: if (drawLine) gr.Add(_indicatorElement, double.NaN); Вы пользуетесь сигнатурой этого метода? Быть может я что то делаю не так, но я не могу запихать double в метод так как его невозможно привести к типу IIndicatorValue.

Sprite
Sprite

Константин: Вы пользуетесь сигнатурой этого метода? Быть может я что то делаю не так, но я не могу запихать double в метод так как его невозможно привести к типу IIndicatorValue. Да, но у этого метода есть куча перегрузок. Если ваш _indicatorElement будет типом ChartLineElement - то всё должно получиться. UPDATE По сути если вам не надо делать разрывы больше чем соседние свечки вы можете просто поменяете тип линии (DrawStyle) на Dots и получите вместо линии, как на картинке в первом посте, серии горизонтальных точек с разрывами. Или, если точки не подходят и хочется именно линии, то нужно для какой-то свечки организовать разрыв, вставляя double.NaN или сделать два элемента и рисовать их поочередно заполняя то один то другой значениями double.NaN. Ну или как писал support - используйте аннотации, но там есть свои баги.

Константин
Константин 作者

sprite:

Константин: Вы пользуетесь сигнатурой этого метода? Быть может я что то делаю не так, но я не могу запихать double в метод так как его невозможно привести к типу IIndicatorValue. Да, но у этого метода есть куча перегрузок. Если ваш _indicatorElement будет типом ChartLineElement - то всё должно получиться. UPDATE По сути если вам не надо делать разрывы больше чем соседние свечки вы можете просто поменяете тип линии (DrawStyle) на Dots и получите вместо линии, как на картинке в первом посте, серии горизонтальных точек с разрывами. Или, если точки не подходят и хочется именно линии, то нужно для какой-то свечки организовать разрыв, вставляя double.NaN или сделать два элемента и рисовать их поочередно заполняя то один то другой значениями double.NaN. Ну или как писал support - используйте аннотации, но там есть свои баги.

Одним double.nan не получилось обойтись. Сделал на основе индикатора и рендера отрисовки.