Description
This is an cumulative volume indicator based of the version by LonesomeTheBlue on TradinbView:
Here is how to use it:
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo.Indicators
{
[Cloud("Close", "Open", FirstColor = "Lime", SecondColor = "Crimson")]
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class CumulativeDeltaVolume : Indicator
{
[Parameter("As Heiken Ashi", DefaultValue = false)]
public bool AsHeikenAshi { get; set; }
[Parameter("Smoothing", DefaultValue = 5)]
public int Period { get; set; }
[Parameter("Show Bars", DefaultValue = true)]
public bool ShowBars { get; set; }
[Output("Open", PlotType = PlotType.DiscontinuousLine, LineColor = "Gray", Thickness = 1)]
public IndicatorDataSeries Open { get; set; }
[Output("Close", PlotType = PlotType.DiscontinuousLine, LineColor = "Gray", Thickness = 1)]
public IndicatorDataSeries Close { get; set; }
[Output("High", PlotType = PlotType.Points, LineColor = "Green", Thickness = 3)]
public IndicatorDataSeries High { get; set; }
[Output("Low", PlotType = PlotType.Points, LineColor = "Red", Thickness = 3)]
public IndicatorDataSeries Low { get; set; }
private IndicatorDataSeries delta;
private IndicatorDataSeries cumDelta;
private IndicatorDataSeries O;
private IndicatorDataSeries C;
private IndicatorDataSeries H;
private IndicatorDataSeries L;
private ExponentialMovingAverage ema;
private int candleWidth;
protected override void Initialize()
{
delta = CreateDataSeries();
cumDelta = CreateDataSeries();
O = CreateDataSeries();
C = CreateDataSeries();
H = CreateDataSeries();
L = CreateDataSeries();
ema = Indicators.ExponentialMovingAverage(cumDelta, Period);
if (ShowBars)
{
UpdateVisibleCandles();
Chart.ZoomChanged += OnZoomChanged;
Chart.SizeChanged += OnSizeChanged;
Chart.DragEnd += OnDragEnd;
Chart.ScrollChanged += OnScrollChanged;
}
}
void OnZoomChanged(ChartZoomEventArgs obj)
{
UpdateVisibleCandles();
}
void OnSizeChanged(ChartSizeEventArgs obj)
{
UpdateVisibleCandles();
}
void OnDragEnd(ChartDragEventArgs obj)
{
UpdateVisibleCandles();
}
void OnScrollChanged(ChartScrollEventArgs obj)
{
UpdateVisibleCandles();
}
public override void Calculate(int index)
{
double volume = Bars.TickVolumes[index];
double open = Bars.OpenPrices[index];
double close = Bars.ClosePrices[index];
double high = Bars.HighPrices[index];
double low = Bars.LowPrices[index];
double topWick = high - Math.Max(open, close);
double bottomWick = Math.Min(open, close) - low;
double body = Math.Abs(close - open);
delta[index] = ((topWick + bottomWick) / 2.0 + body) / (topWick + bottomWick + body);
delta[index] = volume * (double.IsNaN(delta[index]) ? 0.5 : close >= open ? delta[index] : -delta[index]);
double cumDeltaPrev = double.IsNaN(cumDelta[index - 1]) ? 0.0 : cumDelta[index - 1];
cumDelta[index] = delta[index] + cumDeltaPrev;
O[index] = ema.Result[index - 1];
C[index] = ema.Result[index];
H[index] = double.IsNaN(ema.Result[index - 1]) ? ema.Result[index] : Math.Max(ema.Result[index], ema.Result[index - 1]);
L[index] = double.IsNaN(ema.Result[index - 1]) ? ema.Result[index] : Math.Min(ema.Result[index], ema.Result[index - 1]);
if (AsHeikenAshi)
{
Open[index] = double.IsNaN(Open[index - 1]) ? (O[index] + C[index]) / 2.0 : (Open[index - 1] + Close[index - 1]) / 2.0;
Close[index] = (O[index] + H[index] + L[index] + C[index]) / 4.0;
High[index] = Math.Max(Math.Max(H[index], Open[index]), Close[index]);
Low[index] = Math.Min(Math.Min(L[index], Open[index]), Close[index]);
}
else
{
Open[index] = O[index];
Close[index] = C[index];
High[index] = H[index];
Low[index] = L[index];
}
if (ShowBars)
{
UpdateCandle(index);
}
}
void UpdateVisibleCandles()
{
candleWidth = (int)(IndicatorArea.Width / (0.666 * Chart.MaxVisibleBars));
candleWidth = candleWidth < 3 ? 3 : candleWidth;
for (int i = Chart.FirstVisibleBarIndex; i <= Chart.LastVisibleBarIndex; i++)
{
UpdateCandle(i);
}
}
void UpdateCandle(int index)
{
Color color = Open[index] > Close[index] ? Color.OrangeRed : Color.Lime;
IndicatorArea.DrawTrendLine("line" + index, index, High[index], index, Low[index], color, 1, LineStyle.Solid);
IndicatorArea.DrawTrendLine("candle" + index, index, Open[index], index, Close[index], color, candleWidth, LineStyle.Solid);
}
}
}
cW22Trader
Joined on 16.03.2021
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Cumulative Delta Volume.algo
- Rating: 5
- Installs: 3072
- Modified: 12/06/2022 20:56
Comments
I appreciate your effort. But this is actually a kind of volume of the ticks and not the actual volume of the contracts that have been traded. The cTrader has 'tick volume' or simply put 'number of ticks'. One can take a position with 10 contracts at a given price. Another can take 0.1 position on the same price. In reality it means 10.1 volume contracts at that particular price. But cTrader sees that as a single tick, because all the contracts were at the same price. If the first person with 10 contracts on price x had taken position and second person 0.1 contract on price x+1 had taken position. Then the tick volume on first price (of 10 contracts) was 1 and tick volume on second price (of 0.1 contract) was also 1.
Because tick is a price change and has nothing to do with number of contracts at a specific price. Because cTrader only has the number of ticks and no volume of contracts, this indicator or any other that does anything with volume is misleading.
Thanks for share the post. I use this code in my project and its works smoothly. Appreciate your efforts.
<a href="https://www.samedayassignments.com/buy-assignment/">Buy Assignment</a>
thanks. It is great