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

How to convert a NT7 DataSeries[] array to NT8 ?

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

    How to convert a NT7 DataSeries[] array to NT8 ?

    How to convert a NT7 DataSeries[] array to NT8 ?

    The attached strategy example includes a simplified snip of NT7 code capable of helping me manage the complexities of combining my strategies into one per instrument. A re-write would be an extensive amount of work.


    I have not yet found a solution to convert the included DataSeries arrays. I was tempted to replace them with 'Dictionaries of Arrays' but hen the data will have lost it's linkage to the Dataseries used to create them.


    I am asking for help on how to replicate this NT7 example of DataSeries 2D array of arrays, DataSeries[] using a bar-aligned Series<T> solution in NT8?


    I replaced the declaration of 'DataSeries[]' with 'Series<double>[]', seems to compile fine

    Code:
    
    // data series creation in NT7
    private DataSeries[] entryMarketValueByOrder;
    
    // replacement data series creation in NT8 - replaced 'DataSeries[]' with 'Series<double>[]', seems to complie fine
    private Series<double>[] entryMarketValueByOrder;


    Key question #1 -- What is the correct syntax for the 'New' statement in OnStateChange() to create the ISeries<T> array?

    Code:
    
    /// Key question #1 - [B]What is the correct syntax within OnStateChange() to create the ISeries<T> array?[/B]
    /// The following statement produces a complie error "Method name expected" code CS0149
    /// Testing alternative designs and a search of NT and external resources failed to surface solutions
    
    orderStopLoss = new Series<double>[500](this, MaximumBarsLookBack.Infinite);



    Key question #2 -- What is the correct syntax to set values within the ISeries<T> array?

    Code:
    
    /// Key question #2 - What is the correct syntax to set values within the ISeries<T> array?
    
    
    // NT7 syntax >   positionStopLossByOrder[positionNumber] = (DataSeries)entryMarketValueByOrder;
    
    
    // Syntax proposed for NT8  >  positionStopLossByOrder[positionNumber] = (Series<double>)entryMarketValueByOrder;
    
    
    
    
    
    // Example of the NT7 DataSeries[] in use in the lines just below
    
    entryMarketValueByOrder[m_pos][barOffset[planNumber]];.
    
    positionStopLossByOrder = entryMarketValueByPlan[positionNumber][barOffset[planNumber]] + ticksOffset[planNumber] * TickSize;
    
    
    //
    The example strategy code does not compile. I did not see how to export it as a Zip so attaching as a *.cs file.



    Key question #3 -- Is there a 'better, faster, cheaper, more reliable, ... recommended alternative solution?


    Thanks for your help!

    HedgePlay
    Attached Files
    Last edited by hedgeplay; 10-14-2020, 06:57 PM.

    #2
    Originally posted by hedgeplay View Post
    Key question #1 -- What is the correct syntax for the 'New' statement in OnStateChange() to create the ISeries<T> array?

    Code:
    orderStopLoss = new Series<double>[500](this, MaximumBarsLookBack.Infinite);
    // This code will declare an array of Series<double> elements
    private Series<double>[] orderStopLoss;

    // This code will allocate an array of 500 references to Series<double> and
    // assign the entire array reference to orderStopLoss
    orderStopLoss = new Series<double>[500];

    Originally posted by hedgeplay View Post
    Key question #2 -- What is the correct syntax to set values within the ISeries<T> array?
    // This code will allocate a Series<double> and assign the Series<double> reference
    // to the nth element within the orderStopLoss array
    orderStopLoss[n] = new Series<double>(this, MaximumBarsLookBack.Infinite);

    // This code will store a double value into the 0th index of the Series<double>
    // reference stored at the nth index in the array orderStopLoss
    orderStopLoss[n][0] = Close[0];

    All code written off the top of my head.

    Comment


      #3

      Thanks so much David!


      I will give those a go.

      Comment


        #4
        David's post above is a great help!

        A few follow-up questions David, NT team or others. .

        The shorter constructor David posted above seems to work well:
        E.g. orderStopLoss = new Series<double> [500];




        Hmmmm. What did I just build?

        I assume this shorter constructor matched a shorter overload of the constructor most often published for use to create a Series object.
        E.g. myDoubleSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);



        I further assume this shorter constructor normally automatically applies the default values, see the quote at the bottom.
        E.g. (this, MaximumBarsLookBack.TwoHundredFiftySix)



        Cool. Given that I created the Series with 500 values ( = new Series<double> [500]; ) where does that leave me with regards to the defaults?

        Was the Series array built with any advantages of bindings implied by the normal default of 'this'?

        Was the Series array built with a MaximumBarsLookBack value of 256, .Infinite or something else?

        Thanks!

        ISeries<T> https://ninjatrader.com/support/help...ddatapoint.htm

        Note: By default NinjaTrader limits the number of values stored for Series<T> objects to 256 from the current bar being processed. This drastically improves memory performance by not holding onto old values that are generally not needed. Should you need more values than the last 256 please be sure to create the Series<T> object so that it stores all values instead through the use of the MaximumBarsLookBack property.

        .
        Last edited by hedgeplay; 10-14-2020, 08:59 PM.

        Comment


          #5
          Originally posted by hedgeplay View Post
          The shorter constructor David posted above seems to work well:
          E.g. orderStopLoss = new Series<double> [500];

          Hmmmm. What did I just build?
          Well, that code creates an array that holds 500 elements, and
          each element in the array is a reference to a Series<double>.

          Originally posted by hedgeplay View Post
          I assume this shorter constructor matched a shorter overload of the constructor most often published for use to create a Series object.
          E.g. myDoubleSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);
          Yes, the above code creates a single Series<double> ... but if you want an
          array of Series<double>, that is not the same thing as a single Series<double>

          The code in my prior post is not a shorter overload -- it is an array of Series<double>.

          Ergo, your assumption is incorrect.
          The shorter construct is creating an array. That's it.

          The 500 elements of the array, where each element is its own Series<double>,
          is different code.

          Creating the array is not the same thing as creating the elements in the array.
          You need code to create the array of Series<double>[500] -- execute this code once.
          You need code to create the Series<double> elements -- execute this code 500 times.
          Different code, different purposes.

          Originally posted by hedgeplay View Post
          I further assume this shorter constructor normally automatically applies the default values, see the quote at the bottom.
          E.g. (this, MaximumBarsLookBack.TwoHundredFiftySix)
          Incorrect.
          But I think you're more confused than wrong.

          Originally posted by hedgeplay View Post
          Cool. Given that I created the Series with 500 values ( = new Series<double> [500]; ) where does that leave me with regards to the defaults?
          I dunno, are you wanting an array of 500 elements, where each element in the
          array is a completely separate Series<double>?

          Or, are you wanting just one Series<double> that has 500 elements?

          If you want the latter, realize that's not possible -- you don't allocate or pre-specify
          the number of elements for a Series<double> -- that's not how they work.

          Be very careful, you must understand this:
          You do not pre-allocate elements in a Series like you do with an array.

          The values,
          MaximumBarsLookBack.TwoHundredFiftySix
          MaximumBarsLookBack.Infinite

          are actually 'maximum growth factors', and tell NinjaScript how big the Series can
          become -- new elements are only added to the Series when a bar closes. After
          256 bars, the 257th bar means the oldest element in the Series must be dropped,
          but this is skipped if you specify 'Infinite'.

          Originally posted by hedgeplay View Post
          Was the Series array built with any advantages of bindings implied by the normal default of 'this'?
          None whatsoever.

          You saw the code where I defined a single Series<double> and assigned it to
          the nth element in the array, right? Well, I meant 'n' to be generic. You'd have to
          allocate 499 additional data series to fill in the other elements of the array -- and
          you'd specify 'this' to each of those -- no shortcuts involved.

          Originally posted by hedgeplay View Post
          Was the Series array built with a MaximumBarsLookBack value of 256, .Infinite or something else?
          You may be confusing an Array and a Series.

          An 'Array' is not the same thing as a 'Series' -- even though their indexing schemes look
          the same (as far as how you type them), they do not mean the same thing.

          Let start with the obvious:
          MaximumBarsLookBack has absolutely nothing to do with Arrays.

          An Array is a C# thing, it has a set number of elements that you specify. It does not
          expand.

          A Series is a NinjaScript thing, it starts out empty. As new bars are added to the chart, new
          elements are added to each Series you've created, up to a maximum of 256, or unlimited if
          set to 'Infinite'. The MaximumBarsLookBack is a feature of NinjaScript, it only applies to a
          Series, never to an array.

          Remember, you (the programmer) are extremely limited in how you specify the maximum
          number of elements that a Series can hold -- you have two choices: 256 or Infinite -- that's it.
          The designers of NinjaScript created this restriction on purpose.

          Elements are added to the Series automatically by NinjaScript -- a new element is added
          to every Series you've defined each time a bar closes, this is done automatically for you
          just before OnBarUpdate is called.

          Does this help?
          Last edited by bltdavid; 10-14-2020, 09:58 PM.

          Comment


            #6
            Sorry, I never looked at your attached file of code.

            Perhaps I am the one confused.

            Ask all the questions you want -- I'll help you to understand 'Series' like an expert.

            Comment


              #7
              Does this help?
              Yes it does Thank you.

              I agree, I am probably a little loose with the terms Series and Array. I normally think of a run-of-the-mill NT Series<double> as a one dimensional classic time series array, or bar series array with the additional properties NT has added to keep it in sync with the Bars, use with the NT platforms' ISeries,T> interface, etc.

              Also, I have zero history with NT7's DataSeries objects and so am not exactly clear on functionally how they differ from NT8's Series<double>.



              There a number of the DataSeries[] constructs in this app deployed for a number of uses.

              If there was not a desire to keep as much of data series synced with NT8's bar by bar operations my go to solution for managing this data with these type of relationships and frequency would be:

              1) build a struct with a data class hosting the data elements in each final cell in the array

              2) Then Bar by Bar:
              2a) load those class data elements
              2b) stuff the class as a string into a List<T> <int, string>
              2c) stuff the List<T> as an object into a Dictionary <Int, object> using for the Int key either each bar number of a parse of DataTime.Now.Ticks

              But by moving to Dictionaries you have lost so much from exiting the NT8 synchronized environment.


              Think of an example: byBarByPositionEntryOrderPrice[ x ][ y ]

              I have been thinking that with a strong bias to keep the data functioning in the NT synchronized ecosystem the highest priority is to ensure the first " = new", the first constructor builds the primary index, the [ x ] in the example above, as a full and true member of the NT data ecosystem.

              So I was pursuing a path like the command below but have not yet found an overload or approach that works.
              byBarByPositionEntryOrderPrice = new Series<double>[500].(this, MaximumBarsLookBack.Infinite);


              If the shorter constructor you posted does in fact stay synchronized to the Bars that could be the hot ticket.
              orderStopLoss = new Series<double> [500];






              Ask all the questions you want -- I'll help you to understand 'Series' like an expert.
              Cool!

              I think the simple, pragmatic, summary drive-to-closure question is, based on what you posted in your first response do we now have the ability to replace the highlighted DataSeries[] functionality in the first post text and attachment, in simple form just below?.


              // data series creation in NT7
              private DataSeries[] entryMarketValueByOrder;
              private DataSeries[] positionStopLossByOrder;

              // NT7 Bar-by-Bar execution syntax using the DataSeries[]
              positionStopLossByOrder [positionNumber ] = (DataSeries)entryMarketValueByOrder;
              positionStopLossByOrder = entryMarketValueByPlan[ positionNumber ][ barOffset[planNumber ]] + ticksOffset[ planNumber ] * TickSize;
              Last edited by hedgeplay; 10-15-2020, 12:41 AM.

              Comment


                #8
                I've looked at your attachment in your original post.

                Could you please attach the original NT7 code that wish to convert?

                Comment


                  #9
                  Could you please attach the original NT7 code that wish to convert?
                  I cant. So I downloaded NT7 to build a functioning example to work from.

                  Code:
                  //
                  
                  
                  [Description("Sample demonstration of the creation and use of a DataSeries[] Array.")]
                  public class SampleNT7DataSeriesArrays : Strategy
                  {
                  private int positionNumber = 42;
                  private int[] positions;
                  
                  // Delcare common use of DataSeries
                  private DataSeries byBarNumberOfPositionsOpen;
                  
                  // Declare DataSeries as a 2D array
                  private DataSeries[] byBarByPositionValueAtRisk;
                  
                  protected override void Initialize()
                  {
                  
                  // Syncs a DataSeries object to the primary bar object
                  byBarNumberOfPositionsOpen = new DataSeries(this); // as expected compiles
                  
                  // byBarByPositionValueAtRisk = new DataSeries[100].(this); // does not compile, no constructor found that compiles
                  //
                  byBarByPositionValueAtRisk = new DataSeries[100]; /// compiles
                  }
                  
                  
                  //

                  What I found is that the class with the example using this constructor ( byBarByPositionValueAtRisk = new DataSeries[100].(this); ) does not compile.

                  It is extremely unlikely it 'used to work and now does not" and NT has not posted offering any clarifying paths forward. . So I am declaring this NT7 class "unfinished project work that had not yet successfully compiled," a Red Herring.


                  The classes that did compile use the DataSeries[] constructor you posted above that does not include .(this) The rest of the classes from the repository seemed to compile fine but I am going to execute some module by module functionality validation testing on NT7 before I spend any more time migration this code base to NT8.

                  It is impressive to see how you frequently generously reach out to help others work through issues.
                  Thanks so much for your help.

                  HedgePlay


                  Closing Note:

                  I will add a note for anyone who finds this thread while searching for solutions to similar problems.

                  I developed a hypothesis that because the .NET Array Class inherits from the ICollection and IList interfaces it might not be too much of a stretch to find a path to utilize the (this) keyword.

                  After spending a few hours today digging deep into the .NET source code for 'this' keyword and the DataSeries, Series and Array Classes I have to conclude I was wrong and my hypothesis fails. In the limited amount of time I could spend on this topic I only saw where
                  the Array class is still too much only the reference to the data object and not ever enough the object itself.
                  Last edited by hedgeplay; 10-15-2020, 07:11 PM.

                  Comment


                    #10
                    Originally posted by hedgeplay View Post
                    I can't.
                    Bummer!

                    Originally posted by hedgeplay View Post
                    It is impressive to see how you frequently generously reach out to help others work through issues.
                    Thanks so much for your help.
                    My pleasure!

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by AveryFlynn, Today, 04:57 AM
                    1 response
                    10 views
                    0 likes
                    Last Post NinjaTrader_Erick  
                    Started by Max238, Today, 01:28 AM
                    4 responses
                    37 views
                    0 likes
                    Last Post Max238
                    by Max238
                     
                    Started by r68cervera, Today, 05:29 AM
                    1 response
                    8 views
                    0 likes
                    Last Post NinjaTrader_ChelseaB  
                    Started by geddyisodin, Today, 05:20 AM
                    1 response
                    11 views
                    0 likes
                    Last Post NinjaTrader_Gaby  
                    Started by timko, Today, 06:45 AM
                    2 responses
                    14 views
                    0 likes
                    Last Post NinjaTrader_ChristopherJ  
                    Working...
                    X