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

OnRender Drawing Historical

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

    OnRender Drawing Historical

    Hello,

    My Indicator draws a rectangle around every 100 bars, when the counter resets, the box shifts to the new set of bars. I'm trying to plot historically OnRender... With regular drawing tools if we add +CurrentBar to the title it would repeat the drawing tool historically. How could this be done OnRender?
    My research has lead my to add something like:
    Code:
    for (int index = 0; index <= ChartBars.Count; index+=100)
    before my drawing new SharpDX.RectangleF but it's not plotting anything historically nor most recent, and it's giving me the following error:
    "Error on calling 'OnRender' method on bar 3529492:Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
    Does that mean that since cacheDictionary was cleared, it can no longer access that data? if so, how can I fix that?

    Here is the code I'm using OnBarUpdate:
    Code:
    if (CurrentBars[0] >= savedBar + 100)
                {
                    savedBar    = CurrentBars[0];
                    cacheDictionary.Clear();
                }
    My goal is to draw new object OnRender everytime cacheDictionary clears while maintaining historical drawings. Any advice?
    Last edited by KINGKODA; 12-27-2018, 01:19 AM.

    #2
    Hello KINGKODA,

    Thanks for your post.

    Before going too much further with what you are attempting, we should note some best practices and how we should be using SharpDX for custom rendering to avoid certain issues.

    When we are using OnRender, we want to focus on only rendering what is in visible space, which would be between ChartBars.FromIndex and ChartBars.ToIndex. We would do this instead of drawing everything created by the chart with each render pass. It would be be advised to loop through this range, and then using the bar indexes here, reference your Series objects with GetValueAt to get particular values for what is visible on the chart. You would then use these indexes and values with the ChartControl.GetXByBarIndex and ChartScale.GetYByValue to get coordinates for where you need to draw.

    Code:
    protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
    {
      ClearOutputWindow();
      // restricting this loop to only the ChartBars.From/ToIndex limits the loop to only what is visible on the chart
      for (int barIndex = ChartBars.FromIndex; ChartBars.FromIndex <= ChartBars.ToIndex; barIndex++)
      {
        Print("");
        Print(ChartControl.GetXByBarIndex(ChartBars, barIndex));
        Print(ChartScale.GetYByValue(Close.GetValueAt(barIndex)));
      }
    }
    The error received typically has to do with resource management for SharpDX rendering where say a SharpDX brush is created, the RenderTarget changes, and then the SharpDX brush is accessed again. This is because SharpDX brushes and several other SharpDX resources are device-dependent and are only valid for that particular RenderTarget. We don't have control over how the RenderTarget gets created, but we are given the OnRenderTargetChanged method to pick up on when the RenderTarget changes.

    Proper resource management to avoid these errors involves two possible approaches:

    1. Creating device-dependent resources at the beginning of OnRender() and disposing of the resources at the end of OnRender()
    2. Disposing and then recreating device-dependent resources within OnRenderTargetChanged

    The latter is much more performant and ultimately recommended over the former, but the former is still valid use.

    More information on best practices for SharpDX rendering are noted here - https://ninjatrader.com/support/help...arpDXResources

    OnRenderTargetChanged - https://ninjatrader.com/support/help...getchanged.htm

    My goal is to draw new object OnRender everytime cacheDictionary clears while maintaining historical drawings. Any advice?
    I'm not sure what your cacheDictionary involves, but for rendering rectangles that are based off some chart data I would recommend looping through ChartBars.FromIndex and ChartBars.ToIndex in OnRender, check if what you want to draw should be rendered, and then perform your SharpDX drawing as necessary. Your resources will then need to be handled based on the rules mentioned above. (From the perspective of rendering, we are simply looking at data on the chart and if we should render anything as opposed to differentiating historical and realtime data)

    Let me know if there is anything else I can do to help.
    JimNinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by f.saeidi, Today, 10:19 AM
    0 responses
    2 views
    0 likes
    Last Post f.saeidi  
    Started by kujista, Today, 06:23 AM
    4 responses
    14 views
    0 likes
    Last Post NinjaTrader_ChelseaB  
    Started by traderqz, Yesterday, 09:06 AM
    2 responses
    16 views
    0 likes
    Last Post traderqz  
    Started by traderqz, Today, 12:06 AM
    3 responses
    6 views
    0 likes
    Last Post NinjaTrader_Gaby  
    Started by RideMe, 04-07-2024, 04:54 PM
    5 responses
    28 views
    0 likes
    Last Post NinjaTrader_BrandonH  
    Working...
    X