Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Mode from a Series double

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

    Mode from a Series double

    Hello Jesse, I'm getting those compile errors

    NinjaScript File Error Code Line Column
    Testa.cs 'NinjaTrader.NinjaScript.Series<double>' does not contain a definition for 'GroupBy' and no extension method 'GroupBy' accepting a first argument of type 'NinjaTrader.NinjaScript.Series<double>' could be found (are you missing a using directive or an assembly reference?) CS1061 221 20
    NinjaScript File Error Code Line Column
    Testa.cs 'double' does not contain a definition for 'Max' and no extension method 'Max' accepting a first argument of type 'double' could be found (are you missing a using directive or an assembly reference?) CS1061 222 19
    NinjaScript File Error Code Line Column
    Testa.cs 'double' does not contain a definition for 'First' and no extension method 'First' accepting a first argument of type 'double' could be found (are you missing a using directive or an assembly reference?) CS1061 223 15
    My simplified script
    PHP Code:
    namespace NinjaTrader.NinjaScript.Indicators
    {
         private Series<double> Rng0;
         private Series<double> Rng1;
    
         private Series<double> Rng0Rng1;
    
         private double groups;
    
    
         public class Testa : Indicator
         {
              protected override void OnStateChange()
              {
                   if (State == State.SetDefaults)
                   {
                        BarsBack = 360;
                        Rng0Index = 0;
                        Rng1Index = 0;
    
    
              private double CalcMode()
              {
                   double groups = Rng0Rng1.GroupBy(v => v);
    
                   int maxCount = groups.Max(g => g.Count());
    
                   int mode = groups.First(g => g.Count() == maxCount).Key;
              }
    
    
              protected override void OnBarUpdate()
              {
                   CountIf(() => Rng0[Rng0Index] - Rng1[Rng1Index] >= 15*TickSize, BarsBack);
    
                   Rng0Rng1[Rng0Index] = Rng0[Rng0Index] - Rng1[Rng1Index];
    
                   var mode = CalcMode();
        } 
    

    What's wrong with the 'double' with 'GroupBy' 'Max' and 'First' ? Thanks!
    Last edited by PaulMohn; 03-02-2022, 10:21 AM.

    #2
    Hi Paul, thanks for posting.

    I moved your post from the old one from 2016. If a post is more than a year old, please make a new topic and link the relevant threads.


    The methods you are using on the Series<t> objects are Linq statements. You are getting compile errors because Series<T> objects are not "linq-able". See the documentation for Series<T> here:


    Best regards,
    -ChrisL

    Comment


      #3
      Hi Chris. Ok thanks for the info about new threads. But could you change the title to "Mode from a Series double" (so its easier to find later thanks).

      Following an other way from this tutorial

      , I tried this
      PHP Code:
      namespace NinjaTrader.NinjaScript.Indicators
      {
          private Series<double> Rng0;
          private Series<double> Rng1;
      
          private Series<double> Rng0Rng1;
      
      
          public class Testa : Indicator
          {
            protected override void OnStateChange()
            {
              if (State == State.SetDefaults)
              {
                BarsBack = 360;
                Rng0Index = 0;
                Rng1Index = 0;
      
            private double CalcMode()
            {
              double maxNumber = 0;
              double maxAppearances = 0;
      
            for (int i = 0; i < BarsBack; i++)
              {
                int count = 0;
      
                for (int j = 0; j < BarsBack; j++)
                {
                  if(count > maxAppeareances)
                  {
                    maxNumber = Rng0Rng1[i];
                    maxAppearances = count;
                  }
                }
              }
            }
      
      
            protected override void OnBarUpdate()
            {
            Rng0Rng1[Rng0Index] = Rng0[Rng0Index] - Rng1[Rng1Index];
      
            double mode = CalcMode();
            } 
      

      but I don't know how to handle the array part (the int dataSet = { x, y, z etc. }; at
      https://youtu.be/xKR3uA-Ytno?t=407 )
      with the series double


      And I get this other compile error

      NinjaScript File Error Code Line Column
      Testa.cs 'NinjaTrader.NinjaScript.Indicators.Testa.CalcMode ()': not all code paths return a value CS0161 179 18
      I then tried with

      PHP Code:
      namespace NinjaTrader.NinjaScript.Indicators
      {
          private Series<double> Rng0;
          private Series<double> Rng1;
      
          private Series<double> Rng0Rng1;
      
      
          public class Testa : Indicator
          {
            protected override void OnStateChange()
            {
              if (State == State.SetDefaults)
              {
                BarsBack = 360;
                Rng0Index = 0;
                Rng1Index = 0;
      
            private double CalcMode()
            {
              int[] dataSet = Rng0Rng1;
              double maxNumber = 0;
              double maxAppearances = 0;
      
            for (int i = 0; i < BarsBack; i++)
              {
                int count = 0;
      
                for (int j = 0; j < BarsBack; j++)
                {
                  if(count > maxAppeareances)
                  {
                    maxNumber = Rng0Rng1[i];
                    maxAppearances = count;
                  }
                }
              }
            }
      
      
            protected override void OnBarUpdate()
            {
            Rng0Rng1[Rng0Index] = Rng0[Rng0Index] - Rng1[Rng1Index];
      
            double mode = CalcMode();
            } 
      

      But it throws this other error
      NinjaScript File Error Code Line Column
      Testa.cs Cannot implicitly convert type 'NinjaTrader.NinjaScript.Series<double>' to 'int[]' CS0029 181 20
      I then tried with
      PHP Code:
      namespace NinjaTrader.NinjaScript.Indicators
      {
          private Series<double> Rng0;
          private Series<double> Rng1;
      
          private Series<double> Rng0Rng1;
      
      
          public class Testa : Indicator
          {
            protected override void OnStateChange()
            {
              if (State == State.SetDefaults)
              {
                BarsBack = 360;
                Rng0Index = 0;
                Rng1Index = 0;
      
            private double CalcMode()
            {
              int[] dataSet = Rng0Rng1[0];
              double maxNumber = 0;
              double maxAppearances = 0;
      
            for (int i = 0; i < BarsBack; i++)
              {
                int count = 0;
      
                for (int j = 0; j < BarsBack; j++)
                {
                  if(count > maxAppeareances)
                  {
                    maxNumber = Rng0Rng1[i];
                    maxAppearances = count;
                  }
                }
              }
            }
      
      
            protected override void OnBarUpdate()
            {
            Rng0Rng1[Rng0Index] = Rng0[Rng0Index] - Rng1[Rng1Index];
      
            double mode = CalcMode();
            } 
      

      but it throws this error
      NinjaScript File Error Code Line Column
      Testa.cs Cannot implicitly convert type 'double' to 'int[]' CS0029 181 20
      How do you handle the series double with this new function and get the mode? Thanks!

      Comment


        #4
        Hello PaulMohn,

        As a heads up, these are C# errors.

        private double CalcMode()

        This method was declared to return a double value.
        You need to return a double in the method.
        return 0.0;

        Or use void as the method type if you don't plan to return a value.
        private void CalcMode()


        int[] dataSet = Rng0Rng1;

        You are trying to assign objects of different types to variables of a different type.

        Rng0Rng1 is a series. dataSet is declared as an int[] array.
        These are not the same object type. dataSet cannot hold a Series<double> object.

        int[] dataSet = Rng0Rng1[0];

        Same as before, tou are trying to assign objects of different types to variables of a different type.

        Rng0Rng1 is a series. Rng0Rng1[0] is the last bar in the series and is a double.
        dataSet is declared as an int[] array.
        These are not the same type.


        You could use a loop from 0 to CurrentBar assign each series bar value to the element in the int array.
        Code:
        dataSet = new int[CurrentBar];
        for (int = 0; i < CurrentBar; i++)
        {
        dataSet[i] = (int)Rng0Rng1[i];
        }
        Last edited by NinjaTrader_ChelseaB; 03-02-2022, 03:51 PM.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Thanks Chelsea for your helping directions.

          I've reviewed the C# doc on arrays, list and .add()
          https://docs.microsoft.com/en-us/dot...nsional-arrays
          Probably a really simple one this - I'm starting out with C# and need to add values to an array, for example: int[] terms; for(int runs = 0; runs &lt; 400; runs++) { terms[] = runs; } For tho...


          I realized I did not reproduce the snippet entirely and have corrected

          PHP Code:
              private double CalcMode()
              {
                List<double> dataSet = new List<double>();
          
                double maxNumber = 0;
                double maxAppearances = 0;
          
                for (int i = 0; i < CurrentBar; i++)
                {
                  int count = 0;
          
                  for (int j = 0; j < CurrentBar; j++)
                  {
                    dataSet.Add((double)Rng0Rng1[0]);
          
                    if(dataSet[i] == dataSet[j])
                    {
                      count++;
                    }
                  }
          
                  if(count > maxAppearances)
                  {
                    maxNumber = Rng0Rng1[i];
                    maxAppearances = count;
                  }
          
                }
                return maxNumber;
              } 
          

          No compile errors are thrown anymore, but now the indicator seems to calculate endlessly, and the prints are running endlessly in the output window.

          Can you please advise about what wrong with the new list code?

          Also, how do I kill the endless indicator process? Thanks!
          Last edited by PaulMohn; 03-02-2022, 01:53 PM.

          Comment


            #6
            Hello PaulMohn,

            You have a for loop inside of a for loop.

            For every bar, you are looping through every bar again. If there are 100 bars, this would loop 100 times for each bar, or 10,000 times. It would do this every time CalcMode() is called. If this called on every bar update, this would be 1,000,000 loops on just 100 bars of data.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Oh, ok. I reproduced this working example.


              Click image for larger version  Name:	loop in loop.png Views:	0 Size:	126.3 KB ID:	1192162

              Loops in loops is not usable in Ninjatrader? If they are how would you modify it to make it work? if they are not, I've another example but more complex I rather stick to the simpler one. Thanks.

              I managed to stop the loop by simply closing the window (it wouldn't give access to the Properties window).
              Last edited by PaulMohn; 03-02-2022, 02:18 PM.

              Comment


                #8
                Hello PaulMohn,

                Loops within loops can be done in C#. But think about how much work you are demanding of the processor.

                I don't understand what the loop within the loop does..

                A single loop would be used to add bars to a list object because you want a list and not a series.. But I'm not sure what you are trying to achieve with nested loops.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Oh ok, i rather avoid it if there's no way to make it cheap on the resources. My question was from this post originally

                  ally

                  I'd like to calculate and return the mode value of the series of doubles from Rng0Rng1[0] value.
                  I've found a third way more complex but without nested loop


                  Here's the script from the demo video (copied it manually but it should be correct)
                  PHP Code:
                  namespace BasicStatisticApp
                  {
                    public partial class MainForm : Form
                  
                      // Data storage
                      private int[] rawData;
                      private int[] sortedData;
                      private int size, lowerLimit, upperLimit;
                  
                  
                      public mainForm()
                      {
                        initializeComponent();
                      }
                  
                      /// <summary>
                      /// Event handler to read the inputs - generate Data and Sort the data.
                      /// </summary>
                      /// <param name="sender"></param>
                      /// <param name="e"></param>
                  
                  
                      // Function to calculate the mean of the data
                      private void CalcMean()
                      {
                        double sum = 0;
                        for(int i=0; i<size; i++)
                        {
                          sum += rawData[i];
                        }
                  
                        return sum / size;
                      }
                  
                      // Generate the Random Data Set & then Sort the Random Data Set
                      private void btnGenerate_Click(object sender, EventArgs e)
                      {
                        // Parse values
                        size = int.Parse(txtsize.Text);
                        lowerLimit = int.Parse(txtLower.Text);
                        upperLimit = int.Parse(txtUpper.Text);
                  
                        // allocate
                        rawData = new int[size];
                        sortedData = new int[size];
                  
                        // Generate data
                        Random random = new Random();
                        for(int i=0; i<size; i++)
                        {
                          rawData[i] = random.Next(lowerLimit, upperLimit +1);
                          sortedData[i] = rawData[i];
                        }
                  
                        // sort
                        sortedData();
                  
                        // Load into Lists
                        lstRaw.Items.Clear();
                        lstSorted.Items.Clear();
                  
                        for(int i=0, i<size; i++)
                        {
                          lstRaw.Items:Add(rawData[i]);
                          lstSorted.Items.Add(sortedData[i]);
                        }
                      }
                  
                      private void SortedData()
                      {
                        for(int i=0; i<size; i++)
                        {
                          for(int j=i+1; j<size; j++)
                          {
                            if(sortedData[i] > sortedData[j])
                            {
                              int tmp = sortedData[i];
                              sortedData[i] = sortedData[j];
                              sortedData[j] = tmp;
                            }
                          }
                        }
                      }
                  
                      private double CalcMedian()
                      {
                        double median = 0;
                        int mid = 0;
                  
                        // check the size
                        if(size % 2 == 0)
                        {
                          mid = size / 2;
                  
                          median = (sortedData[mid] + sortedData[mid+1]) / 2.0;
                        }
                        else
                        {
                          mid = size / 2;
                          median = sortedData[mid];
                        }
                  
                        return median;
                      }
                  
                      // CallMean, mode and median functions
                      // display Histogram
                      private void btnCalculate_Click(object sender, EventArgs e)
                      {
                        int[] freq = CalculateFrequencies();
                  
                        txtMean.Text = CalcMean().ToString("0.00");
                        txtMode.Text = CalcMode(freq).ToString("0.00");
                        txtMedian.Text = CalcMedian().ToString("0.00");
                  
                        // Now we display the Chart
                        this.histogramChart.Series.Clear();
                        var series = this.histogramChart.Series.Add("Random Variable");
                        for(int i=0; i<freq.Lenght; i++)
                        {
                          series.Points.AddXY(i, freq[i]);
                        }
                      }
                  
                      // Function to calculate the frequencies of the numbers
                      private void CalculateFrequencies()
                      {
                        // new array
                        int[] freq = new int[upperLimit + 1];
                  
                        for(int i=0; i<size; i++)
                        {
                          freq[rawData[i]] += 1;
                        }
                  
                        return freq;
                      }
                  
                  
                      // Mode
                      private int CalcMode(int [] frequenies)
                      {
                        // find max frequency
                        int max = frequenies[0];
                        int maxIndex = 0;
                  
                        for(int i=0; i<frequenies.Length; i++)
                        {
                          if(max < frequenies[i])
                          {
                            max = frequenies[i];
                            maxIndex = i;
                          }
                        }
                  
                        return maxIndex; // this is our mode
                      }
                  } 
                  

                  Comment


                    #10
                    I make an extra post to avoid to much characters limit.
                    Here are the three snippets related to the mode function

                    PHP Code:
                        // CallMean, mode and median functions
                        // display Histogram
                        private void btnCalculate_Click(object sender, EventArgs e)
                        {
                          int[] freq = CalculateFrequencies();
                    
                          txtMean.Text = CalcMean().ToString("0.00");
                          txtMode.Text = CalcMode(freq).ToString("0.00");
                          txtMedian.Text = CalcMedian().ToString("0.00");
                    
                          // Now we display the Chart
                          this.histogramChart.Series.Clear();
                          var series = this.histogramChart.Series.Add("Random Variable");
                          for(int i=0; i<freq.Lenght; i++)
                          {
                            series.Points.AddXY(i, freq[i]);
                          }
                        } 
                    
                    PHP Code:
                        // Function to calculate the frequencies of the numbers
                        private void CalculateFrequencies()
                        {
                          // new array
                          int[] freq = new int[upperLimit + 1];
                    
                          for(int i=0; i<size; i++)
                          {
                            freq[rawData[i]] += 1;
                          }
                    
                          return freq;
                        } 
                    
                    PHP Code:
                    
                    
                    // Mode
                        // Mode
                        private int CalcMode(int [] frequenies)
                        {
                          // find max frequency
                          int max = frequenies[0];
                          int maxIndex = 0;
                    
                          for(int i=0; i<frequenies.Length; i++)
                          {
                            if(max < frequenies[i])
                            {
                              max = frequenies[i];
                              maxIndex = i;
                            }
                          }
                    
                          return maxIndex; // this is our mode
                        } 
                    

                    Comment


                      #11
                      My raw adaptation to Ninjatrader
                      PHP Code:
                          // Function to calculate the frequencies of the numbers
                          private double CalculateFrequencies()
                          {
                            // new array
                            int[] freq = new int[upperLimit + 1]; // I don't know how to adapt that
                      
                            for(int i=0; i<size; i++)
                            {
                              freq[Rng0Rng1[i]] += 1;
                            }
                      
                            return freq;
                          }
                      
                          // Mode
                          private int CalcMode(int [] frequenies)
                          {
                            // find max frequency
                            int max = frequenies[0];
                            int maxIndex = 0;
                      
                            for(int i=0; i<frequenies.Length; i++)
                            {
                              if(max < frequenies[i])
                              {
                                max = frequenies[i];
                                maxIndex = i;
                              }
                            }
                      
                            return maxIndex; // this is our mode
                          }
                      
                          protected override void OnBarUpdate()
                          {
                            int[] freq = CalculateFrequencies();
                            double mode = CalcMode(freq);
                          } 
                      

                      But I can't figure out the int[] freq = new int[upperLimit + 1]; part, and i'm not sure how to change the arrays to fit it to Ninjatrader.
                      What would you recommend? Thanks!
                      Last edited by PaulMohn; 03-02-2022, 03:41 PM.

                      Comment


                        #12
                        Hello PaulMohn,

                        This thread will remain open for any community members that would like to assist you with understanding the custom logic and calculations you have posted.

                        As far as getting the series data to int array so that you can use Mode, it would just be a single loop from 0 to CurrentBar. See the corrected suggestion in post #4.

                        (As a tip, an int[] array is not resizable so it needs to be re-instantiated if the array size grows. A list would be resizable and the loop would not be necessary. You could just list.Add() the new value on each bar update)
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Ok thanks Chelsea for the tip i'll work from there. About the calculations and custom logic I understand most of it, it's just the upperlimit+1 reference i have difficulty conceptualizing to adapt to my use case. I'll study the list use and see if I can use without the upperlimit reference. Thanks again!

                          Comment


                            #14
                            Thanks Chelsea for the corrected example in post #4 .
                            I've been trying to follow your list tip (looking for a non Linq solution as Chris said in post #2) with some doc help
                            https://social.msdn.microsoft.com/Fo...=csharpgeneral
                            How can I find the mode of a list of numbers? I know the logic of it (I think) but I don't know how to implement that logic or convert what my brain thinks into workable code. This is what I know...

                            https://stackoverflow.com/questions/...ode-in-array-c


                            and came up with a no compile error snippet (but still with a Dictionary and 2 distinct foreach loops)
                            PHP Code:
                                private double CalcMode()
                                {
                                  List<double> list = new List<double>(CurrentBar);
                            
                                  // Initialize the return value
                                  double mode = default(double);
                                  // Test for a null reference and an empty list
                                  if (list != null && list.Count() > 0)
                                  {
                                    // Store the number of occurences for each element
                                    Dictionary<double, double> counts = new Dictionary<double, double>();
                                    // Add one to the count for the occurence of a character
                                    foreach (double Rng0Rng1 in list)
                                    {
                                      if (counts.ContainsKey(Rng0Rng1))
                                        counts[Rng0Rng1]++;
                                      else
                                        counts.Add(Rng0Rng1, 1);
                                    }
                                    // Loop through the counts of each element and find the
                                    // element that occurred most often
                                    double max = 0;
                                    foreach (KeyValuePair<double, double> count in counts)
                                    {
                                      if (count.Value > max)
                                      {
                                        // Update the mode
                                        mode = count.Key;
                                        max = count.Value;
                                      }
                                    }
                                  }
                                  return mode;
                                } 
                            

                            but the mode return 0 zero value.

                            You said
                            A list would be resizable and the loop would not be necessary. You could just list.Add() the new value on each bar update)
                            How would a loop not be necessary with the list?
                            And would it also allow for no dictionary need in the solution you recommend?

                            Any idea why the above snippet returns 0 zero value?
                            Or do you have a way to check the mode value (I don't grasp what to print to check it)? Thanks.

                            Also, I see in the original snippet (first link above tot eh social microsoft forum) the Function has some parameters (
                            (this IEnumerable<int> source) ).

                            How do I know/can check which parameter would be needed for my case? Thanks!
                            Last edited by PaulMohn; 03-03-2022, 02:35 PM.

                            Comment


                              #15
                              Hello PaulMohn,

                              The list was just a mention as an array would need to be recreated on each new bar which would cost cpu and memory.

                              Each time OnBarUpdate() updates, a list can add a new element. So the entire array does not have to be recreated, since the list can expand with new elements.

                              private List<double> listOfSeriesValues;

                              In State.DataLoaded:
                              (corrected)
                              listOfSeriesValues = new List<double>();

                              In OnBarUpdate():
                              listOfSeriesValues.Add(Rng0Rng1[0]);

                              listOfSeriesValues now has all of the Rang0Rng1 series info.

                              A google search of list mode returned a post on a C# educational forum (stackoverflow) on getting the mode from a list.
                              I have a list: List&lt;double&gt; final=new List&lt;double&gt;(); final.Add(1); final.Add(2); final.Add(3); What sort of method could I use to find the mode of this list? Also, if there are two mo...



                              I wouldn't be able to say why your custom logic is returning a 0. I would recommend you debug the code and print out each step. Print the values in the conditions, print the values used in calculations, print the values after assignments.

                              Below is a link to a forum post that demonstrates using prints to understand behavior.
                              https://ninjatrader.com/support/foru...121#post791121

                              Below is a link to the microsoft documentation on IEnumerable<T>.
                              https://docs.microsoft.com/en-us/dot...1?view=net-6.0


                              This thread will remain open for community members that would like to assist with your custom calculations and logic.
                              Last edited by NinjaTrader_ChelseaB; 03-06-2022, 07:33 PM.
                              Chelsea B.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              617 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              357 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              105 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              561 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              566 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X