Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Countif() Condition as separate variables

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

    Countif() Condition as separate variables

    I'm trying to pass a custom local variable as parameter in the condition of Countif()

    My debugging test result in the picture attached

    In the picture the var4 gives the result "5" (always the max countif() value possible) with custom local variable (see bottom right corner of the chart)
    while the novar gives the result "4" (the correct countif() value) of the countif without the custom local variable.

    The var4 related snippet

    PHP Code:
    double var0 = High[0];
    double var1 = Low[0];
    double var2 = 15*TickSize;
    bool var3 = var0 - var1 >= var2;
    int var4 = CountIf(() => var3, BarsBack);
    
    Draw.TextFixed(
         this,
         "testa",
         "var4: " + var4 + "\t\n\n",
         TextPosition.BottomRight,
         Brushes.Green,
         myFont,
         Brushes.Transparent,
         Brushes.Transparent,
         0); 
    

    The novar related snippet

    PHP Code:
    Draw.TextFixed(
         this,
         "testb",
         "novar: " + CountIf(() => High[0] - Low[0] >= 15*TickSize, BarsBack) + "\t\n",
         TextPosition.BottomRight,
         Brushes.Green,
         myFont,
         Brushes.Transparent,
         Brushes.Transparent,
         0); 
    

    Why aren't the var4 and novar results matching?

    How to make them match? Thanks



    #2
    Hello PaulMohn,

    bool var3 = var0 - var1 >= var2;
    int var4 = CountIf(() => var3, BarsBack);

    var3 is not a function bool expression, its just a value of true or false.

    With CountIf() you are supplying true (not an expression). Meaning you are asking if true is equal to true on each bar.

    You will need to supply a function expression that returns a bool.

    CountIf(() => High[0] - Low[0] >= 15 * TickSize, BarsBack)
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hello Chelsea and thanks for the clarification. But I need to use High[0] and Low[0] as separate variable for later use in a switch.
      How can I do that with the countif? it seems it's not possible with what you say. or is there a way to supply a function expression that returns a bool with custom variables in countif?
      I can't think of a way other than countif.
      Would you please help with what I could do to reach the goal? Thanks.

      Comment


        #4
        Hello PaulMohn,

        You can assign and use those variables later if you want. You don't have to erase them. But for CountIf() a double variable isn't going to give you the previous bars values, a Series<double> is needed for that which holds a value for each bar on the chart, that CountIf() can loop through. Further, a single true value is not an expression that can be evaluated for each bar.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Ah ok thanks for the tips I'll test with the Series next. About my other post do you have any insight? i'm not making progress there too. Thanks!

          Comment


            #6
            I'm looking at the doc for Series<T>
            I'm not sure if that's what I must do.
            I need the series to the ones on the chart, whatever time frame the chart has.

            Here the Series<T> snippets
            Code:
            private Series<double> myDoubleSeries; // Define a Series<T> variable. In this instance we want it
                                                  // as a double so we created a Series<double> variable.
            
            private Series<double> mySecondaryDoubleSeries; // Define a Series<T> variable. In this instance we want it
                                                          // as a double so we created a Series<double> variable.
            
            // Create a Series object and assign it to the variable
            protected override void OnStateChange()
            {
                if (State == State.Configure)
                {
                    // Add a secondary data series to sync our Secondary Series<double>
                    AddDataSeries(BarsPeriodType.Minute, 1);
                }
                else if (State == State.DataLoaded)
                {
                    // "this" refers to the NinjaScript object itself. This syncs the Series object to historical data bars
                    // MaximumBarsLookBack determines how many values the Series<double> will have access to
                    myDoubleSeries = new Series<double>(this, Maximu mBarsLookBack.Infinite);
            
                    // "BarsArray[1]" refers to the first data series added to the script with AddDataSeries.
                    mySecondaryDoubleSeries = new Series<double>(Bar sArray[1]);
                }
            }
            Code:
            protected override void OnBarUpdate()
            {
              // Calculate the range of the current bar and set the value
                myDoubleSeries[0] = (High[0] - Low[0]);
            
                // Print the current 10 period SMA of range
                Print("Value is " + SMA(myDoubleSeries, 10)[0]);        
            }

            I'm thinking of using it like that.

            PHP Code:
            private Series<double> Hgh; // declare the High[0] 2nd Series
            private Series<double> Lw; // declare the Low[0] 3rd Series
            private Series<double> Clo; // declare the Close[0] 4th Series
            
            protected override void OnStateChange()
            {
                if (State == State.Configure)
                {
                    // Add a secondary data series to sync our Secondary Series<double>
                    AddDataSeries(?, ?); // set the timeframe for the High[0] 2nd Series
                }
            
                else if (State == State.DataLoaded)
                {
                    Hgh = new Series<double>(this, MaximumBarsLookBack.Infinite); // refer and sync to the Hgh series to hist. data
                    Lw = new Series<double>(BarsArray[1]); // "BarsArray[1]" refers to the first data series
                    Clo = new Series<double>(BarsArray[1]); // "BarsArray[1]" refers to the first data series
                }
            
                protected override void OnBarUpdate()
                {
                    double Hgh[0] = High[0];
                    double Lw[0] = Low[0];
            
                    double var0[0] = Hgh[0] - Lw[0];
                    double var1 = 15*TickSize;
                    bool var2  = var0[0] >= var2;
                    int var3 = CountIf(() => var2, BarsBack);
            
                    Draw.TextFixed(
                         this,
                         "testa",
                         "var3: " + var3 + "\t\n\n",
                         TextPosition.BottomRight,
                         Brushes.Green,
                         myFont,
                         Brushes.Transparent,
                         Brushes.Transparent,
                         0);
                }
            } 
            

            Is this the approach you recommended? I'm not yet familiar with new series added so please let me know it that what's needed.
            If yes, how do you make it take the default timeframe of whatever the chart has?

            Just to clarify my goal is simply to have the High[0], Low[0], Close[0] as sort of input selectable in a dropdown (switch) in the indicator properties.
            To preset in the indicator properties the condition for the Countif() method. Thanks!

            I've checked those in references
            NinjaScript Editor - Custom Dropdown Lists?
            User Inputs
            Indicator: Creating a user-defined parameter type (enum)
            Add NInjaScriptProperty where user can choose an Indicator
            Select indicator through [NinjaScriptProperty]

            Last edited by PaulMohn; 02-23-2022, 02:44 PM. Reason: Added: ​​​​​​​To preset in the indicator properties the condition for the Countif() method.

            Comment


              #7
              Hello PaulMohn,

              Highs[1] would be a Series<double> object, same for Closes[1] or Close.

              double high = Highs[1][0];

              high here would be a double value.

              int var3 = CountIf(() => var2, BarsBack);

              var2 is not a lambda express, it is a single bool. This isn't going to work.

              You need to supply a series like the Highs[1] series or the Close series or whatever series, in a lambda expression.

              From what I can see, you don't have any need for a custom series, and you can use the existing series in the script.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #8
                I've searched the documentation and could find a lot of examples about multi-timeframes or multi-instruments uses for Series<T>.

                AddDataSeries()
                Code:
                protected override void OnStateChange()
                {
                    if (State == State.Configure)
                    {
                        // Add a 5 minute Bars object - BarsInProgress index = 1
                        AddDataSeries(BarsPeriodType.Minute, 5);
                
                        // Add a 100 tick Bars object for the ES 09-16 contract - BarsInProgress index = 2
                        AddDataSeries("ES 09-16", BarsPeriodType.Tick, 100);
                    }
                }
                
                protected override void OnBarUpdate()
                {
                    // Ignore bar update events for the supplementary - Bars object added above
                    if (BarsInProgress == 1 || BarsInProgress == 2)
                        return;
                
                    // Go long if we have three up bars on all bars objects
                    if (Close[0] > Open[0] && Closes[1][0] > Opens[1][0] && Closes[2][0] > Opens[2][0])
                        EnterLong();
                }
                The doc I've consulted

                Working with Price Series
                PriceSeries<double>
                Series<T>
                PriceSeries<double>
                Highs
                Multi-Time Frame & Instruments
                Valid Input Data for Indicator Methods

                DataSeries Class




                The threads
                Adding multiple data series in one strategy
                Setting a Variable
                Help with Can't convert Double to Data Series
                Cannot impliciily convert type double to NinjaScript Series,double
                Data Series?
                DataSeries in NinjaTrader 8
                Indicator: Using a Series or DataSeries object to store calculations
                Operator && cannot be applied to operands of type bool and double.
                What's wrong with my code??
                own Series<double> to keep track of the daily OHLC values


                What are Generics? (C# Basics)


                I'm not finding any example of Series<double> with the Highs[0][0] or Lows[0][0] related to my topic (same instrument same timeframe use).

                Can you please refer to any existing doc detailing my use case?
                If no, can you please try and explain?

                For example I (think I) understand that Highs[0][0] means 2 dimensional array

                Highs[0][0] = (the highlighted in red part) get the first (forward array index 0 = the 1st) series of a multi-instruments or of a multi-timeframe of the same instrument.
                Highs[1][0] = (the highlighted in red part) get the 2nd (array index 1 = the 2nd) series of a multi-instruments or of a multi-timeframe of the same instrument.
                Highs[2][0] = (the highlighted in red part) get the 3rd (array index 1 = the 3rd) series of a multi-instruments or of a multi-timeframe of the same instrument.
                and so on (Highs[4][0] = 4th, Highs[4][0] = 5th etc.)

                Highs[0][1] = (the highlighted in red part) get the 1st Bar back starting form the the currently processing one (array index 1 = the 2nd) - from the first series of a multi-instruments or of a multi-timeframe of the same instrument.
                Highs[0][0] = (the highlighted in red part) the currently processing Bar (array index 0 = the 1st) - from the first series of a multi-instruments or of a multi-timeframe of the same instrument.
                Highs[0][7] = (the highlighted in red part) get the 8th Bar back starting form the the currently processing one (array index 7 = the 8th) - from the first series of a multi-instruments or of a multi-timeframe of the same instrument.

                In my use case I won't use multi-instruments or multi-timeframe (I'll only use a single instrument and a single timeframe at a time for the indicator).
                I can guess why I would need an double array (Highs[0][0]) but i'm not sure why (since the Countif() works without it when not using separate variables).
                My guess is countif() needs to access the whole array to draw the valid values from if those are stored in separate variables, but it doesn't need it when the values are retrieves from its own built-in calculations only (though I don't fully grasp why, maybe there is a function that calls that array built-in the countif()).

                Also I've reviewed the lambda expression documentation but the NT8 countif doesn't look similar and the documentation page is very limited (it does not explain the countif() function).

                CountIf()
                Expression lambdas
                Lambda Expressions in C#.Net made easy! | Expression Lambda | Statement Lambda
                Part 99 Lambda expression in c#
                Lambda Expressions & Anonymous Functions

                I don't understand your formulation of the Highs[1]. What does it refers to? To the 2nd series only (with no bar index/array, only the series index/array).
                I couldn't find any example of that formulation in the doc (was it only for implicit illustrative purpose or did you mean something more specific I didn't catch)?

                For my se case, wouldn't I need instead the full double array formulation, with both arrays' indices of 0, like Highs[0][0] (since I don't have multi-instrument nor multi-timeframe).
                Or if Highs[1] is what you really mean, is it to mean : refer to the array itself and to no "single" one of it bar index in particular, for then the Countif to draw from that "1st level"/series level level of the double array? to avoid maybe reproducing the same problem as the High[0] with the Highs[0][0] pointing to a single bar index? i think that makes more sense but I'm only guessing and don't know. Thank you for explaining what you meant.


                I've modified the script so far as
                PHP Code:
                namespace NinjaTrader.NinjaScript.Indicators
                {
                     public class Testa : Indicator
                     {
                          private ISeries<double> var0;
                          private ISeries<double> var1;
                
                          protected override void OnStateChange()
                          {
                               if (State == State.SetDefaults)
                               {
                                    Description = @"Enter the description for your new custom Indicator here.";
                                    Name = "Testa";
                                    Calculate = Calculate.OnBarClose;
                                    IsOverlay = true;
                                    DisplayInDataBox = true;
                                    DrawOnPricePanel = true;
                                    DrawHorizontalGridLines = true;
                                    DrawVerticalGridLines = true;
                                    PaintPriceMarkers = true;
                                    ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                                    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                                    //See Help Guide for additional information.
                                    IsSuspendedWhileInactive = true;
                                    BarsBack = 5;
                               }
                               else if (State == State.Configure)
                               {
                               }
                          }
                
                          protected override void OnBarUpdate()
                          {
                
                               if(CurrentBar < 5)
                               {
                                    return;
                               }
                
                               NinjaTrader.Gui.Tools.SimpleFont myFont = new NinjaTrader.Gui.Tools.SimpleFont("Courier New", 12) { Size = 15, Bold = true };
                
                
                               ISeries<double> var0 = Highs[1][0];
                               ISeries<double> var1 = Lows[1][0];
                               double var2 = 5*TickSize;
                               bool var3 = var0 - var1 >= var2;
                               int var4 = CountIf(() => var0 - var1 >= var2, BarsBack);
                
                               Draw.TextFixed(
                                    this,
                                    "testa",
                                    "var3: " + var3 + "\t\n\n",
                                    TextPosition.BottomRight,
                                    Brushes.Green,
                                    myFont,
                                    Brushes.Transparent,
                                    Brushes.Transparent,
                                    0); 
                

                Comment


                  #9
                  I'm not sure what's the issue and i can't find helpful threads with solutions. Also I'm not sure know to declare/initialize the Series<double>.
                  I've tested both Series<double> and ISeries<double>

                  With

                  public class Testa : Indicator
                  {

                  private ISeries<double> var0;
                  private ISeries<double> var1;

                  protected override void OnBarUpdate()
                  {
                  ISeries<double> var0 = Highs[1][0];
                  ISeries<double> var1 = Lows[1][0];


                  I'm getting those 4 compile errors with the above script

                  ISeries<double> var0 = Highs[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'double' to 'NinjaTrader.NinjaScript.ISeries<double>' CS0029 75 27
                  ISeries<double> var1 = Lows[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'double' to 'NinjaTrader.NinjaScript.ISeries<double>' CS0029 76 27
                  bool var3 = var0 - var1 >= var2;
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.ISeries<double>' and 'NinjaTrader.NinjaScript.ISeries<double>' CS0019 78 18
                  int var4 = CountIf(() => var0 - var1 >= var2, BarsBack);
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.ISeries<double>' and 'NinjaTrader.NinjaScript.ISeries<double>' CS0019 79 32

                  with

                  public class Testa : Indicator
                  {

                  private ISeries<double> var0;
                  private ISeries<double> var1;

                  protected override void OnBarUpdate()
                  {
                  ISeries<double> var0 = Highs[1];
                  ISeries<double> var1 = Lows[1];

                  I get the 3rd and 4th errors only

                  bool var3 = var0 - var1 >= var2;
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.ISeries<double>' and 'NinjaTrader.NinjaScript.ISeries<double>' CS0019 78 18
                  int var4 = CountIf(() => var0 - var1 >= var2, BarsBack);
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.ISeries<double>' and 'NinjaTrader.NinjaScript.ISeries<double>' CS0019 79 32

                  with

                  public class Testa : Indicator
                  {

                  private Series<double> var0;
                  private Series<double> var1;

                  protected override void OnBarUpdate()
                  {
                  Series<double> var0 = Highs[1][0];
                  ISeries<double> var1 = Lows[1][0];

                  I get those 4 compile errors

                  Series<double> var0 = Highs[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'NinjaTrader.NinjaScript.PriceSeries' to 'NinjaTrader.NinjaScript.Series<double>' CS0029 75 26
                  Series<double> var1 = Lows[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'NinjaTrader.NinjaScript.PriceSeries' to 'NinjaTrader.NinjaScript.Series<double>' CS0029 76 26
                  bool var3 = var0 - var1 >= var2;
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.Series<double>' and 'NinjaTrader.NinjaScript.Series<double>' CS0019 78 18
                  int var4 = CountIf(() => var0 - var1 >= var2, BarsBack);
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.Series<double>' and 'NinjaTrader.NinjaScript.Series<double>' CS0019 79 32

                  with

                  public class Testa : Indicator
                  {

                  private ISeries<double> var0;
                  private ISeries<double> var1;

                  protected override void OnBarUpdate()
                  {
                  Series<double> var0 = Highs[1];
                  Series<double> var1 = Lows[1];

                  I get those 4 compile errors as well

                  Series<double> var0 = Highs[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'double' to 'NinjaTrader.NinjaScript.Series<double>' CS0029 75 26
                  Series<double> var1 = Lows[1];
                  NinjaScript File Error Code Line Column
                  Testa.cs Cannot implicitly convert type 'double' to 'NinjaTrader.NinjaScript.Series<double>' CS0029 76 26
                  bool var3 = var0 - var1 >= var2;
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.Series<double>' and 'NinjaTrader.NinjaScript.Series<double>' CS0019 78 18
                  int var4 = CountIf(() => var0 - var1 >= var2, BarsBack);
                  NinjaScript File Error Code Line Column
                  Testa.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.Series<double>' and 'NinjaTrader.NinjaScript.Series<double>' CS0019 79 32

                  The second one seems closer to the solution - only 2 compile errors with

                  public class Testa : Indicator
                  {

                  private ISeries<double> var0;
                  private ISeries<double> var1;

                  protected override void OnBarUpdate()
                  {
                  ISeries<double> var0 = Highs[1];
                  ISeries<double> var1 = Lows[1];

                  Is that the correct way?

                  Thanks!

                  Comment


                    #10
                    Hello PaulMohn,

                    Highs is a collection of Series<double> objects that is created by NinjaTrader behind the scenes.

                    Each time you call AddDataSeries() , this will automatically add that series to the Highs, Closes, Lows, Opens, Volumes, etc.

                    I don't think you need a custom series, you just need ensure that in your CountIf() you are supplying an lambda expression that uses series, and not just supplying a single bool value which cannot be evaluated.

                    That said, if you are curious about how to instantiate a custom series, you don't need this for your script, the Series<T> page in the help guide has sample code.


                    In the scope of the class:
                    private Series<double> myDoubleSeries

                    In OnStateChange() when State is State.DataLoaded:
                    myDoubleSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);

                    In OnBarUpdate():
                    myDoubleSeries[0] = Close[0];


                    Using var1, var2, etc is not going to work in CountIf(). You need to use series like High[0] - Low[0] and this needs to be in a lambda expression.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Thanks Chelsea for the short explanation i'm not sure I understand it all yet but i will study it further asa.
                      Since the CountIf cannot take custom variable do you any know another approach without the CountIf that could work? I just can't put it in clear concept in a script idea.

                      I tought of using a foreach loop but it's confuse and seems to0 complicated for the task.
                      1. Get the BarsBack (user Input parameter int) HLC values into an array, for example if 50 bars then get the bars 0 to 49 bars. (the array must be dynamic though i.e. it must get the newest incoming (bars ([0,49]) values in and the oldest ones ([>49) out).
                      2. Loop through that array.
                      3. 2. For each value meeting the criteria (i.e. High[0]-Low[0]>15*TickSize), add it to the loop counter.
                      4. 3. Use the Draw.FixedText method to display the Loop counter result on the Chart window.

                      Would that approach be efficient or would you recommend something better to get the HLC as variables working?

                      Reference
                      Looping Commands
                      Last edited by PaulMohn; 02-24-2022, 10:13 AM. Reason: added reference Looping Commands

                      Comment


                        #12
                        Hello PaulMohn,

                        Using a for loop would likely work.
                        for (int = 0; i < Math.Min(50, CurrentBar); i++)
                        {
                        // condition here
                        }

                        You don't need to use variables that I can see, just supply the series directly.. no need to assign the last bar value to a variable first for the lambda..
                        If you want to assign the last bar value of the High series to a variable to use later, thats fine, just don't use this for the CountIf().
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Chelsea I've made some tests with the MAX() function to isolate the sense of Series Double not working for my use.

                          8, 7, 6 tests
                          returns goods prints.
                          8. (Highs[0] value) value - (Lows[0] value) value Test
                          7. (Highs value) value - (Lows value) value Test
                          6. (High value) value - (Low value) value Test



                          9, 5, 4, 3, 2, 1, 0
                          bad print.
                          9. (Highs[1] value) value - (Lows[1] value) value Test
                          5. Highs[0][0] - Lows[0][0] Test
                          4. Highs - Lows Test
                          3. Highs[1] - Lows[1] Test
                          2. Highs[0] - Lows[0] Test
                          1. High - Low Test
                          0. High[0] - Low[0] Test



                          I'm not sure why and how 8, 7, 6 test work with MAX() function while 9, 5, 4, 3, 2, 1, 0 don't. How should I think of it to understand?
                          What I currently think is that somehow the working snippets access the single values within the arrays, while the not working ones access only whole array level (multiple values, the series) and therefore can't pick the max value from it.

                          Also, why no "[0]" is required for snippets 7 and 6?

                          Also it seems snippet 6 (or 7) would be the right one for my use. Why?

                          Also, what's the reason for the snippet 8 error? and what's the difference between snippet 8 and snippet 7 (the extra "[0]" in snippet 8, doesn't that means the same as with no "[0]" as for snippet 7)? Thanks!

                          Demo
                          https://drive.google.com/file/d/1v-s...ew?usp=sharing

                          The Snippets and Errors / Prints


                          0. High[0] - Low[0] Test
                          PHP Code:
                               double value0 = MAX(High[0] - Low[0], BarsBack)[0];
                               Print("The current MAX High[0] - Low[0] value is " +"\n"+value0.ToString()); 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs The best overloaded method match for 'NinjaTrader.NinjaScript.Indicators.Indicator.MAX( NinjaTrader.NinjaScript.ISeries<double>, int)' has some invalid arguments CS1502 55 20
                          
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Argument 1: cannot convert from 'double' to 'NinjaTrader.NinjaScript.ISeries<double>' CS1503 55 24 
                          


                          1. High - Low Test
                          PHP Code:
                               double value1 = MAX(High - Low, BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value1.ToString()); 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.ISeries<double>' and 'NinjaTrader.NinjaScript.ISeries<double>' CS0019 55 24 
                          


                          2. Highs[0] - Lows[0] Test
                          PHP Code:
                               double value2 = MAX(Highs[0] - Lows[0], BarsBack)[0];
                               Print("The current MAX High - Low value is " +"\n"+value2.ToString()); 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.PriceSeries' and 'NinjaTrader.NinjaScript.PriceSeries' CS0019 55 24
                          &#8203;​​​​​​ 
                          


                          ​​​​​​​3. Highs[1] - Lows[1] Test
                          PHP Code:
                               double value3 = MAX(Highs[1] - Lows[1], BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value3.ToString());
                          &#8203;​​​​​​ 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.PriceSeries' and 'NinjaTrader.NinjaScript.PriceSeries' CS0019 55 24
                          &#8203;​​​​​​ 
                          


                          4. Highs - Lows Test
                          PHP Code:
                               double value4 = MAX(Highs - Lows, BarsBack)[0];
                               Print("The current MAX Highs[1] - Lows[1] value is " +"\n"+value4.ToString());
                          &#8203;​​​​​​ 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Operator '-' cannot be applied to operands of type 'NinjaTrader.NinjaScript.PriceSeries[]' and 'NinjaTrader.NinjaScript.PriceSeries[]' CS0019 55 24
                          &#8203;​​​​​​ 
                          


                          5. Highs[0][0] - Lows[0][0] Test
                          PHP Code:
                               double value5 = MAX(Highs[0][0] - Lows[0][0], BarsBack)[0];
                               Print("The current MAX Highs[0][0] - Lows[0][0] value is " +"\n"+value5.ToString());
                          &#8203;​​​​​​ 
                          
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs The best overloaded method match for 'NinjaTrader.NinjaScript.Indicators.Indicator.MAX( NinjaTrader.NinjaScript.ISeries<double>, int)' has some invalid arguments CS1502 55 20
                          
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Argument 1: cannot convert from 'double' to 'NinjaTrader.NinjaScript.ISeries<double>' CS1503 55 24
                          &#8203;​​​​​​ 
                          


                          6. (High value) value - (Low value) value Test
                          PHP Code:
                               double value6 = MAX(High, BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value6.ToString());
                          
                               double value7 = MAX(Low, BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value7.ToString());
                          
                               double var0 = value6 - value7;
                          
                               Print("The current MAX (High value) value - The current MAX (Low value) value value is " +"\n"+var0.ToString());
                          &#8203;​​​​​​ 
                          
                          PHP Code:
                          The current MAX value is
                          93.17
                          The current MAX value is
                          93.03
                          The current MAX (High value) value - The current MAX (Low value) value value is
                          0.140000000000001
                          &#8203;​​​​​​ 
                          


                          7. (Highs value) value - (Lows value) value Test
                          ​​​​​​​
                          PHP Code:
                               double value8 = MAX(Highs, BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value8.ToString());
                          
                               double value9 = MAX(Lows, BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value9.ToString());
                          
                               double var1 = value8 - value9;
                          
                               Print("The current MAX (Highs value) value - The current MAX (Lows value) value value is " +"\n"+var1.ToString());
                          &#8203;​​​​​​ 
                          
                          ​​​​​​​
                          PHP Code:
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs The best overloaded method match for 'NinjaTrader.NinjaScript.Indicators.Indicator.MAX( NinjaTrader.NinjaScript.ISeries<double>, int)' has some invalid arguments CS1502 55 20
                          
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Argument 1: cannot convert from 'NinjaTrader.NinjaScript.PriceSeries[]' to 'NinjaTrader.NinjaScript.ISeries<double>' CS1503 55 24
                          
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs The best overloaded method match for 'NinjaTrader.NinjaScript.Indicators.Indicator.MAX( NinjaTrader.NinjaScript.ISeries<double>, int)' has some invalid arguments CS1502 58 20
                          
                          NinjaScript File Error Code Line Column
                          SeriesDoubleTest.cs Argument 1: cannot convert from 'NinjaTrader.NinjaScript.PriceSeries[]' to 'NinjaTrader.NinjaScript.ISeries<double>' CS1503 58 24 
                          

                          Success Prints on the next Bar (OnbarClose)
                          PHP Code:
                          The current MAX value is
                          93.26
                          The current MAX value is
                          93.15
                          The current MAX (High value) value - The current MAX (Low value) value value is
                          0.109999999999999 
                          


                          8. (Highs[0] value) value - (Lows[0] value) value Test
                          PHP Code:
                               double value10 = MAX(Highs[0], BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value10.ToString());
                          
                               double value11 = MAX(Lows[0], BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value11.ToString());
                          
                               double var2 = value10 - value11;
                          
                               Print("The current MAX (Highs[0] value) value - The current MAX (Lows[0] value) value value is " +"\n"+var2.ToString()); 
                          
                          PHP Code:
                          The current MAX value is
                          93.17
                          The current MAX value is
                          93.03
                          The current MAX (Highs[0] value) value - The current MAX (Lows[0] value) value value is
                          0.140000000000001 
                          


                          9. (Highs[1] value) value - (Lows[1] value) value Test
                          PHP Code:
                               double value12 = MAX(Highs[1], BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value12.ToString());
                          
                               double value13 = MAX(Lows[1], BarsBack)[0];
                               Print("The current MAX value is " +"\n"+value13.ToString());
                          
                               double var3 = value12 - value13;
                          
                               Print("The current MAX (Highs[1] value) value - The current MAX (Lows[1] value) value value is " +"\n"+var3.ToString()); 
                          
                          PHP Code:
                          Time Category Message
                          25/02/2022 12:44:36 Default Indicator 'SeriesDoubleTest': Error on calling 'OnBarUpdate' method on bar 0: Index was outside the bounds of the array.
                          
                          Indicator 'SeriesDoubleTest': Error on calling 'OnBarUpdate' method on bar 0: Index was outside the bounds of the array. 
                          
                          Attached Files
                          Last edited by PaulMohn; 02-25-2022, 07:09 AM. Reason: Added the Indicator SeriesTest in attachement

                          Comment


                            #14
                            Chelsea I tested adding a series as you showed in post 10

                            PHP Code:
                            namespace NinjaTrader.NinjaScript.Indicators
                            {
                                 public class SeriesDoubleTest : Indicator
                                 {
                                      private Series<double> myDoubleSeries;
                            
                                      protected override void OnStateChange()
                                      {
                                           if (State == State.SetDefaults)
                                           {
                                                Description = @"Enter the description for your new custom Indicator here.";
                                                Name = "SeriesDoubleTest";
                                                Calculate = Calculate.OnBarClose;
                                                IsOverlay = true;
                                                DisplayInDataBox = true;
                                                DrawOnPricePanel = true;
                                                DrawHorizontalGridLines = true;
                                                DrawVerticalGridLines = true;
                                                PaintPriceMarkers = true;
                                                ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                                                //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                                                //See Help Guide for additional information.
                                                IsSuspendedWhileInactive = true;
                                                BarsBack = 5;
                                           }
                                           else if (State == State.Configure)
                                           {
                                           }
                                           else if (State == State.DataLoaded)
                                           {
                                                myDoubleSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);
                                           }
                                      }
                            
                                      protected override void OnBarUpdate()
                                      {
                                           if(CurrentBar < 5)
                                           {
                                                return;
                                           }
                            
                                           myDoubleSeries[0] = High[0] - Low[0];
                            
                                           Print("i " +myDoubleSeries+"\n");
                                      }
                                      #region Properties
                                      [Range(1, int.MaxValue), NinjaScriptProperty]
                                      [Display(ResourceType = typeof(Custom.Resource), Name = "BarsBack", GroupName = "Number of Bars for Stats", Order = 0)]
                                      public int BarsBack
                                      { get; set; }
                                      #endregion
                                 }
                            } 
                            

                            I see
                            "myDoubleSeries" (without the [0]) in
                            PHP Code:
                            myDoubleSeries[0] = High[0] - Low[0];
                            
                            Print("i " +myDoubleSeries+"\n"); 
                            

                            prints the Series type info
                            PHP Code:
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double]
                            i NinjaTrader.NinjaScript.Series`1[System.Double] 
                            

                            While
                            "myDoubleSeries[0]" (with the [0]) in
                            PHP Code:
                            myDoubleSeries[0] = High[0] - Low[0];
                            
                            Print("i " +myDoubleSeries[0]+"\n"); 
                            

                            prints the values
                            PHP Code:
                            i 2.20000000000005
                            i 2.5
                            i 1.5
                            i 0.799999999999955
                            i 2.29999999999995
                            i 1.69999999999982
                            i 1.5
                            i 0.800000000000182
                            i 1.79999999999995
                            i 0.5
                            i 1.69999999999982
                            i 0.600000000000136
                            i 0.799999999999955
                            i 1.20000000000005 
                            

                            So it does works then with myDoubleSeries[0] = High[0] - Low[0];

                            I tested and it works.

                            The solution was to add 3 private Series>double> at the class scope level.
                            The initialize them at the State == State.DataLoaded scope level.
                            Then use them in the OnBarUpdate() scope, and add a [0] to the variables.

                            Success Result image attached

                            Script

                            Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.



                            So if I understand right for it to work it simply needs added private Series<double> declarations and initialization, and an added [0] to the variable.
                            Why? What does the added zero means? Thanks!
                            Attached Files

                            Comment


                              #15
                              Hello PaulMohn,

                              Thanks for your note.

                              This is Brandon responding on behalf of Chelsea who is out of the office at this time.

                              As seen in the help guide syntax, MAX() requires you to pass in a single Series<double> object and an int variable for the parameters.

                              MAX(ISeries<double> input, int period)[int barsAgo]

                              The reason cases 6, 7, and 8 work is because you are passing a single Series<double> object for the Series<double> parameter when calling MAX() instead of trying to subtract multiple series inside of the MAX() method.

                              You cannot subtract one series from another within the MAX() method. You would need to save the High[0] - Low[0] or Highs[1][0] - Lows[1][0] to a custom Series<double> variable and use that variable for the Series<double> input parameter when calling the MAX() method.

                              Note that when using Highs and Lows, you would need to pass a barsSeriesIndex and barsAgo value. For example, Highs[1][0] instead of Highs[1]. See the syntax below from the Highs and Lows help guide pages.

                              Highs[int barSeriesIndex][int barsAgo]

                              Lows[int barSeriesIndex][int barsAgo]


                              For example, you could create a custom Series<double> variable called something like 'mySeriesDouble', assign a value to that Series<double> variable such as High[0]-Low[0] or Highs[1][0] - Lows[1][0], then use mySeriesDouble for the Series<double> input when calling the MAX() method.

                              Note that you should also be ensuring that enough bars have process for all added series being used in your script. A CurrentBars check could be used.

                              "So if I understand right for it to work it simply needs added private Series<double> declarations and initialization, and an added [0] to the variable.
                              Why? What does the added zero means?"


                              The [0] refers the to barsAgo index when calling your custom Series<double> variable. When printing myDoubleSeries, you are printing information about the custom Series<double>. By adding a barsAgo index, myDoubleSeries[0], you are accessing the value of the current bar for that custom series. If you were to want to refer to the previous bar's value, you would use myDoubleSeries[1].

                              See the help guide documentation below.
                              Series<T>: https://ninjatrader.com/support/help...t8/seriest.htm
                              MAX(): https://ninjatrader.com/support/help...aximum_max.htm
                              Highs: https://ninjatrader.com/support/help.../nt8/highs.htm
                              Lows: https://ninjatrader.com/support/helpGuides/nt8/lows.htm
                              CurrentBars: https://ninjatrader.com/support/help...urrentbars.htm

                              Let us know if we may assist further.
                              Last edited by NinjaTrader_BrandonH; 02-25-2022, 10:54 AM.
                              <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              581 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              336 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              103 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              554 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              552 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X