I coded an automatic trend line detection indicator for NinjaTrader months back that uses swing highs/lows to determines the swing points that creates a peak or valley and uses these points to draw a trend line. Here is the main logic. The actual indicator can be downloaded from our support forum in our NinjaScript File Sharing section. Code: protected override void OnBarUpdate() { signal = 0; // Calculate up trend line int upTrendStartBarsAgo = 0; int upTrendEndBarsAgo = 0; int upTrendOccurence = 1; while (Low[upTrendEndBarsAgo] <= Low[upTrendStartBarsAgo]) { upTrendStartBarsAgo = Swing(Strength).SwingLowBar(0, upTrendOccurence + 1, CurrentBar); upTrendEndBarsAgo = Swing(Strength).SwingLowBar(0, upTrendOccurence, CurrentBar); if (upTrendStartBarsAgo < 0 || upTrendEndBarsAgo < 0) break; upTrendOccurence++; } // Calculate down trend line int downTrendStartBarsAgo = 0; int downTrendEndBarsAgo = 0; int downTrendOccurence = 1; while (High[downTrendEndBarsAgo] >= High[downTrendStartBarsAgo]) { downTrendStartBarsAgo = Swing(Strength).SwingHighBar(0, downTrendOccurence + 1, CurrentBar); downTrendEndBarsAgo = Swing(Strength).SwingHighBar(0, downTrendOccurence, CurrentBar); if (downTrendStartBarsAgo < 0 || downTrendEndBarsAgo < 0) break; downTrendOccurence++; } // Always clear out arrows that mark trend line breaks RemoveDrawObject("DownTrendBreak"); RemoveDrawObject("UpTrendBreak"); // We have found an uptrend and the uptrend is the current trend if (upTrendStartBarsAgo > 0 && upTrendEndBarsAgo > 0 && upTrendStartBarsAgo < downTrendStartBarsAgo) { RemoveDrawObject("DownTrendLine"); // Reset the alert if required if (triggerBarIndex != CurrentBar - upTrendEndBarsAgo) { triggerBarIndex = 0; ResetAlert("Alert"); } double startBarPrice = Low[upTrendStartBarsAgo]; double endBarPrice = Low[upTrendEndBarsAgo]; double changePerBar = (endBarPrice - startBarPrice) / (Math.Abs(upTrendEndBarsAgo - upTrendStartBarsAgo)); // Draw the up trend line DrawRay("UpTrendLine", upTrendStartBarsAgo, startBarPrice, upTrendEndBarsAgo, endBarPrice, UpTrendColor, DashStyle.Solid, LineWidth); // Check for an uptrend line break for (int barsAgo = upTrendEndBarsAgo - 1; barsAgo >= 0; barsAgo--) { if (Close[barsAgo] < endBarPrice + (Math.Abs(upTrendEndBarsAgo - barsAgo) * changePerBar)) { DrawArrowDown("UpTrendBreak", barsAgo, High[barsAgo] + TickSize, Color.Blue); // Set the signal only if the break is on the right most bar if (barsAgo == 0) signal = 2; // Alert will only trigger in real-time if (AlertOnBreak && triggerBarIndex == 0) { triggerBarIndex = CurrentBar - upTrendEndBarsAgo; Alert("Alert", Priority.High, "Up trend line broken", "Alert2.wav", 100000, Color.Black, Color.Red); } break; } } } // We have found a downtrend and the downtrend is the current trend else if (downTrendStartBarsAgo > 0 && downTrendEndBarsAgo > 0 && upTrendStartBarsAgo > downTrendStartBarsAgo) { RemoveDrawObject("UpTrendLine"); // Reset the alert if required if (triggerBarIndex != CurrentBar - downTrendEndBarsAgo) { triggerBarIndex = 0; ResetAlert("Alert"); } double startBarPrice = High[downTrendStartBarsAgo]; double endBarPrice = High[downTrendEndBarsAgo]; double changePerBar = (endBarPrice - startBarPrice) / (Math.Abs(downTrendEndBarsAgo - downTrendStartBarsAgo)); // Draw the down trend line DrawRay("DownTrendLine", downTrendStartBarsAgo, startBarPrice, downTrendEndBarsAgo, endBarPrice, DownTrendColor, DashStyle.Solid, LineWidth); // Check for a down trend line break for (int barsAgo = downTrendEndBarsAgo - 1; barsAgo >= 0; barsAgo--) { if (Close[barsAgo] > endBarPrice + (Math.Abs(downTrendEndBarsAgo - barsAgo) * changePerBar)) { DrawArrowUp("DownTrendBreak", barsAgo, Low[barsAgo] - TickSize, Color.Blue); // Set the signal only if the break is on the right most bar if (barsAgo == 0) signal = 1; // Alert will only trigger in real-time if (AlertOnBreak && triggerBarIndex == 0) { triggerBarIndex = CurrentBar - downTrendEndBarsAgo; Alert("Alert", Priority.High, "Down trend line broken", "Alert2.wav", 100000, Color.Black, Color.Green); } break; } } } }