Volume on the chart

The indicator, which was inherited from the standard Volume indicator, was created in this example. The OnCalculate method was redefined and left empty (to avoid unnecessary calculations). And outlined the rendering logic in the OnRender method. Colours are taken from the base indicator DataSeries.

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

Is this article helpful for you?