Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Reading exposed vars from indicator inside Strategy

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

    Reading exposed vars from indicator inside Strategy

    I have two questions about reading exposed variables from and indicator into a Strategy that I want to be sure about before proceeding.

    1) if we have an indicator with exposed variable and it is read in a strategy with something like StrategyVar = IndicatorXYZ().ExposedVar. Is my reading of the documents correct in that the act of reading it forces an OnbarUpdate() if necessary, in the indicator, given there is an Update() in the get of the public variable.

    2) I wish to maintain settable property inputs to the indicatorXYZ but do not wish to list them in the exposed indicator as overloads. Is there a way to do that.
    i.e. I do not want it to look like StrategyVar = IndicatorXYZ(true,false,0,true).ExposedVar . There are too many inputs. At first I thought just removing the [NinjaScriptProperty] would do it, but since most of them are public it didn't like that.

    Thanks
    Jerry​

    #2
    I figured out question #2 but I have an issue with the reading the exposed Variable. As soon as the Strategy attempts to read the exposed variable it generates an error in the indicator and then an error in the strategy. Note that in the print below OnBarUpdate errored out on bar #3 So it is like when the Strategy invoked the indicator it restarted from bar 1 and then generated the error. Obviously it has to do with the exposed variable not being set in some way but I can't seem to figure out why. Any help would be appreciated.
    Jerry

    Indicator 'PivotIndicator': Error on calling 'OnBarUpdate' method on bar 3: Object reference not set to an instance of an object.
    CurrentBar = 824 Strategy dir = 0
    Strategy 'Trader': Error on calling 'EventHandlerBarsUpdate' method: Object reference not set to an instance of an object.​

    Comment


      #3
      Hello JerryWar,

      "if we have an indicator with exposed variable and it is read in a strategy with something like StrategyVar = IndicatorXYZ().ExposedVar. Is my reading of the documents correct in that the act of reading it forces an OnbarUpdate() if necessary, in the indicator, given there is an Update() in the get of the public variable."

      Yes, this is correct. Calling Update() in the getter would update OnBarUpdate before returning the value.


      "I wish to maintain settable property inputs to the indicatorXYZ but do not wish to list them in the exposed indicator as overloads. Is there a way to do that."
      Use the Browsable(false) attribute to remove public variables from the UI inputs.

      Do not use the NinjaScriptProperty attribute if you want to remove public variables from the overload parameters.


      "As soon as the Strategy attempts to read the exposed variable it generates an error in the indicator and then an error in the strategy. "

      I would not expect just exposing the variable to cause this error. If you comment out all logic in OnBarUpdate() does the error persist?
      If not, what specific line of code is causing the error?
      Chelsea B.NinjaTrader Customer Service

      Comment


        #4
        Its getting generated in the strategy called "Trader" when it reads the var.
        Print("CurrentBar = "+CurrentBar +" Strategy dir = "+PivotIndicator().DIR );
        but the error is generated in the indicator in OnBarUpdate() I can only assume its on the variable but I will comment out everything except the property update section and set the var to a constant and see what happens. I have tried all sort of things with it and nothing has let me narrow it down further If I comment out the public variable I am sure it will not like that.

        Comment


          #5
          Hello JerryWar,

          "I will comment out everything except the property update section and set the var to a constant and see what happens. "

          Yes, please report back if the error can be reproduced with all code in OnBarUpdate() commented out.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            Chelsea, Can the variable in the indicator where the data is originating be Public as well. After reading as much as I did I was left with the impression it had to be private. But That doesn't work for the code. So what I had done was to set the public variable the data came from to a private in the indicator OnbarUpdate() .
            Would this cause problems ?

            Instead of commenting everything out, I did the opposite and created a new strategy just to read the exposed variable. Of course it worked.
            So If the above is not an issue then I will start commenting out.

            Also in the indicator , when the error is generated. It happens on Bar 3.
            right after
            if (IsFirstTickOfBar ) {
            if (CurrentBar<=2 )
            {
            return;
            }
            There is no lookback necessary for what I am doing. I have set it to 1000 in which case it errors out on bar 1001. Like something is causing the indicator to reset thru all its bars when the variable is read.

            Thanks for the help
            Jerry

            Comment


              #7
              Hello Jerry,

              If the public variable is calling Update() this should return a private variable. (This will prevent the Update() from being called in the getter from the value being set from OnBarUpdate()

              What is the specific line of code causing an error?
              Chelsea B.NinjaTrader Customer Service

              Comment


                #8
                ChelseaB thank you for that. I suspected it was problematic. This weekend took me down a rabbit whole with this code. But I finally was able to nail it down.

                In the indicator. This portion of code.

                Ticks = Instrument.MasterInstrument.RoundToTickSize
                ((ChartPanel.MaxValue-ChartPanel.MinValue)/TickSize);
                PixelsPerTick = ChartPanel.H/Ticks;
                yPixelOffset = Convert.ToInt32(PixelsPerTick * offsetTicks);


                Generated the unhandled exception only when the exposed variables were used. I surmised it was a thread issue. So I used the Dispatcher

                Dispatcher.InvokeAsync(() =>
                {
                Ticks = Instrument.MasterInstrument.RoundToTickSize
                ((ChartPanel.MaxValue-ChartPanel.MinValue)/TickSize);
                PixelsPerTick = ChartPanel.H/Ticks;
                yPixelOffset = Convert.ToInt32(PixelsPerTick * offsetTicks);
                });

                Which removed one source of the issue. But i found another.

                SolidColorBrush existingBrush = (SolidColorBrush) ShortBrush;
                Brush newBackBrush = new SolidColorBrush(existingBrush.Color);
                newBackBrush.Opacity =.5;
                newBackBrush.Freeze();
                if (Calculate==Calculate.OnEachTick) {BackBrushes[1] = newBackBrush;}
                else {BackBrush = newBackBrush;}

                and I did the same.

                Dispatcher.InvokeAsync(() =>
                {
                SolidColorBrush existingBrush = (SolidColorBrush) ShortBrush;
                Brush newBackBrush = new SolidColorBrush(existingBrush.Color);
                newBackBrush.Opacity =.5;
                newBackBrush.Freeze();
                if (Calculate==Calculate.OnEachTick) {BackBrushes[1] = newBackBrush;}
                else {BackBrush = newBackBrush;}​
                });

                while it appears to work, I think it is potentially problematic. The Tick calculation based on the symbol I think can be moved to State==State.Dataloaded so it doesn't effect or delay OnBarUpdate()
                But I am unsure of what to do about the background color change. If the Dispatcher waits onbarupdate for one bar that would be disastrous. Can you help fine tune this.

                Thanks
                Jerry​​​​

                Comment


                  #9
                  ChelseaB, So it turns out that exactly what I was afraid of happening, is happening. The data is getting hosed up by the dispatcher. In fact, their are print statements in the code, The print statements do not reflect the background color unless I remove the dispatcher statements. I am at a loss as to how to get around this issue.
                  Regarding the issue with the public Variable I was using , to get around that issue I set it equal to a private in OnbarUpdate and then used that private in the getter. I hope that still isn't part of this issue.

                  I use the private variable from the getter as a direction variable in Onbarupdate. That section of code is setting the background color and is also the section of the code that is the problem outlined above. Is it possible that their is a conflict between the dispatcher and the Freeze() function used in setting the brushes.

                  I replaced custom brush with standard one so I didn't have to use freeze. That cleared up half the problems but it is still unusable. The CurrentBar numbers are all out of sequence. Jumping backwards at times two bars or more. The currentBar and their times don't match up and in some places are off by 14 minutes. (using playback) I can't believe what I am seeing.

                  the further I go the more problems I am finding.

                  Jerry
                  Last edited by JerryWar; 07-30-2024, 07:38 AM.

                  Comment


                    #10
                    Hello Jerry,

                    Setting the BackBrush or BarBrush would not require using a dispatcher invoke, however using the ChartControl, ChartPanel, or ChartScale would need a dispatcher invoke.

                    The value being set to the public variable should not be in a dispatcher.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      ChelseaB, Thanks for that. I ran into an older post by you which outlined my problem. I cached the brushes and now they work fine.

                      I think Accessing the ticksize can be done once and should not be done in OnBarUpdate().

                      Ticks = Instrument.MasterInstrument.RoundToTickSize((Chart Panel.MaxValue-ChartPanel.MinValue)/TickSize);
                      But getting the chartPanel.H .
                      PixelsPerTick = ChartPanel.H/Ticks;
                      so I can calculate the relative offset has to be done anytime the chart gets resized.
                      Is there a State.Change that detects that ?
                      How can I handle that to minizine use of the dispatcher.

                      Thanks
                      Jerry

                      Comment


                        #12
                        Hello Jerry,

                        "I think Accessing the ticksize can be done once and should not be done in OnBarUpdate()."

                        The TickSize property can be used in OnBarUpdate() (or anytime after State.DataLoaded) and can be used as many times as you would like. This does not require a dispatcher.


                        "But getting the chartPanel.H .
                        PixelsPerTick = ChartPanel.H/Ticks;
                        so I can calculate the relative offset has to be done anytime the chart gets resized.
                        Is there a State.Change that detects that ?​"

                        OnRender() will the run when the chart is resized.

                        No, the State property does not change.

                        "How can I handle that to minizine use of the dispatcher."

                        Assuming this is called from a method that is not OnRender():

                        if (ChartControl != null)
                        {​
                        ChartControl.Dispatcher.InvokeAsync(() => {
                        Print(ChartPanel.H/Ticks);
                        });
                        }​
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Thanks ChelseaB

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by argusthome, 03-08-2026, 10:06 AM
                          0 responses
                          111 views
                          0 likes
                          Last Post argusthome  
                          Started by NabilKhattabi, 03-06-2026, 11:18 AM
                          0 responses
                          59 views
                          0 likes
                          Last Post NabilKhattabi  
                          Started by Deep42, 03-06-2026, 12:28 AM
                          0 responses
                          38 views
                          0 likes
                          Last Post Deep42
                          by Deep42
                           
                          Started by TheRealMorford, 03-05-2026, 06:15 PM
                          0 responses
                          42 views
                          0 likes
                          Last Post TheRealMorford  
                          Started by Mindset, 02-28-2026, 06:16 AM
                          0 responses
                          78 views
                          0 likes
                          Last Post Mindset
                          by Mindset
                           
                          Working...
                          X