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

Recursive Property

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

    Recursive Property

    Hello,

    My coding runs into some recursive issue which I believe is beyond my knowledge to resolve.

    The indicator of MA Envelopes runs well, but when I tried to code it into multiple time frame, this issue comes up.

    Code:
    // This namespace holds all indicators and is required. Do not change it.
    namespace NinjaTrader.Indicator
    {
        /// <summary>
        /// Moving Average Envelopes
        /// </summary>
        [Description("Plots % envelopes around a moving average")]
        public class Envelopes : Indicator
        {
            #region Variables
    		private int				matype				= 3;
    		private int				period				= 26;
    		private double			envelopePercentage = 0.618;
    		private double          innerPercentage    = 0.381;
    		private int             timeFrame          =30; 
    		#endregion
    
            /// <summary>
            /// This method is used to configure the indicator and is called once before any bar data is loaded.
            /// </summary>
            protected override void Initialize()
            {
    			// Adds a plot for the MA values to be stored in
    			Add(new Plot(Color.Gold, "Upper"));
    			Add(new Plot(Color.Red, "Middle"));
    			Add(new Plot(Color.Gold, "Lower"));
    			Add(new Plot(Color.Khaki, "InnerUpper"));
    			Add(new Plot(Color.Khaki, "InnerLower"));
    			Plots[1].Pen.DashStyle = DashStyle.Dash;
    			
    			Add(PeriodType.Minute,timeFrame);
    			
                Overlay				= true;
            }
    
            /// <summary>
            /// Called on each bar update event (incoming tick)
            /// </summary>
            protected override void OnBarUpdate()
            {
    			double maValue = 0;
    
    			switch (matype)
    			{
    				case 1:
    				{	
    					Middle.Set(maValue = EMA(BarsArray[1], Period)[0]);
    					break;
    				}
    				case 2:
    				{
    					Middle.Set(maValue = HMA(BarsArray[1], Period)[0]);
    					break;
    				}
    				case 3:
    				{
    					Middle.Set(maValue = SMA(BarsArray[1], Period)[0]);
    					break;
    				}
    				case 4:
    				{
    					Middle.Set(maValue = TMA(BarsArray[1], Period)[0]);
    					break;
    				}
    				case 5:
    				{
    					Middle.Set(maValue = TEMA(BarsArray[1], Period)[0]);
    					break;
    				}
    				case 6:
    				{
    					Middle.Set(maValue = WMA(BarsArray[1], Period)[0]);
    					break;
    				}
    			}
    			
    			Upper.Set(maValue + (maValue * EnvelopePercentage / 100));
    			Lower.Set(maValue - (maValue * EnvelopePercentage / 100));
    			InnerUpper.Set(maValue + (maValue*InnerPercentage/100));
    			InnerLower.Set(maValue - (maValue*InnerPercentage/100));
            }
    		
            #region Properties
    		[Description("1 = EMA, 2 = HMA, 3 = SMA, 4= TMA, 5 = TEMA, 6 = WMA")]
    		[GridCategory("Parameters")]
    		[Gui.Design.DisplayNameAttribute("Moving average type")]
    		public int MAType
    		{
    			get { return matype; }
    			set { matype = Math.Min(6, Math.Max(1, value)); }
    		}
    		
    		[Description("Numbers of bars used for calculations")]
    		[GridCategory("Parameters")]
    		[Gui.Design.DisplayNameAttribute("Period")]
    		public int Period
    		{
    			get { return period; }
    			set { period = Math.Max(1, value); }
    		}
    		[Description("Percentage around MA that envelopes will be drawn")]
    		[GridCategory("Parameters")]
    		[Gui.Design.DisplayNameAttribute("Envelope percent offset")]
    		public double EnvelopePercentage
    		{
    			get { return envelopePercentage; }
    			set { envelopePercentage = Math.Max(0.01, value); }
    		}
    		[Description("Percentage around MA that envelopes will be drawn")]
    		[GridCategory("Parameters")]
    		[Gui.Design.DisplayNameAttribute("Envelope percent offset")]
    		public double InnerPercentage
    		{
    			get { return innerPercentage; }
    			set { innerPercentage = Math.Max(0.01, value); }
    		}
    		[Description("Numbers of bars used for calculations")]
    		[GridCategory("Parameters")]
    		[Gui.Design.DisplayNameAttribute("timePeriod")]
    		public int timeFrame
    		{
    			get { return timeFrame; }
    			set { timeFrame= Math.Max(1, value); }
    		}
    		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries Upper
            {
                get { return Values[0]; }
            }
    		
    		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries Middle
            {
                get { return Values[1]; }
            }
    
    		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries Lower
            {
                get { return Values[2]; }
            }
    		
    		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries InnerUpper
            {
                get { return Values[3]; }
            }
    		
    		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries InnerLower
            {
                get { return Values[4]; }
            }
            #endregion
        }
    }

    The notification is included in the attachment.

    Thank you !!
    Attached Files
    Last edited by wolfcuring; 05-25-2016, 01:56 AM.

    #2
    [Description("Numbers of bars used for calculations")]
    [GridCategory("Parameters")]
    [Gui.Design.DisplayNameAttribute("timePeriod")]
    public int timeFrame
    {
    get { return timeFrame; }
    set { timeFrame= Math.Max(1, value); }
    }
    You have a property defined as above. The parts in red show that your public property is the same as its backing store. Make them different,

    Comment


      #3
      Hello wolfcuring,

      Thank you for your post.

      koganam is correct. The new property that would be public would need to be named differently or at the least have the first letter capitalized.

      Comment


        #4
        Thank you Koganam, Thank you Patrick,

        Now, the indicator compiles well, without any grammatical error, but it just does not plot on the Chart. I checked over and over again, the logic is copied from the default MA Envelopes, and seems all right.

        Besides, what is the rule about upper and lower case concerning variables ? For example, when stated in the Variables region, it is mAType, when used in EMA(BarsArray[1], MAPeriod)[0], it is upper case.

        Code:
        namespace NinjaTrader.Indicator
        {
            /// <summary>
            /// Envelopes that can plot any time period desired. 
            /// </summary>
            [Description("Envelopes that can plot any time period desired. ")]
            public class MTFEnvelopes : Indicator
            {
                #region Variables
                // Wizard generated variables
                    private int mAPeriod = 26; // Default setting for MAPeriod
                    private int mAType = 3; // Default setting for MAType
                    private int timeFrame = 30; // Default setting for TimeFrame
                    private double outerPercent = 0.618; // Default setting for OuterPercent
        		    private double innerPercent =0.381; 
                // User defined variables (add any user defined variables below)
                #endregion
        
                /// <summary>
                /// This method is used to configure the indicator and is called once before any bar data is loaded.
                /// </summary>
                protected override void Initialize()
                {
                    Add(new Plot(Color.FromKnownColor(KnownColor.Firebrick), PlotStyle.Line, "MA"));
                    Add(new Plot(Color.FromKnownColor(KnownColor.Green), PlotStyle.Line, "Upper"));
                    Add(new Plot(Color.FromKnownColor(KnownColor.Green), PlotStyle.Line, "Lower"));
                    Add(new Plot(Color.FromKnownColor(KnownColor.Gold), PlotStyle.Line, "InnerUpper"));
        			Add(new Plot(Color.FromKnownColor(KnownColor.Gold), PlotStyle.Line, "InnerLower"));
        			
        			Add(PeriodType.Minute,timeFrame); 
                    Overlay				= true;
                }
        
                /// <summary>
                /// Called on each bar update event (incoming tick)
                /// </summary>
                protected override void OnBarUpdate()
                {
                    double maValue = 0;
        
        			switch (mAType)
        			{
        				case 1:
        				{	
        					MA.Set(maValue = EMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        				case 2:
        				{
        					MA.Set(maValue = HMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        				case 3:
        				{
        					MA.Set(maValue = SMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        				case 4:
        				{
        					MA.Set(maValue = TMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        				case 5:
        				{
        					MA.Set(maValue = TEMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        				case 6:
        				{
        					MA.Set(maValue = WMA(BarsArray[1], MAPeriod)[0]);
        					break;
        				}
        			}
        			
        			Upper.Set(maValue + (maValue * OuterPercent / 100));
        			Lower.Set(maValue - (maValue * OuterPercent / 100));
        			InnerUpper.Set(maValue + (maValue * InnerPercent / 100));
        			InnerLower.Set(maValue - (maValue * InnerPercent / 100));
                }
        
                #region Properties
                [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public DataSeries MA
                {
                    get { return Values[0]; }
                }
        
                [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public DataSeries Upper
                {
                    get { return Values[1]; }
                }
        
                [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public DataSeries Lower
                {
                    get { return Values[2]; }
                }
        
                [Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public DataSeries InnerUpper
                {
                    get { return Values[3]; }
                }
                
        		[Browsable(false)]	// this line prevents the data series from being displayed in the indicator properties dialog, do not remove
                [XmlIgnore()]		// this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
                public DataSeries InnerLower
                {
                    get { return Values[4]; }
                }
        		
                [Description("The period that Moveing Average calculates.")]
                [GridCategory("Parameters")]
                public int MAPeriod
                {
                    get { return mAPeriod; }
                    set { mAPeriod = Math.Max(1, value); }
                }
        
                [Description("Choice among different MA types.")]
                [GridCategory("Parameters")]
                public int MAType
                {
                    get { return mAType; }
                    set { mAType = Math.Max(1, value); }
                }
        
                [Description("Time frame you choose.")]
                [GridCategory("Parameters")]
                public int TimeFrame
                {
                    get { return timeFrame; }
                    set { timeFrame = Math.Max(1, value); }
                }
        
                [Description("Percentage off the Moveing Average.")]
                [GridCategory("Parameters")]
                public double OuterPercent
                {
                    get { return outerPercent; }
                    set { outerPercent = Math.Max(0, value); }
                }
        		
        		[Description("Percentage off the Moveing Average.")]
                [GridCategory("Parameters")]
                public double InnerPercent
                {
                    get { return innerPercent; }
                    set { innerPercent = Math.Max(0, value); }
                }
                #endregion
            }
        }

        Comment


          #5
          Hello wolfcuring,

          Thank you for your update on this matter.

          When enabling the indicator do you receive any messages in the Log tab of the Control Center regarding the indicator? If so, what do these messages report?

          Comment


            #6
            The Log file said like this:

            Error on calling 'OnBarUpdate' method for indicator 'MTFEnvelopes' on bar 0: You are accessing an index with a value that is invalid since its out of range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.

            Comment


              #7
              Hi Patrick,

              You reminds me. So, I added the following two lines on top of the OnBarUpdate(), and it worked.

              if (CurrentBars[0] <= mAPeriod+1 || CurrentBars[1] <= mAPeriod+1 ) return;
              if(BarsInProgress!=0) return;

              So, the first line is to guarantee that there are enough bars to calculate, but, why it must work under the primary DataSeries ?

              Comment


                #8
                Hello wolfcuring,

                Thank you for your response.

                Your code in OnBarUpdate() is not specified to run only in BarsInProgress == 1, so it also runs when BarsInProgress == 0.

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by Javierw.ok, Today, 04:12 PM
                0 responses
                4 views
                0 likes
                Last Post Javierw.ok  
                Started by timmbbo, Today, 08:59 AM
                2 responses
                10 views
                0 likes
                Last Post bltdavid  
                Started by alifarahani, Today, 09:40 AM
                6 responses
                40 views
                0 likes
                Last Post alifarahani  
                Started by Waxavi, Today, 02:10 AM
                1 response
                18 views
                0 likes
                Last Post NinjaTrader_LuisH  
                Started by Kaledus, Today, 01:29 PM
                5 responses
                15 views
                0 likes
                Last Post NinjaTrader_Jesse  
                Working...
                X