If you’ve been trading for more than a week, you’re likely familiar with the "Alligator" — Bill Williams’ classic trend-following powerhouse. It’s reliable, visual, and a staple on many charts. But let’s be honest: the original version can feel like a sleepy reptile that takes way too long to wake up.
By the time the Jaw, Teeth, and Lips finally align, half the move is already in the rearview mirror. To fix this, we have ported the popular Near Zero Lag Williams Alligator (originally seen on ThinkScript) over to NinjaTrader 8.
Why Port This to NinjaTrader?
NinjaTrader 8 is a powerhouse for precision execution and backtesting. By using a Zero Lag version of the Alligator, you’re essentially giving the reptile a shot of espresso.
The "Zero Lag" Advantage
Standard moving averages are inherently lagging because they rely on past data. The "Zero Lag" version replaces traditional smoothing with a calculation that weights recent price action more heavily, allowing the lines to pivot significantly faster.
- Faster Crossovers: Get into the "Awakening" phase several bars earlier.
- Decisive Spacing: The lines fan out more clearly when a real move starts.
- Precision Exits: When the trend dies, the Zero Lag version "pivots" immediately, helping you keep more of your profit.
Trading Techniques
1. The Sleeping Alligator (Range)
When the Jaw, Teeth, and Lips are tangled or moving horizontally, the Alligator is sleeping. This is your cue to sit on your hands.
Pro Tip: The longer the Alligator sleeps, the hungrier it will be when it wakes up. Expect a massive breakout after long periods of consolidation.
2. The Awakening (The Entry)
- Long Entry: Price breaks above all three lines, and the lines align in the order: Lips (Green) > Teeth (Red) > Jaw (Blue).
- Short Entry: Price breaks below all three lines, and the lines align in the order: Jaw (Blue) > Teeth (Red) > Lips (Green).
3. The Sated Alligator (The Exit)
In the Zero Lag version, the Green line (Lips) is your primary exit trigger. When the Lips cross back over the Red line, the "meal" is over. Because this version has near-zero lag, this crossover happens much closer to the actual price peak than the standard version.
The NinjaTrader 8 Code
Below is the C# code for the Zero Lag Williams Alligator. Save this as a .cs file in your NinjaTrader's Indicators folder and compile it through the NinjaScript editor.
// Zero Lag Williams Alligator for NinjaTrader 8
// Adapted from the Near Zero Lag ThinkScript community version
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Indicators.OranselIndustries
{
public class NearZeroLagWilliamsAlligator : Indicator
{
private Series<double> iTrendJaw;
private Series<double> iTrendTeeth;
private Series<double> iTrendLips;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Near Zero-Lag Williams Alligator Using the Dr Ehlers ITrend";
Name = "NearZeroLagWilliamsAlligator";
Calculate = Calculate.OnBarClose;
IsOverlay = true;
DisplayInDataBox = true;
DrawOnPricePanel = true;
PaintPriceMarkers = true;
ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
IsSuspendedWhileInactive = true;
Jaw = 13;
Teeth = 8;
Lips = 5;
AddPlot(Brushes.Blue, "JAW");
AddPlot(Brushes.Red, "TEETH");
AddPlot(Brushes.Cyan, "LIPS");
}
else if (State == State.DataLoaded)
{
iTrendJaw = new Series<double>(this);
iTrendTeeth = new Series<double>(this);
iTrendLips = new Series<double>(this);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 10)
return;
// Calculate ITrend for JAW (with 8 bar offset)
double priceJaw = CurrentBar >= 8 ? (High[8] + Low[8]) / 2.0 : (High[0] + Low[0]) / 2.0;
iTrendJaw[0] = GetITrend(priceJaw, Jaw, iTrendJaw);
// Calculate ITrend for TEETH (with 5 bar offset)
double priceTeeth = CurrentBar >= 5 ? (High[5] + Low[5]) / 2.0 : (High[0] + Low[0]) / 2.0;
iTrendTeeth[0] = GetITrend(priceTeeth, Teeth, iTrendTeeth);
// Calculate ITrend for LIPS (with 3 bar offset)
double priceLips = CurrentBar >= 3 ? (High[3] + Low[3]) / 2.0 : (High[0] + Low[0]) / 2.0;
iTrendLips[0] = GetITrend(priceLips, Lips, iTrendLips);
// Set plot values
Values[0][0] = iTrendJaw[0];
Values[1][0] = iTrendTeeth[0];
Values[2][0] = iTrendLips[0];
}
private double GetITrend(double price, int length, Series<double> iTrendSeries)
{
double alpha = 2.0 / (length + 1);
if (CurrentBar < 6)
{
// Initialization period
double price0 = price;
double price1 = CurrentBar >= 1 ? ((High[1] + Low[1]) / 2.0) : price;
double price2 = CurrentBar >= 2 ? ((High[2] + Low[2]) / 2.0) : price;
return (price0 + 2 * price1 + price2) / 4.0;
}
else
{
// Get previous prices (adjusting for the offset already applied)
double price0 = price;
double price1 = (High[1] + Low[1]) / 2.0;
double price2 = (High[2] + Low[2]) / 2.0;
double iTrend1 = iTrendSeries[1];
double iTrend2 = iTrendSeries[2];
return (alpha - alpha * alpha / 4.0) * price0 +
0.5 * alpha * alpha * price1 -
(alpha - 0.75 * alpha * alpha) * price2 +
2.0 * (1.0 - alpha) * iTrend1 -
(1.0 - alpha) * (1.0 - alpha) * iTrend2;
}
}
#region Properties
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name="Jaw", Description="Jaw Period", Order=1, GroupName="Parameters")]
public int Jaw { get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name="Teeth", Description="Teeth Period", Order=2, GroupName="Parameters")]
public int Teeth { get; set; }
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name="Lips", Description="Lips Period", Order=3, GroupName="Parameters")]
public int Lips { get; set; }
[Browsable(false)]
[XmlIgnore]
public Series<double> JAW
{
get { return Values[0]; }
}
[Browsable(false)]
[XmlIgnore]
public Series<double> TEETH
{
get { return Values[1]; }
}
[Browsable(false)]
[XmlIgnore]
public Series<double> LIPS
{
get { return Values[2]; }
}
#endregion
}
}
Comparison Table
| Component | Period | Classic Offset | Zero Lag Benefit |
|---|---|---|---|
| Lips (Green) | 5 | 3 Bars | Instant reaction to momentum shifts |
| Teeth (Red) | 8 | 5 Bars | Catches the "meat" of the move earlier |
| Jaw (Blue) | 13 | 8 Bars | Provides a faster trend baseline |
Final Thoughts
The Zero Lag Williams Alligator is like upgrading from a standard telescope to a high-definition radar. It doesn't change the underlying physics of the market, but it certainly makes the picture clearer and faster to react to.
Remember, the Alligator is a trend-follower. It thrives in trending markets but can get "choppy" in tight ranges. Always use it alongside volume or a momentum oscillator like the Awesome Oscillator for the best results.
Back to Blog