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

Calling Alert() from Subclass not firing

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

    Calling Alert() from Subclass not firing

    In order to be as object oriented as possible, I am using a subclass within my indicator. When I call the Alert() function, it doesn't do anything.

    What am I doing wrong or what can I do to make this work?

    Code:
    namespace NinjaTrader.Indicator
    {
       public class MyClass1 : Indicator
       { ... }
    
       public class MyClass2 : MyClass1
       {
          public void DoAlert()
          { 
             Alert(...);
          }
       }
    }

    I've tried base.Alert(), this.Alert(), Alert() by itself. I've also tried creating a function in MyClass1 that calls Alert() and then MyClass2 simply calls that function in MyClass1, but same behavior.

    Everything compiles fine and a Print() shows that it is getting to the code, but it just doesn't do anything when called.

    Any help is greatly appreciated,

    Daniel

    #2
    Originally posted by neoikon View Post
    In order to be as object oriented as possible, I am using a subclass within my indicator. When I call the Alert() function, it doesn't do anything.

    What am I doing wrong or what can I do to make this work?

    Code:
    namespace NinjaTrader.Indicator
    {
       public class MyClass1 : Indicator
       { ... }
    
       public class MyClass2 : MyClass1
       {
          public void DoAlert()
          { 
             Alert(...);
          }
       }
    }
    I've tried base.Alert(), this.Alert(), Alert() by itself. I've also tried creating a function in MyClass1 that calls Alert() and then MyClass2 simply calls that function in MyClass1, but same behavior.

    Everything compiles fine and a Print() shows that it is getting to the code, but it just doesn't do anything when called.

    Any help is greatly appreciated,

    Daniel
    How are you testing this? Backtest?

    Comment


      #3
      Originally posted by koganam View Post
      How are you testing this? Backtest?
      No, just simply loading the indicator. Not in back test mode.

      Daniel

      Comment


        #4
        Daniel,

        Does the PlaySound() work in the place of the alert?
        http://www.ninjatrader.com/support/h...?playsound.htm
        Cal H.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_Cal View Post
          Daniel,

          Does the PlaySound() work in the place of the alert?
          http://www.ninjatrader.com/support/h...?playsound.htm
          Thank you for the response. No PlaySound() does not work either. Neither does SendMail().

          Print() still works. ;]

          One extra note that my original email didn't mention is the second class (MyClass2) is an instantiated object. In other words:

          Code:
          // In MyClass1
          MyClass2 MC2;
          
          protected override void Initialize() {
             MC2 = new MyClass2(); // Created within Initialize() of MyClass1
          }
          
          protected override void OnBarUpdate() {
             MC2.DoAlert(); // Called within OnBarUpdate() in MyClass1
          }
          EDIT: I just tried creating the object within OnStartUp() instead of Initialize() and no change.
          Last edited by neoikon; 12-19-2013, 09:13 AM.

          Comment


            #6
            Hi Daniel,

            Would you be willing to share the full script?

            If you like you can send this to me at supprt[at]ninjatrader[dot]com
            Put ATTN Cal in the subject and a reference to this thread in the body.
            Cal H.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by NinjaTrader_Cal View Post
              Hi Daniel,

              Would you be willing to share the full script?

              If you like you can send this to me at supprt[at]ninjatrader[dot]com
              Put ATTN Cal in the subject and a reference to this thread in the body.
              Thank you so much for the offer, but it's close to 16,000 lines of code. Perhaps I can create a simple test script, similar to the pseudocode I've been posting.

              After much playing, moving code around, etc. I did notice that the subclass still thinks that the base's "Historical" flag is true, even when it shouldn't be. Thus, it could be in a different state of mind, thinking that the chart is still loading, etc., which would explain why alerts, sounds, emails aren't triggering, but Print() works.

              So, I need to make sure I am organizing all this properly... or see if I can cause a refresh of the objects, so the base is in the correct state.

              Comment


                #8
                Neo,

                Without playing with the code to verify I have an idea.

                As you may be aware NinjaTrader generates some "magic" code at the end of the indicator file when you compile. What that code does is hook the indicator into NinjaTrader so NinjaTrader can use it in the various locations Indicators are used in the product.

                I suspect that this footer code is not getting generated for your subclass. In which case you would have to create it manually. This can get a little complex though which is why this method would be unsupported.

                -Brett

                Comment


                  #9
                  I'm a bit fearful touching NT's "magic code" and I don't want to set precedent to have to continue doing that in the future as I make changes to the indicator. So, that's going to be an extremely last resort...

                  However, when using class "extensions" instead of "inheritance", the indicator chart objects are all up to date and the Alert() and PlaySound() work! ...BUT, the performance is noticeably terrible.

                  Still searching for an elegant solution...

                  Comment


                    #10
                    With your 16,000 lines of code file that performance degradation could be coming from anywhere and would not suspect C# Inharience/extensions first.

                    Your sure you have isolated the performance problem down to this?

                    Anything I can do help point you in the right direction in trying to squash performance issues?

                    Let me know.

                    -Brett

                    Comment


                      #11
                      I still have the untouched (non-inheritance, non-extension) version of the code. Running them side-by-side, on two different charts (same symbol, same amount of data loaded, no other indicators etc), the original version will refresh (F5) in about 1/2 a second. The new, re-arranged version using extensions, takes about 3 seconds.

                      The functionality is all the same, but that doesn't mean I'm still not doing something idiotically and incorrectly expensive in the new version. ;]

                      I realize it is very difficult from your end to offer help without seeing code and that this is outside of the normal scope of forum support with NinjaScript, so I am extremely grateful for the responses you've given.

                      Below is an example function that simply outputs a bit of Text. If the requested location is in the future, it uses the Time[] array, otherwise it uses a BarIndex. Being that I need access to the Bars, CurrentBar, Time[], and DrawText() objects, I am extending the Indicator class (first param).


                      Code:
                      internal static class Utils
                      {
                      	internal static void smartDrawText(this Indicator oIndi, string Tag, bool AutoScale, string Label, int x, double y,
                      		int pixelOffset, Color TextColor, Font TextFont, StringAlignment stringAlignment, int Opacity)
                      	{
                      		bool bBarInFuture = (x < -1);
                      				
                      		if (oIndi.Bars.Count - oIndi.CurrentBar == 1 && bBarInFuture)
                      			x++;
                      
                      		// If one of our points is in the future, then we use the BarIndex.  Otherwise, we want the Time[]
                      		if (bBarInFuture)
                      			oIndi.DrawText(Tag, AutoScale, Label, x, y, pixelOffset, TextColor, TextFont, stringAlignment, Color.Empty, Color.White, Opacity);
                      		else
                      			oIndi.DrawText(Tag, AutoScale, Label, oIndi.Time[x], y, pixelOffset, TextColor, TextFont, stringAlignment, Color.Empty, Color.White, Opacity);
                      	}
                      }
                      I'd love to pass the Indicator object by reference instead of value, but I don't believe you can do that with extensions.

                      Multiply this type of setup with lots and lots of functions and you have a slow indicator. ;]

                      EDIT 1: I've heard different things, that extensions are simply a syntax for the compiler and that it's not a matter of an object being passed ref/value. I've also heard that it's boxing up the object by value (which would be expensive). The slowness I'm seeing is indicating the latter?

                      My goal is to simply follow better OOD ahead of the changes that are coming with NT8. I was also hoping to GAIN performance, but it seems like I'm going the other direction!

                      EDIT 2: After some debugging, I did find an expensive operation that was being called repeatedly OnBarUpdate() and causing the massive slowdown. Now, it seems I'm back into that 1/2 sec reload time! Full speed ahead with further conversion!

                      Daniel
                      Last edited by neoikon; 12-20-2013, 01:07 PM.

                      Comment


                        #12
                        Np,

                        Glad to help, yea so you can mostly consider and extension method the same as a regular method (performance anyways) just with one of the inputs automated for you and is just a convenience layer for the progammer.

                        Typically you don't use extension methods if you are going to chain a bunch of parameters after it as that takes the convenience out of using the extension methods. (Which again is just a convenience layer vs a regular method). This is just a coding practice note and nothing wrong with how your doing it now though. Also you are passing the indicator by reference and not via value as it is a Class object, all class object pass by reference.

                        There is no performance impact such as boxing or anything like that: Boxing only occurs when you feed a generic item to a non generic method which you are not doing. Example below:

                        //No boxing
                        MyMethod(int myInt)
                        MySecondMethod(int myInt)

                        //Boxing
                        MyMethod(int myInt)
                        MySecondMethod(object myInt)


                        Therefor you really should not have any major performance impact here with how you are doing this, something else must be to blame I believe.

                        In which case the only thing to do to track it down is to use the .net System.Diagnostics and use the Timer to find out how long things are taking.

                        Provides classes that allow you to interact with system processes, event logs, and performance counters.


                        Code:
                        using System.Diagnostics;
                        // ...
                        
                        Stopwatch sw = new Stopwatch();
                        
                        sw.Start();
                        
                        // ... Your code you want to time here.
                        
                        sw.Stop();
                        
                        Print("Elapsed=" + sw.Elapsed);
                        Last edited by NinjaTrader_Brett; 12-20-2013, 02:51 PM.

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by Perr0Grande, Today, 08:16 PM
                        0 responses
                        2 views
                        0 likes
                        Last Post Perr0Grande  
                        Started by elderan, Today, 08:03 PM
                        0 responses
                        5 views
                        0 likes
                        Last Post elderan
                        by elderan
                         
                        Started by algospoke, Today, 06:40 PM
                        0 responses
                        10 views
                        0 likes
                        Last Post algospoke  
                        Started by maybeimnotrader, Today, 05:46 PM
                        0 responses
                        12 views
                        0 likes
                        Last Post maybeimnotrader  
                        Started by quantismo, Today, 05:13 PM
                        0 responses
                        7 views
                        0 likes
                        Last Post quantismo  
                        Working...
                        X