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

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<doubleRng0;
         private 
    Series<doubleRng1;

         private 
    Series<doubleRng0Rng1;

         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);

                   
    int maxCount groups.Max(=> g.Count());

                   
    int mode groups.First(=> g.Count() == maxCount).Key;
              }


              protected 
    override void OnBarUpdate()
              {
                   
    CountIf(() => Rng0[Rng0Index] - Rng1[Rng1Index] >= 15*TickSizeBarsBack);

                   
    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
    Chris L.NinjaTrader Customer Service

    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<doubleRng0;
          private 
      Series<doubleRng1;

          private 
      Series<doubleRng0Rng1;


          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 0BarsBacki++)
              {
                
      int count 0;

                for (
      int j 0BarsBackj++)
                {
                  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<doubleRng0;
          private 
      Series<doubleRng1;

          private 
      Series<doubleRng0Rng1;


          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 0BarsBacki++)
              {
                
      int count 0;

                for (
      int j 0BarsBackj++)
                {
                  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<doubleRng0;
          private 
      Series<doubleRng1;

          private 
      Series<doubleRng0Rng1;


          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 0BarsBacki++)
              {
                
      int count 0;

                for (
      int j 0BarsBackj++)
                {
                  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 th...


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

          PHP Code:
              private double CalcMode()
              {
                List<
          doubledataSet = new List<double>();

                
          double maxNumber 0;
                
          double maxAppearances 0;

                for (
          int i 0CurrentBari++)
                {
                  
          int count 0;

                  for (
          int j 0CurrentBarj++)
                  {
                    
          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 sizelowerLimitupperLimit;


                      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=0i<sizei++)
                        {
                          
                  sum += rawData[i];
                        }

                        return 
                  sum size;
                      }

                      
                  // Generate the Random Data Set & then Sort the Random Data Set
                      
                  private void btnGenerate_Click(object senderEventArgs 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=0i<sizei++)
                        {
                          
                  rawData[i] = random.Next(lowerLimitupperLimit +1);
                          
                  sortedData[i] = rawData[i];
                        }

                        
                  // sort
                        
                  sortedData();

                        
                  // Load into Lists
                        
                  lstRaw.Items.Clear();
                        
                  lstSorted.Items.Clear();

                        for(
                  int i=0i<sizei++)
                        {
                          
                  lstRaw.Items:Add(rawData[i]);
                          
                  lstSorted.Items.Add(sortedData[i]);
                        }
                      }

                      private 
                  void SortedData()
                      {
                        for(
                  int i=0i<sizei++)
                        {
                          for(
                  int j=i+1j<sizej++)
                          {
                            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 == 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 senderEventArgs 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=0i<freq.Lenghti++)
                        {
                          
                  series.Points.AddXY(ifreq[i]);
                        }
                      }

                      
                  // Function to calculate the frequencies of the numbers
                      
                  private void CalculateFrequencies()
                      {
                        
                  // new array
                        
                  int[] freq = new int[upperLimit 1];

                        for(
                  int i=0i<sizei++)
                        {
                          
                  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=0i<frequenies.Lengthi++)
                        {
                          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 senderEventArgs 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=0i<freq.Lenghti++)
                          {
                            
                    series.Points.AddXY(ifreq[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=0i<sizei++)
                          {
                            
                    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=0i<frequenies.Lengthi++)
                          {
                            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=0i<sizei++)
                            {
                              
                      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=0i<frequenies.Lengthi++)
                            {
                              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<doubledoublecounts = new Dictionary<doubledouble>();
                                    
                            // 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(Rng0Rng11);
                                    }
                                    
                            // Loop through the counts of each element and find the
                                    // element that occurred most often
                                    
                            double max 0;
                                    foreach (
                            KeyValuePair<doubledoublecount 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 m...



                              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 jaybedreamin, Today, 05:56 PM
                              0 responses
                              3 views
                              0 likes
                              Last Post jaybedreamin  
                              Started by DJ888, 04-16-2024, 06:09 PM
                              6 responses
                              18 views
                              0 likes
                              Last Post DJ888
                              by DJ888
                               
                              Started by Jon17, Today, 04:33 PM
                              0 responses
                              1 view
                              0 likes
                              Last Post Jon17
                              by Jon17
                               
                              Started by Javierw.ok, Today, 04:12 PM
                              0 responses
                              6 views
                              0 likes
                              Last Post Javierw.ok  
                              Started by timmbbo, Today, 08:59 AM
                              2 responses
                              10 views
                              0 likes
                              Last Post bltdavid  
                              Working...
                              X