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

Plotting existing indicator in another indicator - AddPlot

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

    Plotting existing indicator in another indicator - AddPlot

    Hello,
    This is probably both an indicator development and a platform support issue.

    I have used the advice in this now closed thread to plot an existing indicator in another indicator and also a secondary series of this indicator. The original indicator takes less than 5 seconds to load to a chart, but the new indicator is taking at least 5 minutes, even when I comment out the secondary series. If I use the 32bit version of NT8, it often runs out of memory whilst trying to load the indicator and crashes. If I use the 62bit version of NT8 it takes about 5MINs to load or offload the indicator to or from a chart - this thread deals with the memory hogging problem with NT8. In addition, the secondary series plot has gaps in it, despite me setting it in if (BarsInProgress == 0), which I was advised in this thread should stop the gaps.

    Now I am able to create both plots to the chart using another method, that is to open a second hidden data series on a chart and load the source indicator a second time using the second data series, and that works fine, but I think that will eventually use up too much RAM and CPU, as the second data series although hidden is still running in the background.

    Is there anything I can do to clean up my indicator to make it load faster, and also to stop the gaps from appearing in the secondary series plots? I have inserted the code below.
    Code:
    //This namespace holds Indicators in this folder and is required. Do not change it. 
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	public class My2ndDataSeriesPlots : Indicator
    	{
    
    		
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description									= @"Plots based on primary data series and a second plot based on secondary dataseries";
    				Name										= "My2ndDataSeriesPlots";
    				Calculate									= Calculate.OnBarClose;
    				IsOverlay									= true;
    				DisplayInDataBox							= true;
    				DrawOnPricePanel							= true;
    				DrawHorizontalGridLines						= true;
    				DrawVerticalGridLines						= true;
    				PaintPriceMarkers							= true;
    				ScaleJustification							= NinjaTrader.Gui.Chart.ScaleJustification.Left;
    				//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;
    				Period										= 14;
    				SecondaryDataSeriesValue					= 36;
    				AddPlot(new Stroke(Brushes.Red,3), PlotStyle.Line, "PrimaryOS"); // Defines the plot for Values[0]
    				AddPlot(new Stroke(Brushes.DarkBlue,3), PlotStyle.Line, "PrimaryOB"); // Defines the plot for Values[1]
    				AddPlot(new Stroke(Brushes.Magenta, 3), PlotStyle.Hash, "SecondaryOS"); // Defines the plot for Values[2]
    				AddPlot(new Stroke(Brushes.Green, 3), PlotStyle.Hash, "SecondaryOB"); // Defines the plot for Values[3]
    			}
    			else if (State == State.Configure)
    			{
    				AddDataSeries(BarsPeriodType.Tick, SecondaryDataSeriesValue);
    			}
    			else if (State == State.DataLoaded)
    			{
    				Name = ""; //See State == State.SetDefaults to set name so it appears in indicator list
    
    			}
    			
    			else if (State == State.Historical)
      		{
          		// Make sure our object plots above the chart bars
          		SetZOrder(int.MaxValue);
      		}
    		}
    
    		protected override void OnBarUpdate()
    		{
    			// Checks if OnBarUpdate() is called from an update on the primary Bars - because added a 15M dataseries 21/01/2017
    			if (BarsInProgress == 0)
    			{
    			
                // Use this method for calculating your indicator values. Assign a value to each
    			if (CurrentBars[0] <= BarsRequiredToPlot || CurrentBars[1] <= BarsRequiredToPlot)
    			{
    				return;
    			}
    			
    			Values[0][0] = (MyBuySell05BearBull(14, 4, 0.8, 0.2, 0.98).BslShortPeriodBear[0]);
    			Values[1][0] = (MyBuySell05BearBull(14, 4, 0.8, 0.2, 0.98).BslShortPeriodBull[0]);
    			Values[2][0] = (MyBuySell05BearBull((BarsArray[1]), 14, 4, 0.8, 0.2, 0.98).BslShortPeriodBear[0]);
    			Values[3][0] = (MyBuySell05BearBull((BarsArray[1]), 14, 4, 0.8, 0.2, 0.98).BslShortPeriodBull[0]);
    			}
    		}
    
    		#region Properties
    		[NinjaScriptProperty]
    		[Range(1, int.MaxValue)]
    		[Display(Name="Period", Description="Default moving average period", Order=1, GroupName="Parameters")]
    		public int Period
    		{ get; set; }
    
    		[NinjaScriptProperty]
    		[Range(1, int.MaxValue)]
    		[Display(Name="SecondaryDataSeriesValue", Description="Value for Secondary data series", Order=2, GroupName="Parameters")]
    		public int SecondaryDataSeriesValue
    		{ get; set; }
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> PrimaryOS
    		{
    			get { return Values[0]; }
    		}
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> PrimaryOB
    		{
    			get { return Values[1]; }
    		}
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> SecondaryOS
    		{
    			get { return Values[2]; }
    		}
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> SecondaryOB
    		{
    			get { return Values[3]; }
    		}
    		#endregion
    Thank you.

    #2
    Hello GeorgeW,

    I would recommend you first try and find the cause of the performance hit.

    If you comment out the calls to other indicators in this script and set these plots to hard coded values, is the script still sluggish?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thank you for your response, ChelseaB,

      The reason I did it the way I did was because I could not find a way to "Set" the secondary series when I hard coded the values. Here is how I set the primary series in the original indicator:
      Code:
      /* To set calculated values to our DataSeries we use the Set() method. */
      			myDataSeriesBear[0] = ((bearVolPerTick/ bullVolPerTick)/Period); 
      			myDataSeriesBull[0] = ((bullVolPerTick/ bearVolPerTick)/Period); 
      			/* Plotting the SMA of the intermediate calculation step stored in DataSeries object*/
      
      			BslShortPeriodBear[0] = (SUM(myDataSeriesBear, Period)[0]);
      			BslShortPeriodBull[0] = (SUM(myDataSeriesBull, Period)[0]);
      Now I need to use the same hard coded values to set the secondary series, but I could not find a way to refer to the secondary series in the hard coded values that worked. I was advised in one of the threads that I referred to in my original post that it would look similar to Closes[1][0], but that does not work when applying it to bearVolPertick[1][0], bullVolPerTick[1][0] or (bearVolPerTick/ bullVolPerTick)[1][0], as I get Error CS0021 "Cannot apply indexing with [] to an expression of type 'double' " . So how would I set and then plot the secondary series based on the values in my computations.
      myDataSeriesBear2nd[0] = ?
      myDataSeriesBull2nd[0] = ?
      BslShortPeriodBear2nd[0] = ?
      BslShortPeriodBull2nd[0] = ?
      Last edited by GeorgeW; 02-20-2017, 03:41 AM.

      Comment


        #4
        I have been able to get the secondary series plots to work partially. I have had to go back earlier in the computations where the prices and volume are used, copy and paste them, then apply the secondary series indexing to them e.g. Closes[1][0]. When on the same script as the primary series I got no plots at all (not even the primary), but when I moved it to a separate script it plotted. I’m not sure why there is this behaviour, but I can then load separate indicators for the primary plots and the secondary and I get all the plots, and they load in seconds as opposed to the previous 5mins. Any ideas why they may not work when both the primary and secondary series calculations are in the same indicator?
        Last edited by GeorgeW; 02-21-2017, 04:24 AM.

        Comment


          #5
          Hello ChelseaB,

          I have managed to get both the primary and secondary series indicators to plot, but I have a couple of questions:

          Both the primary series and secondary series plots now have different values to those they have when I load them to a primary chart and a hidden chart by loading an indicator twice. It may be because the scale has changed when they are both loaded to just one chart from the same indicator. Is this to be expected?

          Additionally, in using if (BarsInProgress == 0) to process the values for the secondary series so that there are no steps/gaps in the plot (which is what I believe is being advised in the Multi-Time Frame & Instruments section of the manual on True Event Driven OnBarUpdate() method - "Setting values to plots should be done in the primary series in OnBarUpdate()."), it seems to me that this will make the secondary plot start to look more like the primary plot along many of its sections than it otherwise would if it were loaded as a separate indicator from a hidden chart and so using BarsInProgress of the hidden chart. Is that correct?

          Comment


            #6
            Hi GeorgeW,

            I'm suggesting a process of elimination to find which indicator is causing the behavior.

            Start by ensuring the secondary series is not causing any issues.

            Any plot will only hold one value for each primary series. So when in historical data it would make sense to update this when the primary series is processing

            So try plotting the last update to the tick series after the primary updates. For now don't call any indicators.
            With AddDataSeries(BarsPeriodType.Tick, SecondaryDataSeriesValue);

            if (BarsInProgress == 0 && CurrentBars[0] > 0 && CurrentBars[1] > 1)
            {
            Values[0][0] = Closes[1][1];
            Values[1][0] = Closes[1][1];
            Values[2][0] = Closes[1][1];
            Values[3][0] = Closes[1][1];
            }

            This would all plot in the same place but is a quick simple test to show adding the secondary series and using a value for this is not (or is) causing a performance hit.

            The next step would be to call one indicator and test the performance. If it loads quickly, comment it out and test the next..

            The goal is to find where the performance hit is coming from. Once you have the code causing the issue, we can further advise.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hello ChelseaB,

              I carried out the test using Closes[1][1] and that worked fine. I then added the indicator one plot at a time. Loading the 2 primary plots took 18secs. To load the secondary series faster I had to change the BarsArray[1] in that section of the code to Inputs[1]. 2 primary plots and one secondary plot took 34secs to load, and all 4 plots took 51secs. This is much faster than the 5mins I had been experiencing, and the RAM was not being used to near its limit. But if I want to load to several charts it may still take some time. All the plots were accurate.
              As it is the same indicator being called 4 times for each plot, is there a way of calling it once that would reduce the load?

              I have tried to build the indicator by copying all the calculations into the indicator rather than importing an indicator. The indicator loaded in less than 5 seconds, but there are problems in that only one of the primary plots is accurate, and the 2nd primary plot keeps dropping to zero and staying there, until I reload NinjaScript or the Historical data, then the plot moves to the correct position, but on the close of a later bar returns to zero. The 2 secondary plots are also anywhere from slightly to more strongly out.
              Last edited by GeorgeW; 02-22-2017, 12:49 PM.

              Comment


                #8
                Hi GeorgeW,

                OnBarUpdate() will trigger once for each series that's been added to the script.
                You can control what code is processed by checking the value of BarsInProgress.
                To have something only update for the primary series, use a condition that only evaluates the code when BarsInProgress is 0.

                For example:
                if(BarsInProgress != 0)
                return;




                I would not expect changing the series you are getting values from (BarsArray[1] vs Closes[1] vs Inputs[1]) to change the performance. All of these series are always created and updated whether or not you decide to use these.

                However, triggering code in every BarsInProgress instead of only when the primary series is processing would cause higher use of CPU resources.

                Your variables should also be reused instead of recreated to conserve memory.

                If you have identified the script causing heavy resources use, the next step is to analyze this script by reducing logic to find what is causing heavy resource use.

                Is there a lot of logic in the indicator?
                Are there variables being declared inside of methods?
                Is there rendering happening in OnRender()?
                Chelsea B.NinjaTrader Customer Service

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by alifarahani, Today, 09:40 AM
                6 responses
                36 views
                0 likes
                Last Post alifarahani  
                Started by Waxavi, Today, 02:10 AM
                1 response
                17 views
                0 likes
                Last Post NinjaTrader_LuisH  
                Started by Kaledus, Today, 01:29 PM
                5 responses
                14 views
                0 likes
                Last Post NinjaTrader_Jesse  
                Started by Waxavi, Today, 02:00 AM
                1 response
                12 views
                0 likes
                Last Post NinjaTrader_LuisH  
                Started by gentlebenthebear, Today, 01:30 AM
                3 responses
                17 views
                0 likes
                Last Post NinjaTrader_Jesse  
                Working...
                X