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
Feedback sent
We appreciate your effort and will try to fix the article