• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Please help me understand ...

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

    Please help me understand ...

    In spite of some of my recent posts, I'd really rather my indicators fit in gracefully with NinjaTrader and not have to be deliberately overriding NinjaTrader behavior. Perhaps it would help if I had a better understanding of why NinjaTrader acts as it does..

    NinjaTrader restores the values for anything it wants to be persistent between construction and Initialize(). That makes perfect sense -- just think of Initialize() as Part 2 of the constructor. NinjaTrader obviously cannot restore any values before the actual constructor, so it does so right after the constructor and then calls "Constructor Part 2" -- Initialize(). Fine so far.

    What I do not understand is why NinjaTrader also restores the values again, right after Initialize(). Could someone please explain the logic? What is NinjaTrader trying to accomplish by restoring any persistent data again, after Initialize() has completed? As far as I can see, that means an indicator that changes anything persistent in Initialize() has to pay attention and also make the changes later. Note that any changes needed to set things up for the Indicators dialog cannot be deferred to OnStartup(), because
    • NT requires that some things be done in Initialize(). For example, any attempt to Add() anything later on will cause NinjaTrader to throw an exception.
    • OnStartup() cannot be used to initialize anything that will appear in the Indicators dialog, because OnStartup() is never called for an indicator instance used with the dialog.

    In fact, due to the additional restoration NT does after Initialize() has completed, the indicator has to implement the ICustomTypeDescriptor interface and enforce the changes the indicator wants in GetProperties(). Otherwise the changes will be undone before the dialog gets to see them.

    Please pardon me, but the logic of this escapes me, and seems sub-optimal. Please help me understand just why NinjaTrader restores persistent data after Initialize() has completed. As far as I can see things would be simpler and cleaner for the indicator if that were not so.

    Thanks,
    EV

    #2
    Originally posted by ETFVoyageur View Post
    In spite of some of my recent posts, I'd really rather my indicators fit in gracefully with NinjaTrader and not have to be deliberately overriding NinjaTrader behavior. Perhaps it would help if I had a better understanding of why NinjaTrader acts as it does..

    NinjaTrader restores the values for anything it wants to be persistent between construction and Initialize(). That makes perfect sense -- just think of Initialize() as Part 2 of the constructor. NinjaTrader obviously cannot restore any values before the actual constructor, so it does so right after the constructor and then calls "Constructor Part 2" -- Initialize(). Fine so far.

    What I do not understand is why NinjaTrader also restores the values again, right after Initialize(). Could someone please explain the logic? What is NinjaTrader trying to accomplish by restoring any persistent data again, after Initialize() has completed? As far as I can see, that means an indicator that changes anything persistent in Initialize() has to pay attention and also make the changes later. Note that any changes needed to set things up for the Indicators dialog cannot be deferred to OnStartup(), because
    • NT requires that some things be done in Initialize(). For example, any attempt to Add() anything later on will cause NinjaTrader to throw an exception.
    • OnStartup() cannot be used to initialize anything that will appear in the Indicators dialog, because OnStartup() is never called for an indicator instance used with the dialog.

    In fact, due to the additional restoration NT does after Initialize() has completed, the indicator has to implement the ICustomTypeDescriptor interface and enforce the changes the indicator wants in GetProperties(). Otherwise the changes will be undone before the dialog gets to see them.

    Please pardon me, but the logic of this escapes me, and seems sub-optimal. Please help me understand just why NinjaTrader restores persistent data after Initialize() has completed. As far as I can see things would be simpler and cleaner for the indicator if that were not so.

    Thanks,
    EV
    A lot of things that happen in Initialize() are persistent by design and even will survive programming changes followed by F5 reload. The only way to be sure that your code is Initialize()d as modified by your most current changes is to actually remove and then reload the indicator. Did you do that? Very cumbersome, yes, I know.

    Comment


      #3
      Mr K,

      Thanks for the comments.

      My question is a basic architectural one. Based on my tracing, NT initializes persistent data before calling Initialize() and then restores that data again (for the same instance) after calling Initialize(). This is consistent with some remarks I have found in this forum about changes to persistent data in Initialize() not still being there when OnStartup() is called.

      I really would like to know what purpose NT has for doing additional restoration of persistent data after Initialize(). I would think setting that up prior to calling Initialize() would suffice, but evidently NT does not think so. I'd really like to cooperate with their architectural model if I can, instead of having to reverse engineer it so I can defeat it.

      As to your reload comment -- I have noted that sometimes my code changes take effect immediately, sometimes F5 is needed, and sometimes I must remove the old version and add the indicator again. I do not have a good mental model of when it is necessary to remove-and-add the indicator -- I just do it when I do not see my expected changes. Any guidance on when remove-and-add is required?

      --EV

      Comment


        #4
        Originally posted by ETFVoyageur View Post
        Mr K,

        Thanks for the comments.

        My question is a basic architectural one. Based on my tracing, NT initializes persistent data before calling Initialize() and then restores that data again (for the same instance) after calling Initialize(). This is consistent with some remarks I have found in this forum about changes to persistent data in Initialize() not still being there when OnStartup() is called.

        I really would like to know what purpose NT has for doing additional restoration of persistent data after Initialize(). I would think setting that up prior to calling Initialize() would suffice, but evidently NT does not think so. I'd really like to cooperate with their architectural model if I can, instead of having to reverse engineer it so I can defeat it.

        As to your reload comment -- I have noted that sometimes my code changes take effect immediately, sometimes F5 is needed, and sometimes I must remove the old version and add the indicator again. I do not have a good mental model of when it is necessary to remove-and-add the indicator -- I just do it when I do not see my expected changes. Any guidance on when remove-and-add is required?

        --EV
        Ah, the various stylings of NinjaTrader! I have never been able to know exactly when I must remove/add, so I just hit F5, and if I do not see that which I expect, I remove/add.

        For sure I know that adding/removing any of the Plot or Line definitions requires remove/add. I surmise that it is a load-persistence issue. If the indicator object is already loaded, it would appear that reloading uses the cached object, and so changes properties on it (including any new ones), but will not remove or Initialize new objects that were processed in Initialize().

        Comment


          #5
          Hello,

          As a general rule, you will need to remove and re-add an indicator if you have changed anything that is set or impacted in the UI of the Indicators window (same goes for strategies, as well).

          ETFVoyageur, we do not have anything specifically documented which will explain what you are looking for, but I am going to take a look into the way that Initialize() works and get back to you soon with some information/insight into why it works the way it works.
          Dave I.NinjaTrader Product Management

          Comment


            #6
            Originally posted by NinjaTrader_Dave View Post
            Hello,

            As a general rule, you will need to remove and re-add an indicator if you have changed anything that is set or impacted in the UI of the Indicators window (same goes for strategies, as well).
            Not quite. It is more as I said: properties can get updated/added and they show up in the PropertyGrid; but not objects that were created or initialized in the Initialize() method. Even there, some things can be changed and show up dynamically. Definitely Plots and Lines cannot be dynamically added or removed.

            Comment


              #7
              Hello,

              I've got a bit more information for you. The reason you are seeing this behavior is because Initialize() is called once when the Indicators window is opened, as a way to prepare the various properties, lines, and plots of the different indicator Types available. Then, Initialize() is called once more when an indicator is actually applied to a chart. We understand how this can be less than optimal when you are trying to control your class variables at different points during initialization, but there is not a way to specifically execute code on one call to Initialize() but not the other.

              In order to stick within the architecture of NinjaTrader 7, there will not be a way to get around the way this works. That being said, we have completely re-thought the way that indicator initialization works in NinjaTrader 8 to resolve this dilemma.

              In NinjaTrader 8, we’ve done away with Initialize() / OnStartUp() / OnTermination(), and replaced them with OnStateChange(). OnStateChange() breaks up the different phases that an indicator goes through during initialization and beyond, allowing you much more precise control over where and when your class variables and other fields are managed through various States. For example, we now distinguish between State.SetDefaults (which you can think of as the first pass-through of Initialize() in NinjaTrader 7) and State.Configure (which you can think of as the second pass-through of Initialize() in NinjaTrader 7). Thus, if you were to set up class variables in State.Configure, you would not need to worry about them being reset to defaults after initialization.

              Other states include:
              • State.Historical - called once the object begins to process historical data
              • State.Realtime - called once the object begins to process real time data
              • State.Transition - called once the object is finished processing historical data, but before it begins processing real-time data
              • State.DataLoaded - called only once after all data series have been loaded
              • State.Terminated - called when the object terminates


              Here is a quick breakdown of why NinjaTrader 7’s Initialize() works the way it does. When a new instance of an indicator is created, the Clone() method does three things: First, it loops though all of the properties contained in the Type that you are instantiating (the indicator Type), and sets them to default values. After that, it does the same for all lines and plots contained in that Type.

              If you wish, you should be able to override Clone() in your code to alter the behavior in NinjaTrader 7:

              Code:
               public override object Clone()
                {
                   // return an object
                }
              Dave I.NinjaTrader Product Management

              Comment


                #8
                Dave,

                Thanks for your information. This reply is to just the NinjaTrader 7 part of it.

                I've got a bit more information for you. The reason you are seeing this behavior is because Initialize() is called once when the Indicators window is opened, as a way to prepare the various properties, lines, and plots of the different indicator Types available.
                Understood. Actually, a new instance of the indicator is created for this purpose -- that's why Initialize() is called at all. There is one thing you are leaving out, and that my original question asked about. After Initialize() returns NT once again sets persistent data to the values it is trying to persist. This occurs right after the indicator returns from Initialize(), undoes any changes Initialize() may have made, and happens before any other calls (such as the calls to ToString() and GetProperties()) that occur before the dialog is posted. My question is why NT does this. This is what has been a problem for me and I see no redeeming value. My appeal was for an explanation of why this behavior is taking place.

                Then, Initialize() is called once more when an indicator is actually applied to a chart.
                At least the implication there is not correct. Initialize() is not called once more on the same instance. At this point NT has created another new instance of the indicator to apply to the chart. Initialize() is, naturally, called on this new instance. (It is really important to keep track of which instance is being called by NT or else any tracing/debugging is very confusing. That's why my indicators have implemented a monotonically increasing "object ID" -- so that I can tell which instance any call is being made on.)

                At any rate, as always, NT resets the persistent data after the indicator returns from Initialize() and before anything else is called. This resetting after Initialize() has returned is the behavior I would like to understand the purpose of. I am unaware of any useful purpose for this; as far as I can see it is just pure bad behavior. I will admit that most indicators never care, because they are not changing any persistent data in Initialize(). Of course there is a chicken-and-egg issue here -- I have seen in these forums that one should not make changes in Initialize() because they will not stick.

                So why does NT do that?

                We understand how this can be less than optimal when you are trying to control your class variables at different points during initialization, but there is not a way to specifically execute code on one call to Initialize() but not the other.

                In order to stick within the architecture of NinjaTrader 7, there will not be a way to get around the way this works.
                That's not the point. I have no trouble with how Initialize() itself works. My problem is with what NT does after Initialize() returns. The fact is that my Initialize() code does not care when or why it is called. It does react to the value of the properties, though. That means that Initialize() may do different things in the second instance, depending on what values the user used the dialog to set.

                The user's new settings will be passed to the second instance (NT persisting properties before Initialize() -- a Good Thing). That could result in the second instance doing such things as creating different lines and/or plots than the first instance did. My impression is that NT does not expect this and does not allow for it, which causes various problems.

                So, once again, the same question: Why does NT reinitialize the persistent data after Initialize() has returned? That is what I am trying to understand.

                --EV

                Comment


                  #9
                  Dave,

                  Here's the reply to the rest of your message. I split the replies so the initial NinjaTrader7 part would be clear and not become overly long.

                  In NinjaTrader 8, we’ve done away with Initialize() / OnStartUp() / OnTermination(), and replaced them with OnStateChange(). OnStateChange() breaks up the different phases that an indicator goes through during initialization and beyond, allowing you much more precise control over where and when your class variables and other fields are managed through various States.
                  Wow! Thanks for the information. I can see that custom indicators will definitely have to be re-written for NinjaTrader 8. Will ICustomTypeDescriptor still be supported? I rely on GetProperties() for several things, such as removing unwanted properties from the Indicators dialog and implementing persistent data properties. I do not care about that interface, but I do need that capability.

                  For example, we now distinguish between State.SetDefaults (which you can think of as the first pass-through of Initialize() in NinjaTrader 7) and State.Configure (which you can think of as the second pass-through of Initialize() in NinjaTrader 7).
                  I do not want to get pedantic, but as I explained in my previous post there is no such thing as more than one pass through Initialize() and I believe it makes it hard for developers to have the correct mental model when it is referred to that way. What does happen in NT7 is that a new object is created, and its Initialize() is called, when putting up the dialog. Another new instance is created, and its Initialize() is called, when putting up the chart. In no case does Initialize() get called more than once for any given object instance -- it is important that developers understand this.

                  Thus, if you were to set up class variables in State.Configure, you would not need to worry about them being reset to defaults after initialization.
                  Two questions:
                  • Does this mean that, for any given instance, NT8 sets the persistent data only once (unlike NinjaTrader 7)?
                  • Will NinjaTrader still be creating multiple indicator instances, as it does in NT7?


                  Here is a quick breakdown of why NinjaTrader 7’s Initialize() works the way it does. When a new instance of an indicator is created, the Clone() method does three things: First, it loops though all of the properties contained in the Type that you are instantiating (the indicator Type), and sets them to default values. After that, it does the same for all lines and plots contained in that Type.

                  If you wish, you should be able to override Clone() in your code to alter the behavior in NinjaTrader 7:
                  I expect Clone() happens before the call to Initialize(), since those thing are all set before Initialize() is called. Understood. What I still do not understand is why NT resets everything once again after Initialize() has returned.

                  --EV
                  Last edited by ETFVoyageur; 07-13-2015, 05:28 PM.

                  Comment


                    #10
                    Dave,

                    BTW: it just occurred to me that my previous could be interpreted as concern about NT8. In fact, based on just what you said, NT8 sounds quite nice. The devil is in the details -- I'm anxious for NT8 to be released so I can give it a try -- but so far it sounds good.

                    --EV

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by yeshujbp, Today, 02:50 PM
                    0 responses
                    1 view
                    0 likes
                    Last Post yeshujbp  
                    Started by tonynt, Today, 12:39 PM
                    0 responses
                    11 views
                    0 likes
                    Last Post tonynt
                    by tonynt
                     
                    Started by Martyb, 06-13-2019, 05:14 AM
                    10 responses
                    78 views
                    0 likes
                    Last Post iq200
                    by iq200
                     
                    Started by Erwin Beckers, 11-04-2018, 02:39 AM
                    4 responses
                    71 views
                    2 likes
                    Last Post brucerobinson  
                    Started by ntbone, Today, 01:25 AM
                    0 responses
                    6 views
                    0 likes
                    Last Post ntbone
                    by ntbone
                     
                    Working...
                    X