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

Update on Property Getter is Slow

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

    Update on Property Getter is Slow

    Hi,

    I am trying to update a series of values prior to rendering. I am using Update() inside the getter for the series. It works fine in general but as the indicator runs on multiple charts, it sometimes lags significantly. is there a way to force update the series more quickly to prevent this lagging behaviour?

    #2
    Hello Zeos6,

    Thank you for the post.

    I wanted to see if you had a small sample of what you are currently trying to do that you can provide.

    The general use for Update() would not be suggested for rendering or any case where it is called over and over very quickly. This is most commonly reserved for specific single use cases. Generally, this would be for single calls to the indicator where it may need to be Updated before that call.

    An example would be the ZigZag indicator. Calling this indicator externally you can access its LowBar method which has Update() to make sure the values used in the method are updated at that time. Because LowBar is a custom method and not a Series this is needed. The indicator its self does not use LowBar or Update in the other parts of its syntax for rendering, it instead uses the values it collected from the series it has. This is going to likely be the solution for you as well or to avoid using Update and instead try to utilize the existing structures that do not require being Updated where you can.

    Depending on why you are using Update there may be a better more efficient solution. Can you provide more detail surrounding the specific reason you needed to use Update for this indicator?

    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Thank you for your reply Jesse.
      You are correct re the Update(). The series, however, is being shared across indicators so it is appropriate in the getter.

      I have stripped down the code. The code works fine but when running on multiple charts, it lags on a few charts. Your suggestions would be appreciated. Thank you.

      Code:
      private Series<Tuple<int, int>> MyWC;
      
      (State == State.DataLoaded)
      {
          MyWC = new Series<Tuple<int, int>>(this, MaximumBarsLookBack.Infinite);
      }
      
      protected override void OnBarUpdate()
      {
          Tuple<int, int> currentMyWCValue = FindMyWCValue(param1: referenceParam1Value);
      
          // Assign value to series
          MyWC[0] = currentMyWCValue;
      }
      
      On Render()
      protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
      {
          PaintMyWC(chartControl, chartScale);
      }
      
      private void PaintMYWC(ChartControl chartControl, ChartScale chartScale)
      {            
          // Save original antialias mode for the chart
          SharpDX.Direct2D1.AntialiasMode oldAntialiasMode    = RenderTarget.AntialiasMode;
          RenderTarget.AntialiasMode                = SharpDX.Direct2D1.AntialiasMode.Aliased;
      
          // Save original wcBrushDX opacity value
          float original_wcBrushDXOpacity = wcBrushDX.Opacity;
                      
          float tx = 0;
          float ty = 0;
                  
          SharpDX.RectangleF rect = new SharpDX.RectangleF();
          SharpDX.Vector2    vec1 = new SharpDX.Vector2();
          SharpDX.Vector2    vec2 = new SharpDX.Vector2();
      
          Action<int> paintWC = (barIndex) =>
          {
              GlyphTypeface gtf     = new GlyphTypeface();
              System.Windows.Media.Typeface tFace = new System.Windows.Media.Typeface(new System.Windows.Media.FontFamily(textFont.Family.ToString()), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
                      tFace.TryGetGlyphTypeface(out gtf);
                      
              // Create SharpDX format and layout based on specified 'textFont' font and "Font_Size' font size
              TextFormat tf = new TextFormat(new SharpDX.DirectWrite.Factory(), textFont.Family.ToString(), SharpDX.DirectWrite.FontWeight.Bold, SharpDX.DirectWrite.FontStyle.Normal, (float)textFont.Size);        
              tf.TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading;
      
              // Convert WC to string format
              string currentWC = MyWC.GetValueAt(barIndex).Item1.ToString();
      
              // Create layout for the WC text
              TextLayout tl = new TextLayout(Core.Globals.DirectWriteFactory, currentWC, tf, GetTextWidth(currentWC), tf.FontSize);
                      
              // Position text
              int positioningIndex = (Calculate == Calculate.OnBarClose) ? barIndex+1 : barIndex;
              float index    = (float)chartControl.GetXByBarIndex(ChartBars, positioningIndex);
                          
              tx = index + (GetTextWidth(currentWC)/5.0f);
      
              double price, textOffset;
              if (MyWC.GetValueAt(barIndex).Item2 < 0)
              {
                  price        = Bars.GetHigh(barIndex);
                  textOffset    = -0.75f * (TextSize * gtf.Baseline);
              }
              else
              {
                  price = Bars.GetLow(barIndex);
                  textOffset    = -0.75f * (TextSize * gtf.Baseline);
              }
      
              ty = (float)(chartScale.GetYByValue(price) + textOffset);
      
              vec1.X = tx;
              vec1.Y = ty;                
      
              RenderTarget.DrawTextLayout(vec1, tl, wcBrushDX);
                          
              // Dispose of textLayout
              tl.Dispose();
                              
              // Dispose of textFormat
              tf.Dispose();
                      
              // Dispose of fonts/type
              gtf        = null;
              tFace    = null;
          };
      
      if (condition 1 > 0)
          {
              // Paint the required WC
              paintWC(CurrentBar);
          }
          else
          {
              for(int i = ChartBars.FromIndex; i <= ChartBars.ToIndex; i++)
              {                
                  paintWC(i);
              }
          }
      
          // Reset opacity value
          wcBrushDX.Opacity = original_wcBrushDXOpacity;
                      
          // Reset AntialiasMode
          RenderTarget.AntialiasMode = oldAntialiasMode;
      }

      Comment


        #4
        Hello Zeos6,

        Unfortunately, this sample doesn't really help explain your question as this does not show the Update() use. I also can't run this to see what is happening. Do you have a sample that can compile and show the problem?

        What I can suggest for future samples would be to instead prepare a brand new script and only include the syntax to show the structure being used/problem to support your question. After making sure that shows the problem and can compile, you can then export that along with any other indicators it may call on. This is so our support/other forum members can test that case to understand the question completely.

        If you are sharing data between scripts but need to use Update(), the solution is very likely going to be to not use the approach that you are now. As noted Update is generally used for very specific use cases, storing data in a series and accessing it later is not usually one of those cases especially if you have a script with OnBarUpdate calling it.

        The standard sharing model in NinjaScript does not require the use of Update when you call on a hosted script so it may be that you have not included some syntax that would be required to share the data. I dont see you calling the indicator in your sample to have its OnBarUpdate called so that may be the problem.

        Being that the assumption is Update() is causing the slowness, I have attached a sample of exposing a Series<T> and calling it from another indicator without using Update(). I used Tuple<int, int> from your sample and can see the value being passed. Can you review my sample and see if we are on the same page here regarding what you are doing? If not, can you create a compilable/testable sample for me to further review?


        Please let me know if I may be of additional assistance.
        Attached Files
        JesseNinjaTrader Customer Service

        Comment


          #5
          Hi Jesse,

          Thank you for the reply. Perhaps I wasn't clear in my communication but:

          1. The Update() is not really an issue. It is working fine.

          2. What is, or seems to be, the issue is that my series is not updating its value before the value gets rendered.The indicator runs on multiple charts and whilst it works just fine on several charts, it lags on two of the charts. And yes, the settings are all the same for the indicator. So clearly there is a lag in terms of accessing the values. It might be the GetValueAt() function, or maybe the delegate is the issue here. Basically my question is: How can I force the series to update before it is rendered?

          Comment


            #6
            Hello Zeos6,

            Thank you for the reply.

            In this situation, I wouldnt have a suggestion to force an update as I do not know that is the correct solution here. This is likely due to some portion of the logic you are using but I would be unable to see that from what you have provided so far.

            If you feel this is related to a specific portion of code you have used, I would suggest you start with that and create a more simple test to confirm that. If this only lags on a few charts, and they are the same each time that might indicate the logic is at fault on those instruments. Otherwise, if it is random, that may be related to poor performance of something you are doing in the logic in general. This may require you to change the way you are doing that logic. These are items you can further isolate by further reducing and testing your code.

            If you can provide a specific sample that demonstrates the problem I would be happy to review that to help however I can.


            Please let me know if I may be of additional assistance.
            JesseNinjaTrader Customer Service

            Comment


              #7
              Thanks Jesse.

              This isn't really helpful. Of course I am not asking you to write code for me but I thought I was asking a relatively simple question. It appears to me that GetValueAt() for series is not performant when it comes to rendering because it doesn't update the series object in a timely manner.It seems that using TriggerCustomEvent() approach might be better as it forces synchronization and update.

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by sidlercom80, 10-28-2023, 08:49 AM
              166 responses
              2,233 views
              0 likes
              Last Post sidlercom80  
              Started by thread, Yesterday, 11:58 PM
              0 responses
              1 view
              0 likes
              Last Post thread
              by thread
               
              Started by jclose, Yesterday, 09:37 PM
              0 responses
              6 views
              0 likes
              Last Post jclose
              by jclose
               
              Started by WeyldFalcon, 08-07-2020, 06:13 AM
              10 responses
              1,414 views
              0 likes
              Last Post Traderontheroad  
              Started by firefoxforum12, Yesterday, 08:53 PM
              0 responses
              11 views
              0 likes
              Last Post firefoxforum12  
              Working...
              X