Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

lightweight as possible.

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

    #16
    Wrapping up ...

    The link to the Terminate discussion -- NinjaTrader_Matthew's detailed description appears correct overall but some details seem to have changed since then. In particular, the instance he describes for populating the "Configures:" list is created but immediately afterward another instance is also created and then terminated. I have no idea why this added instance; I also do not know any reason to care. It just adds to the main point -- that SetDefaults is called a lot and must be kept light.

    -----

    Explicit indicator constructor -- I know of no reason to have an explicit indicator constructor::
    • NinjaTrader adds its own constructor and that is the one that is used to construct the instance.
    • One job of a constructor is to call the base class constructor. In this case, the NT constructor does that so any attempt by an explicit indicator constructor to do so would be evil.
    • The other important aspect of a constructor is to run first so it can initialize things. As demonstrated earlier in this thread, an explicit indicator constructor does not run first -- SetDefaults is called before that "constructor" is run.
    • Any constructor shares one aspect with SetDefaults -- that both are run for every instance of the indicator. That means that both of them must be kept similarly light. In other words, lightness is just as important for a constructor as it is for SetDefaults.
    My conclusion is that there is never a benefit for an explicit indicator constructor and there are downsides, such as confusion of when it will be run. Since its code must be light enough for SetDefaults anyway, I suggest putting any code that would have gone into a constructor into SetDefaults instead of attempting a constructor. There is no downside, and there is no uncertainty as to when that code will run.

    -----

    For an indicator, the very first call to its code will be OnStateChange() with State = SetDefaults. That call will happen exactly once. SetDefaults need not be concerned with being called again -- it never will be called again. All other code can assume that it has already been called.
    • Is that really true?
    • Can caching result in an instance being taken from the cache and having SetDefaults called another time?

    -----

    My thanks for the links to the indicator lifetime and state mechanism. That has never been an issue, though. The information I have asked about, and still do not know the answer to, is how, considering the several sources, an indicator's data gets initialized. When, from construction until the start of State=Configure does the data get changed? When is stored data read in and applied? Where do Clone() and ModifyProperties() fit into this scheme? Why does SetDefaults have to rely on dynamic setting of its own variables that could be initialized at compile time? Etc.

    --EV
    Last edited by ETFVoyageur; 05-11-2024, 10:30 PM.

    Comment


      #17
      Originally posted by ETFVoyageur View Post
      SetDefaults need not be concerned with being called again -- it never will be called again.
      Never?
      You sure about that?

      (EDIT: Yeah, I see that is basically your question as well,
      you're asking if this is true or not -- I'm not sure either,
      thus my rhetorical question above, which helped me to
      segue into some food for thought discussion below.)

      What about indicators that are being called from a Strategy,
      and what if that Strategy is being executed in the Strategy
      Analyzer in Optimizer mode?

      I think multiple Strategy instances are created and each
      instance is executed with different settings -- I think these
      instances get reused when they finish (Support can verify)
      but I think that might mean your indicator instances being
      used by the Strategy will see a second SetDefaults when
      they are also reused. (Haven't tested this, but regardless,
      I think assuming an indicator instance will only ever see
      one call for the State.SetDefaults strikes me as a bit
      naive.)

      Originally posted by ETFVoyageur View Post
      Why does SetDefaults have to rely on dynamic setting of its own variables that could be initialized at compile time?
      This is probably more a C# technical issue.

      You need to remember properties vs variables.

      Property initial values should be defined in SetDefaults.

      Why?
      Properties cannot be initialized at compile time.

      Variables can be initialized at compile time, or they
      could be initialized inside SetDefaults as well, for sake
      of consistency.

      With variables, it is your choice.
      With properties, not so much.

      With public properties that are set by the user in the
      property grid, the correct way to initialize these is via
      State.SetDefaults.

      -=o=-

      Well, C# 6 now allows it. Before C# 6 you needed to
      use a private 'backing store' variable for your property
      and it was that private variable that was initialized at
      compile time, giving the illusion that the public property
      was also being initialized at compile time.

      Just my 2˘.

      Last edited by bltdavid; 05-11-2024, 11:04 PM. Reason: segue

      Comment


        #18
        "I see that is basically your question..." Yes, I am asking whether NT Support agrees or disagrees with my conclusions, including how SetDefaults is treated.

        Whether or not SetDefaults can be called more than once is important if it is to be used instead of a constructor for initialization. A constructor can happen only once, even with cached objects. Calling SetDefaults more than once would be a major difference that would have to be taken into account.

        Initialization -- as you noted, with the version of C# we are using, properties can be initialized at compile time so my question stands. Why not do as much compile-time initialization as possible?

        I don't mean to be pedantic, but I think that it is both reasonable and important to have a well-defined environment.

        Comment


          #19
          Originally posted by ETFVoyageur View Post
          Initialization -- as you noted, with the version of C# we are using, properties can be initialized at compile time so my question stands. Why not do as much compile-time initialization as possible?
          Many versions of NT predate the use of C# version 8,
          thus any NinjaScript released as source code should
          probably stay compatible with C# 5 (and avoid the use
          of the C# version 8 feature that allows compile time
          initialization of auto properties).

          I think 'where to initialize' leans somewhat towards
          personal preferences -- I mean, if it works for you,
          no one is really gonna stop you.

          Comment


            #20
            I think 'where to initialize' leans somewhat towards
            personal preferences -- I mean, if it works for you,
            no one is really gonna stop you.
            It is more than just a style matter. Compile time initialization won't help if NT alters any properties before SetDefaults is called. It could also be an issue if SetDefaults is called more than once (currently an open question).

            So my question to NT SUpport remains whether or not there is any reason why compile-time initialization will fail to do the correct thing.

            By the way, I'm not with you on the C# 5.0 issue. Why isn't the answer to write any property you want to initialize at compile time with an explicit variable instead of an implicit one? Writing the automatic form may be nicer stylistically, but if you must be compatible with an older C# don't do it. You won't be missing any functionality, just style.
            Last edited by ETFVoyageur; 05-12-2024, 09:27 PM.

            Comment


              #21
              Hello ETFVoyageur,

              From my understanding, for a single instance State.SetDefaults will only be called once.

              There will be many instances created for various purposes, including populating the UI.

              Once an instance progresses to State.Configure, it will not run through State.SetDefaults again.

              Anytime a workspace is opened that has that script saved, this would be cloning a new instance.

              SetSefaults should only be used for populating default property values for the UI for new instances and there shouldn't be any other logic here.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #22
                Thanks, Chelsea,

                Thanks for your comments. Just to be clear, here is my understanding, based on what you have said. I don't want to be tiresome, but I do want to be sure I understand the details. Please let me know if any of my understandings are mistaken.
                • SetDefaults will be called exactly once for any given instance of an indicator. It will never be called a second time for that instance. Indicator caching, for example, will not violate this.
                • SetDefaults will be the first indicator code executed -- no other indicator code will have been executed when SetDefaults runs.
                • When SetDefaults runs, the indicator instance will be as compiled -- nothing will have altered any of its variables.
                • Any outside effects, such as actions by the constructor NT adds or anything to do with deserialization, will not occur before SetDefaults runs. Those sorts of things will happen after SetDefaults has run and before Configure runs.
                Given those things, I conclude that compile-time initialization, where possible, seems to me to be preferred, if only because it is slightly more efficient at runtime. There's not a lot of difference, so I suppose it is as much a style matter as anything. The important point is that there is nothing wrong with relying on compile-time initialization, and doing so will not cause any problems.

                I also noticed that your wording is consistent with my emerging view that indicators should not have an explicit constructor.
                SetSefaults should only be used for populating default property values for the UI for new instances and there shouldn't be any other logic here.
                As we have discovered, an explicit constructor is run, but not as a constructor. It is effectively part of SetDefaults and has as much performance impact as SetDefaults. It should live by your wording just as much as SetDefaults should. That would mean there is nothing for the constructor to do, so why have one? (I do see potential downsides to using a constructor, such as surprises due to the out-of-order execution and failure to realize that its performance impact is as bad as that of SetDefaults.)

                Comment


                  #23
                  Hello ETFVoyageur,

                  "SetDefaults will be called exactly once for any given instance of an indicator. It will never be called a second time for that instance. Indicator caching, for example, will not violate this."

                  Correct.

                  "SetDefaults will be the first indicator code executed -- no other indicator code will have been executed when SetDefaults runs."

                  Our development has not yet gotten back to me on this.

                  "When SetDefaults runs, the indicator instance will be as compiled -- nothing will have altered any of its variables."

                  During SetDefaults yes, but after this a template or workspace loading can change the values.

                  "Any outside effects, such as actions by the constructor NT adds or anything to do with deserialization, will not occur before SetDefaults runs. Those sorts of things will happen after SetDefaults has run and before Configure runs."

                  From my understanding yes, templates and workspace values are set after SetDefaults.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #24
                    Chelsea,

                    Thanks for following up.

                    During SetDefaults yes, but after this a template or workspace loading can change the values.
                    I agree. I was concerned about Clone() so I looked at my debug printout. What happens is as you indicate.
                    • The new instance runs SetDefaults
                    • Clone() is called. I presume that the system does its other copying at that time, too.
                    • The new instance runs Configure
                    This is just to confirm what you are saying. It appears to me that things are unchanged when SetDefaults runs, then the instance is updated, and then Configure runs.

                    Comment


                      #25
                      Hello ETFVoyageur,

                      Our development has gotten back to me with more information.

                      They've let me know:
                      • The constructor of the derived class is called first
                      • But before the derived classes constructor’s body is executed, the constructors of base classes are called
                      • The SetState(State.SetDefaults) is triggered from on of the base classes constructor
                      Chelsea B.NinjaTrader Customer Service

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                      0 responses
                      607 views
                      0 likes
                      Last Post Geovanny Suaza  
                      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                      0 responses
                      353 views
                      1 like
                      Last Post Geovanny Suaza  
                      Started by Mindset, 02-09-2026, 11:44 AM
                      0 responses
                      105 views
                      0 likes
                      Last Post Mindset
                      by Mindset
                       
                      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                      0 responses
                      560 views
                      1 like
                      Last Post Geovanny Suaza  
                      Started by RFrosty, 01-28-2026, 06:49 PM
                      0 responses
                      561 views
                      1 like
                      Last Post RFrosty
                      by RFrosty
                       
                      Working...
                      X