Volume on the chart

В этом примере создали индикатор, который унаследовали от стандартного индикатора Volume. Переопределили метод OnCalculate, оставив его пустым(чтобы не производить ненужные расчеты). И прописали логику отрисовки в методе OnRender. Цвета взяты из датасерий базового индикатора.

[DisplayName("Volume on the chart")]
    public class VolumeOnChart : Volume
    {
        private decimal _height = 15;

        public decimal Height
        {
            get { return _height; }
            set
            {
                if (value < 10 || value > 100)
                    return;

                _height = value;
            }
        }

        public VolumeOnChart()
        {
            EnableCustomDrawing = true;
            SubscribeToDrawingEvents(DrawingLayouts.LatestBar);
            Panel = IndicatorDataProvider.CandlesPanel;
        }

        protected override void OnCalculate(int bar, decimal value)
        {
            
        }

        protected override void OnRender(RenderContext context,  DrawingLayouts layout)
        {
            var maxValue = 0m;
            var maxHeight = ChartInfo.Region.Height * _height/100m;
            var positiveColor = ((ValueDataSeries)DataSeries[0]).Color.Convert(); // color from positive dataseries
            var negativeColor = ((ValueDataSeries)DataSeries[1]).Color.Convert(); // color from negative dataseries
            var neutralColor = ((ValueDataSeries)DataSeries[2]).Color.Convert(); // color from neutral dataseries
            var filterColor = ((ValueDataSeries)DataSeries[3]).Color.Convert(); // color from filter dataseries


            for (int i = FirstVisibleBarNumber; i <= LastVisibleBarNumber; i++)
            {
                var candle = GetCandle(i);
                var volumeValue = Input == InputType.Volume ? candle.Volume : candle.Ticks;

                maxValue = Math.Max(volumeValue, maxValue);
            }

            for (int i = FirstVisibleBarNumber; i <= LastVisibleBarNumber; i++)
            {
                var candle = GetCandle(i);
                var volumeValue = Input == InputType.Volume ? candle.Volume : candle.Ticks;

                Color volumeColor;

                if (UseFilter && volumeValue > FilterValue)
                {
                    volumeColor = filterColor;
                }
                else
                {
                    if (DeltaColored)
                    {
                        if (candle.Delta > 0)
                        {
                            volumeColor = positiveColor;
                        }
                        else if (candle.Delta < 0)
                        {
                            volumeColor = negativeColor;
                        }
                        else
                        {
                            volumeColor = neutralColor;
                        }
                    }
                    else
                    {
                        if (candle.Close > candle.Open)
                        {
                            volumeColor = positiveColor;
                        }
                        else if (candle.Close < candle.Open)
                        {
                            volumeColor = negativeColor;
                        }
                        else
                        {
                            volumeColor = neutralColor;
                        }
                    }
                }

                var x = ChartInfo.GetXByBar(i);
                var height = (int)(maxHeight * volumeValue / maxValue);

                var rectangle = new Rectangle(x, ChartInfo.Region.Height - height, (int)ChartInfo.PriceChartContainer.BarsWidth, height);
                context.FillRectangle(volumeColor, rectangle);
            }
        }

        public override string ToString()
        {
            return "Volume on the chart";
        }
    }