Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Why is State.Terminated() run when another, different indicator is loaded?

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

    Why is State.Terminated() run when another, different indicator is loaded?

    I cannot think of any reason why State.Terminated is run on other indicators, when a new indicator is loaded onto a chart. We end up with NinjaTrader cleaning objects/resources that are still needed by a class, and all because we loaded another, completely independent class? That breaks the primary purpose of encapsulation in OOP.

    Want to see a demo? Please download the indicator attached, and put it on a chart, then load any other indicator, and see what happens. As the TextFixed object belongs to the posted indicator, it is obvious that loading another, unrelated indicator onto the chart, is running a method in the previously loaded indicator. Why?!?

    Funnily enough, if when loading the second indicator, one does it by "Apply"ing, then cancelling, the spurious State.Terminated code does not run, and the indicators are all loaded. This means incontrovertibly, that the spurious run only happens when one hits "OK" to load the indicator. Regardless, the termination routine of a class should not be triggered by anything from anywhere, but the actual, conscious, termination of the class itself.

    No, the workaround that I have described is not a valid response to this. Encapsulation rules must be obeyed. ALWAYS!
    Attached Files
    Last edited by koganam; 03-07-2016, 12:42 PM.

    #2
    I noticed the text at the bottom of this page: http://ninjatrader.com/support/helpG...tatechange.htm
    eDanny
    NinjaTrader Ecosystem Vendor - Integrity Traders

    Comment


      #3
      Originally posted by eDanny View Post
      I noticed the text at the bottom of this page: http://ninjatrader.com/support/helpG...tatechange.htm
      If you are referring to this:
      When an indicator is configured on a chart while a Compile is taking place in the NinjaScript Editor, it can appear that the script passes through State.Terminated. However, this is the result of a copy of the script being initialized at compile-time, NOT the result of the indicator on the chart being disabled and re-initialized.
      that is not it at all. No compilation is taking place. It happens merely from loading another indicator on the chart.

      A corollary that makes no sense to me either, is that when you remove an indicator, all the other indicators are reloaded. How do I know? Because of the way that this indicator was deliberately written. One way to remove the text from the chart is to reload the indicator, at which time, State.Configure is run, and removes the text. The same thing happens when you have that text on the chart, then remove the indicator that you just added: showing that the indicator left on the chart is being reloaded.

      Comment


        #4
        Sorry, I was referring to the paragraph prior where this is found:

        For example, opening the Indicators window will trigger State. SetDefaults for all indicators in the system, and closing the Indicators window will trigger State.Terminated for all Indicators.
        eDanny
        NinjaTrader Ecosystem Vendor - Integrity Traders

        Comment


          #5
          Originally posted by eDanny View Post
          Sorry, I was referring to the paragraph prior where this is found:

          For example, opening the Indicators window will trigger State. SetDefaults for all indicators in the system, and closing the Indicators window will trigger State.Terminated for all Indicators.
          Ah, I see it now, and it is still a violation of encapsulation behavior. Another class's resources should never be disposed of by a different class, unless that different class is doing so as an object that was processed directly by the first class, and explicitly told to dispose of resources.

          This is a very bad design. I just had resources disposed of in a Strategy that I was running live, and it triggered a bad exception that left the strategy in an indeterminate state with plenty of profit on the line. I had to intervene to manually manage the position to a close, as the only safe thing to do. The annoying part is that if I had not been forced to close the position, the strategy would be in bigger profit than it was. I am most displeased. In the meantime, as the strategy has not generated any new orders after being restarted, I might as well have been trading manually all along.

          I should not have been trading live with a beta? Maybe. It does not change the reality. After all, NT7 did not run OnTermination() on everything, when something happened elsewhere.
          Last edited by koganam; 04-02-2016, 09:54 PM. Reason: Corrected spelling and grammar.

          Comment


            #6
            Just updated file in the original thread, so that it more clearly shows from whence the State.Terminated was run.

            Comment


              #7
              Sorry to hear of the trouble. From a design perspective, we agree that SetDefaults/Terminated should only run from the instance of NinjaScript object that is currently being executed.

              State.SetDefaults and State.Terminated are both set as you bring up the list of Indicators/Strategies and close the list on all types that match the dialog you are using. This should be a completely unrelated instance to the object you are currently running.

              Although it is currently designed that State.Terminated can be set through various actions as the other user pointed out, in principle, what you are reporting is understandably unexpected, and I'd like to help understand exactly what happened so we can run this by our developers, or update documentation as needed.

              In principle, you should only clean up resources of which you have actually instantiated during NinjaScript object's lifetime. For example, if you're making resources in State.Configure, you should ensure that State.Configure has run before you clean up that resource later in State.Terminated. However, in our design, this is not exactly a requirement as an indicator configured and running on the chart should not interfere with another. For example:

              Indicator has "MyVariable" object, which you set up on State.Configure. This object is also later cleaned up in State.Terminated without any reference checking, it simply disposes of the object anytime State.Terminated is ran.

              Since the object itself was set up in State.Configure in Indicator instance A, the reference to that "MyVariable" object could only be seen by Indicator instance A. When you bring up your list of indicators, which then generates Indicator instance B, its State.Terminated would be set as you closed the indicator dialog, but there would not be a "MyVariable" object of instance B to dispose of. This action would not interfere with the first instance's object, unless of course, MyVariable was static...

              In your example - the draw text methods are static, so you can run into situations just as you have demonstrated. On a related note, it would be unexpected that you can call any of the Draw... methods from State.Terminated, so we are looking into that separately

              Can you give me an idea of what type of resource you were using? Was this just a drawing object as you are demonstrating? If it was anything other than a static resource, I would completely agree that something unexpected is occurring and would want to run the exact situation you ran into on the field past our developers.
              MatthewNinjaTrader Product Management

              Comment


                #8
                Originally posted by NinjaTrader_Matthew View Post
                Sorry to hear of the trouble. From a design perspective, we agree that SetDefaults/Terminated should only run from the instance of NinjaScript object that is currently being executed.

                State.SetDefaults and State.Terminated are both set as you bring up the list of Indicators/Strategies and close the list on all types that match the dialog you are using. This should be a completely unrelated instance to the object you are currently running.

                Although it is currently designed that State.Terminated can be set through various actions as the other user pointed out, in principle, what you are reporting is understandably unexpected, and I'd like to help understand exactly what happened so we can run this by our developers, or update documentation as needed.

                In principle, you should only clean up resources of which you have actually instantiated during NinjaScript object's lifetime. For example, if you're making resources in State.Configure, you should ensure that State.Configure has run before you clean up that resource later in State.Terminated. However, in our design, this is not exactly a requirement as an indicator configured and running on the chart should not interfere with another. For example:

                Indicator has "MyVariable" object, which you set up on State.Configure. This object is also later cleaned up in State.Terminated without any reference checking, it simply disposes of the object anytime State.Terminated is ran.

                Since the object itself was set up in State.Configure in Indicator instance A, the reference to that "MyVariable" object could only be seen by Indicator instance A. When you bring up your list of indicators, which then generates Indicator instance B, its State.Terminated would be set as you closed the indicator dialog, but there would not be a "MyVariable" object of instance B to dispose of. This action would not interfere with the first instance's object, unless of course, MyVariable was static...

                In your example - the draw text methods are static, so you can run into situations just as you have demonstrated. On a related note, it would be unexpected that you can call any of the Draw... methods from State.Terminated, so we are looking into that separately

                Can you give me an idea of what type of resource you were using? Was this just a drawing object as you are demonstrating? If it was anything other than a static resource, I would completely agree that something unexpected is occurring and would want to run the exact situation you ran into on the field past our developers.
                Thank you for your response Matthew. What you are saying is pretty much what I am saying too. Did you take good notice of this piece, in my original post?
                Funnily enough, if when loading the second indicator, one does it by "Apply"ing, then cancelling, the spurious State.Terminated code does not run, and the indicators are all loaded. This means incontrovertibly, that the spurious run only happens when one hits "OK" to load the indicator.
                What this means is that you are running every class's State.Terminate event only when we hit "OK", but not when we hit "Apply". This violates both what NT7 did, and what Windows Object Model does (not sure if WOM requires it); namely that the only difference in code between an "OK" button and an "Apply" button should be that they run the same code, but the "Apply" button leave the dialog box open, while the "OK" button closes the dialog box. That running of the State.Terminated event is the real issue here. I understand your reference to the static method, but no static object is being removed. The static method itself should not run under the circumstances.

                As to the objects in question that caused me to start this investigation, no, it is not a DrawObject. It is a somewhat complex, large decision engine which is used to essentially run a backtest on each new bar, to determine the expectancy of reaching a target number of ticks, as opposed to hitting a number of ticks to a Stop, then using different size criteria to determine if a trade may be placed, and what the parameters of said trade should be. This decision engine is implemented as a separate class, and an instance is loaded by the Strategy. (So it is not a static class, evidently, as we are loading an instance). This DecisionEngine() instance is disposed of in the State.Terminated event of the Strategy.

                In any case, the demo code that I posted is not disposing of a Text object in OBU or even State.Terminated, so the disposal of that Text object is not part of the issue. Yes, the Text object is being removed (in State.Configure) because we want to demonstrate and isolate when State.Terminated is being run, spuriously or not.

                What happened in this case, is that I opened and loaded another indicator, because I wanted to see if price was hitting the Volatility Bands, in which case, I might start thinking of doing something. As soon as I hit "OK" to load the Volatility Bands, things went haywire. It was kind of obvious to me that the DecisionEngine() object has been destroyed and and the OBU had tried to access the now null object.

                Naturally, if I create and load an object in State.Configure, the only place I check that it loaded correctly is after I create it, not before I access it in another handler. So, in this case, even a null check in OBU is not sufficient, as though such may prevent an access violation, the destroyed DecisionEngine() can no longer provide the parameters for any more trades. So all a null check in OBU would do is prevent the trigger of the violation, but the strategy would take no further trades: a case in which the graceful failure is itself appropos of nothing as regards my purpose to actually take trades that set up. After all, I cannot take trades if none set up, and no trade can set up if the DecisionEngine() object has been destroyed.

                Thanks for your time.
                Last edited by koganam; 03-07-2016, 10:18 PM.

                Comment


                  #9
                  NT8 indicators do not implement Dispose()?

                  Originally posted by NinjaTrader_Matthew View Post
                  Sorry to hear of the trouble. From a design perspective, we agree that SetDefaults/Terminated should only run from the instance of NinjaScript object that is currently being executed.

                  State.SetDefaults and State.Terminated are both set as you bring up the list of Indicators/Strategies and close the list on all types that match the dialog you are using. This should be a completely unrelated instance to the object you are currently running.

                  Although it is currently designed that State.Terminated can be set through various actions as the other user pointed out, in principle, what you are reporting is understandably unexpected, and I'd like to help understand exactly what happened so we can run this by our developers, or update documentation as needed.

                  In principle, you should only clean up resources of which you have actually instantiated during NinjaScript object's lifetime. For example, if you're making resources in State.Configure, you should ensure that State.Configure has run before you clean up that resource later in State.Terminated. However, in our design, this is not exactly a requirement as an indicator configured and running on the chart should not interfere with another. For example:

                  Indicator has "MyVariable" object, which you set up on State.Configure. This object is also later cleaned up in State.Terminated without any reference checking, it simply disposes of the object anytime State.Terminated is ran.

                  Since the object itself was set up in State.Configure in Indicator instance A, the reference to that "MyVariable" object could only be seen by Indicator instance A. When you bring up your list of indicators, which then generates Indicator instance B, its State.Terminated would be set as you closed the indicator dialog, but there would not be a "MyVariable" object of instance B to dispose of. This action would not interfere with the first instance's object, unless of course, MyVariable was static...

                  In your example - the draw text methods are static, so you can run into situations just as you have demonstrated. On a related note, it would be unexpected that you can call any of the Draw... methods from State.Terminated, so we are looking into that separately

                  Can you give me an idea of what type of resource you were using? Was this just a drawing object as you are demonstrating? If it was anything other than a static resource, I would completely agree that something unexpected is occurring and would want to run the exact situation you ran into on the field past our developers.
                  Apropos of this, as I am not able to supply the decision engine class, I started out to write a new file to demonstrate this, only to realize that, unlike in NT7, NT8 indicators do not implement a Dispose() functionality. That means that I cannot just use a simple system indicator to demonstrate this, as there is no provision for explicitly destroying the object.

                  NT7's implementation of IDisposable was much more useful. Even in OBU, it has sometimes been necessary to Dispose() of an object, in order to recreate it with different parameters. Please implement IDisposable on indicators in NT8.

                  e.g., http://ninjatrader.com/support/forum...ad.php?t=66805
                  Last edited by koganam; 03-07-2016, 11:45 PM.

                  Comment


                    #10
                    If you just hit "APPLY", there is still early instances of the indicator in reference. It is not until you close the indicator dialog that these earlier instances are terminated and finalized.

                    Just to be very clear, under the current design, when you add an indicator to a chart via the Chart UI, there are essentially 3 instances which generate throughout the process for 3 different situations. All 3 of these cases run its termination throughout its lifetime:
                    1. The earlier instance used to create the list of indicators by name
                      Terminated when you close the indicators window
                    2. The selected instance which pushes its default settings the UI
                      Terminated when you "remove" the indicator from the configured menu, or after the user press OK/Cancels the indicators window
                    3. The executed instance which runs against the user-configured settings.
                      Terminated when the user performs some action which could cause the indicator to remove/reload (or it hits a fatal error)


                    Although, the termination logic executed during these 3 cases should not interfere with another, as long as your resources were properly set up after the state was configured. The first two instances never go beyond State.Defaults and will then be terminated.

                    I have attached an indicator I am hoping will help clarify the current behavior. I do not have enough incentive this point to request any changes to our developers to our existing design, but I do see this as an area we can expand in our educational resources.

                    In the meantime, please have a look at the following results which I have tracked each instances using a GUID per the attached indicator.

                    Opening And Canceling Indicator Dialog
                    Right click on Chart -> Select Indicators
                    Output-> TestStates{c379ae5c-bd34-44d6-ab4c-78a53f57df33} State=SetDefaults
                    Press Cancel
                    Output-> TestStates{c379ae5c-bd34-44d6-ab4c-78a53f57df33} State=Terminated
                    Adding Unrelated Indicator To Chart
                    Right click on Chart -> select Indicators
                    Output-> TestStates{1fc387cd-1fae-4fa7-ab46-169a2a9a9502} State=SetDefaults
                    Add ADL indicator -> Press OK
                    Output-> TestStates{1fc387cd-1fae-4fa7-ab46-169a2a9a9502} State=Terminated
                    Highlight ADL indicator plot and delete from chart
                    Output-> Nothing output
                    Adding Indicator, Cancel Indicator Dialog
                    Right click on Chart -> Select Indicators
                    Output-> TestStates{d83a7d55-8ff3-4496-b1a1-7a5cbcc95c1e} State=SetDefaults
                    Add "TestStates" indicator
                    Output-> TestStates{e633ba70-4341-428b-b622-cace6a7c9a01} State=SetDefaults
                    Press Cancel
                    Output-> TestStates{d83a7d55-8ff3-4496-b1a1-7a5cbcc95c1e} State=Terminated
                    Output-> TestStates{e633ba70-4341-428b-b622-cace6a7c9a01} State=Terminated
                    Adding Indicator By "Apply" And Then "Cancel"
                    Right click on chart -> select Indicators
                    Output-> TestStates{cf22e3ff-3444-4fe8-b352-62aaeb80ccc0} State=SetDefaults
                    Add "TestStates" indicator
                    Output-> TestStates{5be9a99b-89d0-4ae8-9092-5a84ada89149} State=SetDefaults
                    Press Apply->
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=SetDefaults
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=Configure
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=DataLoaded
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=Historical
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=Transition
                    Output-> TestStates{a23942e6-eac6-4738-a23e-7b44ebd01a4d} State=Realtime
                    Press Cancel
                    Output-> TestStates{cf22e3ff-3444-4fe8-b352-62aaeb80ccc0} State=Terminated
                    Output-> TestStates{5be9a99b-89d0-4ae8-9092-5a84ada89149} State=Terminated
                    Adding Indicator By "OK
                    Right click on chart -> select Indicators
                    Output-> TestStates{f174c056-fbd8-413d-a024-fbc3b0f05371} State=SetDefaults
                    Add "TestStates" indicator
                    Output-> TestStates{6e2eb2d4-8d9a-4a53-b866-0a5d5101712a} State=SetDefaults
                    Press OK
                    Output-> TestStates{f174c056-fbd8-413d-a024-fbc3b0f05371} State=Terminated
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=SetDefaults
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=Configure
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=DataLoaded
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=Historical
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=Transition
                    Output-> TestStates{31120e05-4fbb-4f7b-a4b7-497916d0f8de} State=Realtime
                    Output-> TestStates{6e2eb2d4-8d9a-4a53-b866-0a5d5101712a} State=Terminated
                    Attached Files
                    MatthewNinjaTrader Product Management

                    Comment


                      #11
                      Originally posted by koganam View Post
                      Apropos of this, as I am not able to supply the decision engine class, I started out to write a new file to demonstrate this, only to realize that, unlike in NT7, NT8 indicators do not implement a Dispose() functionality. That means that I cannot just use a simple system indicator to demonstrate this, as there is no provision for explicitly destroying the object.

                      NT7's implementation of IDisposable was much more useful. Even in OBU, it has sometimes been necessary to Dispose() of an object, in order to recreate it with different parameters. Please implement IDisposable on indicators in NT8.

                      e.g., http://ninjatrader.com/support/forum...ad.php?t=66805
                      IDiposiable was not flexible for us to use to support the extended NinjaScript types we added in NinjaTrader 8, which is part the States concept introduced in this version. You can use SetState(State.Finalized) which iterate the NS object from its current state, through terminated, and eventually, finalize and remove any managed resources. If you have unmanaged resources, you can call Dispose() on that particular resource during the parents State.Terminated state.
                      MatthewNinjaTrader Product Management

                      Comment


                        #12
                        Originally posted by NinjaTrader_Matthew View Post
                        If you just hit "APPLY", there is still early instances of the indicator in reference. It is not until you close the indicator dialog that these earlier instances are terminated and finalized.

                        Just to be very clear, under the current design, when you add an indicator to a chart via the Chart UI, there are essentially 3 instances which generate throughout the process for 3 different situations. All 3 of these cases run its termination throughout its lifetime:
                        1. The earlier instance used to create the list of indicators by name
                          Terminated when you close the indicators window
                        2. The selected instance which pushes its default settings the UI
                          Terminated when you "remove" the indicator from the configured menu, or after the user press OK/Cancels the indicators window
                        3. The executed instance which runs against the user-configured settings.
                          Terminated when the user performs some action which could cause the indicator to remove/reload (or it hits a fatal error)


                        Although, the termination logic executed during these 3 cases should not interfere with another, as long as your resources were properly set up after the state was configured. The first two instances never go beyond State.Defaults and will then be terminated.

                        I have attached an indicator I am hoping will help clarify the current behavior. I do not have enough incentive this point to request any changes to our developers to our existing design, but I do see this as an area we can expand in our educational resources.

                        In the meantime, please have a look at the following results which I have tracked each instances using a GUID per the attached indicator.

                        Opening And Canceling Indicator Dialog


                        Adding Unrelated Indicator To Chart


                        Adding Indicator, Cancel Indicator Dialog


                        Adding Indicator By "Apply" And Then "Cancel"


                        Adding Indicator By "OK
                        Thank you very much for this Matthew.

                        I have this morning done a walk through this by tracing, and it seems to me so far that even though the State.Terminated code is run, it is also followed by what is effectively a reload of the indicator, so running through State.Configure again, and recreating the object that was previously disposed in State.Terminated. I tracked it by simply using a StreamWriter and seeing what was going on, especially as I did not get the expected NullReferenceException, in OBU, from the StreamWriter object that was being disposed in State.Terminated.

                        Given that, I reexamined the Dispose() method in my DecisionEngine code, and could not see any mistakes. After rebooting and restarting NT8, I have not been able to induce the error while playing back historically, the very time slot that caused the error yesterday. For those, reasons, I am, therefore, putting this down to some other error in a beta. My troll through the logs unfortunately provides no clues.

                        I must thank you once again for your responsiveness to this matter.

                        Comment


                          #13
                          Indicator load shenanigans redux: It is still evil

                          I have to raise this one again. Unfortunately, it would appear that the partial reload of the indicator only occurs if something was actually disposed in the State.Terminated event, not otherwise. This whole behavior just seems to be a wrong design.

                          Try this, using the file that I have attached. I tried 2 different scenarios, and as my write up used too many words, I have to break this into 2 posts. My questions are in this post, but the second scenario details are in a separate post that follows this one.

                          The use case from the file remarks:
                          //We know that we are going to show this long table of information on the right hand side of the chart.
                          //It will almost certainly overlap the price bars, so we shall, very professionally, create the space
                          //in the margin, then restore the chart if the indicator is removed.
                          Scenario1
                          Setup a chart with a right margin of 100.
                          Keep the Output Window open for tracking purposes.
                          Load the OTShenanigans2 indicator and see how it shifts the chart bars to the left, so that it has enough space for the table, then draws the table into the space. Confirm it with the readout for the values of the margin at entry and as at now.
                          Note that rather strangely, even though it states that it is running State.Terminated, it does not actually run any code, as no Print() shows in the Output Window. (See last line in quote below).
                          Time run: 3/18/2016 6:29:39 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:30:06 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:30:09 PM - Running State Terminated on OTShenanigans2
                          Time run: 3/18/2016 6:30:10 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:30:10 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:30:10 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.DataLoaded
                          BarMarginRightAtEntry: 100 //we stored the entry value
                          CurrentBarMargin: 260 //then we changed it
                          Time run: 3/18/2016 6:30:10 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:30:10 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:30:10 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:30:10 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                          Now open the indicator dialog, but do not load anything. Just click on OK.
                          See how because State.Terminated is run, the right margin is not even restored but set arbitrarily to zero!(Confirm this from the chart)
                          Time run: 3/18/2016 6:33:20 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:33:20 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:33:25 PM - Running State Terminated on OTShenanigans2
                          Time run: 3/18/2016 6:33:26 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:33:26 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.Terminated
                          BarMarginRightAtEntry: 100 //we seem to have restored the margins here
                          CurrentBarMargin: 100
                          Time run: 3/18/2016 6:33:26 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:33:26 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.DataLoaded
                          BarMarginRightAtEntry: 100 //apparently we reload, so run this again
                          CurrentBarMargin: 260
                          Time run: 3/18/2016 6:33:26 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:33:26 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:33:26 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                          Time run: 3/18/2016 6:33:26 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.Terminated
                          BarMarginRightAtEntry: 0 //uh oh. It has now set everything to zero because State.Terminated run again!
                          CurrentBarMargin: 0
                          So now we just remove the OTShenanigans2 indicator from the chart.
                          Strange. We appear to have restored the margin to 100. Even the Print() says so. So what about that zero value we saw?
                          Time run: 3/18/2016 6:42:09 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:42:09 PM - Running State SetDefaults on OTShenanigans2
                          Time run: 3/18/2016 6:42:15 PM - Running State Terminated on OTShenanigans2
                          Time run: 3/18/2016 6:42:16 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.Terminated
                          BarMarginRightAtEntry: 100
                          CurrentBarMargin: 100
                          Here comes the kicker. There would appear to be a residual, delayed effect. Remember that zero margin readout we got that seems to have resolved itself? All on its lonesome, just by waiting, here we go.
                          Time run: 3/18/2016 6:44:04 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                          From State.Terminated
                          BarMarginRightAtEntry: 0
                          CurrentBarMargin: 0

                          But just in case this does not happen, open the chart properties. You will see that the margin actually does read zero. Change it to any other figure, and press OK. You will find that the configuration is ignored, and the margin stays at zero.
                          Repeat the last instruction. Now it does get changed.
                          Results of the residual effects?

                          One could start making "unsupported" noises about changing the margin of the chart, no matter how much more professional that looks. But we must still ask the question: "Why at any time was the value of the BarMarginRightAtEntry made to become zero. Once assigned, it was never used in any calculation. At best it was used as a datastore to hold a single int. Why was that int made zero at any time?

                          The only question left is what happens if we never hit the OK button, and instead hit "Apply", then "Cancel"? It turns out that I was wrong. It actually operates in pretty much the same manner.

                          So again, the question: "Why are members of an object being changed based on actions on another object. Specifically, why is the exit routine of a class being run because of actions outside the class: actions that have nothing to do with the first class?" Opening or closing a dialog box should not cause exit processing in anything unrelated to the target of the invocation of said databox. Most certainly, I cannot see why exit processing is run when I merely open a dialog and close it without doing anything.

                          Scenario2 is posted next, separately.
                          Attached Files
                          Last edited by koganam; 03-21-2016, 03:12 PM.

                          Comment


                            #14
                            Indicator load shenanigans redux: It is still evil. Part 2

                            Scenario2
                            Start from scratch. (The initial behavior is the same as in Scenario1).
                            Setup a chart with a right margin of 100.
                            Keep the Output Window open for tracking purposes.
                            Load the OTShenanigans2 indicator and see how it shifts the chart bars to the left, so that it has enough space for the table, then draws the table into the space. Confirm it with the readout for the values of the margin at entry and as at now.
                            Note that rather strangely, even though it states that it is running State.Terminated, it does not actually run any code, as no Print() shows in the Output Window. (See last line in quote below).
                            Time run: 3/18/2016 7:25:12 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:25:21 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:25:23 PM - Running State Terminated on OTShenanigans2
                            Time run: 3/18/2016 7:25:24 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:25:24 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:25:24 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.DataLoaded
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 260
                            Time run: 3/18/2016 7:25:24 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:25:24 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:25:24 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:25:24 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            Now load any indicator.
                            Time run: 3/18/2016 7:26:39 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:26:39 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:26:45 PM - Running State Terminated on OTShenanigans2
                            Time run: 3/18/2016 7:26:46 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:26:46 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 100
                            Time run: 3/18/2016 7:26:46 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:26:46 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.DataLoaded
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 260
                            Time run: 3/18/2016 7:26:46 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:26:46 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:26:46 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:26:46 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 0
                            CurrentBarMargin: 0
                            No real surprise. Pretty much the same as in Scenario1.
                            Now, remove the indicator that we just added.
                            Time run: 3/18/2016 7:32:23 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:32:23 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:32:32 PM - Running State Terminated on OTShenanigans2
                            Time run: 3/18/2016 7:32:33 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:32:33 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 100
                            Time run: 3/18/2016 7:32:33 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:32:33 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.DataLoaded
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 260
                            Time run: 3/18/2016 7:32:33 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:32:33 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:32:33 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:32:33 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 0
                            CurrentBarMargin: 0
                            Why the heck should state terminated be running when on OTShenanigans2, when I removed a different indicator. I did not terminate anything on OTShenanigans2.
                            Of course, my chart is still royally messed up.
                            Hit F5 while the chart has focus.
                            The chart looks like it has been corrected. Has it really? Regardless, I should not have to do this. I did not do it in NT7, and I should not have to do it now.
                            Time run: 3/18/2016 7:34:39 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 7:34:39 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 100 //this was zero. From where did it actually pull this.
                            CurrentBarMargin: 100
                            Time run: 3/18/2016 7:34:39 PM - Running State Configure on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:34:39 PM - Running State DataLoaded on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.DataLoaded
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 260
                            Time run: 3/18/2016 7:34:39 PM - Running State Historical on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:34:39 PM - Running State Transition on OTShenanigans2(TF 09-15 (3 Minute))
                            Time run: 3/18/2016 7:34:39 PM - Running State Realtime on OTShenanigans2(TF 09-15 (3 Minute))
                            Now let us take off the OTShenanigans2 indicator.
                            Time run: 3/18/2016 11:10:44 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 11:10:44 PM - Running State SetDefaults on OTShenanigans2
                            Time run: 3/18/2016 11:10:50 PM - Running State Terminated on OTShenanigans2
                            Time run: 3/18/2016 11:10:51 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 100
                            CurrentBarMargin: 100
                            We can confirm that the chart looks right.
                            And once again, a few minutes later, all on its lonesome, while I was writing this and no longer interacting with NT8, this.
                            Time run: 3/18/2016 11:11:51 PM - Running State Terminated on OTShenanigans2(TF 09-15 (3 Minute))
                            From State.Terminated
                            BarMarginRightAtEntry: 0
                            CurrentBarMargin: 0
                            So now what can we conclude? Well, refreshing the chart, using F5, after the chart was messed up, did force a reload of things to make them kosher. But even that was just deception, as the margin went to zero, after a while. Again, residual effects?

                            Then, I repeat all the questions from the Scenario1 write up, just so that it looks self-contained: "So again, the question: "Why are members of an object being changed based on actions on another object. Specifically, why is the exit routine of a class being run because of actions outside the class: actions that have nothing to do with the first class?" Opening or closing a dialog box should not cause exit processing in anything unrelated to the target of the invocation of said databox. Most certainly, I cannot see why exit processing is run when I merely open a dialog and close it without doing anything."

                            For everything marked in blue, Why?
                            Last edited by koganam; 03-19-2016, 12:42 PM.

                            Comment


                              #15
                              Thanks for the detailed questions. I am running this by development and will get back to you with our findings.
                              MatthewNinjaTrader Product Management

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by GwFutures1988, Today, 02:48 PM
                              1 response
                              3 views
                              0 likes
                              Last Post NinjaTrader_Clayton  
                              Started by ScottWalsh, 04-16-2024, 04:29 PM
                              6 responses
                              27 views
                              0 likes
                              Last Post ScottWalsh  
                              Started by frankthearm, Today, 09:08 AM
                              10 responses
                              36 views
                              0 likes
                              Last Post frankthearm  
                              Started by mmenigma, Today, 02:22 PM
                              1 response
                              3 views
                              0 likes
                              Last Post NinjaTrader_Jesse  
                              Started by NRITV, Today, 01:15 PM
                              2 responses
                              9 views
                              0 likes
                              Last Post NRITV
                              by NRITV
                               
                              Working...
                              X