Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Strategy Inheritance In NT8

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

    Strategy Inheritance In NT8

    Hello,

    I would like to have my strategy inherit from a base class I created. The inheritance tree is as such:

    Code:
    public abstract class MyBaseClass : Strategy, Interfaces
    {
    
    }
    
    public class MyStrategy : MyBaseClass
    {
    
    }
    This would make life much easier. If you can speak on this, I would appreciate the feedback.

    If this is possible, where can I instantiate the abstract class (since there is no formal constructor available)? Normally, that would be done as such:

    Code:
    public MyStrategy() : base()
    {
    
    }
    ...and that is the part that brings me to wonder if this is possible in NT8.

    If this is illegal in NT8, may you please explain why and provide a potential alternative?

    Thank you,
    John

    #2
    Hello John,

    Thanks for the post.

    Inheritance and polymorphism are supported in NinjaScript. One property of abstract classes is that they are not initialized. Please see the attached script for an example of using abstract classes in NinjaScript. It turns the strategy class (the one created by NinjaTrader) into an abstract class and then defines a virtual function Area(). I implement the Area function in the child class.

    For more information on abstract classes, please see this publicly available link:
    https://docs.microsoft.com/en-us/dot...words/abstract

    You can even place OnBarUpdate(), or any other function that belongs to the base class inside of the child class.

    Please let us know if we may be of any further assistance.
    Attached Files
    Chris L.NinjaTrader Customer Service

    Comment


      #3
      Thanks Chris,

      That is good news. My abstract class defines a constructor, and needs to be instantiated on inheritance as shown below. I annotated the code to be a little more clear about what I am demonstrating. The difference between your example and my application is that my abstract base class has a constructor.



      Base class:
      Code:
      public abstract class MyAbstractClass : Strategy, MyInterfaces
      {
      
          public MyAbstractClass(args) : base(args)
          {
              // This is the constructor of the abstract class. You cant call it directly, it gets called when a class inherits from this base.
          }
      
      }


      Strategy:
      Code:
      // Since MyStrategy inherits from an abstract class with a constructor, this will not compile unless the expected
      // argumens (args) are passed to the abstract classes via construction of the derived class.
      public class MyStrategy : MyAbstractClass
      {
      
          public MyStrategy(args) : base(args)
          {
              // The base class REQUIRES this to happen. Will not compile without it.
              // However, if base class has no constructor, it is not required (as in your example)
              // My question is how to call the base class constructor after I've inherited from it.
          }
      
      }

      Hopefully that is more clear. Thanks for the example code.

      John

      Comment


        #4
        Hello John,

        Thanks for the follow-up.

        You can not call the abstract classes constructor (new Animal()), it is implicitly called when you call the child class constructor. When you call the constructor for your child class and the base class will be instantiated through the child class constructor.

        Example:

        Code:
        abstract class Animal
        {
          public string DefaultMessage { get; set; }
        
          public Animal()
          {
            Console.WriteLine("Animal constructor called");
            DefaultMessage = "Default Message From Base Class";
          }
          public virtual void Speak()
          {
            Console.WriteLine(DefaultMessage);
          }
        }
        
        class Dog : Animal
        {
          public Dog(): //implicit call to base() here. 
          {
            Console.WriteLine("Dog constructor called");
          }
          public override void Speak()
          {
            Console.WriteLine("Custom Speak");
            base.Speak();//We can still use the base implementation. 
           }
        }
        Here would be the output:
        Animal constructor called
        Dog constructor called
        Custom Speak
        Default Speak

        Please let us know if we may be of any further assistance.
        Last edited by NinjaTrader_ChrisL; 10-13-2017, 04:14 PM.
        Chris L.NinjaTrader Customer Service

        Comment


          #5
          I understand that you cannot directly call an abstract class constructor. The example you provided is not addressing my question about a base class with arguments in the constructor. That is, if you add arguments to your Animal base class constructor, your code will not compile unless you add those parameters to the implementing class (Dog) as well.

          Please see these references:
          https://stackoverflow.com/questions/...tor-in-c-sharp
          https://stackoverflow.com/questions/...ss-constructor


          I think it would also help to keep this in the context of a strategy. So I have used your last example and added arguments to the constructor in Animal() then renamed the classes to be strategy-type names.

          Code:
          abstract class MyStrategyBase : Strategy
          {
            public string DefaultMessage { get; set; }
          
            // Here There is an implicit call to base class Strategy ctor only because Strategy
            // doesn't require ctor arguments.
            public MyStrategyBase(string argument) // implicit call to : base() 
            {
              Console.WriteLine("MyStrategyBase constructor called");
              DefaultMessage = "Default Message From Base Class" + argument;
            }
            public virtual void DoSomething()
            {
              Console.WriteLine(DefaultMessage);
            }
          }
          
          class MyStrategy : MyStrategyBase
          {
          
            // Chris, this where my questions are. 
            // Firstly, if I create a constructor MyStrategy, will it be called by NinjaScript?
            // 
            // Secondly, because MyStrategy inherits from MyStrategyBase, 
            // MyStrategy also requires the constructor arguments of MyStrategyBase.
            // Base constructor cannot be "implicitly called" without arguments so the correct way
            // to do this would be to write MyStrategy(string arguments) : base(arguments)
            //
            public MyStrategy() : // Compile error -- "string argument" is not defined for base class 
            {
              Console.WriteLine("MyStrategy constructor called");
            }
          
            public override void DoSomething()
            {
              Console.WriteLine("Custom DoSomething");
              base.DoSomething();//We can still use the base implementation. 
             }
          
          }
          Last edited by jflaggs; 10-13-2017, 02:42 PM.

          Comment


            #6
            Hello John,

            Thanks for the follow-up.

            I will work on a strategy that does this, stand by for that.

            Arguments are passed to the base class using this methodology, as you describe:

            Code:
            abstract class Animal
            {
              public bool isDomesticated;
            
              public Animal(bool _isDomesticated)
              {
                isDomesticated = _isDomesticated;
              }
            
              public void Speak()
              {
                Console.WriteLine("Custom Speak"); 
               }
            }
            
            class Dog : Animal
            {
            
              public string genus;
            
              public Dog(bool isDomesticated, string _genus): base(isDomesticated)
              {
                Console.WriteLine("Dog constructor called");
                genus = _genus;
              }
              public override void Speak()
              {
                Console.WriteLine("Custom Speak");
                base.Speak();//We can still use the base implementation. 
               }
            }
            Please let me know if you have any question on the material.
            Last edited by NinjaTrader_ChrisL; 10-13-2017, 04:42 PM.
            Chris L.NinjaTrader Customer Service

            Comment


              #7
              Yes, that's what I am getting at. Thank you for verifying. Now, to put that in the context of a real strategy, can you please address the first question in my last post?

              Firstly, if I create a constructor MyStrategy, will it be called by NinjaScript?
              To elaborate further:

              Normally when I create an NT strategy, I do not need to explicitly create a formal constructor (I think it is auto-generated in the "do not touch" region). So referring back to my last code snippet, will the constructor (shown below) get called? How, when, or where does it get called? Would be great if you could whip up a small sample strategy that inherits from an abstract class requiring constructor arguments.


              Code:
              MyStrategy(string argument) : base(argument)
              {
                  // Will this constructor be called? Where? When (State)? 
              }

              Thank you

              John

              Comment


                #8
                Hello John,

                Thank you for your patience.

                After some testing, I have found that the way NinjaTrader instantiates objects in the runtime is out of the user's control. We do not have access to the logic that calls 'new' on the constructor, therefore we can not directly instantiate a child class from the NinjaTrader generated class that inherits the Strategy or Indicator base class. The example below does create an instance of 'MyStrategy' but it does so after making an instance of the 'MyStrategy' base class.

                I would recommend using a partial class as a different approach to separate your logic. You will have access to all methods and properties of the partial class inside of your main script. You may extend the Strategy or Indicator class in partial classes. All you will have to do is design your other NinjaScripts to access the data from this indicator. Please see the attached .zip file for a working example.

                Please see this publicly available link on partial classes in C#:
                https://docs.microsoft.com/en-us/dot...es-and-methods

                If we may be of any further assistance, please let us know.
                Attached Files
                Chris L.NinjaTrader Customer Service

                Comment


                  #9
                  Chris,

                  Thank you for making the correction and clearing this up.

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by robforee2, Today, 05:07 PM
                  0 responses
                  1 view
                  0 likes
                  Last Post robforee2  
                  Started by blar58, Today, 03:16 PM
                  1 response
                  6 views
                  0 likes
                  Last Post NinjaTrader_Melissa  
                  Started by alcorr247, Today, 02:52 PM
                  2 responses
                  7 views
                  0 likes
                  Last Post robforee2  
                  Started by Radano, Today, 02:30 PM
                  1 response
                  4 views
                  0 likes
                  Last Post NinjaTrader_ChrisL  
                  Started by DrummerBoy, Today, 01:34 PM
                  3 responses
                  31 views
                  0 likes
                  Last Post NinjaTrader_Clayton  
                  Working...
                  X