• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Time Limit for 2nd condition

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

    Time Limit for 2nd condition

    Hello,
    I am coding an indicator or strategy that will give me a signal when several conditions are met. After the 1st condition is met, the others must occur within say 5 minutes for my signal to be generated. How would I include that 5 minute time limit in the conditions?

    Thanks!

    #2
    Hello GeorgeW,

    Thank you for your post.

    You could do the following:
    Code:
            #region Variables
            private DateTime firstSig;
    		private bool check = false;
            #endregion
    		
            protected override void Initialize()
            {
                
            }
    		
            protected override void OnBarUpdate()
            {
                if (!check && Close[0] > Open[0])
    			{
    				Print(Time[0] + " First Signal.");
    				firstSig = Time[0];
    				check = true;
    			}
    			if (check && Time[0] >= firstSig.AddMinutes(5))
    			{
    				Print(Time[0] + " Second Signal.");
    				check = false;
    			}
            }
    For information on DateTime please visit the following link: https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx
    For information on Time please visit the following link: http://ninjatrader.com/support/helpGuides/nt7/time.htm

    Please let me know if I may be of further assistance.
    Patrick H.NinjaTrader Customer Service

    Comment


      #3
      Hello and Thanks.

      I have followed your example, and it seems to work to a certain extent, as I can see my figures on the Output Screen. However there are a couple of problems.

      Basically I am looking for three signals. Let’s call them Signal 1, 2, and 3. These signals all have a numeric value which are then added together at the end of each 5 minute period. When #1 occurs it has 5 minutes to find #2 (which is not absolutely necessary) and #3 (which is necessary). Within the 5 minute period it is finding more than one instance of #2 and #3 on occasion. It currently only takes the last of those into the summation at the end of the 5 minute period. I would like it to take into account the lowest value for each of #2 and #3 in that final calculation if I am testing whether to go short (the long test will take the highest values). I have been looking to see if I can use MIN, but am not sure it would work, as my period is based on time and not bars. Is there a way for me to do this?

      I have also found that on one occasion the summation included a value from before Signal #1, when it should only include Signal #1 and the lowest of each of #2 and #3 that occurs in the 5 minutes after. Is there a way to ensure this does not happen? (I have just checked, and it does this when there is no instance of #2 in the 5 mins after Signal #1, it goes back and picks up the last #2 before signal #1)

      Thanks!
      Last edited by GeorgeW; 02-17-2016, 11:33 AM.

      Comment


        #4
        To work with only the lowest value from all occurrences of a certain signal, you could first feed the numeric values from those signals into a list, then use MIN on the list itself. That way, you can feed all of the values that appear into a single method, which would return the lowest of them all.

        Edit: This link should prove useful here: http://www.dotnetperls.com/max

        To prevent values prior to a new occurrence of Signal 1 from coming into the mix, assuming you go the route of using lists to store values for each signal, you could clear out the list at the same time you are processing other logic related to the five minute period ending. That way, every time "check" is set to False in Patrick's example, your list would be cleared, as well.
        Dave I.NinjaTrader Product Management

        Comment


          #5
          Using Dave's link above and the example from Ricam here: http://ninjatrader.com/support/forum...ad.php?t=65699 I came up with the additional code below for the array to find the Min value to include in my computation.

          Code:
          #region Using declarations
          using System;
          using System.Linq;
          #endregion
          
          #region Variables
          //Declare an array that will hold data for tovBullBar
          private double[] tovBull;
          private int length;
          #endregion
          
          protected override void Initialize()
          {
          //specify the number of elements in the array, which is the
          integer called length
          tovBull = new double[length];
          }
          
          protected override void OnBarUpdate()
          {
          //the array now contains the number length of object references
          that need to be set to instances of objects
          for (int count = 0; count<length; count++)
          tovBull[count]=tovBullBar;
          
          tovBullBar = tovBull.Min();
          netLvtTOV = Math.Round((tovBearBar + tovBullBar + lvtBullBar)
          
          }
          It complies ok, but then my calculations disappear from the output window, which has this error: "**NT** Error on calling 'OnBarUpdate' method for strategy '"MyTSovSignal03"/e1598cd055b34d079505aef7899c2a20': Sequence contains no elements"
          If I comment out this line "tovBullBar = tovBull.Min();", the computations return to the output window, but still selecting the last value for tovBullBar in the final computation instead of the Min value.

          Any advice for how I might fix this?

          Thanks!

          Comment


            #6
            I think the line "tovBullBar = tovBull.Min();" must be replaced with the code below in order to search for the minimum. But I am getting a CS0127 error which says "a return keyword must not be followed by an object expression!"

            Code:
            double min = tovBull[0];   
            for (int i = 0; i<tovBull.Length; i++)
            if (min > tovBull[i]) min = tovBull[i];
            return min;

            Comment


              #7
              Hello GeorgeW,

              You have not assigned the length variable to a number and are creating a new array with the length variable.

              Ensure that length is assigned to an integer before using it to create your array.

              Also, you are attempting to use a return from within a method that returns void. A method with a return type of void cannot return anything.
              Zachary G.NinjaTrader Customer Service

              Comment


                #8
                Thank you ZacharyG.
                My coding is pretty basic, so please bear with me.
                Does it have to be an integer? Can I assign it to a double? My results are to 2 decimal places.
                I have this under the Initialize region, I assume that is assigning it?
                Code:
                tovBull = new double[tovBull.Length];
                When I comment out Return it compiles but produces no results. I get:
                "**NT** Failed to call method 'Initialize' for strategy "MyTSovSignal03"/e1598cd055b34d079505aef7899c2a20': Object reference not set to an instance of an object."

                Not sure what I need to do about the Return.

                Comment


                  #9
                  Hello GeorgeW,

                  You have not initialized tovBull. tovBull is null.

                  You are then using the length of tovBull (which is null) to initialize tovBull.

                  This is why you are getting the "object reference not set to an instance of an object" error.

                  I would suggest taking a look at the Arrays Tutorial on MSDN for more information about creating arrays: https://msdn.microsoft.com/en-us/lib...(v=vs.71).aspx

                  Additionally, I am not sure what you are trying to do with the return. You cannot return from a void return type method.

                  Once min has been assigned, there is no need to do a return. min is now whatever value you have assigned it.
                  Zachary G.NinjaTrader Customer Service

                  Comment


                    #10
                    Originally posted by GeorgeW View Post
                    Using Dave's link above and the example from Ricam here: http://ninjatrader.com/support/forum...ad.php?t=65699 I came up with the additional code below for the array to find the Min value to include in my computation.

                    Code:
                    #region Using declarations
                    using System;
                    using System.Linq;
                    #endregion
                    
                    #region Variables
                    //Declare an array that will hold data for tovBullBar
                    private double[] tovBull;
                    private int length;
                    #endregion
                    
                    protected override void Initialize()
                    {
                    //specify the number of elements in the array, which is the
                    integer called length
                    tovBull = new double[length];
                    }
                    
                    protected override void OnBarUpdate()
                    {
                    //the array now contains the number length of object references
                    that need to be set to instances of objects
                    for (int count = 0; count<length; count++)
                    tovBull[count]=tovBullBar;
                    
                    tovBullBar = tovBull.Min();
                    netLvtTOV = Math.Round((tovBearBar + tovBullBar + lvtBullBar)
                    
                    }
                    It complies ok, but then my calculations disappear from the output window, which has this error: "**NT** Error on calling 'OnBarUpdate' method for strategy '"MyTSovSignal03"/e1598cd055b34d079505aef7899c2a20': Sequence contains no elements"
                    If I comment out this line "tovBullBar = tovBull.Min();", the computations return to the output window, but still selecting the last value for tovBullBar in the final computation instead of the Min value.

                    Any advice for how I might fix this?

                    Thanks!
                    That is telling you that in that instance, the Array contains no elements. Check for an Array length greater than zero, before you execute the code.

                    Comment


                      #11
                      Thanks ZacharyG and Koganam.

                      The code now mostly works, showing an ArrayLength of 10, which is the number of elements I have defined. 1 main problem remains. I have used Array.Clear to 0 the array after the 3 mins, but even so, where there is a 3 min period that does not include a tovBullBar value and it should therefore return 0 for that value in my computation, the code looks back beyond the 3 min period and picks up the last tovBullBar value. Is my Array.Clear in the correct place?

                      Code:
                      		`#region Using declarations
                      using System;
                      using System.Linq;
                      using System.Collections.Generic;
                      There are other using declarations specific to NinjaScript
                      #endregion
                      
                      {
                          public class MyTSovSignal10 : Strategy
                          {
                              #region Variables
                              
                      			“A number of other variables have been set”
                      			
                      			private int period = 20; // Default setting for Period
                      		
                      			
                      			private DateTime firstSig;
                      			private bool check = false;
                      		
                      			//Declare an array that will hold data for tovBullBar
                      			private double[] tovBull;
                      			private int length = 10;
                      		
                              #endregion
                      
                              protected override void Initialize()
                              {
                                  CalculateOnBarClose = true;
                      			tovBull = new double[length];
                      			for (int i = 0; i < tovBull.Length; i++)
                          			tovBull[i] = double.MaxValue;
                      			
                      		}
                      
                             protected override void OnBarUpdate()
                              {
                      			if (CurrentBar < period) return;
                      			
                      			for (int count = 1; count<length; count++)
                      			tovBull[count]=tovBull[count - 1];							
                      			tovBull[0] = tovBullBar;
                      
                      			//Do a for loop to find the minimum for the tovBull
                      			double tovBullBarMin = tovBull[0];
                      			for (int count = 1; count < tovBull.Length; count++)
                      			{
                      if (tovBullBarMin > tovBull[count]) tovBullBarMin = tovBull[count];	
                      			}
                      				
                      				
                      						
                      			if(Condition for LVTBulls met)
                      			
                      			
                                  {               	
                      		lvtBullBar = (Math.Round(LVTBullBar Calculation);
                      		Print(Time[0] + " First Signal.");
                      		Print (Time.ToString()+" "+"lvtBullBar:"+lvtBullBar);
                      		firstSig = Time[0];
                      		check = true;
                                 }
                      		if (check && Time[0] < firstSig.AddMinutes(3))
                      		{
                      			
                      			//Bull TOV Calculation
                      if (Condition for TOVBullBar met within 3mins of firstsig)
                      			{
                      tovBullBar = (Math.Round(Calculate all instances of tovBullBar in the 3mins since firstsig);
                      			Print (Time.ToString()+" secondSignal.");
                      			Print (Time.ToString()+" "+"tovBullBar:"+tovBullBar);
                      			}
                      		
                      			
                      			//Bear TOV Calculation
                      			if (Condition for TOVBear met)
                      			{
                      tovBearBar = (Math.Round(Calculate all instances of TOVBear);
                      
                      netLvtTOV = Math.Round((lvtBullBar + tovBullBarMin + tovBearBar),2);
                      						
                      			}
                      			
                      			
                      			}
                      			
                      			if (check && Time[0] >= firstSig.AddMinutes(3))
                      			{
                      			Array.Clear(tovBull,0,tovBull.Length);
                      			Print(Time[0] + " Final Signal.");
                      			check = false;`

                      Comment


                        #12
                        Hello GeorgeW,

                        Thanks for your reply.

                        In the area where you clear the array you may also want to reset the variable tovBullBar to zero.
                        Paul H.NinjaTrader Customer Service

                        Comment


                          #13
                          That's done the trick. Thanks Paul.

                          Comment


                            #14
                            Thought I had this licked, but I have found there is still a problem.

                            Currently, the code is picking up only 1 instance of a lvtBullBar in a 3 minute period, and if any tovBearBar is encountered within a 3 minute period from the time the lvtBullBar closed, then the following calculation is done: netLvtTOV = Math.Round((lvtBullBar + tovBullBar + tovBearBar),2);

                            The tovBullBar is the Min of a bar that may or may not occur several times between the lvtBullBar and the tovBearBar.

                            In pseudo code, this is what I am trying to achieve.
                            1. All instances of lvtBullBars should be picked up.
                            2. If within 3 minutes of a lvtBullBar there is a tovBearBar, and another lvtBullBar has not occurred before:
                            a. Carry out the calculation: netLvtTOV = Math.Round((lvtBullBar + tovBullBar + tovBearBar),2);
                            b. The tovBullBar is the Min of a bar that may or may not occur several times between the lvtBullBar and the tovBearBar. But once there is another lvtBullBar or 3mins have elapsed, the tovBullBar can no longer be used in the calculation.
                            3. So essentially, within any 3min period if only 1 lvtBullBar (let’s call it #1) has occurred and there are several tovBearBars, there will be several calculations using #1. But if before the 3mins is up there are other lvtBullBars, new calculations will be based on the latest.

                            Current Code:
                            Code:
                            protected override void OnBarUpdate()
                            			
                            			
                                    {
                            			for (int count = 1; count<tovBull.Length; count++) //Think count = 1 here, because next line count - 1 cannot be smaller than 0
                            			tovBull[count]=tovBull[count - 1]; //shuffle along by one
                            			tovBull[0] = tovBullBar;//adds latest to front of the array, because you shuffled along by one, latest is always index 0			
                            if(!check && (CrossAbove(myBsc.BuySellChangePlot, overboughtBSChange, 2)) && (myBsc.BuySellChangePlot[0] > overboughtBSChange) && (myBsc.BuySellChangePlot[0]) > (myBsc.BuySellChangePlot[1]) && (myBsl.BuySellLine[0] > OverboughtBSL) && ((Close[0] > Open[0]) || ((Open[0] == Close[0]) && (Math.Abs(High[0] - Open[0]) < Math.Abs(Low[0] - Open[0])))))				
                            
                                        {                	
                            lvtBullBar = (Math.Round((myBsc[0]),2));
                            firstSig = Time[0];
                            check = true;
                                        }
                            
                            if (check && Time[0] < firstSig.AddMinutes(maxSignalTime))
                            {			
                            if (((Close[0] > Open[0]) || ((Open[0] == Close[0]) && (Math.Abs(High[0] - Open[0]) < Math.Abs(Low[0] - Open[0]))))&& (myBsc.BuySellChangePlot[0]) < (myBsc.BuySellChangePlot[1]))
                            {
                            	tovBullBar = (Math.Round((myBsc[0]) - (myBsc[1]),2));
                            				
                            	//Do a for loop to find the minimum for the tovBull
                            	for (int i = 0; i<tovBull.Length; i++)
                            	if (tovBull[i] < tovBullBar) tovBullBar = tovBull[i]; 				
                            }
                            
                            if (((Close[0] < Open[0])||((Open[0] == Close[0]) &&(Math.Abs(High[0] - Open[0]) > Math.Abs(Low[0] - Open[0])))) && (myBsc.BuySellChangePlot[0] < oversoldBSChange) && (myBsc.BuySellChangePlot[0]) < (myBsc.BuySellChangePlot[1]))
                            {
                            	tovBearBar = (Math.Round((myBsc[0]) - (myBsc[1]),2));		
                            				
                            	netLvtTOV = Math.Round((lvtBullBar + tovBullBar + tovBearBar),2);
                            								
                            	Print (Time.ToString()+" "+"ArrayValues:"+tovBull[0]+" "+tovBull[1]+" "+tovBull[2]+" "+tovBull[3]+" "+tovBull[4]+" "+tovBull[5]+" "+tovBull[9]);
                            }
                            
                            }
                            			
                            if (check && Time[0] >= firstSig.AddMinutes(maxSignalTime))
                            {
                            	Array.Clear(tovBull,0,9);			
                            tovBullBar = 0; //reset tovBullBar to 0 to complete clearing of it
                            	check = false;
                            }
                            }
                            I have tried removing the “check” from the entire code, because that is what seems to be restricting the lvtBullBar to 1 in a 3min period. This allows all the lvtBullBars to be picked up (on Print output screen), but then the tovBullBars are no longer restricted to those between a lvtBullBar and each tovBearBar, but they are also being picked up for periods before the lvtBullBar, and some even for periods greater than 3mins.

                            Any ideas would be welcomed.
                            Thanks!
                            Last edited by GeorgeW; 03-02-2016, 10:25 AM.

                            Comment


                              #15
                              Hello GeorgeW,

                              Thanks for your post.

                              While we do not provide debugging service I would suggest having a careful review of the following statement:

                              Code:
                              			if(!check && (CrossAbove(myBsc.BuySellChangePlot, overboughtBSChange, 2)) 
                              			&& (myBsc.BuySellChangePlot[0] > overboughtBSChange) 
                              			&& myBsc.BuySellChangePlot[0]) > (myBsc.BuySellChangePlot[1]) 
                              			&& (myBsl.BuySellLine[0] > OverboughtBSL) 
                              			&& ((Close[0] > Open[0]) || ((Open[0] == Close[0]) 
                              			&& (Math.Abs(High[0] - Open[0]) < Math.Abs(Low[0] - Open[0])))))				
                                          {                	
                              				lvtBullBar = (Math.Round((myBsc[0]),2));
                              				firstSig = Time[0];
                              				check = true;
                                          }
                              I've shown that the red "()" may not be correctly placed.
                              Paul H.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by yeshujbp, Today, 08:10 PM
                              0 responses
                              1 view
                              0 likes
                              Last Post yeshujbp  
                              Started by backtester831, Today, 06:54 PM
                              0 responses
                              1 view
                              0 likes
                              Last Post backtester831  
                              Started by frayrengytrader, Today, 06:03 PM
                              0 responses
                              3 views
                              0 likes
                              Last Post frayrengytrader  
                              Started by JustAFish, Today, 05:29 PM
                              0 responses
                              5 views
                              0 likes
                              Last Post JustAFish  
                              Started by TraderCAD, Today, 04:27 PM
                              1 response
                              8 views
                              0 likes
                              Last Post TraderCAD  
                              Working...
                              X