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

Structure "code / class" better

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

    Structure "code / class" better

    Hi,

    how can I structure my code better.
    There are variants like
    1. inheritance
    2. Trail
    My class of indicator is getting bigger.
    For a better overview, I would like to change something.

    Current
    PHP Code:

    public class MyFinalIndicatorIndicator
    {
        
    // code


    option A (my imagination)
    PHP Code:

    protected class MyIndikatorAIndicator
    {
        
    // code small basic Part
    }

    protected class 
    MyIndikatorBMyIndikatorA
    {
        
    // code small extension
    }

    public class 
    MyFinalIndikatorMyIndikatorB
    {
        
    // code small extension


    option B (Trails)
    How exactly I use it in NinjaTrader for classes "Trails" for "MyFinalIndikator" is not entirely clear to me.




    And I can't use "protected class" for inheritance. But with "public" the indicator is visible.
    Can I somehow hide the indicator otherwise?


    Does anyone have a tip on how I can better structure a large class in NinjaTrader?
    Last edited by 1001111; 06-07-2020, 10:49 AM.

    #2
    Hello 1001111,

    Inheritance with Indicators and Strategies is not allowed and will break NinjaTrader in some places.

    Use at your own risk.

    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Design an abstract base class, then have your indicators inherit from that class.

      Comment


        #4
        Originally posted by NinjaTrader_ChelseaB View Post
        Hello 1001111,

        Inheritance with Indicators and Strategies is not allowed and will break NinjaTrader in some places.

        Use at your own risk.
        Hello, that's exactly why I'm asking here. What options do I have to structure the code better?


        Originally posted by bltdavid View Post
        Design an abstract base class, then have your indicators inherit from that class.
        Thanks for the hint. But the indicator has to inherit ": Indicator"?


        PHP Code:

        protected abstract class MyIndikatorAbstract
        {
            
        // code small basic Part
        }

        public class 
        MyFinalIndikator MyIndikatorAbstractIndicator 
        {
            
        // code small extension

        Perhaps you can give a brief example of what you meant?

        Comment


          #5
          Originally posted by 1001111 View Post
          Thanks for the hint. But the indicator has to inherit ": Indicator"?
          No, the abstract base class inherits from class Indicator.

          Your indicator will inherit from the abstract base class.

          Originally posted by 1001111 View Post
          Perhaps you can give a brief example of what you meant?
          Add your common utility code to MyIndicatorBase.cs, like this,

          Code:
          abstract public class MyIndicatorBase : Indicator
          {
              protected void PrintString(string format, params object[] args)
              {
                  Print(string.Format(format, args));
              }
              protected double Round2TickSize(double Price)
              {
                  return Instrument.MasterInstrument.Round2TickSize(Price);
              }
              protected string FormatPrice(double Price)
              {
                  return Instrument.MasterInstrument.FormatPrice(Round2TickSize(Price));
              }
          }
          In MyIndicator.cs, your indicator inherits from MyIndicatorBase, like this,

          Code:
          public class MyIndicator : MyIndicatorBase
          {
              ....
              protected void OnBarUpdate()
              {
                  PrintString("Bar={0} Open={1} High={2} Low={3} Close={4}", CurrentBar,
                              FormatPrice(Open[0]), FormatPrice(High[0]),
                              FormatPrice(Low[0]), FormatPrice(Close[0]));
              }
          }
          OnBarUpdate is a method from class Indicator (actually from class IndicatorBase, I think).
          PrintString is a method from class MyIndicatorBase.
          FormatPrice is a method from class MyIndicatorBase.

          The C# inheritance hierarchy allows all 3 methods to be called from class MyIndicator.

          You've effectively inserted a new class in-between your indicator and class Indicator, sort of
          a classic 'man-in-the-middle' kind of thing. By expanding the class inheritance hierarchy, you
          can greatly increase the structure and organization of your personal common code.

          Make sense?
          Last edited by bltdavid; 06-08-2020, 08:56 PM. Reason: Fix typos, breakup long code lines

          Comment


            #6
            Originally posted by 1001111 View Post
            Code:
            public class MyFinalIndikator : [COLOR=#FF0000]MyIndikatorAbstract[/COLOR], [COLOR=#FF0000]Indicator[/COLOR]
            {
            // code small extension
            }
            What you're trying to do above is called "multiple inheritance", and is not
            supported in the C# language. [Sure, "multiple class inheritance" is a valid
            thing in computer languages, but the only mainstream languages that
            really support it are C++ and Python.]

            When defining a class, C# only allows a single base class for inheritance.
            (But you can specify as many interfaces as you want.)

            When you see C# code with the above syntax, only one of the identifiers
            may be a class name, the remainder must be interface names.

            Comment


              #7
              Originally posted by bltdavid View Post

              No, the abstract base class inherits from class Indicator.

              Your indicator will inherit from the abstract base class.
              Thank you very much, I'll try it out

              Comment


                #8
                Originally posted by bltdavid View Post

                Add your common utility code to MyIndicatorBase.cs, like this,

                Code:
                abstract public class MyIndicatorBase : Indicator
                {
                protected void PrintString(string format, params object[] args)
                {
                Print(string.Format(format, args));
                }
                protected double Round2TickSize(double Price)
                {
                return Instrument.MasterInstrument.Round2TickSize(Price);
                }
                protected string FormatPrice(double Price)
                {
                return Instrument.MasterInstrument.FormatPrice(Round2TickSize(Price));
                }
                }

                Unfortunately, this does not work because Ninjatrader always automatically inserts code at the end.

                PHP Code:

                #region NinjaScript generated code. Neither change nor remove.
                     //...
                #endregion 
                and an abstract class cannot be called. But the automatic ninja code tries that


                But what works:
                PHP Code:

                    
                public class IndikatorBase Indicator
                    

                    } 

                In another file
                PHP Code:

                    
                public partial class IndikatorFinal IndikatorBase
                    
                {

                    } 

                In another file
                PHP Code:

                    
                public partial class IndikatorFinal
                    
                {

                    } 


                If the name of the indicator is different, it will be listed. So in such a case maybe 2 times. But I have to live with that.



                Originally posted by NinjaTrader_ChelseaB View Post
                Hello 1001111,

                Inheritance with Indicators and Strategies is not allowed and will break NinjaTrader in some places.

                Use at your own risk.
                I wanted to ask here, maybe the developers of Ninja could say something about how to structure the code elegantly.

                Comment


                  #9
                  Just a note, it's not necessary to use partial classes unless you want to split the code into several pieces. Partial classes can reside in the same file btw.

                  Code:
                  [COLOR=#000000][COLOR=#0000BB]    [/COLOR][COLOR=#007700]public class [/COLOR][COLOR=#0000BB]IndikatorBase [/COLOR][COLOR=#007700]: [/COLOR][COLOR=#0000BB]Indicator
                  [/COLOR][COLOR=#007700]{ 
                  }  [/COLOR][/COLOR]
                  
                  [COLOR=#000000][COLOR=#0000BB]    [/COLOR][COLOR=#007700]public [/COLOR][COLOR=#007700]class [/COLOR][COLOR=#0000BB]IndikatorFinal [/COLOR][COLOR=#007700]: [/COLOR][COLOR=#0000BB]IndikatorBase
                  [/COLOR][COLOR=#007700]{
                  }  [/COLOR][/COLOR]

                  Comment


                    #10
                    With a little trick by placing ": Indicator" on a new line the code generator is disabled and allows for the use abstract classes.

                    Code:
                        public abstract class AbstractIndicator
                            : Indicator {
                            public override string DisplayName {get{ return Name.IsNullOrEmpty() || Name.Length <= 10 ? Name : Name.Substring(0, 9);} }        
                        }

                    Comment


                      #11
                      Originally posted by MojoJojo View Post
                      Just a note, it's not necessary to use partial classes unless you want to split the code into several pieces. Partial classes can reside in the same file btw.
                      I prefer to split the code into several files because it makes it clearer.


                      Originally posted by MojoJojo View Post
                      With a little trick by placing ": Indicator" on a new line the code generator is disabled and allows for the use abstract classes.
                      Thanks for the hint

                      Comment


                        #12
                        Originally posted by NinjaTrader_ChelseaB View Post
                        Hello 1001111,

                        Inheritance with Indicators and Strategies is not allowed and will break NinjaTrader in some places.

                        Use at your own risk.
                        I went over these posts and similar in different threads, and I am still confused. I have an indicator IDraw that draws a bunch of drawing objects based on the price action. I now need to create another indicator that does the same thing plus some new functionality.

                        I am told I cannot use inheritance. Also I cannot create the IDraw from my new indicator because none of the drawing object created by the IDraw indicator will show up on the chart.

                        My question is this: How I convert my IDraw that is a full-blown indicator into a partial class. IDraw is doing everything in its OnBarUpdate() + some helper functions it is calling from OnBarUpdate().

                        Thank you

                        Comment


                          #13
                          Originally posted by LeonK View Post

                          I went over these posts and similar in different threads, and I am still confused. I have an indicator IDraw that draws a bunch of drawing objects based on the price action. I now need to create another indicator that does the same thing plus some new functionality.

                          I am told I cannot use inheritance. Also I cannot create the IDraw from my new indicator because none of the drawing object created by the IDraw indicator will show up on the chart.

                          My question is this: How I convert my IDraw that is a full-blown indicator into a partial class. IDraw is doing everything in its OnBarUpdate() + some helper functions it is calling from OnBarUpdate().

                          Thank you
                          Hello LeonK,

                          Thank you for your note.

                          My colleague has posted some partial class examples here:
                          Explanation: I wrote a base class Indicator class that I'm using to inherit all my other indicators from. So this baseclass is defined as: namespace NinjaTrader.NinjaScript.Indicators.AssistedTrades { public class ATBaseIndicator: Indicator { ... } } And any other indicator is defined as: namespace NinjaTrader.NinjaScr


                          There are also a few details in the help guide on the following page under the header "Partial Classes (Porting methods and properties from UserDefinedMethods.cs)":


                          Please let us know if we may be of further assistance.
                          Emily C.NinjaTrader Customer Service

                          Comment


                            #14
                            Originally posted by bltdavid View Post
                            Design an abstract base class, then have your indicators inherit from that class.
                            Thank you much for your posts on using abstract classes in NT8. I managed to create an abstract base class for my indicators and then derive two other indicators from it.

                            Here is my new challenge. My abstract class AbstractSDZones is drawing a bunch of rectangles that are drawing objects, not plots. How can I reuse the code of my abstract class that is derived from NT's Indicator class in a strategy?

                            Here is an example to illustrate what I need to accomplish. The rectangles I've mentioned are supply and demand zones. Say currently the price is above a demand zone and below a supply zone. My strategies would go short if the price goes up to the supply and long if it drops back to the demand. Different strategies would add different filters and triggers but the demand / supply requirements are common for all of them.

                            Thanks!

                            Comment


                              #15
                              Originally posted by LeonK View Post
                              I managed to create an abstract base class for my indicators and then derive two other indicators from it.

                              Here is my new challenge. My abstract class AbstractSDZones is drawing a bunch of rectangles that are drawing objects, not plots. How can I reuse the code of my abstract class that is derived from NT's Indicator class in a strategy?

                              Here is an example to illustrate what I need to accomplish. The rectangles I've mentioned are supply and demand zones. Say currently the price is above a demand zone and below a supply zone. My strategies would go short if the price goes up to the supply and long if it drops back to the demand. Different strategies would add different filters and triggers but the demand / supply requirements are common for all of them.
                              Same as you would in the normal case, right?

                              I mean, you could just move/copy the code into
                              the inheritance hierarchy of your strategy. That
                              is, strategies can use the same abstract base
                              class idea, so just create an abstract base class
                              that inherits from Strategy and copy your code
                              to that file.

                              I guess you have 3 options. Let's discuss.

                              So, to wit, the first option is to make a strategy
                              specific version of your abstract class and have
                              your strategy inherit from that. Copy the indy file
                              to the Strategies folder, you can leave the class
                              name the same, but change the namespace,
                              delete the auto-generated code, touch up what
                              ever else ... it should be a quick edit. Then have
                              your strategy inherit from this base class, just like
                              your indy inherits from the indy base class.

                              The 2nd option is also obvious. Update your indy
                              with needed public properties that you can call
                              from your strategy, This indicator does all the
                              drawing, all the sup/dem zone calcs, and makes
                              this data available via public properties (or public
                              variables or methods) -- your strategy uses your
                              sup/dem indy just like any other indy -- no strategy
                              specific abstract base class needed -- your strat
                              uses the public properties/variables/methods of
                              your current sup/dem indy (ie, welcome to the world
                              of API design as it pertains to 'strat using indy'

                              The 3rd option is to make use of some class some
                              where high in the NT hierarchy that both Indicator
                              and Strategy inherit from and hope that that class
                              is a partial class and then move your indy abstract
                              class into a new file that is 'partial class SomeClass',
                              and then your code should be available in both indys
                              and strategies. This 3rd option may not be possible,
                              I mean you still need a BarsInProgress context, and
                              all the normal stuff when you see in OnStateChange
                              and OnBarUpdate ...

                              I'd say go with option 2.
                              Make the indy that currently inherits from your indy
                              base class provide public properties (and/or variables)
                              and methods that (because they're public) are then
                              available to your strategy. You may have some private
                              variables in your indy right now that, if you changed them
                              to public, your strat could access. This might be all you
                              need to do.

                              If option 2 is really too hard, then choose option 1, but
                              then you have two files with effectively the same code,
                              and maintenance of that kind of situation when fixing
                              bugs or adding new features (although doable) can
                              be a big pita.

                              Good luck!

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by bortz, 11-06-2023, 08:04 AM
                              47 responses
                              1,610 views
                              0 likes
                              Last Post aligator  
                              Started by jaybedreamin, Today, 05:56 PM
                              0 responses
                              9 views
                              0 likes
                              Last Post jaybedreamin  
                              Started by DJ888, 04-16-2024, 06:09 PM
                              6 responses
                              19 views
                              0 likes
                              Last Post DJ888
                              by DJ888
                               
                              Started by Jon17, Today, 04:33 PM
                              0 responses
                              6 views
                              0 likes
                              Last Post Jon17
                              by Jon17
                               
                              Started by Javierw.ok, Today, 04:12 PM
                              0 responses
                              16 views
                              0 likes
                              Last Post Javierw.ok  
                              Working...
                              X