Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Automatic Trend Channel

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Automatic Trend Channel

    Hello, I am wanting to implement a strategy into NT8 that tracks the last X bars (volume or tick bars) and finds channels and automatically draws a trend channel. I have experimented a little bit and have been able to do draw static channels.

    I know there is a dynamic SupDemZone indicator on futures.io which tracks upper/lower moves and continuations and can draw zones. I feel as though this could be modified to instead of tracking zones, track highs/lows and draw trends instead.

    Furthermore, if given the chance to draw trend channels, could a strategy be implemented such that on a trend break EnterLong() or EnterShort() ??

    Thanks

    #2
    Hello rdavido,

    Thanks for writing in.

    You may program a strategy to create TrendChannel drawing objects that follow draw trend lines based on a certain look-back period. You may also program logic to EnterLong() and EnterShort() depending on if the the current price crosses above or crosses below one of those trend lines.

    Let's look at an example of Draw.TrendChannel():

    Code:
    		private TrendChannel myTC;
    		protected override void OnBarUpdate()
    		{
    			if(CurrentBar < 10)
    				return;
    			
    			myTC = Draw.TrendChannel(this, "tag1", true, 10, Low[10], 0, Low[0], 10, Low[10] - 5 * TickSize);           
    			//Add your custom indicator logic here.
    		}
    The code above will draw a trend line from the low price of 10 bars ago to the current low price, and will draw a parallel line from ten bars ago with a negative offset of 5 ticks from the low price of that bar.

    You may then program a strategy to check if the current price crosses above or crosses below this trend line. You can expose the variable from your indicator to do this and reference this variable in a CrossAbove() or CrossBelow() condition in your strategy.

    Please reference the documentation below for syntax, usage and samples of the components used to create this indicator/strategy.

    Draw.TrendChannel() - http://ninjatrader.com/support/helpG...endchannel.htm

    TrendChannel Object - http://ninjatrader.com/support/helpG...endchannel.htm

    CrossAbove() - http://ninjatrader.com/support/helpG...crossabove.htm

    CrossBelow() - http://ninjatrader.com/support/helpG...crossbelow.htm

    Exposing indicator values sample- http://ninjatrader.com/support/forum...ead.php?t=4991

    Please let me know if you have any questions.
    JimNinjaTrader Customer Service

    Comment


      #3
      Thank you for the reply. Is there a way to create a dynamic, moving trend line activator, that instead of looking at the last 10 bars, looks as far back as needed to create a channel? Also, is there a way to discern uptrend versus downtrend. In the example you provide, it draws low to the next low. On my testing, that creates a rising channel. How could one program a way to discern up versus downtrend?

      Thanks

      Comment


        #4
        Hello rdavid,

        Thanks for writing back.

        I am not sure what you mean by "looks as far back as needed to create a channel." The Drawing Object only creates a line and a parallel line offset to it. You may identify if the line is in an upward trend or a downward trend by calculating the slope of the line.

        I suggest using the point-slope formula. You will need to grab the coordinates of each anchor of the TrendChannel and calculate the change in Y coordinates and divide it by the change in X coordinates. When calculating the change in Y, you must keep in mind that the chart draws from the top left coordinate, not the bottom left coordinate. This means that we must calculate the change in Y coordinates as dY = Y1 -Y2 instead of dY = Y2 - Y1.

        I have provided sample code that outlines what you need to do to calculate the Slope from your TrendChannel.

        Code:
        private ChartScale myChartScale;
        
        
        protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
        	myChartScale = chartScale;
        }
        
        protected override void OnBarUpdate()
        {
        	if(CurrentBar < 10)
        	return;
        	
        	TrendChannel myTC = Draw.TrendChannel(this, "tag1", true, 10, Low[10], 0, Low[0], 10, Low[10] - 5 * TickSize);
        	if (myChartScale != null)
        	{
        		double xCoordinate1 = myTC.TrendStartAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).X;
        		double xCoordinate2 = myTC.TrendEndAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).X;
        		double deltaX = xCoordinate2 - xCoordinate1;
        		double yCoordinate1 = myTC.TrendStartAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).Y;
        		double yCoordinate2 = myTC.TrendEndAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).Y;
        		double deltaY = yCoordinate1 - yCoordinate2; // This reversal is intended as the Chart draws from top left, not bottom left.
        		double Slope = deltaY / deltaX;
        		Print(Slope);
        		Print( "X1 " + xCoordinate1);
        		Print( "X2 " + xCoordinate2);
        		Print( "Y1 " + yCoordinate1);
        		Print( "Y2 " + yCoordinate2);
        	}
        	
        }
        The key notes to keep in mind is that we are using GetPoint on the TrendStartAnchor property of the TrendChannel object. GetPoint requires that we provide ChartControl ChartPanel and ChartScale as input arguments. Since ChartScale is not immediately available, we create a myChartScale variable and assign it in OnRender().

        You may reference the relevant documentation below:

        Trend Channel object - http://ninjatrader.com/support/helpG...endchannel.htm

        GetPoint() method - https://ninjatrader.com/support/help.../?getpoint.htm

        Point Structure - https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx

        OnRender() - http://ninjatrader.com/support/helpG...s/onrender.htm

        Please let me know if you have any questions on the material.
        JimNinjaTrader Customer Service

        Comment


          #5
          What I mean by "as far back" is that the definitions for drawing the trend line in the aforementioned sample is 10 bars ago. However, what if I wanted to make it more dynamic where a channel emerges, say, 5 bars ago, or as late as 15 bars ago. I also want it such that it creates additional trendline channels.

          Thank you for your help thus far.

          Comment


            #6
            Hello rdavid,

            Thanks for clearing that part up.

            You may use a variable to represent the number of bars you would want to look back. This variable can be a user defined input where the the user can specify if they want to draw trend lines with a different look back period. This variable could also be calculated dynamically to produce changing trend lines as the market changes.

            I am not sure how a day trader would want to accurately detect trends on the fly. This task is best left up to you, your own experimentations, and any professional trade advise you seek out.

            You may use the Strategy Builder to create a template for user defined inputs.



            Creating the input variable above will result in the code below:

            Code:
            public class MyCustomStrategy : Strategy
            	{
            		protected override void OnStateChange()
            		{
            			if (State == State.SetDefaults)
            			{
            				Description									= @"Enter the description for your new custom Strategy here.";
            				Name										= "MyCustomStrategy";
            				Calculate									= Calculate.OnBarClose;
            				EntriesPerDirection							= 1;
            				EntryHandling								= EntryHandling.AllEntries;
            				IsExitOnSessionCloseStrategy				= true;
            				ExitOnSessionCloseSeconds					= 30;
            				IsFillLimitOnTouch							= false;
            				MaximumBarsLookBack							= MaximumBarsLookBack.TwoHundredFiftySix;
            				OrderFillResolution							= OrderFillResolution.Standard;
            				Slippage									= 0;
            				StartBehavior								= StartBehavior.WaitUntilFlat;
            				TimeInForce									= TimeInForce.Gtc;
            				TraceOrders									= false;
            				RealtimeErrorHandling						= RealtimeErrorHandling.StopCancelClose;
            				StopTargetHandling							= StopTargetHandling.PerEntryExecution;
            				BarsRequiredToTrade							= 20;
            				// Disable this property for performance gains in Strategy Analyzer optimizations
            				// See the Help Guide for additional information
            				IsInstantiatedOnEachOptimizationIteration	= true;
            				[B]MyInput					= 1;[/B]
            			}
            			else if (State == State.Configure)
            			{
            			}
            		}
            
            		protected override void OnBarUpdate()
            		{
            			
            		}
            
            		[B]#region Properties
            		[NinjaScriptProperty]
            		[Range(1, int.MaxValue)]
            		[Display(ResourceType = typeof(Custom.Resource), Name="MyInput", Order=1, GroupName="NinjaScriptStrategyParameters")]
            		public int MyInput
            		{ get; set; }
            		#endregion[/B]
            If you have any other questions, please don't hesitate to ask.
            JimNinjaTrader Customer Service

            Comment


              #7
              Is there a way to make this dynamic versus static?

              Or, for example, within the last 100 bars... 50 bars ago, the channel is down, however, 20 bars ago, the channel turns positive, so I want it to draw a new channel, leaving the old channel. Is there a way to create a dynamic "tag" versus "tag1"?

              As for using "Slope", do I say:

              Code:
               if (Slope > 1)
              {
               // Do something
              }
              Additionally, when running the indicator, I receive this error in the output window:

              Code:
              Indicator 'AutoTrend'. Error on calling 'OnBarUpdate' method on bar 0: Object reference not set to an instance of an object.
              Here is what I have:

              Code:
              #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
              
              //This namespace holds Indicators in this folder and is required. Do not change it. 
              namespace NinjaTrader.NinjaScript.Indicators
              {
              	public class AutoTrend : Indicator
              	{
              		protected override void OnStateChange()
              		{
              			if (State == State.SetDefaults)
              			{
              				Description									= @"Enter the description for your new custom Indicator here.";
              				Name										= "AutoTrend";
              				Calculate									= Calculate.OnBarClose;
              				IsOverlay									= false;
              				DisplayInDataBox							= true;
              				DrawOnPricePanel							= true;
              				DrawHorizontalGridLines						= true;
              				DrawVerticalGridLines						= true;
              				PaintPriceMarkers							= true;
              				ScaleJustification							= NinjaTrader.Gui.Chart.ScaleJustification.Right;
              				//Disable this property if your indicator requires custom values that cumulate with each new market data event. 
              				//See Help Guide for additional information.
              				IsSuspendedWhileInactive					= false;
              			}
              			else if (State == State.Configure)
              			{
              				
              			}
              		}
              			private ChartScale myChartScale;
              
              			protected override void OnRender(ChartControl chartControl, ChartScale chartScale) {
              				myChartScale = chartScale;
              			}
              			protected override void OnBarUpdate()
              			{
              				
              				TrendChannel myTC = Draw.TrendChannel(this, "tag1", true, 10, Low[10], 0, Low[0], 10, Low[10] - 5 * TickSize);
              				if (myChartScale != null)
              				{
              					double xCoordinate1 = myTC.TrendStartAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).X;
              					double xCoordinate2 = myTC.TrendEndAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).X;
              					double deltaX = xCoordinate2 - xCoordinate1;
              					double yCoordinate1 = myTC.TrendStartAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).Y;
              					double yCoordinate2 = myTC.TrendEndAnchor.GetPoint(ChartControl, ChartPanel, myChartScale, false).Y;
              					double deltaY = yCoordinate1 - yCoordinate2; // This reversal is intended as the Chart draws from top left, not bottom left.
              					double Slope = deltaY / deltaX;
              					Print(Slope);
              					Print( "X1 " + xCoordinate1);
              					Print( "X2 " + xCoordinate2);
              					Print( "Y1 " + yCoordinate1);
              					Print( "Y2 " + yCoordinate2);
              					
              //					if (Slope > 1)
              //					{
              //						myTC.TrendEndAnchor.Price += 15;
              //					}
              				}
              			
              			}
              
              		}
              	}
              
              #region NinjaScript generated code. Neither change nor remove.
              
              namespace NinjaTrader.NinjaScript.Indicators
              {
              	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
              	{
              		private AutoTrend[] cacheAutoTrend;
              		public AutoTrend AutoTrend()
              		{
              			return AutoTrend(Input);
              		}
              
              		public AutoTrend AutoTrend(ISeries<double> input)
              		{
              			if (cacheAutoTrend != null)
              				for (int idx = 0; idx < cacheAutoTrend.Length; idx++)
              					if (cacheAutoTrend[idx] != null &&  cacheAutoTrend[idx].EqualsInput(input))
              						return cacheAutoTrend[idx];
              			return CacheIndicator<AutoTrend>(new AutoTrend(), input, ref cacheAutoTrend);
              		}
              	}
              }
              
              namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
              {
              	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
              	{
              		public Indicators.AutoTrend AutoTrend()
              		{
              			return indicator.AutoTrend(Input);
              		}
              
              		public Indicators.AutoTrend AutoTrend(ISeries<double> input )
              		{
              			return indicator.AutoTrend(input);
              		}
              	}
              }
              
              namespace NinjaTrader.NinjaScript.Strategies
              {
              	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
              	{
              		public Indicators.AutoTrend AutoTrend()
              		{
              			return indicator.AutoTrend(Input);
              		}
              
              		public Indicators.AutoTrend AutoTrend(ISeries<double> input )
              		{
              			return indicator.AutoTrend(input);
              		}
              	}
              }
              
              #endregion
              Last edited by rdavido; 03-04-2017, 04:28 PM.

              Comment


                #8


                Using Renko Bars, one can clearly identify channels. I am wanting a script that automatically draws trend lines and buys (or sells) upon breakout.

                Comment


                  #9
                  Hello rdavid,

                  Thanks for your reply.

                  As mentioned, you may program your own logic to determine how many bars you would like to look back for your Trend Channel.

                  Whether you would like to use Renko bars to determine the look back period or how steep of a slope to trigger order entries is up to you.

                  You may add unique tags for your drawing objects as well. Please consider the following:
                  Code:
                  Draw.Line(this, "tag1"[B]+CurrentBar[/B], false, 10, 1000, 0, 1001, Brushes.LimeGreen, DashStyleHelper.Dot, 2);
                  Adding +CurrentBar to the tag will make each tag unique as CurrentBar will never be the same for each OnBarUpdate(). You will need to keep track of the bar number or unique tag in which you draw the Trend Channels if you wish to remove one of the drawing objects later. Please see the RemoveDrawObject documentation for more information: https://ninjatrader.com/support/help...?draw_line.htm

                  In the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients as well as our partners.

                  If you wish to debug the code on your own, I would suggest to add Print() statements throughout OnBarUpdate() to see how far your indicator travels through OnBarUpdate() before it throws the error you were receiving. This error typically occurs when an object is being referenced for some number of bars ago before those bars exist in the data series.

                  Debugging NinjaScript - http://ninjatrader.com/support/forum...ead.php?t=3418

                  You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. Please let me know if you would like our business development follow up with you with a list of professional NinjaScript Consultants who would be happy to create this script or any others at your request.

                  Please let me know if I may be of further help.
                  JimNinjaTrader Customer Service

                  Comment


                    #10
                    Originally posted by rdavido View Post
                    Hello, I am wanting to implement a strategy into NT8 that tracks the last X bars (volume or tick bars) and finds channels and automatically draws a trend channel. I have experimented a little bit and have been able to do draw static channels.

                    I know there is a dynamic SupDemZone indicator on futures.io which tracks upper/lower moves and continuations and can draw zones. I feel as though this could be modified to instead of tracking zones, track highs/lows and draw trends instead.

                    Furthermore, if given the chance to draw trend channels, could a strategy be implemented such that on a trend break EnterLong() or EnterShort() ??

                    Thanks

                    If you wish to create dynamic channels then you first need to determine the condtion required for a trend change. A trend change would terminate the current channel and then start a new one.

                    I know two ways of achieving this:

                    (1) You may use a volatility based zig zag indicator. The indicator would require a minimum deviation that can be expressed as a multiple of the range or average true range over a selected lookback period. Once a countermove exceeds the minimum deviation, this would correspond to a trend change.

                    When there is a trend change then the indicator can autodraw a new channel in line with the direction of the new trend. Best use linear regression channels with a fixed width or Raff Channels with a channel width that autoadjusts.

                    (2) You may also use Raff Channels or similar channels and define a trend change as the condition where a bar closes outside of the channel (above the channel in a downtrend, or below the channel in an uptrend), You would then draw a new channel in the direction of the emerging trend.

                    Such a system can be easily set up. However, you need to be aware that the trend change only becomes visible with a lag. The top is only confirmed after a breakout to the downside. The bottom is only confirmed after a breakout to the upside.

                    Comment


                      #11
                      Originally posted by Harry View Post
                      If you wish to create dynamic channels then you first need to determine the condtion required for a trend change. A trend change would terminate the current channel and then start a new one.

                      I know two ways of achieving this:

                      (1) You may use a volatility based zig zag indicator. The indicator would require a minimum deviation that can be expressed as a multiple of the range or average true range over a selected lookback period. Once a countermove exceeds the minimum deviation, this would correspond to a trend change.

                      When there is a trend change then the indicator can autodraw a new channel in line with the direction of the new trend. Best use linear regression channels with a fixed width or Raff Channels with a channel width that autoadjusts.

                      (2) You may also use Raff Channels or similar channels and define a trend change as the condition where a bar closes outside of the channel (above the channel in a downtrend, or below the channel in an uptrend), You would then draw a new channel in the direction of the emerging trend.

                      Such a system can be easily set up. However, you need to be aware that the trend change only becomes visible with a lag. The top is only confirmed after a breakout to the downside. The bottom is only confirmed after a breakout to the upside.
                      Harry, thanks for your replay. If i used a ZigZag, or even better, PriceActionSwing for NT8, how would I define a swing? Do you have a sample piece of code to get me going?

                      Comment


                        #12
                        Originally posted by rdavido View Post
                        Harry, thanks for your replay. If i used a ZigZag, or even better, PriceActionSwing for NT8, how would I define a swing? Do you have a sample piece of code to get me going?
                        NinjaTrader 8 comes with a zigzag indicator, but it has a few short comings:


                        (1) The minimum deviation can only be expressed in points or percent,

                        I personally prefer that the zigzag autoadjusts to volatility and like to use a minimum deviation which is a multiple of the average true range over a longer lookback period.

                        (2) The current preliminary swing is not displayed.

                        There is a reason that it is not displayed. The last swing is repainting as it evolves with price action. It only becomes final, once a new preliminary swing has been formed in the opposite direction. I personally prefer to display the last swing and have it evolving.

                        (3) When you scroll back, the swing is calculated from future data.

                        This is an absolute no-go, as the swing should only use data from the chart. Can be achieved via a custom plot.

                        The main problem of all sorts of swing indicators is that a swing point can only be identified with hindsight knowledge. You need to wait until price has made a countermove exceeding the minimum deviation. Once this has happened, you can draw the swing high point or swing low point N bars ago.

                        Therefore the last swing point is always preliminary. The second but the last is a final confirmed swing high or low.

                        I have not yet programmed a zigzag for NT8, so you would need to look for it elsewhere.

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by ursavent, Today, 12:54 PM
                        1 response
                        3 views
                        0 likes
                        Last Post NinjaTrader_Jesse  
                        Started by cre8able, Today, 01:01 PM
                        0 responses
                        4 views
                        0 likes
                        Last Post cre8able  
                        Started by manitshah915, Today, 12:59 PM
                        0 responses
                        3 views
                        0 likes
                        Last Post manitshah915  
                        Started by Mizzouman1, Today, 07:35 AM
                        3 responses
                        17 views
                        0 likes
                        Last Post NinjaTrader_Gaby  
                        Started by RubenCazorla, Today, 09:07 AM
                        2 responses
                        13 views
                        0 likes
                        Last Post NinjaTrader_ChelseaB  
                        Working...
                        X