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

nested for loop of a barIndex

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

    nested for loop of a barIndex

    I am trying to get the volume between specific barIndexes.

    Anyone know how you nest this:

    for(int barIndex = index; barIndex <= ChartBars.ToIndex; barIndex++)
    {
    double highPrice = Bars.GetHigh(barIndex);
    double lowPrice = Bars.GetLow(barIndex);
    double vols = Bars.GetVolume(barIndex);

    sumvolms += vols;


    if(cma < highPrice && cma > lowPrice)
    {
    for(int barIndex0 = barindex; barIndex0 <= ChartBars.ToIndex; barIndex++)
    {

    It says that barIndex dont exist. I just want the volume between index and each price that cross the if statement.

    any hints?
    thanks

    #2
    Hello frankduc,

    It looks like this is a general C# question, I would suggest using external resources for this type of question. You could start at the following public link for nesting loops in C#: https://www.tutorialspoint.com/cshar...sted_loops.htm There are many other guides and samples for this question, you can search online for "C# nested for loop".

    The error you are seeing is caused by using a variable where it is not defined. It may be due to the structure you used however the sample you provided is not clear enough to see the problem.

    I would suggest to review C# materials surrounding nesting for loops first. You can compare some samples against what you created to see if anything sticks out as the problem. You have used barIndex in one of your loops so It could be related to where you have used barIndex in the script or if you tried to use this variable outside the loop.



    Please let me know if I may be of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      I solve the nested loop but i am having error script related to NT or c#.

      My cma will evolve in time and i want to test every price in the loop in my if statement.

      double Price = Bars.GetClose(barIndex);

      List<double> xlist = new List<double>() {Price};

      for(int x = 0; x < xlist.Count; x++)
      {
      xlist[x];
      }
      if(xlist < highPrice && xlist > lowPrice)

      Its returning error:

      NinjaScript File Error Code Line Column
      SampleDisplayBarsAgo.cs Only an assignment, call, increment, decrement, wait, and new object expressions can be used as a CS0201 instruction.



      thanks

      Comment


        #4
        Hello frankduc,

        This is not specific to NinjaScript, this is a general C# error. You can read about this error in the following public page: https://docs.microsoft.com/en-us/dot...essages/cs0201

        Without seeing what line this was reported for it would be hard to say, however the following syntax looks odd:

        Code:
        xlist[x];
        You may try removing that line to see if the error resolves.

        It also looks like you are using the list later in the condition without an index, you likely have a few problems in this syntax and will need to undo and re-try whatever you were attempting.

        If you need assistance with using List<T> I would suggest using C# educational sites to learn more about their use. Lists are not a NinjaScript type so this is not going to be a documented/supported item in the help guide however there are a large number of sites which offer information on lists in C#.


        Please let me know if I may be of further assistance.

        JesseNinjaTrader Customer Service

        Comment


          #5
          Is it possible to declare a variable with NT method as a class level? Like private double closePrice = Bars.GetClose(barIndex); of course i tried and it didn't work.

          Its because i try to nest a for loop in my cma and if i print inside the bracket i get the result of many cma's , but outside the brackets i get only one return. I can figure out why my first for loop wont apply outside the brackets? Do i need to declare all variables as private?

          private double cma = 0;
          double sum1 =0;
          double sum2 = 0;

          for (int i = 0; i <=
          ChartBars.ToIndex
          ; i++)
          {
          for(int barIndex = i; barIndex <= ChartBars.ToIndex; barIndex++)
          {
          double closePrice = Bars.GetClose(barIndex);
          double volumes = Bars.GetVolume(barIndex);

          double clovol = closePrice * volumes;


          sum1 += clovol++;
          sum2 += volumes++;

          cma = sum1 / sum2;

          Print(cma);
          }
          }

          Print(cma);
          Last edited by frankduc; 08-21-2019, 06:22 AM.

          Comment


            #6
            Hello frankduc,

            Is it possible to declare a variable with NT method as a class level? Like private double closePrice = Bars.GetClose(barIndex); of course i tried and it didn't work.
            No, this is not specific to NinjaScript. You cannot use runtime variables as a variable declaration like this. If you want to use the Bars object it needs to be defined before you used it. This would need to be called from within OnBarUpdate or where it has a value. Class level variables need a non-variable default such as = 0, later you can reset it once the object in question has a value.

            Its because i try to nest a for loop in my cma and if i print inside the bracket i get the result of many cma's , but outside the brackets i get only one return. I can figure out why my first for loop wont apply outside the brackets? Do i need to declare all variables as private?
            In what you provided you are:
            • Resetting the value for cma over and over. Each time you loop, cma gets a new value because you used a variable outside the loop and you are assigning a new value in the loop.
            • The print directly below it should be printed many times or as many as your loop iterates because it is inside the loop.
            • The print which is outside of the loop can only print one time, its not in the loop. That would also be the last value set for cma, or the last iteration of your loop.

            I am not really certain what you are going for with the supplied code however you are exploring concepts of C# which are not specific to NinjaScript. If this is a difficult concept to tackle in NinjaScript I would suggest to start more simple with C# for loops outside of NinjaScript. Here are some ways you can do that.

            MSDN allows you to run the code in the browser so you don't need to install visual studio, I would suggest reviewing some of the looping samples if using for loops is not yet clear: https://docs.microsoft.com/en-us/dot...for#code-try-1

            You can also use public compiler services like https://dotnetfiddle.net/ to test C# code in the browser. This is helpful if you want to just test C# code, you wont need to make a whole indicator or setup a test chart to test it.

            One way to simplify this question so you can work through the problem would be to stop using NinjaScript variables and hard code all values. For example, replace the ChartBars.ToIndex with a specific value to give the loop a finite amount of iterations. Also replace the Bars.GetClose(barIndex); code with specific values essentially removing all NinjaScript code. Next take your loop into one of the testing platforms like dotnetfiddle or visual studio and test the loop and output the values.



            Please let me know if I may be of further assistance.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Well, the cma returns the cumulative average of all bars between foundIndex and
              ChartBars.ToIndex. It return one value outside the brackets like 2230.23
              I am trying to reproduce the RMMA indicators with you can set as many moving average as there is bars.

              The RMMA use a for loop

              for (int i = LowPeriod; i <= HighPeriod; i += StepAverage)
              {
              switch (MaToUse)
              {
              case MultiMA1types.DEMA:
              Values[count][0] = DEMA(i)[0];
              break;

              So i was thinking i could simply use a nested for loop to increment from 0 to
              ChartBars.ToIndex and replace foundIndex by i from the first for loop to get every cma's for every bars.

              That in return produce a large amount of datas (cma's) like 2230.23, 2231.25, 2232.21 etc one for each bars (representing a cma for each bars) The RMMA when you use with a
              StepAverage of 1 create as many MA as there is bars and can be quite slow. I am not even sure yet it returns the right answer because of the slowness and recurent printing.

              My nested for loop just lead to freezing after a moment when displayed in Output Window. If the cma returns only one value it means it returns one value for all my codes. I need the cma to return multiple values, like Print inside the brackets, outside to work for the rest of the other cma variables in the code of the indicator.

              Thanks for the info and webpages i didn't know you could test in the browser codes.

              Comment


                #8
                Hello frankduc,

                I am not even sure yet it returns the right answer because of the slowness and recurent printing.
                Yes this type of calculation would not be suggested for OnRender.

                If you are using 0 to the count, that is for all bars in the series which is not the intended use for OnRender. In most cases on render should only be used to render data for the visible bars. Is there a reason you are not using OnBarUpdate for this use case? OnBarUpdate would be a good candidate for 0 to count processing, that covers each bar.

                OnRender is called very frequently, which can be ever faster than 1 tick frequency so it will use a lot of CPU if you are doing something that takes time to calculate. It would likely be suggested to pre calculate the data in OnBarUpdate and then just render that data from OnRender for this type of use case.

                If you are trying to use the RMMA, you could copy its logic to OnBarUpdate and then use OnRender to display that in a custom way, that would be the most efficient way to approach this. If there is more context to the problem that I am missing you could certainly add that so we can cover that as well.

                I look forward to being of further assistance.





                JesseNinjaTrader Customer Service

                Comment


                  #9
                  Like i said in previous posts the project started using sampledisplaybarsago as the skeleton of the indicator. I needed the cursorpointX but it cant be used in
                  OnBarUpdate. Now that i did get rid of it, everything could be moved to OnBarUpdate. I am almost done with the project and i was planning to move everything to OnBarUpdate after testing in OnRender that everything is fine.

                  Your idea to copy the logic of RMMA to OnBarUpdate could be the solution. The VWMA included in the RMMA returns for the first value the same value as the CMA. I only need the first value and i dont need it to be draw in the chart, only the value to send it to my calculations.

                  So VWMA would replace CMA in
                  if(cma < highPrice && cma > lowPrice)

                  I only hope the if statement will test each returns brought by the RMMA and not just the last, otherwise i will be missing values at the end of the pipeline.

                  I have one issue with RMMA, where can we get the last values return by the multiple moving averages in the code?

                  I cant Print() that part so its not that:
                  case MultiMA1types.VWMA:
                  Values[count][0] = VWMA(i)[0];
                  break;

                  I am looking where is the variable that will give me the first value at the beginning (of the VWMA) of the chart at the right side and cant find it. You have any clue?

                  Thanks
                  Attached Files

                  Comment


                    #10
                    Hello frankduc,

                    I am looking where is the variable that will give me the first value at the beginning (of the VWMA) of the chart at the right side and cant find it. You have any clue?
                    The way this was worded is a little difficult to understand.

                    The Beginning of the chart is the Left most bar.
                    The End of the chart is the Right most bar.

                    What data are you trying to get in contrast to the descriptions above?

                    From the description you provided, it sounds like you want the Right most bar or zero BarsAgo.


                    I look forward to being of further assistance.

                    JesseNinjaTrader Customer Service

                    Comment


                      #11
                      I was thinking about that this weekend and using RMMA does not solve all the issues, it help for a part of the problem but not all. Lets put that aside for a moment.

                      I have another question: I did some tests and replace cma by Price (in theory its the same because all cma's will cross some of those prices)

                      for(int barIndex = index; barIndex <= ChartBars.ToIndex; barIndex++)
                      {

                      double Price = Bars.GetClose(barIndex);

                      if(cma < highPrice && cma > lowPrice)



                      In this case all the Price between index and ChartBars.ToIndex are listed in the variable Price.

                      Price gather many close price: 2014, 2015, 2018 .etc

                      If i replace cma by Price it will process all the prices all together.

                      I want each value to be calculated one bye one. Like if it was :

                      if(2014 < highPrice && 2014 > lowPrice)

                      if(2015 < highPrice && 2015 > lowPrice)



                      Is there a method or group method that allow to do this?

                      The problem is that after it pass the if statement it pass throught many formulas and a lambda expression chose one value.
                      If i have many cma's or replace them by Price like i said it will process all togheter all the prices in Price. Not the biggest problem its just that the lambda at the end is always returning one value when i want it to return a value per price.

                      So the price will be process one by one and then at the end of the pipeline one answer for each price. So i can use addplot to project a line in the chart. Right now replace cma by Price returning one value because of the lambda.

                      I am clueless how to do that. Any hints?

                      thank you

                      Comment


                        #12
                        Hello frankduc,

                        Is there a method or group method that allow to do this?
                        You could likely make one of your own, this does not look like anything familiar that may be included in NinjaScript.


                        I am clueless how to do that. Any hints?
                        A lot of the questions you have asked on this topic fall back on fundamental C# concepts which are not going to be detailed in the help guide or by our support. For example creating custom methods, looping logic and lambda statements are parts of C#, these are not NinjaScript subjects that I can dive into. You can review these subjects individually in contrast to C# to better understand their specific uses.

                        If you are having difficulty with some syntax you have created, I always suggest to try and simplify that syntax. A lambda statement is generally not considered a simplified statement even though it is less syntax. These statements take more foresight to pick the correct use case for that type of syntax over a standard loop or variable. I would suggest experimenting outside of NinjaTrader with C# lambda statements gain a better understanding of the problem you are facing here. It sounds like the syntax you have used is not right for the explained use case, you noted you get one result back but wanted more results, that is not likely the correct syntax for that use case.

                        I look forward to being of further assistance.



                        JesseNinjaTrader Customer Service

                        Comment


                          #13
                          Someone came up with an interesting solution to my problem.
                          I tried the code on https://dotnetfiddle.net/ it looks like its doing the job. But i have a few issue related to its conversion to ninjatrader.


                          namespace ConsoleCS
                          {
                          using System;
                          using System.Collections.Generic;
                          using System.Linq;

                          public class Program
                          {
                          public static void Main(string[] args)
                          {
                          List<double> numbers = ConstructList();
                          numbers.ToConsole<double>("Unsorted");

                          List<double> sorted = Sort(numbers, 1.23);
                          sorted.ToConsole<double>("Sorted");

                          Console.WriteLine("\nDone.");
                          Console.ReadLine();
                          }

                          private static List<double> Sort(List<double> numbers, double pivot)
                          {
                          List<double> result = new List<double>();
                          while (numbers.Count>0)
                          {
                          var minDistance = numbers.Min(n => Math.Abs(pivot - n));
                          var closest = numbers.First(n => Math.Abs(pivot - n) == minDistance);
                          numbers.Remove(closest);
                          result.Add(closest);
                          }

                          return result;
                          }

                          private static List<double> ConstructList()
                          {
                          List<double> result = new List<double>();
                          result.Add(1.22);
                          result.Add(1.26);
                          result.Add(1.33);
                          result.Add(1.21);
                          result.Add(1.215);
                          result.Add(1.225);
                          return result;
                          }
                          }
                          }

                          namespace ConsoleCS
                          {
                          using System;
                          using System.Collections.Generic;

                          public static class EnumerableHelper
                          {
                          public static void ToConsole<T>(this IEnumerable<T> enumerable)
                          {
                          foreach (T item in enumerable)
                          {
                          Console.WriteLine(item);
                          }
                          }

                          public static void ToConsole<T>(this IEnumerable<T> enumerable, string caption)
                          {
                          Console.WriteLine(caption);
                          foreach (T item in enumerable)
                          {
                          Console.WriteLine(item);
                          }

                          Console.WriteLine("");
                          }

                          public static void ToConsole<T>(this IEnumerable<T> enumerable, Func<T, string> toString)
                          {
                          foreach (T item in enumerable)
                          {
                          Console.WriteLine(toString(item));
                          }
                          }

                          public static void ToConsole<T>(this IEnumerable<T> enumerable, string caption, Func<T, string> toString)
                          {
                          Console.WriteLine(caption);
                          foreach (T item in enumerable)
                          {
                          Console.WriteLine(toString(item));
                          }

                          Console.WriteLine("");
                          }
                          }
                          }

                          In NT terms
                          public static void Main(string[] args) , private static List<double> Sort(List<double> numbers, double pivot), public static void is this different class from OnRender? Is it transferable?

                          Can
                          Console.WriteLine(toString(item)); be replace by Print(toString(item));

                          ToConsole<T> is it link to Console.WriteLine?

                          thanks

                          Comment


                            #14
                            Hello frankduc,

                            public static void Main(string[] args) , private static List<double> Sort(List<double> numbers, double pivot), public static void is this different class from OnRender? Is it transferable?
                            This would be a C# concept, the Main void is the starting place for a C# console program. This would be similar to one of the states in OnStateChange being called a single time.

                            You could migrate the code that is inside the Main method to NinjaScript, however I couldn't say where you would put it as I don't know what the goal is with this new code.

                            I can say that you will not keep the void Main and also anything that is currently static needs to be made non-static. A console application uses static variables if you do not create a class, NinjaScript does not use static variables because you are inside a class.

                            Code:
                            Console.WriteLine(toString(item)); be replace by Print(toString(item));
                            Correct, Print is used in NinjaScript because it has a specific output window and is part of NinjaScript. When you work in a C# console application you instead write to the Console because that is all there is to use to output.


                            Please let me know if I may be of further assistance.
                            JesseNinjaTrader Customer Service

                            Comment


                              #15
                              After new test it came up this way. On https://dotnetfiddle.net/
                              it turns ok but translate that into ninjascript is not that obvious, at least for me.


                              {
                              double pivot = 1.23;


                              List<double> numbers = ConstructList();
                              numbers.ToConsole<double>("Unsorted");
                              numbers.Sort(Comparer<double>.Create((x, y) => Math.Abs(pivot - x)
                              < Math.Abs(pivot-y) ? -1 : Math.Abs(pivot - x) > Math.Abs(pivot - y) ? 1 : 0));
                              numbers.ToConsole<double>("Sorted");


                              Console.WriteLine("\nDone.");
                              Console.ReadLine();
                              }


                              private static List<double> ConstructList()
                              {
                              List<double> result = new List<double>();
                              result.Add(1.22);
                              result.Add(1.26);
                              result.Add(1.33);
                              result.Add(1.21);
                              result.Add(1.215);
                              result.Add(1.225);
                              return result;
                              }


                              What's bothering me is the ToConsole part........what is that and what to do with that? i mean i cant see anything in
                              https://docs.microsoft.com related to that. Seems related to console writeline.

                              Any thoughts on that matter?

                              Thanks
                              Last edited by frankduc; 08-29-2019, 11:44 AM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by algospoke, Yesterday, 06:40 PM
                              2 responses
                              19 views
                              0 likes
                              Last Post algospoke  
                              Started by ghoul, Today, 06:02 PM
                              3 responses
                              14 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by jeronymite, 04-12-2024, 04:26 PM
                              3 responses
                              45 views
                              0 likes
                              Last Post jeronymite  
                              Started by Barry Milan, Yesterday, 10:35 PM
                              7 responses
                              20 views
                              0 likes
                              Last Post NinjaTrader_Manfred  
                              Started by AttiM, 02-14-2024, 05:20 PM
                              10 responses
                              181 views
                              0 likes
                              Last Post jeronymite  
                              Working...
                              X