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

Custom ChartStyle: not using data to repaint bars. Caching?

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

    Custom ChartStyle: not using data to repaint bars. Caching?

    I have my own ChartStyle derived bar drawing style [MyChartStyle] that paints bars differently based on flags stored in an Series<int> [BarFlags] of my indicator [MyIndicator].

    And, I am again stumped and have read all the samples, docs and forum posts that I can find.

    * It seems that some kind of caching is going on in [MyChartStyle] because it appears to be using an old version of [BarFlags].

    * Is there some documentation for how bar series data is cached (if so) or when or if snapshots are taken and used for new Series<T> objects of an indicator?

    * Or is there a way to force NT to discard any cached objects once I update things? Yes, I added a call Update() in the getter for this series object.


    Some code:

    Code:
        public class vaCustomStyle : ChartStyle
            private MyIndicator cachedIndicator = null;
    
            public override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars chartBars)
                    MyIndicator myIndicator = GetMyIndicator(chartControl);
                    Series<int> barFlagsSeries = (myIndicator != null && myIndicator.BarFlags != null) ? myIndicator.BarFlags : null;
    
                    Print(string.Format("☰☰☰☰ Render B ars from {0} to {1}; {2} to {3}; flag count = {6}   ➽➽❰{4}❱  ⊢{5}⊣", chartBars.FromIndex, chartBars.ToIndex, bars.GetTime(chartBars.FromIndex), bars.GetTime(chartBars.ToIndex), chartBars != null && chartBars.Bars != null && chartBars.Bars.Instrument ! = null ? chartBars.Bars.Instrument.FullName : "<no  instrument>", myIndicator == null ? "☹" : myIndicator.DebugGuid, barFlagsSeries != null ? barFlagsSeries.Count.ToString() : "null"));
    
                    for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
                        int barFlags = barFlagsSeries  != null && barFlagsSeries.Count > 0 && idx < barFl agsSeries.Count && barFlagsSeries.IsValidDataPoint At(idx) ? barFlagsSeries.GetValueAt(idx) : 0;
    
    ....
    
            private MyIndicator GetMyIndicator(Chart Control chartControl)
            {
                try
                {
                    if (cachedIndicator== null)
                    {
                        if (chartControl != null && chartControl.Indicators != null)
                        {
                            for (int i = 0; i < chartControl.Indicators.Count; i++)
                            {
                                if (chartControl.Indicators[i] is NinjaTrader.NinjaScript.Indicators.MyIndicator)
                                {
                                    cachedIndicator = chartControl.Indicators[i] as NinjaTrader.NinjaScript.Indicators.MyIndicator;
                                    return cachedIndicator;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    cachedIndicator = null;
                }
                return cachedIndicator;
            }
    *** THE MOST INTERESTING thing with my repro is that if I change the bar style to some other bar style and change it back then everything paints correctly but changing the bar time frame does not fix the painting as it uses the old series. << this is why I suspected some caching.

    And here is some output.

    ☰☰☰☰ Render Bars from 723 to 827; 9/25/2020 8:20:00 AM to 9/25/2020 5:00:00 PM ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰ painting HIGH volume candle @ 747 [9/25/2020 10:20:00 AM]

    MANUALLY CHANGE TO A DIFFERENT BAR STYLE AND BACK...

    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Configure)
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Configure)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Active)
    ☰☰☰☰ Render Bars from 723 to 827; 9/25/2020 8:20:00 AM to 9/25/2020 5:00:00 PM ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰ painting HIGH volume candle @ 723 [9/25/2020 8:20:00 AM]
    ☰ painting HIGH volume candle @ 724 [9/25/2020 8:25:00 AM]
    ☰ painting HIGH volume candle @ 726 [9/25/2020 8:35:00 AM]
    ☰ painting HIGH volume candle @ 728 [9/25/2020 8:45:00 AM]
    ☰ painting HIGH volume candle @ 732 [9/25/2020 9:05:00 AM]
    ☰ painting HIGH volume candle @ 733 [9/25/2020 9:10:00 AM]
    ☰ painting HIGH volume candle @ 738 [9/25/2020 9:35:00 AM]
    ☰ painting HIGH volume candle @ 740 [9/25/2020 9:45:00 AM]
    ☰ painting HIGH volume candle @ 744 [9/25/2020 10:05:00 AM]
    ☰ painting HIGH volume candle @ 745 [9/25/2020 10:10:00 AM]
    ☰ painting HIGH volume candle @ 746 [9/25/2020 10:15:00 AM]
    ☰ painting HIGH volume candle @ 752 [9/25/2020 10:45:00 AM]
    ...

    A totally different set of data!

    --------

    So, I added a call to Reset() in State.DataLoaded

    Code:
        public partial class MyIndicator : Indicators
    
            private Series<int> barFlags;
    
            protected override void OnStateChange()
    
                else if (State == State.Configure)
                    barFlags = new Series<int>(this, MaximumBarsLookBack.Infinite);
    
                else if (State == State.DataLoaded)
                    barFlags.Reset();
    
            protected override void OnBarUpdate()
                    barFlags[0] = some calculated value;
    
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<int> BarFlags
            {
                get
                {
                    Update();
                    return barFlags;
                }
            }
    And now I always see the count of this object as 0 until I switch to another style and switch back.

    ☰☰☰☰ Render Bars from 4033 to 4137; 9/25/2020 3:16:00 PM to 9/25/2020 5:00:00 PM; flag count = 0 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Configure)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Active)
    ☰☰☰☰ Render Bars from 4033 to 4137; 9/25/2020 3:16:00 PM to 9/25/2020 5:00:00 PM; flag count = 4138 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣

    Another example with 5 minute bars...

    ☰☰☰☰ Render Bars from 723 to 827; 9/25/2020 8:20:00 AM to 9/25/2020 5:00:00 PM; flag count = 0 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(SetDefaults)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Configure)
    ☰☰☰☰ MyCustomStyle.OnStateChange(Active)
    ☰☰☰☰ Render Bars from 723 to 827; 9/25/2020 8:20:00 AM to 9/25/2020 5:00:00 PM; flag count = 828 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰ painting HIGH volume candle @ 723 [9/25/2020 8:20:00 AM]
    ☰ painting HIGH volume candle @ 724 [9/25/2020 8:25:00 AM]

    ** I can manually refresh the load with F5 and it paints just the same. Scrolling around, renders the same.

    Here is the log when I refresh with F5.

    ☰☰☰☰ Render Bars from 4033 to 4137; 9/25/2020 3:16:00 PM to 9/25/2020 5:00:00 PM; flag count = 0 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(SetDefaults) ★☆★ ➽➽❰<no instrument>❱ ⊢⊣
    ★☆★ MyIndicator.OnStateChange(Terminated) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Configure) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(DataLoaded) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Historical) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Transition) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Realtime) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰☰☰☰ Render Bars from 4033 to 4137; 9/25/2020 3:16:00 PM to 9/25/2020 5:00:00 PM; flag count = 0 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣

    F5 Refresh

    ★☆★ MyIndicator.OnStateChange(SetDefaults) ★☆★ ➽➽❰<no instrument>❱ ⊢⊣
    ★☆★ MyIndicator.OnStateChange(Terminated) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Configure) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(DataLoaded) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Historical) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Transition) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ★☆★ MyIndicator.OnStateChange(Realtime) ★☆★ ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    ☰☰☰☰ Render Bars from 4033 to 4137; 9/25/2020 3:16:00 PM to 9/25/2020 5:00:00 PM; flag count = 0 ➽➽❰GC 12-20❱ ⊢b03a7638-846b-4d37-804b-1a8e28303ffd⊣
    Last edited by ntdev; 10-01-2020, 04:47 AM.

    #2
    Hello ntdev.

    * It seems that some kind of caching is going on in [MyChartStyle] because it appears to be using an old version of [BarFlags].
    The indicators do have caching so that could play a role here, really this use is outside of the normal indicator/series use case so I couldn't really say if that is related to what you described. A chartStyle generally needs to do its own calculations from OnRender rather than pull indicator data or try to reference existing calculated data. If its possible I would suggest to move the indicators calculation into the chart style and modify it to work from OnRender directly.

    One item is that you are only getting the indicator when your variable is null, you may want to try and just get the indicator on every iteration to ensure you have the latest version of the indicator. because there is no expectation that your chart style loads after the indicator it may be that you are accessing an old indicator.

    * Is there some documentation for how bar series data is cached (if so) or when or if snapshots are taken and used for new Series<T> objects of an indicator?
    There is no documentation surrounding the internal caching in the platform. There are various different caches such as historical bar data or indicators but nothing which you would ever need to interact with at a NinjaScript level so that is not documented. The platform would handle all caching when necessary.


    * Or is there a way to force NT to discard any cached objects once I update things? Yes, I added a call Update() in the getter for this series object.
    There is no way to force the platform to clear cahces as that would degrade performance, or constantly having to recache items. Trying to manipulate the cache in any way is not really a way to approach this problem.

    Update() is used for specific use cases in Indicators when you expose a public property or data that is not plot based. You can see a sample of where that would be used in the following links:



    Code:
    else if (State == State.DataLoaded)
    barFlags.Reset();
    This would have no effect from data loaded, Reset is also used for specific cases while processing bars. This should not be used from DataLoaded but could be used to clear a plotted value from a bar.





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

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by egordleo, Today, 05:50 AM
    0 responses
    4 views
    0 likes
    Last Post egordleo  
    Started by kevinenergy, 02-17-2023, 12:42 PM
    118 responses
    2,778 views
    1 like
    Last Post kevinenergy  
    Started by briansaul, Today, 05:31 AM
    0 responses
    9 views
    0 likes
    Last Post briansaul  
    Started by fwendolynlpxz, Today, 05:19 AM
    0 responses
    4 views
    0 likes
    Last Post fwendolynlpxz  
    Started by traderqz, Yesterday, 12:06 AM
    11 responses
    28 views
    0 likes
    Last Post NinjaTrader_Gaby  
    Working...
    X