Volume on the chart

Modified on Fri, 04 Aug 2023 at 01:21 PM

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

 

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select atleast one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article