Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Controlling indicator configuration GUI

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

    #16
    Using reflection to set the attribute is a failure, unless someone can tell me what I am missing.

    My setup:
    • A chart with an instance of each of two of my indicators
    • The indicators share a common base class of mine
    • The base class is a subclass of Indicator
    • There are some properties that are the same in both indicators.
    • The goal is to encapsulate those parameters
    • The only possibly workable solution anyone has proposed is based on .NET reflection, allowing attribute modification from Initialize()

    Here's what I have found out by using Reflection to examine the properties and attributes for my two indicators.

    if one indicator has its own (local) copy of the property and the other indicator depends on the base class copy of the property all works fine:
    • Neither indicator affects the other when changing the property value
    • The .NET Reflection method successfully changes the Browsable attribute, and that successfully controls whether or not the property is shown in the indicators' configuration dialog.
    • Neither indicator affects the other when changing the attribute's value

    However, if both indicators depend on the base class property (i.e. neither has a local instance of the property)
    • Neither indicator affects the other when changing the property value
    • The .NET Reflection method successfully changes the Browsable attribute
    • One indicator changing the attribute's value does affect the other indicator -- they both get the same attribute value. That means the property can be hidden or shown programmatically (from Initialize()) but any such action will affect both indicators. It is not possible for one to show the property and the other not to.
    • I have confirmed this unpleasant aspect of attribute values both by .NET Reflection and by observing the indicators configuration dialog.

    That's it -- properties in the base class do provide instance-specific values, as one would expect for non-static base class values. However, the property's attribute value is not instance-specific -- it is shared. That means, unless someone can tell me what I am missing, that using the base class to encapsulate properties is not a successful plan. Any thoughts on how to make the base class property attributes be instance-specific?

    (I say instance specific, but I could live with indicator class-specific. Just not common to the whole base class, as they are at the moment.)

    --EV

    Comment


      #17
      Hello EV,

      What I believe is happening is that NinjaTrader is using the cached instance of the base class effecting both.

      Have tried to use a partial class instead of a base class to do what you are looking for?
      JCNinjaTrader Customer Service

      Comment


        #18
        The base class is already declared as "public abstract class". NinjaTrader has not inserted the usual magic caching code at the bottom -- I suppose because it is an abstract class.

        --EV

        Comment


          #19
          Originally posted by ETFVoyageur View Post
          The base class is already declared as "public abstract class". NinjaTrader has not inserted the usual magic caching code at the bottom -- I suppose because it is an abstract class.

          --EV
          After market close, I will see if I can confirm that this is the same when using a partial class. I have not seen this problem yet, but then again, I do have local overrides on the properties, which I just happened to do so that I could see them directly in the code, instead of having to go look again in the partial class.

          Comment


            #20
            FWIW: my local override was just a testing artifact. I'd be content with just the property in just the base class except that as far as I can tell the attributes are base-class-wide, not per-instance.

            In fact, I don't really want them in the derived class -- the original point was to get them encapsulated so that they are coded in only one place.

            --EV

            Comment


              #21
              Originally posted by ETFVoyageur View Post
              FWIW: my local override was just a testing artifact. I'd be content with just the property in just the base class except that as far as I can tell the attributes are base-class-wide, not per-instance.

              In fact, I don't really want them in the derived class -- the original point was to get them encapsulated so that they are coded in only one place.

              --EV
              Understood. What I mean is that I too will remove the local overrides on the Properties, and see if I see the same behavior, as my method and Properties are implemented in a partial class rather than a base class. I really do not expect to see a difference in behavior, but I would like to confirm such.

              I do not mind having the local overrides anyway. It still allows me to set base properties, class-wide, and only change them in the indicator itself, so that is just fine by me. For me, it is a small price to pay to be able to hide Properties at will, in any Indicator I please.

              Comment


                #22
                Weirdness with properties

                Sorry this is long ... I don't know how to make it short ...

                I am putting this in the thread because it may relate to the attribute problems I have been seeing. In any case, it is all part of my trying to encapsulate a property for common use. The problem I went to work on this time is programmatically initializing a property. After all, different indicators may use the same encapsulated property, but they may want different initial values. That means the initialization must be done programmatically -- i.e. at run time. It must be done at either construction or in Initialize(), because OnStartUp() is too late -- if you put it there it interferes with the user manually setting the property in the configuration dialog. I obviously ran into a problem with that, or else I would not be writing this post. I have some pretty thorough debug printing I can enable, so I was able to get a pretty good idea of what is happening to me.

                The first thing is to say what is not a problem -- i.e. what worked as expected. If I have a plain vanilla property in the derived class then there is no problem. I can initialize it in either the constructor or in Initialize() and all is well. No outside "helper" tries to interfere.

                The problem comes when I try to have a base class property, with a derived class override. It does not matter whether I structure it as a virtual property (base class) and an override property (derived class) or a plain property in each class. Either way, the derived class passes everything on to the base class get/set methods. And either way I have a problem with an unwanted "helper".

                The problem is that when the derived class sets the property from the constructor someone else comes along and resets the property after the constructor completes, and before Initialize() is called. No such reset is done unless the constructor altered the property's value. Same thing with Initialize() -- someone jumps in after Initialize() returns and before OnStartUp() is called and resets the property if Initialize() altered it. As with the constructor case, no such "helper" call is made unless Initialize() changed the property value.

                One thing to note is that the property in question is a color. It is statically initialized to Orange (which works fine in another derived class that does not have a local instance). The derived class with the problem is trying to change the property initial value to Aqua. The "helper" who jumps in forces it to be Lime. The only reason I can think of for Lime is some unwanted caching going on -- Lime is what the property was before I got into tonight's testing. Stopping NT and restarting (with no initial chart) does not help -- the "helper" still knows about Lime when I do create my first chart.

                SIde note: there is some other unwanted initialization going on also. Instrument.FullName is set to "BIDU (daily)" up until it gets set to the right value (whatever I am charting) when Initialize() is called. I'm guessing BIDU is another caching artifact. Seems very wrong -- Instrument should either match what I am charting, or else be invalid until it gets enough info -- being initially set to a wrong value makes no sense to me.

                I'll include my debug print/trace output at the bottom -- it may be hard to read ... sorry if that is so. I hope it helps understand the problem. Notes about it:
                • I give every indicator object instance I create a unique ID -- that was essential to making sense in an environment where so many temps are created. This ID serves no purpose other than debugging printout.
                • in the trace below, the first thing on the line is the ID, so you can keep straight intermingled executions.
                • I have included everything. I have drawn a line where the interesting part starts. #38 is the first interesting thing. #47 is the object that is really shown in the chart, and the one whose settings actually matter.
                • RwbIndicator is the base class and RwbMultiSlope is the derived class
                • RwbIndicator:set/get are the base class property setter and getter

                Ooops .. post too long ... I'll have to post the trace in a followup post


                --EV

                Comment


                  #23
                  Weirdness with properties: part 2 (the trace)

                  (#10) DEBUG: entering RwbMultiSlope() constructor
                  (#10) 4:23:15 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                  (#10) DEBUG: leaving RwbMultiSlope() constructor
                  (#28) DEBUG: entering RwbMultiSlope() constructor
                  (#28) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                  (#28) DEBUG: leaving RwbMultiSlope() constructor
                  (#29) DEBUG: entering RwbMultiSlope() constructor
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                  (#29) DEBUG: leaving RwbMultiSlope() constructor
                  (#28) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:get(BullColor) bullColor=Color [Lime]
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a BIDU (Daily) Entered RwbMultiSlope RwbIndicator:Initialize
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a BIDU (Daily) Entered RwbMultiSlope Initialize
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a BIDU (Daily) Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                  (#29) 4:23:17 AM isConstructed CurrentBar=n/a BIDU (Daily) Leaving RwbMultiSlope Initialize
                  (#29) 01/01/00 isInitialized CurrentBar=-1 BIDU (Daily) Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                  (#29) 01/01/00 isInitialized CurrentBar=-1 BIDU (Daily) Entered RwbMultiSlope ToString isInitialized=True
                  Stuff above this line is various temp objects, and can be ignored for the purpose of understanding the problem.
                  ================================================== ===============

                  (#38) DEBUG: entering RwbMultiSlope() constructor
                  (#38) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                  (#38) DEBUG: leaving RwbMultiSlope() constructor
                  #38 is evidently a temporary object. I do not know its purpose. The trace above shows that in the constructor I changed the statically initialized color Orange to be Aqua

                  (#29) 01/01/00 isInitialized CurrentBar=-1 BIDU (Daily) Entered RwbMultiSlope RwbIndicator:get(BullColor) bullColor=Color [Lime]
                  #29 is another temporary object of unknown purppose -- this is its last appearance, so don't worry about it

                  (#38) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                  Here is the "helper" resetting #38 from Aqua to Lime for #38. I do not know where it got the "Lime" ... my best guess is from something cached

                  (#47) DEBUG: entering RwbMultiSlope() constructor
                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                  (#47) DEBUG: leaving RwbMultiSlope() constructor
                  Here is the chart object getting created. The property color is getting changed from Orange to Aqua, just as #39's was.

                  (#38) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:get(BullColor) bullColor=Color [Lime]
                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                  It looks as if the above two lines are a pair, but that my not be true. It looks as if the "helper" is getting the color (Lime) from #39 and then setting that color in #47. In any case, the "helper" is forcing #47 to be Lime Note that this is happening after #47 returned from its constructor, and before Initialize() was called. The call to do this color setting does not happen unless the constructor changed the color.

                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a UNKNOWN INSTRUMENT Entered RwbMultiSlope ToString isInitialized=False

                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a SPY (Daily) Entered RwbMultiSlope RwbIndicator:Initialize
                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a SPY (Daily) Entered RwbMultiSlope Initialize
                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a SPY (Daily) Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                  (#47) 4:23:17 AM isConstructed CurrentBar=n/a SPY (Daily) Leaving RwbMultiSlope Initialize
                  The above lines show #47 Initialize() method setting the property from Lime (which the "helper" forced) back to Aqua. I put setting that in both the constructor and Initalize() for testing -- the problem is still real if you do just one or the other.

                  (#47) 01/01/00 isInitialized CurrentBar=-1 SPY (Daily) Entered RwbMultiSlope RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                  There he goes again ... the "helper" just set the color back from Aqua to Lime again. Note that this is after Initialize() returned, and before OnStartUp() is called. The call to do this color setting does not happen unless Initialize() changed the color.

                  ================================================== ============
                  Normal stuff below here -- including calling OnStartUp() after the "helper" has forced the Lime color
                  (#47) 01/01/00 isInitialized CurrentBar=-1 SPY (Daily) Entered RwbMultiSlope ToString isInitialized=True
                  (#47) 01/02/96 isInitialized CurrentBar=0 SPY (Daily) Entered RwbMultiSlope RwbIndicator:OnStartUp
                  (#47) 01/02/96 isInitialized CurrentBar=0 SPY (Daily) Entered RwbMultiSlope OnStartUp
                  (#47) 01/02/96 isStarted CurrentBar=0 SPY (Daily) Entered RwbMultiSlope OnBarUpdate first bar
                  (#47) 02/11/14 isStarted CurrentBar=4559 SPY (Daily) Entered RwbMultiSlope OnBarUpdate last bar
                  Last edited by ETFVoyageur; 02-12-2014, 07:54 AM.

                  Comment


                    #24
                    Long post

                    My apologies for such a long post about the problem ... I did not know how to describe it more tersely. Read the prose description first, and then the trace. (I included the trace output because it really shows what is happening.) The bottom line is:
                    • Something other than my code is messing with my property
                    • Why is that "helper" stepping in? How can I avoid that?
                    • Why is some cached value (Lime) even involved? There is nothing about Lime in the current code. The property is being statically initialized to Orange, and the code is trying to dynamically set it to Aqua.
                    • Why is the problem only when the base class is involved with the property?


                    --EV
                    Last edited by ETFVoyageur; 02-12-2014, 08:08 AM.

                    Comment


                      #25
                      Hello EV,

                      Anytime a Indicator window, Strategy Window, or basically any drop down menu where a list of NinjaScript Objects is display it is going to be when Initialize() which is why Dynamically setting anything inside of the Initialize() method is not supported.

                      By the looks of it you are hold, setting, and getting your objects inside of the Derived class, which if you have another Indicator inside of the same chart is accessing that same Derived class since the previous Indicator is going to be cached inside of NinjaTrader. This is where the values are coming from it appears to be.
                      JCNinjaTrader Customer Service

                      Comment


                        #26
                        Originally posted by NinjaTrader_JC View Post
                        Hello EV,

                        Anytime a Indicator window, Strategy Window, or basically any drop down menu where a list of NinjaScript Objects is display it is going to be when Initialize() which is why Dynamically setting anything inside of the Initialize() method is not supported.

                        By the looks of it you are hold, setting, and getting your objects inside of the Derived class, which if you have another Indicator inside of the same chart is accessing that same Derived class since the previous Indicator is going to be cached inside of NinjaTrader. This is where the values are coming from it appears to be.
                        I am having trouble understanding your comment. When should the code be dynamically initializing properties if not in Initialize()? I also do not understand why you think I have a derived class accessing another derived class. In fact, we are talking of two concrete derived classes (the indicators, RwbMomentum and RwbMultiSlope) both of which are derived from one common abstract base class (RwbIndicator)

                        The problems I do not understand are:
                        • Changes to attributes of base class properties are base-class-wide, not per-instance as I would expect. I am expecting attributes to behave like variables in this respect -- each concrete subclass has its own copy. That is evidently not true, so I need to know just how they do behave.


                        • Something (the "helper") is noticing when I modify a property in either the constructor or in Initialize() and stepping in to coerce the value back to what it thinks the value should be. The value it coerces to appears to be some sort of cached value -- it is not one that is in any current code. This only happens for virtual properties, or when the derived class property hides the base class property. Why is some outside code, in just some cases, coercing my class' properties, especially back to some irrelevant value?

                        --EV

                        Comment


                          #27
                          Here is a trace that should be easier to read. I’m trying to make it as clear as I can in the hope that someone can tell me what is going on – why outside code is messing with my property value.
                          • Better status, and columns crisper than the previous trace
                          • The numbers in the first column are ID's that are unique per-indicator instance
                          • Lines during the indicator’s own code are in plain text – those are the “good guys”
                          • Lines caused by outside code are in bold text – those are the “bad guys” that need to be explained
                          • Lines unrelated to the problem (some ToString() calls) are in plain italic text
                          • I had not previously paid attention to #28, but am now much more focused on it -- that is where the Lime color first appears and I cannot see how it got there.
                          • This is the complete output for just bringing up a new chart
                          • FWIW: #47 is the instance that actually gets into the chart


                          The point of this is that some code, other than the indicator’s code, is interfering and undoing the changes the indicator makes to its BullColor property. I am hoping that someone can explain what is going on, why it is happening, and what I can do about it – i.e. how can the indicator dynamically set the initial value of its own property?

                          --EV

                          ========== ========== ========== ========== ==========

                          (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                          (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                          (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                          (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                          (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                          (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                          (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                          (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                          (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor
                          Note that the constructor for each of the above three objects changed the BullColor property value from Orange (the static initialization) to Aqua

                          (#28) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                          (#29) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                          It looks as if the “helper” uses #28 to get the color to coerce #29 to. Note that this is happening after the constructor, and before entering Initialize().

                          IMPORTANT: I have no idea how #28 got to be Lime -- its static initialization is Orange, and the constructor set it to Aqua. If something had later used the property's set method to set Lime, there would be trace printout (from RwbIndicator:set) saying so. No one should have been able to bypass the property set and access the backing store directly -- that is declared "private".


                          (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered RwbIndicator:Initialize
                          (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered Initialize
                          (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                          (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Leaving Initialize
                          Initialize() once again sets BullColor to Aqua

                          (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                          The “helper” once again coerces the color to Lime. Who is doing this, and why? Note that this is happening after Initialize(), and before entering OnStartUp().

                          (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered ToString isInitialized=True

                          (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                          (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                          (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                          (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                          (#38) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                          It looks as if the “helper” uses #29 to get the color to coerce #38 to. Note that this is happening after the constructor, and before entering Initialize().

                          (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                          (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                          (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                          (#38) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                          (#47) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                          It looks as if the “helper” uses #38 to get the color to coerce #47 to. Note that this is happening after the constructor, and before entering Initialize().

                          (#47) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered ToString isInitialized=False

                          (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered RwbIndicator:Initialize
                          (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered Initialize
                          (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                          (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Leaving Initialize

                          (#47) INITIALIZED 01/01/00 CurrentBar=-1 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                          The “helper” once again coerces the color to Lime. Note that this is happening after Initialize(), and before entering OnStartUp().

                          (#47) INITIALIZED 01/01/00 CurrentBar=-1 NUGT (Daily) RwbMultiSlope Entered ToString isInitialized=True

                          (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:OnStartUp
                          (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                          (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered OnStartUp
                          (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                          (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Leaving OnStartUp

                          (#47) updatingBars 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:OnBarUpdate first bar
                          (#47) updatingBars 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered OnBarUpdate first bar
                          (#47) updatingBars 02/10/14 CurrentBar=797 NUGT (Daily) RwbMultiSlope Entered OnBarUpdate last bar
                          Last edited by ETFVoyageur; 02-12-2014, 08:25 PM.

                          Comment


                            #28
                            Hello ETFVoyageur,

                            When should the code be dynamically initializing properties if not in Initialize()?
                            There is not a supported way/time to dynamically change this property, since it is called multiple times it can be changed to values that you would not expect.

                            Although, this is not supported let me see if I can explain it better after doing some more tests on my side.
                            JCNinjaTrader Customer Service

                            Comment


                              #29
                              Originally posted by ETFVoyageur View Post
                              Here is a trace that should be easier to read. I’m trying to make it as clear as I can in the hope that someone can tell me what is going on – why outside code is messing with my property value.
                              • Better status, and columns crisper than the previous trace
                              • The numbers in the first column are ID's that are unique per-indicator instance
                              • Lines during the indicator’s own code are in plain text – those are the “good guys”
                              • Lines caused by outside code are in bold text – those are the “bad guys” that need to be explained
                              • Lines unrelated to the problem (some ToString() calls) are in plain italic text
                              • I had not previously paid attention to #28, but am now much more focused on it -- that is where the Lime color first appears and I cannot see how it got there.
                              • This is the complete output for just bringing up a new chart
                              • FWIW: #47 is the instance that actually gets into the chart


                              The point of this is that some code, other than the indicator’s code, is interfering and undoing the changes the indicator makes to its BullColor property. I am hoping that someone can explain what is going on, why it is happening, and what I can do about it – i.e. how can the indicator dynamically set the initial value of its own property?

                              --EV

                              ========== ========== ========== ========== ==========

                              (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                              (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                              (#10) constructing 5:01:07 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                              (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                              (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                              (#28) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                              (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                              (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                              (#29) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor
                              Note that the constructor for each of the above three objects changed the BullColor property value from Orange (the static initialization) to Aqua

                              (#28) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                              (#29) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                              It looks as if the “helper” uses #28 to get the color to coerce #29 to. Note that this is happening after the constructor, and before entering Initialize().

                              IMPORTANT: I have no idea how #28 got to be Lime -- its static initialization is Orange, and the constructor set it to Aqua. If something had later used the property's set method to set Lime, there would be trace printout (from RwbIndicator:set) saying so. No one should have been able to bypass the property set and access the backing store directly -- that is declared "private".


                              (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered RwbIndicator:Initialize
                              (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered Initialize
                              (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                              (#29) initializing 5:01:10 PM CurrentBar=n/a BIDU (Daily) RwbMultiSlope Leaving Initialize
                              Initialize() once again sets BullColor to Aqua

                              (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                              The “helper” once again coerces the color to Lime. Who is doing this, and why? Note that this is happening after Initialize(), and before entering OnStartUp().

                              (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered ToString isInitialized=True

                              (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                              (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                              (#38) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                              (#29) INITIALIZED 01/01/00 CurrentBar=-1 BIDU (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                              (#38) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                              It looks as if the “helper” uses #29 to get the color to coerce #38 to. Note that this is happening after the constructor, and before entering Initialize().

                              (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered Constructor
                              (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Orange] value=Color [Aqua]
                              (#47) constructing 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Leaving Constructor

                              (#38) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                              (#47) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                              It looks as if the “helper” uses #38 to get the color to coerce #47 to. Note that this is happening after the constructor, and before entering Initialize().

                              (#47) CONSTRUCTED 5:01:10 PM CurrentBar=n/a UNKNOWN INSTRUMENT RwbMultiSlope Entered ToString isInitialized=False

                              (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered RwbIndicator:Initialize
                              (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered Initialize
                              (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Lime] value=Color [Aqua]
                              (#47) initializing 5:01:10 PM CurrentBar=n/a NUGT (Daily) RwbMultiSlope Leaving Initialize

                              (#47) INITIALIZED 01/01/00 CurrentBar=-1 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:set(BullColor) bullColor=Color [Aqua] value=Color [Lime]
                              The “helper” once again coerces the color to Lime. Note that this is happening after Initialize(), and before entering OnStartUp().

                              (#47) INITIALIZED 01/01/00 CurrentBar=-1 NUGT (Daily) RwbMultiSlope Entered ToString isInitialized=True

                              (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:OnStartUp
                              (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                              (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered OnStartUp
                              (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:get(BullColor) bullColor=Color [Lime]
                              (#47) starting 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Leaving OnStartUp

                              (#47) updatingBars 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered RwbIndicator:OnBarUpdate first bar
                              (#47) updatingBars 12/08/10 CurrentBar=0 NUGT (Daily) RwbMultiSlope Entered OnBarUpdate first bar
                              (#47) updatingBars 02/10/14 CurrentBar=797 NUGT (Daily) RwbMultiSlope Entered OnBarUpdate last bar
                              2 things to try.
                              1. Set your property values in OnStartUp() or using a (CurrentBar == 0) filter.
                              2. See if using the [RefreshProperties(System.ComponentModel.RefreshProperties.All)] attribute on the property makes a difference one way or the other.
                              Last edited by koganam; 02-13-2014, 06:35 PM.

                              Comment


                                #30
                                Thanks for the replies. I figured it out and should have posted earlier today. My apologies for not doing so. I was doing some further testing first, and then lost sight of the fact that I should promptly update this thread. It turns out there is nothing wrong with either my code or the NT code. There are two cases, and in both cases everything is fine (now that I understand them).

                                Case #1: loading the chart -- this means loading the default chart template. NT is correctly forcing the property settings to be the correct ones for the default chart template. The default value for the property is irrelevant, whether set statically or dynamically. All that matters is the value saved in the default template.

                                Case #2: loading a new indicator instance into the chart -- in this case, the indicator default does matter, because it is needed to initialize the configuration dialog for the new indicator instance. In this case, NT is again correct -- it does not interfere. That means the indicator's default value is used -- whether it is set statically, or whether it is set dynamically in Initialize().

                                The bottom line is that you can dynamically initialize a property's default value in Initialize(). Everything works.
                                • In the cases where the default is not being used, NT will force the correct value.
                                • In the cases where the default is to be used, NT stays out of the way and the property's default value will be used -- whether it is set statically or dynamically
                                • You cannot set a default value later, such as OnStartUp(), because doing so will override what a user sets in the configuration dialog.

                                -----

                                On another note: I have become convinced that my original comment on attribute scoping is correct. That problem will have to be addressed a different way. I have some ideas from Googling, but they will have to wait for some other day.

                                I would like to suggest that Version 8 should provide some sane supported way to handle property encapsulation. Doing so is just good software engineering if you have multiple indicators whose property use intersects. For now, since the above is settled, I'll limp along with virtual properties -- not a great solution, but should be workable.

                                --EV
                                Last edited by ETFVoyageur; 02-13-2014, 07:18 PM.

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by louiseruch, Today, 01:11 AM
                                0 responses
                                1 view
                                0 likes
                                Last Post louiseruch  
                                Started by kujista, Today, 12:39 AM
                                0 responses
                                3 views
                                0 likes
                                Last Post kujista
                                by kujista
                                 
                                Started by tonynt, 05-21-2019, 06:27 AM
                                11 responses
                                536 views
                                1 like
                                Last Post NinjaTrader_Jason  
                                Started by fitspressotablettry, Today, 12:36 AM
                                0 responses
                                1 view
                                0 likes
                                Last Post fitspressotablettry  
                                Started by Lancer, 01-29-2020, 10:15 PM
                                7 responses
                                469 views
                                1 like
                                Last Post NinjaTrader_Jason  
                                Working...
                                X