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

Best practice for programming efficient indicators for the NT Strategy Analyzer?

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

    Best practice for programming efficient indicators for the NT Strategy Analyzer?

    Hello!

    I have som thoughts about best practice for programming computational efficient indicators for the NT Strategy Analyzer (as well as for real time trading).

    1. What is the most efficient output Class? Is a DataSeries more efficient than a StringSeries for instance? Would it be eaven less expensive to expose just a double?

    2. I think I have read that it's important to turn off draw objects and print statements in the code. But what about plots? Since the plot Collection holds an infit number of bars I understand that a plot is more expensive than a DataSeries with 256 bars. But how expensive is the plotting itself compared to a non plotting DataSeries with MaximimBarsLookBack = Infinite? If you just call the indicator in a strategy, but don't add the indicator to a chart, will the computational cost needed for plotting be avoided?

    3. I do nest indicators frequently. What is the most efficient way to call an indicator from another indicator?

    I have read this article: http://www.movethemarkets.com/downloads/rwt/rwt004 that argues that you should avoid to use indicators "in-line" in the OnBarsUpdate() method. Instead they recomend that you declare the indicator as a varaible of the calling indicator and initialize it in the OnStartUp() mehod of the calling indicator. The reason for this would be to prevent the strategy analyzer to create a lot of unnecessary instances of the indicator during backtesting? Do you agree?

    4. I have recently started using the System.Collections.Generic List < T > Class and the Dictionary Class in my programming. I read in a post in this forum that the Strategy Analyzer doesn't automatically Dispose objects from these calsses as expected in c#. If so, what code should I put in the OnTermination() method to make the NT7 Strategy Analyzer properly Dispose a Lists or a Dictionary after each "loop"? Would these two lines be sufficient?

    Code:
    protected override void OnTermination()
            {
                // Dispose List
                myList = null;            
                System.GC.Collect();
            }
    // Best Regards
    Last edited by poseidon_sthlm; 02-27-2011, 06:51 AM.

    #2
    Poseidon_sthlm, I will have someone get back to you tomorrow.
    AustinNinjaTrader Customer Service

    Comment


      #3
      1. Unfortunately we would not know if a DataSeries is more or less expensive than a StringSeries. In general, if you only need a single double value, exposing just that value would be the least expensive approach. If you want a series thought then you would still want to create something like a DataSeries object to expose.

      2. Unfortunately we do not have information on actual resource differences between just a DataSeries versus a plotted series. In general though, it is best practices to only plot what is absolutely necessary. If you do not want to visualize it, do not plot it.

      3. The style of calling indicators outlined in the article can be more efficient.

      4. You should never call the garbage collector unless you are absolutely sure with what you are doing in this area. Just setting the list to null should be sufficient.
      Josh P.NinjaTrader Customer Service

      Comment


        #4
        Thanks for the prompt reply.

        /Regards

        Comment


          #5
          Further details

          Dear poseidon_sthlm or NT team,

          Would you be able to email or post the information you were referring to? Unfortunately, the download link in 3) http://www.movethemarkets.com/downloads/rwt/rwt004
          is not working anymore.

          In addition, which forum entries were you referring to in 4) or at least could you provide some further information here?

          thank you so much, wtmnn

          Comment


            #6
            Hello!
            I didn't save that article. But the essence was that, to prevent NT from creating new instances of an referenced indicator, you should always instantiate the referenced indicators on the first bar, for instance in the OnStartUp() method.

            Calling indicator:
            Code:
                    // Variables
                    private customIndicator myCustomIndicator; // Declare indicator as a variable
                        
                    protected override void Initialize()
                    {
                    }
                    
                    protected override void OnStartUp()
                    {    
                        myCustomIndicator = customIndicator(parameter); // Instantiate indicator only once
                    }
                    protected override void OnBarUpdate()
                    {
                        double myValue = myCustomIndictaor.OutputSeries[0];    // Reference indicator like this
                        
                        double myValue = customIndicator(parameter).OutputSeries[0]; // Don't reference indicator this way
                    }
            Concering 4) I don't remember were I read it.

            // Best Regards
            Poseidon_Sthlm

            Comment


              #7
              Thank you fpr your fast reply

              I really appreciate it. wtmnn

              Comment


                #8
                There's a copy of the article cached at archive.org:

                http://web.archive.org/web/201004282...ds/rwt/rwt004/

                One lesson I've learned the hard way is to never call "new" inside of OnBarUpdate or anything that is called by OnBarUpdate. "new" is computationally pretty expensive, and if you use it inside of OnBarUpdate in a strategy, and then run the strategy through the optimizer, you can allocate memory faster than the garbage collector can reclaim it, and bring your computer to its knees when it runs out of memory. I've run into this problem when working on mathematical rountines that need working storage; I've learned to pre-allocate any required working storage in OnStartUp and then re-use it instead of calling "new" all the time.

                Comment


                  #9
                  Looks like the author is maintaining this document and others at this new site:

                  whitmark
                  NinjaTrader Ecosystem Vendor - Whitmark Development

                  Comment


                    #10
                    Originally posted by whitmark View Post
                    Looks like the author is maintaining this document and others at this new site:

                    http://richardtodd.name/docs/pdf/eff...injaScript.pdf
                    link is dead. bummer.

                    webarchive still works

                    Comment


                      #11
                      Based information provided by Poseidon_Sthlm I made modifications to my indicator that was calling other indicators inline.

                      Here is my interpretation of "Best Practice" on use of Bollinger and EMA Indicators. Does anyone have any additional suggestions?

                      Code:
                       
                      [FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]#region[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] Variables[/SIZE][/FONT]
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]private[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] iLen = [/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]14[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]; [/SIZE][/FONT][/SIZE][/FONT]
                      private[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] Bollinger myBollinger ; [/SIZE][/FONT]
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]private[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] EMA myEMA ; [/SIZE][/FONT]
                       
                      [SIZE=2][FONT=Courier New][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]#endregion [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
                       
                      [FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]protected [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]override [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] OnStartUp()[/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]{[/FONT][/SIZE]
                      [SIZE=2][FONT=Courier New]myBollinger = Bollinger(Close, [/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080].25[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2], iLen); [/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]myEMA = EMA([/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]4[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]) ; [/SIZE][/FONT]
                       
                      [SIZE=2][FONT=Courier New]isGreenWave = [/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] BoolSeries([/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]) ; [/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]isRedWave = [/FONT][/SIZE][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] BoolSeries([/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]) ; [/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]} [/FONT][/SIZE]
                       
                      [SIZE=2][FONT=Courier New][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]protected [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]override [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] OnBarUpdate()[/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]{[/FONT][/SIZE]
                       
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] myBollingerUpper = myBollinger.Upper[[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]] ; [/SIZE][/FONT]
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] myBollingerMiddle = myBollinger.Middle[[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]] ; [/SIZE][/FONT]
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] myBollingerLower = myBollinger.Lower[[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]] ; [/SIZE][/FONT]
                       
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]double[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] myEMAVal = myEMA[[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]] ; [/SIZE][/FONT]
                      [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2] (myEMAVal >= myBollingerMiddle && Close[[/SIZE][/FONT][/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080][FONT=Courier New][SIZE=2][COLOR=#800080]0[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][FONT=Courier New][SIZE=2]] > myBollingerUpper) [/SIZE][/FONT]
                      [SIZE=2][FONT=Courier New]{[/FONT][/SIZE]
                      [/SIZE][/FONT][/FONT][/SIZE][/SIZE][/FONT][/FONT][/SIZE][/SIZE][/FONT].....
                      Additionally, does anyone have access to the referenced document?

                      Does NT have a better document addressing "Best Practices" at this point. Being that the focus of NT8 will be on "performance" coding I am thinking that they have spent a lot of time on this topic lately.
                      Last edited by tornadoatc; 01-22-2013, 09:05 PM.

                      Comment


                        #12
                        &quot;Calling Upon Indicators Efficiently in NinjaScript&quot; by Richard Todd

                        Attached is the original blog post by Richard Todd from Aug 18, 2009.

                        As far as your example goes, tornadoatc, I don't think I would go to the bother of allocating a local variable (e.g., double myBollingerUpper = myBollinger.Upper[0]; ) unless I was going to reference it several times in the subsequent code. I have not conducted any research to determine this, but wonder if there is any material trade-off between local variable allocation/assignment/access vs multiple direct access of an indicator object's members/items. Perhaps others have an opinion on this point.
                        Attached Files
                        whitmark
                        NinjaTrader Ecosystem Vendor - Whitmark Development

                        Comment


                          #13
                          I'v learned from NT support ( http://www.ninjatrader.com/support/f...8&postcount=13 ) that one should always initialize a called indicator in the OnBarUpdate() method like this, to prevent update issues:

                          Code:
                                  protected override void OnBarUpdate()
                                  {
                                      // Initialize
                                      double v1 = myIndicator[0];
                                      
                                      //Reference
                                      output1 = myIndicator.Output1[0];
                                      output2 = myIndicator.Output2[0];
                                  }
                          / poseidon_sthlm
                          Last edited by poseidon_sthlm; 01-24-2013, 04:04 AM.

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by mmenigma, Today, 02:22 PM
                          0 responses
                          2 views
                          0 likes
                          Last Post mmenigma  
                          Started by frankthearm, Today, 09:08 AM
                          9 responses
                          35 views
                          0 likes
                          Last Post NinjaTrader_Clayton  
                          Started by NRITV, Today, 01:15 PM
                          2 responses
                          9 views
                          0 likes
                          Last Post NRITV
                          by NRITV
                           
                          Started by maybeimnotrader, Yesterday, 05:46 PM
                          5 responses
                          26 views
                          0 likes
                          Last Post NinjaTrader_ChelseaB  
                          Started by quantismo, Yesterday, 05:13 PM
                          2 responses
                          21 views
                          0 likes
                          Last Post quantismo  
                          Working...
                          X