Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Performance: Does NJ Cache Indicators you use in your indicator?

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

    Performance: Does NJ Cache Indicators you use in your indicator?

    If I call an indicator many times in my code eg:

    if ( (MACD(12,26,9)[2] < MACD(12,26,9)[1]) && (MACD(12,26,9)[1] > MACD(12,26,9)[0]) ) {
    dataMACDTr[
    1] = PEAK;


    Is Ninja caching its of values OR does it recalc the indicator each time I call it?
    Why?
    I'm wondering if it would be a better practice to rewrite this to create my own dataSeries, populate it once on each bar, then refer to its values. eg:

    private IntSeries dataMACD; // cached values

    protected override void OnBarUpdate()
    {
    dataMACD.Set(MACD(12,26,9)[0]);
    :
    :
    if ( (dataMACD[2] < dataMACD[1]) && (dataMACD[1] > dataMACD[0]) ) {
    dataMACDTr[
    1] = PEAK;


    Thanks

    #2
    David, you should not need to create a data series object just for this as the called instance of the indicator is cached automatically by NT (as long as the same paramter combo is used).

    Comment


      #3
      It's true that NT caches it, but from a clean programming standpoint I'd at least go with:

      Code:
        MACD macd = MACD(12,26,9);
      
        if(macd[1] > macd[0]) etc. etc. etc.
      ... so that you don't have all the redundant error-prone parameter typing, and because the cache lookup is fast but not free.

      Comment


        #4
        OK from the examples given I can see how to efficiently access the result of another indicator.

        protected override void OnBarUpdate()
        {
        if(CurrentBar < 50)
        return;

        SMA mySMA50 = SMA(50);

        // plot SMA
        MySMAPlot.Set(mySMA50[0]);

        //do something interesting with SMA
        if(mySMA50[0]>mySMA50[1]);
        }

        Is there an elegant way for me to convince the other indicator to handle it's own display?

        Comment


          #5
          Have you tested this?

          Originally posted by RichardTodd View Post
          It's true that NT caches it, but from a clean programming standpoint I'd at least go with:

          Code:
            MACD macd = MACD(12,26,9);
           
            if(macd[1] > macd[0]) etc. etc. etc.
          ... so that you don't have all the redundant error-prone parameter typing, and because the cache lookup is fast but not free.
          I do see where you are coming from, the code looks cleaner. But ...
          1. You can alleviate the parameter typing by using constants. eg:
          // Variables Section
          constint periodD = 7;
          constint periodK = 14;
          constint smooth = 3;


          // OnBarUpdate() Section
          if (Stochastics(periodD, periodK, smooth)[1] > Stochastics(periodD, periodK, smooth)[0]) {
          Plot2.Set(dataMA[
          0]);
          }
          else {
          Plot2.Set(dataSD[
          0]);
          }
          2. You assert that " cache lookup is fast but not free." Do you know this for a fact ie: Have you read the MSIL that the code generates to see what is really happening or is this more of a general comment?
          The way I interpreted Bernard's answer was that under the covers they create a DataSeries & store the results of the calculation then just get the value by indexing into it. So if I then create another DataSeries & do exactly the same thing, performance gain will be zero, but it costs me memory & CPU to create it. Possibly a perf impact as both dataseries (caches) will fight for space in the CPU's Level 1 memory cache.

          So my conclusion was to use C# consts & go with the code pattern outlined above.

          Please tell me if you think I've overlooked / misunderstood anything.
          Dave

          Comment


            #6
            Not sure I understand?

            I don't really understand your question. Is it how do I create a DataSeries OR how do I get a DataSeries to plot.
            Could you expand on what you are hoping to achieve?


            1. If you create a new DataSeries, you can't just tell it to "Go Plot yourself".

            To Create a new plot you need to :-
            a. Get it to serialize itself. Add this in region properties section.
            But change "FungHoPlot1" to the name you want to diaplay. Also ensure "Values[1]" numbers run consecutively (0,1,2 etc) & are in the same order as the Plots you've added.

            Code:
            [FONT=Calibri]       [Browsable(false)]        // this line prevents the data series from being displayed in the indicator properties dialog, do not remove[/FONT]
            [FONT=Calibri]        [XmlIgnore()]                // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove[/FONT]
            [FONT=Calibri]        public DataSeries[B][COLOR=blue] FungHoPlot1[/COLOR][/B][/FONT]
            [FONT=Calibri]        {[/FONT]
            [FONT=Calibri]            get { return Values[[B][COLOR=blue]1[/COLOR][/B]]; }[/FONT]
            [FONT=Calibri]        }[/FONT]
            [FONT=Calibri][/FONT]


            b. In the initialize section, create another Plot.

            Add(new Plot(Color.FromKnownColor(KnownColor.LightBlue), PlotStyle.Line, "FungHoPlot1"));

            c. In the OnBarUpdate section. Give it a value.
            FungHoPlot1.Set(dataMyDataSeries[0]);


            Was this your question or am I totally off track.

            Comment


              #7
              Originally posted by David Lean View Post
              I don't really understand your question. Is it how do I create a DataSeries OR how do I get a DataSeries to plot.
              Could you expand on what you are hoping to achieve?

              ...snip...

              Was this your question or am I totally off track.

              David:

              Thanks for your reply.
              You were not off track.
              I was probably not clear enough.

              I am trying to write an indicator that:
              a. initializes, displays and accesses the results of other indicators
              b. performs logic using the results of the other indicators
              c. displays the results of the logic

              My first pass at it is to implement (a) without wasting resources.
              It is structured like your FungHoPlot1 example and seems to be working.

              Code:
              // property defn
              [FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]public[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New] DataSeries SMA200D[/FONT]
              [FONT=Courier New]{[/FONT]
              [/FONT][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]get[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New] { [/FONT][/FONT][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]return[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New] Values[[/FONT][/FONT][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080]0[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New]]; }[/FONT]
              [FONT=Courier New]}[/FONT]
              [/FONT]
              [FONT=Courier New][FONT=Courier New][FONT=Verdana]// user parameter[/FONT][/FONT][/FONT]
              [FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]private[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]int[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New] nBars200Day = [/FONT][/FONT][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080]200[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New]; [/FONT][/FONT][FONT=Courier New][COLOR=#008000][FONT=Courier New][COLOR=#008000][FONT=Courier New][COLOR=#008000]// 40 on a weekly chart[/COLOR][/FONT]
              [/COLOR][/FONT][/COLOR][/FONT]
              // Initialize
              [FONT=Courier New][FONT=Courier New]Add([/FONT][/FONT][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]new[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New] Plot(Color.FromKnownColor(KnownColor.Black), PlotStyle.Line, [/FONT][/FONT][FONT=Courier New][COLOR=#800000][FONT=Courier New][COLOR=#800000][FONT=Courier New][COLOR=#800000]"SMA200D"[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New]));[/FONT]
              [/FONT]
               
              // OnBarUpdate
              [FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]if[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New]( CurrentBar < nBars200Day ) [/FONT]
              [/FONT][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff][FONT=Courier New][COLOR=#0000ff]return[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New];[/FONT]
              [FONT=Courier New]SMA200D.Set(SMA(nBars200Day)[[/FONT][/FONT][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080][FONT=Courier New][COLOR=#800080]0[/COLOR][/FONT][/COLOR][/FONT][/COLOR][/FONT][FONT=Courier New][FONT=Courier New]]);[/FONT]
              [/FONT]
              memory wasted?
              --------------------
              When I make the call SMA(nBars200Day)[0] for the first time I am assuming that an instance of SMA is initialized and cached somewhere.
              Has an SMA instance allocated a whole DataSeries for its Values(0)? If so I am assuming that my indicator is allocating a redundant DataSeries with my plot call. Am I doubling memory usage by wanting to display an SMA?

              If so is there a way to not waste memory while accessing and displaying another indicator from within an indicator?

              Instead of calling Add( Plot(...)...) I would like to call Add(SMA(200)) and have the right thing happen. But Add() doesn't show that as a signature.

              I can post the first pass of my indicator if that would be helpful.
              -Terry-

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
              0 responses
              579 views
              0 likes
              Last Post Geovanny Suaza  
              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
              0 responses
              334 views
              1 like
              Last Post Geovanny Suaza  
              Started by Mindset, 02-09-2026, 11:44 AM
              0 responses
              101 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
              551 views
              1 like
              Last Post RFrosty
              by RFrosty
               
              Working...
              X