Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Adding Plots Dynamically

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

    Adding Plots Dynamically

    In NT7 I could easily add plots dynamically since Initialize() was also called on pressing OK or Apply. Unfortunately for me NT8 is much more "air tight" in this regard.
    The plots can now only be added during State.SetDefaults and pressing OK or Apply starts already from State.Configure where adding plots is illegal.
    I did few experiments and was hoping that SetState(State.SetDefaults) will bring me back to where I could set the plots. But this didn't execute OnStateChange and I am back to square one.
    This capability (to add plots depending on user selection in PropertyGrid) is crucial for my last few years of work to not get wasted. Adding them all would result in having 40+ plots fraction of which would be used (and many other complexities). So for me it is basically step down from existing functionality, though I understand my problem may not be so common.

    I have attached simplified indicator presenting the problem (after changing PlotsNumber and/or color components it should recreate the plots) and would appreciate some ideas and possible solution to the problem.
    Attached Files

    #2
    Hmm ... I see your point. We'll look into.

    Comment


      #3
      Originally posted by NinjaTrader_Dierk View Post
      Hmm ... I see your point. We'll look into.
      Thank you, much appreciated!

      Comment


        #4
        That will be changed with next beta (#8198): you then could add plots even in state .Configure.

        Thanks for reporting.

        Comment


          #5
          Originally posted by NinjaTrader_Dierk View Post
          That will be changed with next beta (#8198): you then could add plots even in state .Configure.

          Thanks for reporting.
          Excellent! This is really a huge deal for me.

          Just in case: I suppose AddLine will work from Configure as well?

          If possible, the user friendly addition would be to refresh PropertyGrid on Apply if there has been changes introduced in Configure state (such as Plots, colors in my example). This is minor issue in comparison to the change you are making so I could live without it, but would be nice.

          Also, whenever I work with dynamic plots I always implement in my code a dictionary which maps plot name to Values[x]:
          Code:
          public Dictionary<string, Series<T>> PlotMap
          this way I can easily request plot values by its name (crucial for dynamic plots) eg.
          Code:
          DynamicPlotsSMA(14,30).PlotMap["sma17"][0]
          I've found it to be extremely helpful so if you feel like implementing it yourself in the base class I wouldn't mind

          Thanks again.

          Comment


            #6
            It would accelerate the process of ironing out issues if you could post your requirements right away so we would not need to revisit similar issues again and again...

            1) on AddLine: the same logic change will be applied there. Thanks for reporting
            2) on PropertiesGrid: we will test the Apply logic
            3) there is no need for a dictionary since you always could find a plot by name like this
            Code:
            Plots.FirstOrDefault(p => name == "MyName")

            Comment


              #7
              Originally posted by NinjaTrader_Dierk View Post
              It would accelerate the process of ironing out issues if you could post your requirements right away so we would not need to revisit similar issues again and again...
              Point taken
              Originally posted by NinjaTrader_Dierk View Post
              1) on AddLine: the same logic change will be applied there. Thanks for reporting
              2) on PropertiesGrid: we will test the Apply logic
              3) there is no need for a dictionary since you always could find a plot by name like this
              Code:
              Plots.FirstOrDefault(p => name == "MyName")
              3: not really - this brings only Plot object which doesn't hold Values (Series<T>) and that's the point of the dictionary -> to map plot to its values

              Do you guys ever sleep?

              Comment


                #8
                on 3): pls check out .Plots and .Values. They match -> you can find the right series in .Values by findings the right index in .Plots. Linq might come in handy... using a dictionary does not yield performance gains for a 'small' number of items in the collection.

                The team works in different timezones...

                Comment


                  #9
                  Long time ago I did this with indexes but found it not estethically pleasing
                  Pure Linq would not be the most user friendly as IEnumerable doesn't have GetIndex natively implemented, so accessing values with pure Linq would be something like:
                  Code:
                  DynamicPlotsSMA(14,30).Values[Plots.Select((p, i) => new {Plot = p, Index = i}).Where(x => x.Plot.Name == "TestPlot").Select(x => x.Index)][0];
                  Fortunately there are Lists which have FindIndex so it gets simpler:
                  Code:
                  DynamicPlotsSMA(14,30).Values[Plots.ToList().FindIndex(p => p.Name == "TestPlot")][0];
                  Still not great but I liked your challenge so here is extension class that makes it simple:
                  Code:
                  namespace NinjaTrader.NinjaScript.Indicators
                  {
                      public static class PlotsExtension
                      {
                          public static int GetIndex(this IEnumerable<Plot> plots, string name)
                          {
                              return plots.ToList().FindIndex(p => p.Name == name);
                          }
                          public static Series<double> FindPlotValues(this Indicator ind, string name)
                          {
                              return ind.Values[ind.Plots.GetIndex(name)];
                          }
                      }
                  }
                  Now my code looks like this:
                  Code:
                  DynamicPlotsSMA(14,30).FindPlotValues("TestPlot")[0];
                  I'll have to check what is more performant but thanks for the challenge!

                  Comment


                    #10
                    Why not keeping things simple(have not tested though)?
                    Code:
                    double d = Values[Array.IndexOf(Plots, Plots.First(p => p.Name == "MyName"))][0];

                    Comment


                      #11
                      Originally posted by NinjaTrader_Dierk View Post
                      Why not keeping things simple(have not tested though)?
                      Code:
                      double d = Values[Array.IndexOf(Plots, Plots.First(p => p.Name == "MyName"))][0];
                      That will also work, interestingly ToArray() doesn't have IndexOf yet Array does.
                      Thanks.

                      Comment


                        #12
                        Originally posted by NinjaTrader_Dierk View Post
                        It would accelerate the process of ironing out issues if you could post your requirements right away so we would not need to revisit similar issues again and again...

                        1) on AddLine: the same logic change will be applied there. Thanks for reporting
                        2) on PropertiesGrid: we will test the Apply logic
                        3) there is no need for a dictionary since you always could find a plot by name like this
                        Code:
                        Plots.FirstOrDefault(p => name == "MyName")
                        Update:
                        on 2) Unfortunately not doable without significant under-the-hood changes which is why we will leave that.

                        Comment


                          #13
                          Originally posted by NinjaTrader_Dierk View Post
                          Update:
                          on 2) Unfortunately not doable without significant under-the-hood changes which is why we will leave that.
                          Thanks for the update- not a deal breaker - I will just keep clicking OK and reopen Indicators list

                          Comment


                            #14
                            adding Plots.Remove(Plot) and Plots.RemoveAll()

                            I have been successfully adding plots dynamically from Configure state for a while now.
                            There is only one caveat to the functionality - plots added in Configure state are never visible in the property grid. Since they are generated basing on other properties and Configure is executed only after pressing OK button it is understandable but I wanted to suggest a possible solution to make it possible to preview the plots in the property grid.
                            If Plots would have Remove method (ie. Plots.Remove(Plot) and Plots.RemoveAll() we could generate plots first in SetDefaults then in Configure remove all plots and generate them again (this time with changed settings). This would give us an option to eg. manually adjust generated plot details if desired.
                            So my question is - would it be possible to add these methods?

                            Comment


                              #15
                              Hello gregid,

                              Thank you for your post.

                              I will forward to development.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              657 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              373 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              109 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              574 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              579 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X