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

Basic C# question - how to variablize a function call

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

    Basic C# question - how to variablize a function call

    I am calling CrossAbove. The usual syntax is:

    CrossAbove(EMA(10), EMA(20), 1)

    but I want to make the EMA(10) part generic. I may use EMA or WMA, so I can't hard code specific data series name.

    I want to do this:

    CrossAbove(MA_Fast, MA_Slow, 1)

    where MA_Fast would be the value EMA(10) or WMA(10)

    I don't know C# well enough to do this. If I put "EMA(10)" into a string var MA_Fast, won't it try passing the string to CrossAbove instead of the data series?

    In shell parlance, I want to expand the string variable before the CrossAbove call is made, which is done using the shell command eval. This could be done using a pre-processor, but that is overkill.

    What is the C# way of doing this?

    I sort of got there with this syntax I saw:

    EMA MA_Fast = EMA(fastperiod);

    This allowed me to call CrossAbove(MA_Fast, ...)

    But when I tried to use this for different MA calls, I can't redefine the local variable. I'm not sure what this syntax really means: MA_Fast is a variable of type EMA which is a pointer to the indicator function?

    Please help - I'm new to C#. Thanks.

    #2
    Hello cashinvestor,

    The syntax is right for assigning these to a variable name and then later using. Can you please clarify what you mean by:
    But when I tried to use this for different MA calls, I can't redefine the local variable.
    Can you share the line of code that you're trying to use here and give brief explanation of what it should do?
    Ryan M.NinjaTrader Customer Service

    Comment


      #3
      code sample

      from a switch statement

      case2:
      Add(EMA(s2_EMA_FastPeriod));
      Add(EMA(s2_EMA_SlowPeriod));


      EMA maFast = EMA(s2_EMA_FastPeriod);
      EMA maSlow = EMA(s2_EMA_SlowPeriod);
      break;


      case3:
      Add(WMA(s3_WMA_FastPeriod));
      Add(WMA(s3_WMA_SlowPeriod));


      WMA maFast = WMA(s3_WMA_FastPeriod);
      WMA maSlow = WMA(s3_WMA_SlowPeriod);
      break;

      and then later want to call CrossAbove(maFast, maSlow, 1)

      but I get a compiler error:
      a local variable named maFast is already defined in this scope

      Comment


        #4
        In which overridden method is your switch code located?

        Comment


          #5
          the switch statement is in the Initialize function. The CrossAbove is in the OnBarUpdate. I'm not sure I understand your question.

          I commented out all but one occurrence and after the switch statement I try to access the variable name and get a compiler error:
          The name 'mafast' does not exist in the current context

          Print("maFast: " + maFast + " maSlow: " + maSlow);


          update:
          I moved the maFast line out of the switch statement and onto the same level as the Print line in Initialize. The compiler got past that. Then I get the same compiler error from the same Print reference in the OnBarUpdate function.

          So this seems to be an issue with scope. When I put the maFast definition line in the switch statement, outside the switch statement is a different scope (or context). Then between Initialize and OnBarUpdate it is a different context.

          I need to variablize the data series name in the Initialize function and then use it in the OnBarUpdate. I'm lost here. I know there has to be a way to do it.

          I was thinking maybe I need to move it above Initialize. But I'm passing in the period values through the strategy parameters. Don't I need to have the switch statement in the Initialize routine, or can it be outside Initialize?

          update:
          I tried putting it outside Initialize and inside OnBarUpdate. None of this is working. I also want to do something like this:

          ma_Fast_value = mafast[0];

          but this doesn't seem to work either. Is this possible?


          update:
          I also need to do the same type of thing for a string variable - ATM name. I'm passing in a number of different ATM template names and need to assign one to a generic name. Then use that generic name in the ATM create call.

          So I have:

          atmname1
          atmname2
          atmname3

          and want to do something like this:

          atmName = atmname2

          AtmStrategyCreate(Action.Buy, OrderType.Limit, Close[0], 0, TimeInForce.Day, orderId, atmName,


          this is the same idea, only using a string instead of a function call.
          Last edited by cashinvestor; 02-12-2011, 05:38 AM.

          Comment


            #6
            Hello,

            Thanks for your patience.

            You would not be able to do this in Initialize() with your current setup.

            You would need to move this into OnBarUpdate() or OnStartUp() so that it is called after Initialize().

            http://www.ninjatrader.com/support/helpGuides/nt7/index.html?onstartup.htm

            Let me know if I can be of further assistance.

            Comment


              #7
              That is because you are declaring your maFast (etc) instance as type EMA (etc) at the time of writing, in the switch statement. That will limit its scope to the switch statement.

              Here is how I would go about it.
              1. Declare maFast and maSlow as DataSeries,
              2. Populate the DataSeries with EMA, WMA etc, using the switch statement in OnBarUpdate().
              3. Use Crossover logic.

              Without the details of your scheme, which understandably, you might not want to publicly disclose, it is not possible for me to make a rigorous test. However, I did make some assumptions so that I could get this to compile. It may give you a jumping off point.

              #region Variables

              Code:
               private int s3_WMA_FastPeriod = 5;
                      private int s3_WMA_SlowPeriod = 10;
                      private int s3_EMA_FastPeriod = 5;
                      private int s3_EMA_SlowPeriod = 10;
              
              	private WMA wmaFast;
              	private WMA wmaSlow;
              	private EMA emaFast;
              	private EMA emaSlow;
              		
              	private DataSeries maFast;
              	private DataSeries maSlow;

              Code:
                      protected override void Initialize()
                      {
              			maFast = new DataSeries(this);
              			maSlow = new DataSeries(this);
                      }
              Code:
                      protected override void OnStartUp()
                      {
                          wmaFast = WMA(s3_WMA_FastPeriod);
                          wmaSlow = WMA(s3_WMA_SlowPeriod);
                          emaFast = EMA(s3_EMA_FastPeriod);
                          emaSlow = EMA(s3_EMA_SlowPeriod);
                      }
              Code:
                      protected override void OnBarUpdate()
                      {
              			int testExpression = 2;
              			switch (testExpression) {
              				case 2:
              					maFast.Set(wmaFast[0]);
              					maSlow.Set(wmaSlow[0]);
              					break;
              				case 3:
              					maFast.Set(emaFast[0]);
              					maSlow.Set(emaSlow[0]);
              					break;
              				default:
              					
              					break;
              			}
              
              		if (CrossAbove(maFast, maSlow, 1))
                                      {
                                           //do something
                                      }
                      }
              Last edited by koganam; 02-12-2011, 03:15 PM.

              Comment


                #8
                wow - this was the answer I was looking for but the solution was way out there. I'll have to work with this and try it out. Thanks so much.

                My scheme is basically to pass in from the Parameters a choice of which pairs to use - ie. 2 = EMA fast and EMA slow, 3 = WMA fast / WMA slow.

                So at init time I know the choice, but I don't want to hardcode the choices in CrossAbove, just the 1 container that holds the choice. This is my first whack at writing a strategy and using C# so I'm just diving in. I'm also writing this on 6.5 so I guess now I should switch to 7.

                k-man, you kicked butt on this one.

                Comment


                  #9
                  Hello:

                  Like cashinvestor I do not know C# and have a very similar situation but slightly more complicated. I built an indicator (hacked would be a better word) that implements 4 MAs. For each of them the user has the option to choose from 17 MA algorithms and specify a different period for each.

                  I too would like to be able to call the various MA pairs (MA1 x MA2, MA2 x MA3, MA3 x MA4 (and possibly MA1 x MA3, and MA2 x MA4)) and be able to do it by using the indicator and period as specified by the user. The only thing to be determined from the results is that (when) all 3 have crossed in the same direction

                  Is it possible to modify the above code to call the indicators in this manner?

                  Thank you,

                  Comment


                    #10
                    Originally posted by Cheech View Post
                    Hello:

                    Like cashinvestor I do not know C# and have a very similar situation but slightly more complicated. I built an indicator (hacked would be a better word) that implements 4 MAs. For each of them the user has the option to choose from 17 MA algorithms and specify a different period for each.

                    I too would like to be able to call the various MA pairs (MA1 x MA2, MA2 x MA3, MA3 x MA4 (and possibly MA1 x MA3, and MA2 x MA4)) and be able to do it by using the indicator and period as specified by the user. The only thing to be determined from the results is that (when) all 3 have crossed in the same direction

                    Is it possible to modify the above code to call the indicators in this manner?

                    Thank you,
                    That would depend on how you have the inputs set up. Are they monolithic? IOW, is setting the periods completely independent of the type of moving average, such that if a moving average is chosen, then all periods will use that type, or do we have a mish-mash of periods and moving averages that can be set for each Plot?

                    Comment


                      #11
                      Each of the 4 indicators can be set to the MA type and the all of the plot information interdependent of each other, including the periods. In other words a mish mash. While I would hope that the users would set them in some logical order, i.e., fastest to slowest in this case, the indie does not check (at this time) to see if at least the periods settings confirm that premise, ie. each one is larger in value then the previous one. That would still not confirm that the order would be correct because of the characteristic of the individual MAs.. In thinking about it I may add in the logic to confirm at least the intent if not the result..
                      Last edited by Cheech; 11-08-2012, 06:47 AM.

                      Comment


                        #12
                        Originally posted by Cheech View Post
                        Each of the 4 indicators can be set to the MA type and the all of the plot information interdependent of each other, including the periods. In other words a mish mash. While I would hope that the users would set them in some logical order, i.e., fastest to slowest in this case, the indie does not check (at this time) to see if at least the periods settings confirm that premise, ie. each one is larger in value then the previous one. That would still not confirm that the order would be correct because of the characteristic of the individual MAs.. In thinking about it I may add in the logic to confirm at least the intent if not the result..
                        Well, what you describe is a more straight-forward case of selecting a type of moving average to plot, based on an individual selection. That one has been coded many times.

                        Look in the File Sharing section of the forum; there should be quite a few examples. Essentially, you would use an enum for listing and selecting the type of moving average in the GUI parameters, then test each one of your Plots for what type was selected, then branch to the correct defintion.

                        Here are 2 examples.



                        There are quite a few others..

                        Comment


                          #13
                          I hope I didn't confuse the issue here. I have the indicator running using enums and selecting the appropriate type and values as specified by the user. It plots the MAs and paints the regions between them just fine.

                          My request was along the lines of the original poster which was how can I check for MA crossings without having to test and code for each pair possibility. In other words how can i invoke the CrossAbove or CrossBelow functions and pass to it what the users requested, both the MA type and the MA period, in essence a dynamic call to the Cross functions passing a pointer to the MA type and period and not the values themselves.

                          To reiterate, the only way I know how to do this (with my C# (lacking) skills) is to hard code the CrossAbove/Below function calls specifying the various combinations of MAs the users can specify of which there would be 578 (17x17x2 ) and testing with a Case statement to determine which one(s) to use. There must be an easier and more efficient way of doing this. I've done this in other languages ( all pre OO languages) but don't know how to do it in C#.

                          Thank you.
                          Last edited by Cheech; 11-08-2012, 02:30 PM.

                          Comment


                            #14
                            Originally posted by Cheech View Post
                            I hope I didn't confuse the issue here. I have the indicator running using enums and selecting the appropriate type and values as specified by the user. It plots the MAs and paints the regions between them just fine.

                            My request was along the lines of the original poster which was how can I check for MA crossings without having to test and code for each pair possibility. In other words how can i invoke the CrossAbove or CrossBelow functions and pass to it what the users requested, both the MA type and the MA period, in essence a dynamic call to the Cross functions passing a pointer to the MA type and period and not the values themselves.

                            To reiterate, the only way I know how to do this (with my C# (lacking) skills) is to hard code the CrossAbove/Below function calls specifying the various combinations of MAs the users can specify of which there would be 578 (17x17x2 ) and testing with a Case statement to determine which one(s) to use. There must be an easier and more efficient way of doing this. I've done this in other languages ( all pre OO languages) but don't know how to do it in C#.

                            Thank you.
                            You would not need quite that many, but the question you pose is different from that of the original poster. You have 4 MA whose crossover conditions you want to monitor. That does mean that you have to check each combo, especially as they may not even be the same kind of MA.

                            As far as determining which MA each uses you will need 4 switch statements, each with the same 17 branches; one statement to select the MA type for each of your 4 moving averages. That just begs to write a function /method to which you pass the MA, and return the type. That way, you call the method 4 times, instead of writing identical code 4 times. (I am sure you knew that: I include it just for completeness).

                            You will probably need internal bool variables to track which MA's were selected, if they are not all to be enabled at all times.

                            Comment


                              #15
                              Please explain how I would do this without writing "quite that many" functions calls because that might be the answer I'm looking for?

                              Let me make this less complicated so that maybe I can understand how you propose that I do this. Let's say that the indicator (the one I'm "writing") will only plot 2 MA's and also check for when they cross in either direction. The user can select from 17 different MA's (SMA, EMA, HMA, etc) for MA1 and the same 17 for MA2. That makes a total of 17x17 or 289 different possible combinations (actually that would be times 2 for the CrossAbove and CrossBelow)

                              To the extent that I know C# (again very little) unless there is a way to pass the user specified MA and MA period to the Cross functions or some function that can extract the type and period from where ever it is and invoke the CrossAbove and CrossBelow wouldn't I need test to determine what the user specified for MA1 and MA2 and then invoke the correct hard coded Cross functions (similar to the original posters situation)? If that were true I would need all possible combinations.

                              The code that I'm looking for would perform exactly what I just described. Somehow grab what the user specified and invoke the Cross function passing the MA type and period to it, or invoke a function to extract the user specified type and period and invokel the Cross functions. As I see it, in that manner it is similar to the original request as the specific MA type is not "hard coded" in the Cross function calls. I would do this for each MA pair (MA1 xing MA2, MA2 xing MA3, and MA3 xing MA4). Again, the intent here is to determine when all 3 pairs (as configured in the previous sentence) have crossed in the same direction.

                              As you might be able to tell I'm using terminology from a different era of computer technology (I really hate to tell you how far back it was when I started but, it was when "programming" was done by wiring patch panels and the first real computer filled a large room and now there is much more processing power and memory in your phone or calculator, and yeah, I'm an old dude) so I can not describe it in OO terms like the original poster was able to do.


                              Thanks
                              Last edited by Cheech; 11-09-2012, 01:13 AM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Shansen, 08-30-2019, 10:18 PM
                              24 responses
                              942 views
                              0 likes
                              Last Post spwizard  
                              Started by Max238, Today, 01:28 AM
                              0 responses
                              9 views
                              0 likes
                              Last Post Max238
                              by Max238
                               
                              Started by rocketman7, Today, 01:00 AM
                              0 responses
                              4 views
                              0 likes
                              Last Post rocketman7  
                              Started by wzgy0920, 04-20-2024, 06:09 PM
                              2 responses
                              28 views
                              0 likes
                              Last Post wzgy0920  
                              Started by wzgy0920, 02-22-2024, 01:11 AM
                              5 responses
                              33 views
                              0 likes
                              Last Post wzgy0920  
                              Working...
                              X