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

Clarification on MaximumBarsLookBack

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

    Clarification on MaximumBarsLookBack

    myDoubleSeries = new Series<double>(this, MaximumBarsLookBack.Infinite);

    I want to clarify use of the above setting to Infinite

    I have some indicators that do not specify infinite and thus set to default 256.

    The indicator draws some lines on certain bars using the AddPlot and processes the data in onbarupdate.

    If i scroll back on the chart - is the limitation to do with referencing values beyond 256 in the series - so from current bar i can only look back 256?
    If doesnt have anything to do with rendering or how many plot values are stored?

    I am trying to determine an issue i have - i am getting error message in log :
    Chart rendering to a software bitmap failed. There is likely a problem with a chart object's render method. D2D error = 'HRESULT: [0x88990001], Module: [SharpDX.Direct2D1], ApiCode: [D2DERR_WRONG_STATE/WrongState], Message: The object was not in the correct state to process the method. '

    It is not pointing or referencing any specific indicator.

    It happens when i scroll the chart back along the x axis or with the mouse roller .... i get so far and it freezes ... the log message doesnt show until i close ninja and open
    there is nothing in the trace file

    So i am trying to eliminate if the issue is connected to the maximumbarslookback setting and the rendering of those plots

    i have another indicator that renders but his has not triggered any issues for long long time - what is the bitmap failed pointing to ?

    If the chart is scrolled back into history bars does this change the state in anyway in an indicator that is processing the bars to render in onrender?

    thanks

    #2
    Hi explorer101, thanks for your post.

    It is correct that if your Maxlookbackperiod is set to 256 the series will only be able to reach back 256 bars.

    This would not have anything to do with the MaxLookback period. Since the error is coming from DirectX, we won't be able to set any breakpoints, so you should place Print statements in OnRender systematically to find out what the last line of code in OnRender is being called before the crash.
    Chris L.NinjaTrader Customer Service

    Comment


      #3
      I started chart from scratch and not using any chart templates adding one indicator at a time.
      The main one with custom bar rendering i put in statements and chart state is fine and scrolling back and forth had no issue - slow and fast.
      SO i added each of the other indicators one at a time and still couldnt reproduce in new chart and fresh workspace.

      For now it seems fine and went over and over the render code and sharpdx code which has not been an issue.

      What concerns me still with ninja templates and workspaces is if there is an issue and how it can affect templates and workspaces going forward - either intra session or the next day and having no way to know or prove this. There are just some things in ninja that happen that cannot be reproduced and workspaces have always been a source of issue and the structure has not changed much from the past.

      I will keep eye on this but for now is fine - its seems even with try catch statements nothing meaningful gets output for these sharpdx errors - nothing to the log of trace file and one only sees the log on restarting ninjatrader. Even if this is debugged in visual studio will nothing show for this ?

      The fact that sharpdx was a major issue in earlier versions ninja 8 even after the beta - strikes me that i wouldnt be surprised there are still things lurking in the platform with regard to rendering.
      It wasnt clear to me what changed when the team had to do an overhaul of the rendering and sharpdx library.

      From this i see an issue which i dont see really how i can reproduce for you guys easily.

      Comment


        #4
        Hello explorer101,

        I agree with chris that we should expect the script to disable if it hits an error and adding prints in OnRender could point to the last lines that will be reached before the script fails. This can then point to the specific rendering routines which would need to be further looked into. Typically this involves resources that are not disposed properly (Created and disposed in each OnRender pass or disposed and re-created in OnRenderTargetChanged)

        Workspaces and templates would bring in issues if there are faulty components included, or if the file is damaged, it could add a NinjaScript with different/invalid parameters. The DirectX errors would still be from rendering on the chart. In the past, rebuilding the workspace temporarily worked around chart rendering issues in the platform where specific circumstance saved in a workspace would bring up rendering issues. We have not seen reports like this for some time now, but if you are able to encounter DirectX errors without using custom indicators that would have their own custom rendering, we would be interested in receiving a workspace or template that can help to reproduce that issue.

        My Ichimoku Cloud conversion works with Series objects in OnRender and I haven't experienced issues there, so you may find it helpful when working with your own rendering code. I have also attached another example script which may help.

        This indicator was ported from the Ichimoku Cloud indicator for NinjaTrader 7. The Cloud&#8217;s points are constructed identically to the NinjaTrader 7 indicator, however the points are then used to construct new SharpDX PathGeometry Figures. 3/24/2021: Modified the Adjust Chart Margins feature so users are prompted when the indicator wants to change the Chart&#8217;s Right [&#8230;]


        The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.

        ​​​​​​​Please let me know if there is anything else I can do to help.
        Attached Files
        JimNinjaTrader Customer Service

        Comment


          #5
          thanks jim appreciate the reply

          i looked at your example and checked all the brushes in own code and the dispose,

          Is there any harm in checking to free brushes in both onrender at the end and in onrendertargetchanged.

          Most of brushes are defined as indicator parameters System.Windows.Media.Brush and then used in onrender ... _mybrush.ToDxBrush(RenderTarget);
          And also use Stroke in parameters which are used for some items - again works fine

          and this works well - i am not using plots or brushes set in the OnStateChange -

          The help documentation states :

          Tips:

          1.If you are exclusively using resources in OnRender() (e.g., not passing values from OnStateChange() or other events) you only need to create and dispose of the resource in OnRender(). The OnRenderTargetChanged() concepts illustrated below would not need to be applied.


          ...............

          And so there is no need to dispose in OnRenderTargetChanged() - all resources were disposed of in onrender.
          As a catch all i have still been checking any resources in onrendertargetchanged() ie if not null then dispose() and this again did not have any adverse effect.

          Is there any way onrendertargetChanged() could be called whilst currently in onrender() eg if scrolling back or resizing?

          I checked again and loaded the indicator and fast scrolling and resizing and there is no issue.

          The issue seems to arise when i mix this indicator with another that ONLY uses Plots in onbarupdate ie to draw some lines between bars.
          Again initially as i stated above i created a new workspace and this worked fine for sometime.

          The main indicator with alot of custom rendering works perfectly loaded and running.

          Is there any possibility of contention or issue in rendering when multiple indicators are loaded some using custom rendering and others using plots in onbarupdate?

          At least i have localised to this process - given all your testing is on standard ninja indicators and the one you shared could you try adding a few indicators
          to your ichimoku perhaps - that draw lines eg ZigZag and another that draws on the price panel - then fast scroll back and forth and resize with say 15 days data
          and see how that functions.

          I ask as this seems to be the area where something happens.

          Im confident all the disposing is happening correctly and have checked and rechecked - as i appreciate coding errors do arise.

          so this is where i am at any input appreciated

          thanks

          Comment


            #6
            Hello explorer101,

            I have done some extensive testing with this script and have not found any rendering issues.

            I wouldn't recommend mixing disposal in OnRenderTargetChange and OnRender and would recommend using one or the other. (OnRenderTargetChange allows for better performance since disposal and recreation is not happening with every OnRender pass.) If the RenderTarget changes, it will be updated before OnRender is called.

            I may then suggest creating a test script that performs the same rendering routines you are, but in a more simplified version that tests the SharpDX rendering code only. If we can get the issue to be reproduced with a script like this, we could review the code and provide further input. I understand that it is not an always reproducible issue, but anyway we can get closer will help so we could give sound advice. If you have multiple SharpDX Draw commands, it may also help to separate these in other test scripts and try to reproduce with the each Draw separated.

            Disconnecting and reconnection will get other threads involved, which could help expose an issue that comes up from timing. In a previous script I have tested having the indicator applied to multiple charts (about 6,) disconnecting, reconnecting, and then aggressively clicking on the chart toolbar to force RenderTarget changes, and aggressively clicking and dragging on the chart to get the issue reproduced. I ended up having to control more SharpDX resources in OnRenderTargetChanged in that context. Thread is linked below for reference.



            I really would not be able to provide additional insight unless we have some simplified code to look at that reproduces the issue and some steps that we can take (whether it takes a number of attempts or not.)

            If you can break it down any further so we can have a look, we'll be happy to do so.
            JimNinjaTrader Customer Service

            Comment


              #7
              So i reworked the dispose - moving most to onrendertargetchanged - and the brush resets - except for 4 which are dependent on other factors.
              I created fresh charts and so far all seems smoother - not sure but perhaps the sequence of disposing and checking and brush setting in onrender for every pass was too inefficient in some instances triggering these directx errors - so thanks for guidance - i also removed a few setZorder calls i had in other indicators called in onstatechange but dont think that was related.
              So even though i wasnt setting brushes in onstatechange - the onrendertargetchanged is the better efficient location - and updates only when chart resizing scaling etc requires rendertarget to be updated.
              thanks

              Comment


                #8
                Using the OnRenderTargetChanged to free brushes makes a lot of sense. I didn't know it existed and I've been creating and freeing these (and other IDisposables ) in the OnRender itself.
                I'm going to re-write to use OnRenderTargetChanged.
                But what about the final destruction? Shouldn't the resources also be freed ( and not re-allocated this time ) in State == State.Terminated ??

                Comment


                  #9
                  Hello Brillo,

                  Thanks for your message.

                  OnRenderTargetChanged will be processed when RenderTarget is null after State.Terminated at the end of the script's life, so it would not be necessary to dispose in State.Terminated as we would check if the RenderTarget is not null before recreating the SharpDX resource.

                  Let us know if there is anything else we can do to help.
                  JimNinjaTrader Customer Service

                  Comment


                    #10
                    Does this mean we should check for RenderTarget == null inside OnRenderTargetChanged?

                    Comment


                      #11
                      Hello Brillo,

                      Yes. RenderTarget should be checked for null in OnRenderTargetChanged and this allows the resources to be disposed properly upon termination of the script.

                      Your disposal and recreation code can look similar to the following:

                      Code:
                      public override void OnRenderTargetChanged()
                      {
                          if (MyDxBrush != null)
                              MyDxBrush.Dispose();
                      
                          if (RenderTarget != null)
                              MyDxBrushh = MyMediaBrush.ToDxBrush(RenderTarget);                    
                      }
                      We look forward to assisting.
                      JimNinjaTrader Customer Service

                      Comment


                        #12
                        Okay.
                        Is the "identity" of a Windows.Media.Brush member of a script object consistent throughout the lifetime script? I know the dxBrushes are not but what about the Media.Brush from which the dxBrush is created? I'm using the media brush as the index to lookup the dxbrush like this:

                        Code:
                                Dictionary<Brush,SharpDX.Direct2D1.Brush> listDxBrushes = new Dictionary<Brush,SharpDX.Direct2D1.Brush>();
                                public override void OnRenderTargetChanged()
                                {
                                    base.OnRenderTargetChanged();
                                    foreach (SharpDX.Direct2D1.Brush dxBrushInList in listDxBrushes.Values)
                                    {
                                        if (dxBrushInList != null && dxBrushInList.IsDisposed == false)
                                            dxBrushInList.Dispose();
                                    }
                        
                                    listDxBrushes.Clear();
                        
                                    if (RenderTarget == null)
                                        return;
                        
                                    SharpDX.Direct2D1.Brush dxBrush = Plots[1].Brush.ToDxBrush(RenderTarget);
                                    listDxBrushes.Add(Plots[1].Brush, dxBrush);
                        
                                    dxBrush = BrushBuy.ToDxBrush(RenderTarget);
                                    listDxBrushes.Add(BrushBuy, dxBrush);
                                }
                        
                                protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                                {
                                    base.OnRender(chartControl, chartScale);  
                        
                        [B]            // success of this lookup depends on the Plots[1].Brush to be the same as it was in OnRenderTargetChanged[/B]
                        
                        [B]           SharpDX.Direct2D1.Brush dxBrushInList = listDxBrushes[Plots[1].Brush];[/B]
                        
                                   // use the dxBrushInList. don't dispose 
                                 }

                        Comment


                          #13
                          Hello Brillo,

                          I may suggest converting the brush to a string to preserve identity and use the string as the key in your dictionary as opposed to the Brush itself.

                          I addressed an issue in my HeikenAshiSmoothed conversion not too long ago where the Brush was being checked for equality to Brushes.Transparent, but the if we reloaded the script or loaded with a template, my user defined brush did not match Brushes.Transparent. Changing the code so the Brush was converted to a string gave a good way to identify the Brush and compare it with Brushes.Transparent. I would therefore make the recommendation above.

                          HeikenAshiSmoothed also gives some direction for how you can manage DX brushes in a dictionary.

                          https://ninjatraderecosystem.com/use...ashi-smoothed/

                          The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.

                          We look forward to assisting.
                          JimNinjaTrader Customer Service

                          Comment


                            #14
                            Originally posted by NinjaTrader_Jim View Post
                            ..
                            the Brush was being checked for equality to Brushes.Transparent, but the if we reloaded the script or loaded with a template, my user defined brush did not match Brushes.Transparent. Changing the code so the Brush was converted to a string gave a good way to identify the Brush and compare it with Brushes.Transparent.

                            I may suggest converting the brush to a string to preserve identity and use the string as the key in your dictionary as opposed to the Brush itself.
                            I'm glad I asked!
                            Thanks Jim

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by r68cervera, Today, 05:29 AM
                            0 responses
                            2 views
                            0 likes
                            Last Post r68cervera  
                            Started by geddyisodin, Today, 05:20 AM
                            0 responses
                            3 views
                            0 likes
                            Last Post geddyisodin  
                            Started by JonesJoker, 04-22-2024, 12:23 PM
                            6 responses
                            35 views
                            0 likes
                            Last Post JonesJoker  
                            Started by GussJ, 03-04-2020, 03:11 PM
                            12 responses
                            3,239 views
                            0 likes
                            Last Post Leafcutter  
                            Started by AveryFlynn, Today, 04:57 AM
                            0 responses
                            6 views
                            0 likes
                            Last Post AveryFlynn  
                            Working...
                            X