Peak-Valley Algorithm

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;
					}
				}
			}		
        }
 
Back
Top