Indicator Calculation on closed bars only / ignore current bar
Created at 22 Sep 2022, 05:26
Indicator Calculation on closed bars only / ignore current bar
22 Sep 2022, 05:26
Hi,
A newbie in coding for cTrader here, so excuse me if this might be a stupid question.
I have this ZigZag indicator which like any indicator calculates and updates the outputs up to and including the current(which is not closed) bar. I want this indicator to ignore the current bar in its calculations and only to take into account up to and including the last closed bar. And yes I played with "index" variable and changed it to "index-1" and whatnot but it messed up the whole indicator.
Any help, tricks, hints and workarounds would be much appreciated.
using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class MyZigZag : Indicator
{
[Parameter(DefaultValue = 20)]
public int Depth { get; set; }
[Parameter(DefaultValue = 5)]
public int Deviation { get; set; }
[Parameter(DefaultValue = 3)]
public int BackStep { get; set; }
[Output("MyZigZag", LineColor ="#FFFF0000")]
public IndicatorDataSeries Result { get; set; }
#region Private fields
private double _lastLow;
private double _lastHigh;
private double _low;
private double _high;
private int _lastHighIndex;
private int _lastLowIndex;
private int _type;
private double _point;
private double _currentLow;
private double _currentHigh;
private IndicatorDataSeries _highZigZags;
private IndicatorDataSeries _lowZigZags;
#endregion
protected override void Initialize()
{
_highZigZags = CreateDataSeries();
_lowZigZags = CreateDataSeries();
_point = Symbol.TickSize;
}
public override void Calculate(int index)
{
if (index < Depth)
{
Result[index] = 0;
_highZigZags[index] = 0;
_lowZigZags[index] = 0;
return;
}
_currentLow = Functions.Minimum(Bars.LowPrices, Depth);
if (Math.Abs(_currentLow - _lastLow) < double.Epsilon)
_currentLow = 0.0;
else
{
_lastLow = _currentLow;
if ((Bars.LowPrices[index] - _currentLow) > (Deviation * _point))
_currentLow = 0.0;
else
{
for (int i = 1; i <= BackStep; i++)
{
if (Math.Abs(_lowZigZags[index - i]) > double.Epsilon
&& _lowZigZags[index - i] > _currentLow)
_lowZigZags[index - i] = 0.0;
}
}
}
if (Math.Abs(Bars.LowPrices[index] - _currentLow) < double.Epsilon)
_lowZigZags[index] = _currentLow;
else
_lowZigZags[index] = 0.0;
_currentHigh = Bars.HighPrices.Maximum(Depth);
if (Math.Abs(_currentHigh - _lastHigh) < double.Epsilon)
_currentHigh = 0.0;
else
{
_lastHigh = _currentHigh;
if ((_currentHigh - Bars.HighPrices[index] ) > (Deviation * _point))
_currentHigh = 0.0;
else
{
for (int i = 1; i <= BackStep; i++)
{
if (Math.Abs(_highZigZags[index - i]) > double.Epsilon && _highZigZags[index - i] < _currentHigh)
_highZigZags[index - i] = 0.0;
}
}
}
if (Math.Abs(Bars.HighPrices[index] - _currentHigh) < double.Epsilon)
_highZigZags[index] = _currentHigh;
else
_highZigZags[index] = 0.0;
switch(_type)
{
case 0:
if(Math.Abs(_low - 0) < double.Epsilon && Math.Abs(_high - 0) < double.Epsilon)
{
if(Math.Abs(_highZigZags[index]) > double.Epsilon)
{
_high = Bars.HighPrices[index];
_lastHighIndex = index;
_type = -1;
Result[index] = _high;
}
if(Math.Abs(_lowZigZags[index]) > double.Epsilon)
{
_low = Bars.LowPrices[index];
_lastLowIndex = index;
_type = 1;
Result[index] = _low;
}
}
break;
case 1:
if (Math.Abs(_lowZigZags[index]) > double.Epsilon && _lowZigZags[index] < _low && Math.Abs(_highZigZags[index] - 0.0) < double.Epsilon)
{
Result[_lastLowIndex] = double.NaN;
_lastLowIndex = index;
_low = _lowZigZags[index];
Result[index] = _low;
}
if (Math.Abs(_highZigZags[index] - 0.0) > double.Epsilon && Math.Abs(_lowZigZags[index] - 0.0) < double.Epsilon)
{
_high = _highZigZags[index];
_lastHighIndex = index;
Result[index] = _high;
_type = -1;
}
break;
case -1:
if (Math.Abs(_highZigZags[index]) > double.Epsilon && _highZigZags[index] > _high && Math.Abs(_lowZigZags[index] - 0.0) < double.Epsilon)
{
Result[_lastHighIndex] = double.NaN;
_lastHighIndex = index;
_high = _highZigZags[index];
Result[index] = _high;
}
if (Math.Abs(_lowZigZags[index]) > double.Epsilon && Math.Abs(_highZigZags[index]) <= double.Epsilon)
{
_low = _lowZigZags[index];
_lastLowIndex = index;
Result[index] = _low;
_type = 1;
}
break;
default: return;
}
}
}
}
firemyst
23 Sep 2022, 06:48
I think you can do what you want in the Calculate method:
1) create a class variable that's an int that keeps track of previous indexes:
private int _previousIndex;
2) in the initialize method, set _previousIndex = 0
3) In Calculate:
if (index > _previousIndex)
{
//do all your logic
_previousIndex = index;
}
The above code will only run then when it moves to the next bar, thereby not calculating it on the current bar.
@firemyst