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

Accessing dataseries from another Indicator

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

    Accessing dataseries from another Indicator

    Hi,

    I continued this from a previous thread



    which I dont have an answer to as yet.

    I have 2 indicators in my chart. Indy1 does some plots and price analysis and creates some dataseries (actually an array of floatseries). I want to access those dataseries from Indy2. I have checked the notes and suggestions in the previous thread, and there is still something I don't understand.

    Indy1 has a LOT of parameters (about 150).

    From what I gather in the methods mentioned in that thread, and the examples shown, Indy2 needs to Add() or call Indy1. Now thats fine if, as in the examples, Indy1 is something like SMA and all you have to do is call SMA(15) because SMA only has 1 parameter. In my own example I would have to call Indy1(param1, param2, param3.... param150). Thats a nightmare to code, and surely inefficient if for every call (on every price tick) there are 150 parameters pushed and popped from the stack.

    Is there an easier way to access the dataseries of Indy1 from Indy2? I have coded the public get/set using the suggested method for exposing dataseries in Indy1, but what exactly do I have to do in Indy2 to access these dataseries?


    Thanks,
    Will.

    #2
    Hello,

    I can see how that could be cumbersome. However, this is the best way to call Indy1, and koganam was on the right track with his last reply on the other ticket. Under normal circumstances, you would not be working with an indicator with 150 properties, so this would not come into play.

    One thing I can suggest is to never call Indy1 inline, but rather call the constructor one time to assign it to an object. Then, you can simply refer to the object in subsequent calls to Indy1, rather than defining the parameters every single time. However, this may not work if you need to change the properties of Indy1 several times within Indy2.

    What I would honestly suggest is to take a step back and consider rethinking the design of Indy1 to not require so many user-defined properties, if that is at all possible.
    Dave I.NinjaTrader Product Management

    Comment


      #3
      Hi Dave,

      thanks for your reply. It isnt possible to reduce the number of parameters, the indicator was designed to be very configurable and provides several different plots, but on the plus side once the parameters are set they don't need to be changed on the fly.

      One thing I thought of was to load parameters from a configuration file rather than via the indicator interface, but that would mean writing my own application to generate the config file.

      I could however compromise with your other suggestion, about calling the constructor once.

      Two questions...

      firstly, could you provide a code example of how to do that? ie assign it to the object (Indy2?) and then how do I access the dataseries?. Thats a little beyond my c# knowledge.

      Secondly, how do I determine exactly the order and number of the parameters to put in the constructor call? The order in which they appear in the properties section is not necessarily the order in which they appear in the indicator interface. Also, some parameters are non-browsable, do I just exclude those?

      I'm thinking that what I could do is rather than hardcode all the parameters in the Indy2 constructor call, is to duplicate all the parameters of Indy1 into Indy2 as Properties, allow the user to set them using the indicator interface, then supply those parameters in the constructor call. Would that work?

      Thanks,
      Will.
      Last edited by dontpanic; 05-19-2015, 04:58 PM.

      Comment


        #4
        Hello,

        Your idea at the end sounds good to me. You could set up public properties for all the necessary inputs, which would prevent you from having to hardcode all the values with each indicator call. For your second question, you can find the constructor definitions for Indy1 within the "NinjaScript Generated Code" region at the bottom of your script. There should be at least one constructor that shows you the exact sequence needed for the input parameters.

        For your first question, I had an idea on how to accomplish this, but I'm running into some weird results as I try to put together a sample for you. I'm going to have to dive back into this in the morning, but I will get back to you as soon as I can with a working example.
        Dave I.NinjaTrader Product Management

        Comment


          #5
          Thanks for the help Dave. I can begin coding up Indy2 on the assumption that you can show me how to do those couple of tricky bits. Indy2 is going to require an expression parser, so I will work on that for the moment.

          As an overview, Indy1 does some analysis on price and creates a set of dataseries, that are also plotted, and I base my trades on visually reading those plots. What I want to do is build Indy2 that goes a step further and does some analysis on those plots. Now I could of course just build a single indicator that does both, but I wanted to keep the functionality separate, and Indy1 is already quite large and complex so I wanted to follow the separate indicator method. The analysis will be also user definable, hence the expression parser.

          Comment


            #6
            Originally posted by dontpanic View Post
            Hi Dave,

            thanks for your reply. It isnt possible to reduce the number of parameters, the indicator was designed to be very configurable and provides several different plots, but on the plus side once the parameters are set they don't need to be changed on the fly.

            One thing I thought of was to load parameters from a configuration file rather than via the indicator interface, but that would mean writing my own application to generate the config file.

            I could however compromise with your other suggestion, about calling the constructor once.

            Two questions...

            firstly, could you provide a code example of how to do that? ie assign it to the object (Indy2?) and then how do I access the dataseries?. Thats a little beyond my c# knowledge.

            Secondly, how do I determine exactly the order and number of the parameters to put in the constructor call? The order in which they appear in the properties section is not necessarily the order in which they appear in the indicator interface. Also, some parameters are non-browsable, do I just exclude those?

            I'm thinking that what I could do is rather than hardcode all the parameters in the Indy2 constructor call, is to duplicate all the parameters of Indy1 into Indy2 as Properties, allow the user to set them using the indicator interface, then supply those parameters in the constructor call. Would that work?

            Thanks,
            Will.
            The code that I referred you to in the other thread shows you how to do it.
            1. You create an named instance of the object as a variable.
            2. You assign properties to the instance when you initialize it with a constructor in OnStartUp(). You must initialize the object with all properties that are required to be specified. So yes, you will have to specify all 150 of your properties when you initialize the object, but this is the one and only place that you do so.
            3. You use your named instance by referring to it anywhere else in the code.

            Comment


              #7
              Hello,

              koganam is exactly right. Below is an example for you, using EMA where you would use Indy1:

              Code:
                    #region Variables
              		private double x;
              		[B]private EMA indy1Instance;	[/B]
                     #endregion
              
              		
              		protected override void OnStartUp()
              		{
              			[B]indy1Instance = EMA(14);[/B]	// you will want to use "new" here for your custom indicator
              		}
              
                      protected override void OnBarUpdate()
                      {
              			[B]x = indy1Instance[0];[/B]
              			Print(x);
                      }
              Dave I.NinjaTrader Product Management

              Comment


                #8
                Hi,

                making progress...

                Next snag is enums. Indy1 has public enums used as types. How do I declare these, or reference them, in Indy2?

                I have duplicated the enum declarations from Indy1 to Indy2 so each indy has its own set of public enums, all the same, and I guessed that this was going to be wrong, but couldnt find the correct way.

                in Indy2 I'm getting the compiler error

                Argument '98': cannot convert from 'NinjaTrader.Indicator.Indy1.WMTIndParaType' to 'WMTIndParaType'


                Thanks,

                Comment


                  #9
                  Hello dontpanic,

                  Use the full namespace of the enum when calling it in the indicator (the full namespace that is showing in the error), or make the enum outside of the scope of the class but within the indicator namespace and then all indicators will have access to it.
                  Last edited by NinjaTrader_ChelseaB; 05-22-2015, 07:04 AM.
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    Hi Chelsea,

                    I'm not sure how this is working but I removed the enum declarations entirely from Indy2, didnt change the names and now its compiling. I'll put that issue aside and if it comes up again I will try your suggestion.

                    The thing I dont understand now is, within Indy2 when and why I need to use 'new'?

                    In Indy2 I have right now

                    #region Variables
                    private indy1 myIndy1;

                    protected override void OnStartUp()
                    {
                    myIndy1 = Indy1(Close, param1.... param442)
                    }

                    now this compiles without error. If I remove 'Close' as the first parameter, it still compiles, which doesnt sound right.

                    If I do

                    protected override void OnStartUp()
                    {
                    myIndy1 = new Indy1(Close, param1.... param442)
                    }

                    I get the compiler error ninjatrader.indicator.Indy1 does not contain a constructor with 443 arguements. If I remove Close as the first parameter I get the same error but 442 arguements.

                    Yes, Indy1 has 442 input parameters.

                    Now, I copied the constructor directly from Indy1, and I have checked the argument list and as far as I can tell its correct.

                    What should I check next?

                    Thanks,
                    Will.

                    Comment


                      #11
                      Hello dontpanic,

                      The indicator wrapper contains all the constructors needed, creates a new instance behind the scenes as it is call (similar to how its called for a chart), and using new is not required when adding an indicator. This is to make NinjaScript slightly easier to use.

                      For each indicator there is an additional overload that includes an input series. It does not have to be used. When it is not used it defaults to the Input for this indicator. The default for this indicator will be Close unless you choose something else as the input series when adding the indicator to the chart.

                      SMA(Close, 14)[0] is equal to SMA(14)[0]
                      but
                      SMA(High, 14)[0] is not equal to SMA(14)[0]
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        Hi Chelsea, thanks for the info on overload, but either way I'm still getting the compile error. I'm not clear on what you mean by 'adding an indicator'. I was told I didnt need to use Add()...?

                        Sorry, I think I understand what you mean. I'll remove the 'new' keyword, I won't use Add(), and I'll compile, and test to see if I can access the dataseries.

                        Thanks,
                        Will.
                        Last edited by dontpanic; 05-22-2015, 05:10 PM.

                        Comment


                          #13
                          Well, looks like its working. Both indicators compiled and I added a test variable which is exposed, and I can read its value.

                          Now to figure out how to access the exposed array of FloatSeries[] successfully.

                          Update - partly working.

                          In Indy2 I have :-

                          #region variables
                          private Indy1 myIndy1;

                          OnStartup() {
                          myIndy1 = Indy1(params...);
                          }

                          the statement in OnStartup() in indy2 causes Indy1 to get the following error :-

                          Error on calling 'OnStartUp' method for indicator 'Indy1': Object reference not set to an instance of an object.

                          the place where it gets the error doesnt seem to have anything to do with what I am doing in Indy2.

                          Thanks
                          Will.
                          Last edited by dontpanic; 05-23-2015, 12:35 AM.

                          Comment


                            #14
                            update - may have found the cause for this. I didnt realise that the error thats appearing in the output window is when the instance of Indy1 is created by Indy2. The code that its blowing up on is when I try to reference the NT toolstrip

                            System.Windows.Forms.Control[] controls = ChartControl.Controls.Find("tsrTool", false);

                            I guess theres some restriction on this? Logically I don't want those visual components in Indy2 instance anyway, so I will take them out, but then I'm wondering if plotting works.

                            Thanks,
                            Will

                            Comment


                              #15
                              Hi Will,

                              If the indicator is called and is not on a chart, then there is no Chart Control to reference. Thus the error.

                              Add a check to see if ChartControl is null before trying to use it.
                              Chelsea B.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by DJ888, 04-16-2024, 06:09 PM
                              4 responses
                              12 views
                              0 likes
                              Last Post DJ888
                              by DJ888
                               
                              Started by terofs, Today, 04:18 PM
                              0 responses
                              7 views
                              0 likes
                              Last Post terofs
                              by terofs
                               
                              Started by nandhumca, Today, 03:41 PM
                              0 responses
                              6 views
                              0 likes
                              Last Post nandhumca  
                              Started by The_Sec, Today, 03:37 PM
                              0 responses
                              3 views
                              0 likes
                              Last Post The_Sec
                              by The_Sec
                               
                              Started by GwFutures1988, Today, 02:48 PM
                              1 response
                              9 views
                              0 likes
                              Last Post NinjaTrader_Clayton  
                              Working...
                              X