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

BarsInProgress stays at 0 with multiple data series added

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

    BarsInProgress stays at 0 with multiple data series added

    Hi I am doing an ETF rotation strategy/indicator based on http://www.etfreplay.com

    They use a relative strength + volatility based rating. I am sorting by returns for two different periods (A, B) and volatility over period V.

    I had the code working and for some reason it stopped. The BarsInProgress var stays at 0 even though BarsArray has 10 elements in it. I can't understand why. The only thing I did is redefined session templates under instrument manager and downloaded more data from kinetic.

    I would appreciate if someone could look at this prelim code and see if I am doing something stupid that I have overlooked.

    Since I was only playing around I coded it as an indicator where you would be able to selects ETFs defined by an ENUM that would then be added to the primary data series. One would then be able to select the dates and the calculations would be done. For now the dates are hard coded and the script looks for the bar# of the selected date and does the computation. Print() statements are used to debug the code ... I have included a screen shot from yesterday when it was working ,,, today it only runs BarsInProgress = 0 and does't even end up doing the computation as it is called only once BarsInProgress == BarsArray.Length - 1

    Please any input would be appreciated!


    Code:
           protected override void Initialize()
           {		
                           // instantiate the etf collections		
    			etf = new List<EtfData>();
    			
    			// make sure this charts series is added to the list
    			if (!etf.Exists(delegate(EtfData item) { return item.Label == Instrument.FullName; }))
    				etf.Add(new EtfData(Instrument.FullName));							
    
    			// fill the collections with the selected ETFs	
    			if (etfsel != EtfType.ALL)
    			{		
    				if (!etf.Exists(delegate(EtfData item) { return item.Label == etfsel.ToString(); }))
    					etf.Add(new EtfData(etfsel.ToString()));							
    			}
    			else
    			{// add all the ETFs ...
    				
    				// ... by itterating over the values in the enum
    				foreach (EtfType value in Enum.GetValues(typeof(EtfType)))
    				{
    					if (value == EtfType.ALL) 
    						continue;	// with the exception of EtfType.ALL ...
    					
    					if (!etf.Exists(delegate(EtfData item) { return item.Label == value.ToString(); }))
    						etf.Add(new EtfData(value.ToString()));							
    				}
    			}
    			
    			// debug: added etfs
    			
    				Print("added etf(s) :");
    				foreach (EtfData item in etf)
    					Print(item.Label);
    				Print("");
    				ClearOutputWindow();
    						
    
    			
    		    // go through the collection of ETFs and add them as dataseries to BarsArray
    			// note: the indicator's chart series is already in BarsArray on index 0, 
    			// with each addition the corresponding value of BarsInProgress increases by 1 
    			foreach (EtfData item in etf)
    			{
    				if (item.Label == Instrument.FullName) 
    					continue; // dont add it (already in by default)
    				else
    					Add(item.Label, PeriodType.Day, ndays);
    			}
    			
    			// temp code ...
    			endDate = new DateTime(2012, 11, 05);
    			startDate = new DateTime(2012, 08, 05);
    			// .............
    			
    			// create the DateTimeSeries for getting the date of current bar
    			date = new DateTimeSeries(this);
    			
                Overlay	= false;	
    			
    		}
    				
            /// <summary>
            /// Called on each bar update event (incoming tick)
            /// </summary>
            protected override void OnBarUpdate()
            {					
    			// make sure we have the right bars period type
    			if (BarsPeriod.Id != PeriodType.Day && BarsPeriod.Value < 1)
    				return;	
    	
    			if (CurrentBar == 0)
    			{
    				Print("");
    				Print("all data series in BarsArray :");
    				for (int i = 0; i < BarsArray.Length; i++)
    					Print(BarsArray[i].Instrument.FullName);
    				Print("");				
    			
    				Print("");
    				Print("start date: " + startDate.ToString());		
    				Print("end date: " + endDate.ToString());
    				Print("");			
    				
    			}
    				
    			// make sure there are enough bars
    			if (CurrentBar <= GetMaxPeriod()) // in this case <= because [barsago+1] below
    				return;
    
    			/// Bars are already loaded and OnBarUpdate() will run only on a new bar !
    			/// need to use GetBar() to get data for bars with the correct dates
    			
    			int endbar   = Bars.GetBar(endDate);
    			int barsago  = CurrentBar - endbar;
    			int barsagoA = barsago + periodA;
    			int barsagoB = barsago + periodB;
    					
    			if (CurrentBar == endbar)
    			{// perform computation once CurrentBar # and endDate bar # match
    				
    				// debug: flow control
    					
    					Print("Processing ETF << " + etf[BarsInProgress].Label + " >>");
    					Print("BarsInProgress = " + BarsInProgress.ToString());
    					Print("Current bar is # " + CurrentBar.ToString()); 
    					Print("Current end bar is # " + CurrentBar.ToString()); 
    					Print("GetMaxPeriod() = " + GetMaxPeriod().ToString());
    					Print("");
    				
    				// degug: start/end bar prices
    				/*
    					Print("start bar close : " + Close[barsagoA].ToString());		
    					Print("end bar close   : " + Close[barsagoB].ToString());
    				*/
    								
    				/// use BarsInProgress to make sure it is saved to the correct data series
    				
    				// get the 1st return
    				double rA = (Close[barsago] - Close[barsagoA]) / Close[barsagoA];
    				
    				// get the 2nd return
    				double rB = (Close[barsago] - Close[barsagoB]) / Close[barsagoB];
    			
    				// volatility calculation ...
    				// a) get the individual returns for the defined period and 
    				// b) store them in the data set
    				double[] vreturns = new double[periodV];
    				for (int i = barsago + (periodV-1); i >= 0; i--) // itterate down from 19 to 0 values ago from barsago (20 values)
    					vreturns[barsago] = ((Close[barsago] - Close[barsago+1]) / Close[barsago+1]);
    				
    				// compute  volatility
    				// a) using standard deviation and 
    				// b) anualize it by multipling it by 252 
    				//    where 252 = trading days in a year 
    				double v = StandardDeviation(vreturns, periodV) * Math.Sqrt(252);				
    				
    				// save results to etf data
    				etf[BarsInProgress].ReturnA = rA;		
    				etf[BarsInProgress].ReturnB = rB;		
    				etf[BarsInProgress].Volatility = v;			
    				
    				if (BarsInProgress == etf.Count-1) // with all series saved
    				{ // go ahead computing the rank by ...
    				
    					// make a copy of the original data
    					List<List<EtfData>> data = new List<List<EtfData>>();
    
    					// add 3 copies of etf data (one for each sort)
    					data.Add(etf);
    					data.Add(etf);
    					data.Add(etf);
    					
    					// sort the data by returns (A, B) and Volatility (V)
    					// ... need to reverse order for sorting by returns because we need high to low (default sort is low to high)
    					foreach(List<EtfData> container in data)
    					{
    						switch(data.IndexOf(container))
    						{
    							case A: 
    								container.Sort( delegate (EtfData item1, EtfData item2) 
    									{ return item1.ReturnA.CompareTo(item2.ReturnA); });
    								container.Reverse();
    							break;
    							case B: container.Sort( delegate (EtfData item1, EtfData item2) 
    									{ return item1.ReturnB.CompareTo(item2.ReturnB); });
    								container.Reverse();
    							break;
    							case V: container.Sort( delegate (EtfData item1, EtfData item2) 
    									{ return item1.Volatility.CompareTo(item2.Volatility); });
    							break;
    						}
    					}
    					
    					
    					// compute rankby order of all data
    					foreach(List<EtfData> container in data)
    					{
    						foreach (EtfData item in container)
    						{		
    							switch(data.IndexOf(container))
    							{
    								case A: item.RankByA = container.IndexOf(item); break;
    								case B: item.RankByB = container.IndexOf(item); break;
    								case V: item.RankByV = container.IndexOf(item); break;
    							}
    						}
    					}
    				
    					// compute overall rank	using weights & save the results
    					foreach(EtfData item in etf)
    					{
    						item.RankByA = data[0].Find(delegate (EtfData d) { return d.Label == item.Label; }).RankByA;
    						item.RankByB = data[0].Find(delegate (EtfData d) { return d.Label == item.Label; }).RankByB;
    						item.RankByV = data[0].Find(delegate (EtfData d) { return d.Label == item.Label; }).RankByV;
    						item.FinalRank = item.RankByA*weightA + item.RankByB*weightB + item.RankByV*weightV;  
    					}
    				
    				
    					// sort the final etf results
    					etf.Sort( delegate (EtfData item1, EtfData item2) 
    						{
    							return item1.FinalRank.CompareTo(item2.FinalRank);
    						}
    					);
    								
    				
    					// etf should now contain the final result order !
    						
    					// debug: contents of data
    					
    						Print("");
    						Print("*********************");
    						Print("       RESULTS       ");
    						Print("*********************");		
    						foreach (EtfData item in etf)
    						{
    							Print("# " + (etf.IndexOf(item) + 1).ToString()+ " Etf << " + item.Label + " >>");
    							Print("RA = " + (item.ReturnA * 100).ToString("0.0"));
    							Print("RB = " + (item.ReturnB * 100).ToString("0.0"));
    							Print("V  = " + (item.Volatility * 100).ToString("0.0"));
    							Print("");
    						}
    						Print("");		
    				}
    			
    			}		
            }
    Attached Files

    #2
    Hello fx_pete,

    It is recommended that you use the Add() with static variables, as dynamic variables inside the Add() method are not supported.

    With that said you may want to use a try-catch block when using the Add() method.

    Try-Catch: http://www.ninjatrader.com/support/f...ead.php?t=9825

    Example: http://www.ninjatrader.com/support/f...d=4&linkid=512

    Let us know if we can be of further assistance.
    JCNinjaTrader Customer Service

    Comment


      #3
      thanks for the fast reply ...

      I've tried the catch blocks but no errors are caught. What bothers me is that I Print out the contents of BarsArray[] and see that it has all the elements that I expect but the debug Print() statement in the OnBarUpdate() clearly shows that BarsInProgress is always 0. To the best of my knowledge once BarsArray[] has more then one element OnBarUpdate() should run more then once increasing BarsInProgress by one each time. Can you think of something that would interfere with this operation. Ie, have you ever come across a situation where BarsArray[] has more elements but OnBarUpdate() is executed only for the original series?

      Comment


        #4
        Hello fx_pete,

        When dynamically using the Add() method inside Initialize() you may run into some unexpected results.

        If you statically use the Add() for the instruments, does this resolve your problem?

        Happy to be of further assistance.
        JCNinjaTrader Customer Service

        Comment


          #5
          thanks, but tried that and get the same result .... ok now it seems that there may something wrong with loading the data for the instruments. Please can you give me an example of what the instrument manager settings should look like for lets say the SPY symbol for Kinetic (EOD)?

          Comment


            #6
            Hello fx_pete,

            Adding an equity, can be accomplished by opening a chart (any instrument) and start typing in the symbol and a new instrument is automatically created.

            Alternatively, you can manually add it. The attached images below are the setting for the SPY Instrument for Kinetick.

            http://www.ninjatrader.com/support/h...nstruments.htm

            Let us know if we can be of further assistance.
            Attached Files
            JCNinjaTrader Customer Service

            Comment


              #7
              thanks for your help but in the end it turns out that the problem is in the following Add() statement:
              Code:
              Add(item.Label, PeriodType.Day, ndays);
              where ndays is the problem ... as I have defined ndays as number of days to load and not the period length. Fixing this has so far remedied the problem ... for now. I have reinstalled NT and am writing the script from scratch. So far the logic used is identical to one I have included here and no problems. I am however still using a dynamic variable in a call to Add(), that I will keep an eye on for potential problems.

              Thanks again ....

              ps: I knew it was something stupid I did

              Comment


                #8
                How does the performance of the your backtest look like? Was it similar to the results from the original ETF rotation strategy? I did a backtest using your ETF list RWX, TLH, GLD, EFA, EEM, SPY, ICF, IWM, TLT and DBC using https://pyinvesting.com/ but the ETF rotation strategy does not beat the S&P 500 benchmark.

                Click image for larger version

Name:	etf_rotation.PNG
Views:	230
Size:	50.3 KB
ID:	1121123

                Comment


                  #9
                  Hello ivanftp,

                  I see your inquiry is directed at community member, I just wanted to say, welcome to the NinjaTrader forums!
                  Chelsea B.NinjaTrader Customer Service

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by chbruno, Today, 04:10 PM
                  0 responses
                  3 views
                  0 likes
                  Last Post chbruno
                  by chbruno
                   
                  Started by josh18955, 03-25-2023, 11:16 AM
                  6 responses
                  436 views
                  0 likes
                  Last Post Delerium  
                  Started by FAQtrader, Today, 03:35 PM
                  0 responses
                  6 views
                  0 likes
                  Last Post FAQtrader  
                  Started by rocketman7, Today, 09:41 AM
                  5 responses
                  19 views
                  0 likes
                  Last Post NinjaTrader_Jesse  
                  Started by frslvr, 04-11-2024, 07:26 AM
                  9 responses
                  127 views
                  1 like
                  Last Post caryc123  
                  Working...
                  X