"Swing" indicator

Can Ninjatrader “Swing” indicator be added for Tradovate (?).

Here is the NT7 code:-

public class Swing : Indicator
{
#region Variables
private double currentSwingHigh = 0;
private double currentSwingLow = 0;
private ArrayList lastHighCache;
private double lastSwingHighValue = 0;
private ArrayList lastLowCache;
private double lastSwingLowValue = 0;
private int saveCurrentBar = -1;
private int strength = 5;
private DataSeries swingHighSeries;
private DataSeries swingHighSwings;
private DataSeries swingLowSeries;
private DataSeries swingLowSwings;
#endregion

/// This method is used to configure the indicator and is called once before any bar data is loaded.

protected override void Initialize()
{
Add(new Plot(Color.Green, PlotStyle.Dot, “Swing high”));
Add(new Plot(Color.Orange, PlotStyle.Dot, “Swing low”));
Plots[0].Pen.Width = 2;
Plots[0].Pen.DashStyle = DashStyle.Dot;
Plots[1].Pen.Width = 2;
Plots[1].Pen.DashStyle = DashStyle.Dot;

lastHighCache = new ArrayList();
lastLowCache = new ArrayList();

swingHighSeries = new DataSeries(this);
swingHighSwings = new DataSeries(this);
swingLowSeries = new DataSeries(this);
swingLowSwings = new DataSeries(this);

DisplayInDataBox = false;
PaintPriceMarkers = false;
Overlay = true;
}

/// Called on each bar update event (incoming tick)

protected override void OnBarUpdate()
{
if (saveCurrentBar != CurrentBar)
{
swingHighSwings.Set(0); // initializing important internal
swingLowSwings.Set(0); // initializing important internal

swingHighSeries.Set(0); // initializing important internal
swingLowSeries.Set(0); // initializing important internal

lastHighCache.Add(High[0]);
if (lastHighCache.Count > (2 * strength) + 1)
lastHighCache.RemoveAt(0);
lastLowCache.Add(Low[0]);
if (lastLowCache.Count > (2 * strength) + 1)
lastLowCache.RemoveAt(0);

if (lastHighCache.Count == (2 * strength) + 1)
{
bool isSwingHigh = true;
double swingHighCandidateValue = (double) lastHighCache[strength];
for (int i=0; i < strength; i++)
if ((double) lastHighCache[i] >= swingHighCandidateValue - double.Epsilon)
isSwingHigh = false;

for (int i=strength+1; i < lastHighCache.Count; i++)
if ((double) lastHighCache[i] > swingHighCandidateValue - double.Epsilon)
isSwingHigh = false;

swingHighSwings.Set(strength, isSwingHigh ? swingHighCandidateValue : 0.0);
if (isSwingHigh)
lastSwingHighValue = swingHighCandidateValue;

if (isSwingHigh)
{
currentSwingHigh = swingHighCandidateValue;
for (int i=0; i <= strength; i++)
SwingHighPlot.Set(i, currentSwingHigh);
}
else if (High[0] > currentSwingHigh)
{
currentSwingHigh = 0.0;
SwingHighPlot.Reset();
}
else
SwingHighPlot.Set(currentSwingHigh);

if (isSwingHigh)
{
for (int i=0; i<=strength; i++)
swingHighSeries.Set(i, lastSwingHighValue);
}
else
{
swingHighSeries.Set(lastSwingHighValue);
}
}

if (lastLowCache.Count == (2 * strength) + 1)
{
bool isSwingLow = true;
double swingLowCandidateValue = (double) lastLowCache[strength];
for (int i=0; i < strength; i++)
if ((double) lastLowCache[i] <= swingLowCandidateValue + double.Epsilon)
isSwingLow = false;

for (int i=strength+1; i < lastLowCache.Count; i++)
if ((double) lastLowCache[i] < swingLowCandidateValue + double.Epsilon)
isSwingLow = false;

swingLowSwings.Set(strength, isSwingLow ? swingLowCandidateValue : 0.0);
if (isSwingLow)
lastSwingLowValue = swingLowCandidateValue;

if (isSwingLow)
{
currentSwingLow = swingLowCandidateValue;
for (int i=0; i <= strength; i++)
SwingLowPlot.Set(i, currentSwingLow);
}
else if (Low[0] < currentSwingLow)
{
currentSwingLow = double.MaxValue;
SwingLowPlot.Reset();
}
else
SwingLowPlot.Set(currentSwingLow);

if (isSwingLow)
{
for (int i=0; i<=strength; i++)
swingLowSeries.Set(i, lastSwingLowValue);
}
else
{
swingLowSeries.Set(lastSwingLowValue);
}
}

saveCurrentBar = CurrentBar;
}
else
{
if (High[0] > High[strength] && swingHighSwings[strength] > 0.0)
{
swingHighSwings.Set(strength, 0.0);
for (int i=0; i<=strength; i++)
SwingHighPlot.Reset(i);
currentSwingHigh = 0.0;
}
else if (High[0] > High[strength] && currentSwingHigh != 0.0)
{
SwingHighPlot.Reset();
currentSwingHigh = 0.0;
}
else if (High[0] <= currentSwingHigh)
SwingHighPlot.Set(currentSwingHigh);

if (Low[0] < Low[strength] && swingLowSwings[strength] > 0.0)
{
swingLowSwings.Set(strength, 0.0);
for (int i=0; i<=strength; i++)
SwingLowPlot.Reset(i);
currentSwingLow = double.MaxValue;
}
else if (Low[0] < Low[strength] && currentSwingLow != double.MaxValue)
{
SwingLowPlot.Reset();
currentSwingLow = double.MaxValue;
}
else if (Low[0] >= currentSwingLow)
SwingLowPlot.Set(currentSwingLow);
}
}

#region Functions

/// Returns the number of bars ago a swing low occurred. Returns a value of -1 if a swing low is not found within the look back period.

///
///
///
///
public int SwingLowBar(int barsAgo, int instance, int lookBackPeriod)
{
if (instance < 1)
throw new Exception(GetType().Name + ".SwingLowBar: instance must be greater/equal 1 but was " + instance);
else if (barsAgo < 0)
throw new Exception(GetType().Name + ".SwingLowBar: barsAgo must be greater/equal 0 but was " + barsAgo);
else if (barsAgo >= Count)
throw new Exception(GetType().Name + ".SwingLowBar: barsAgo out of valid range 0 through " + (Count - 1) + ", was " + barsAgo + “.”);

Update();

for (int idx=CurrentBar - barsAgo - strength; idx >= CurrentBar - barsAgo - strength - lookBackPeriod; idx–)
{
if (idx < 0)
return -1;
if (idx >= swingLowSwings.Count)
continue;

if (swingLowSwings.Get(idx).Equals(0.0))
continue;

if (instance == 1) // 1-based, < to be save
return CurrentBar - idx;

instance–;
}

return -1;
}

/// Returns the number of bars ago a swing high occurred. Returns a value of -1 if a swing high is not found within the look back period.

///
///
///
///
public int SwingHighBar(int barsAgo, int instance, int lookBackPeriod)
{
if (instance < 1)
throw new Exception(GetType().Name + ".SwingHighBar: instance must be greater/equal 1 but was " + instance);
else if (barsAgo < 0)
throw new Exception(GetType().Name + ".SwingHighBar: barsAgo must be greater/equal 0 but was " + barsAgo);
else if (barsAgo >= Count)
throw new Exception(GetType().Name + ".SwingHighBar: barsAgo out of valid range 0 through " + (Count - 1) + ", was " + barsAgo + “.”);

Update();

for (int idx=CurrentBar - barsAgo - strength; idx >= CurrentBar - barsAgo - strength - lookBackPeriod; idx–)
{
if (idx < 0)
return -1;
if (idx >= swingHighSwings.Count)
continue;

if (swingHighSwings.Get(idx).Equals(0.0))
continue;

if (instance <= 1) // 1-based, < to be save
return CurrentBar - idx;

instance–;
}

return -1;
}

#endregion

#region Properties
[Description(“Number of bars required on each side of the swing point.”)]
[GridCategory(“Parameters”)]
public int Strength
{
get { return strength; }
set { strength = Math.Max(1, value); }
}

/// Gets the high swings.
///
[Browsable(false)]
[XmlIgnore()]
public DataSeries SwingHigh
{
get
{
Update();
return swingHighSeries;
}
}

private DataSeries SwingHighPlot
{
get
{
Update();
return Values[0];
}
}

/// Gets the low swings.

[Browsable(false)]
[XmlIgnore()]
public DataSeries SwingLow
{
get
{
Update();
return swingLowSeries;
}
}

private DataSeries SwingLowPlot
{
get
{
Update();
return Values[1];
}
}

#endregion

I am sure it is not exactly the same but there is a swing indicator included. It is called Price Action Swing.

Maybe that will help.

Thanks,

Donovan

Hi Donovan.
Thx for the reply.

The attached image is an example of the Swing Indicator on NinjaTrader.

The Price Action Swing on Tradovate does draw a zig-zag line to the swing high’s and lows but doesn’t plot the horizontal lines at those swing highs and lows as per the NinjaTrader Swing Indicator.

Many thx

Swing Indicator