• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

BUG: Exception raised when dynamically changing plot color (brush)

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

    BUG: Exception raised when dynamically changing plot color (brush)

    According to the current documentation, the way to dynamically change the color (brush) of a plot is to assign a Brush into the appropriately-indexed sub-element of the PlotBrushes array: http://ninjatrader.com/support/helpG...lotbrushes.htm

    Specifically, to dynamically change the color (brush) of the current bar for an indicator's first (zeroeth) plot to blue, one is supposed to evaluate the following statement:

    PlotBrushes[0][0] = Brushes.Blue;

    However, doing so raises the following exception:

    The calling thread cannot access this object because a different thread owns it.
    at System.Windows.Threading.DispatcherObject.VerifyAc cess()
    at System.Windows.Freezable.Freeze(Boolean isChecking)
    at NinjaTrader.NinjaScript.BrushSeries.Set(Int32 index, Brush value)
    at NinjaTrader.NinjaScript.BrushSeries.set_Item(Int32 barsAgo, Brush value)
    at NinjaTrader.NinjaScript.Indicators.N1MovAvgOmniMA. colorizePlot(Int32 plotIndex, Double nextValue)
    at NinjaTrader.NinjaScript.Indicators.N1LightweightIn dicator.updatePlotAt(Int32 plotIndex)


    Here's the relevant activation frames in my code, showing the path of execution from OnBarUpdate():

    protected virtual void colorizePlot(int plotIndex, double nextValue) {
    if (double.IsNaN(nextValue)) return;
    var prevValue = prevPlotValue(plotIndex);
    if (double.IsNaN(prevValue)) return;
    switch (Math.Sign(nextValue - prevValue)) {
    case 1:
    PlotBrushes[plotIndex][0] = RisingBrush;
    break;
    default:
    PlotBrushes[plotIndex][0] = NeutralDirectionBrush;
    break;
    case -1:
    PlotBrushes[plotIndex][0] = FallingBrush;
    break;
    }
    }

    protected virtual void updatePlotAt(int plotIndex) {
    var nextValue = computePlotValue(plotIndex);

    try {
    if (double.IsNaN(nextValue)) {
    Values[plotIndex].Reset();
    } else {
    setPlotValue(plotIndex, nextValue);
    if (colorizePlots) colorizePlot(plotIndex, nextValue);
    }
    } catch (Exception ex) {
    logMessage(ex.Message);
    logMessage(ex.StackTrace);
    }
    }

    protected override void updatePlots() {
    if (BarsInProgress != 0) return;
    for (int plotIndex = 0; plotIndex < Values.Length; plotIndex++) {
    updatePlotAt(plotIndex);
    }
    }

    protected override void OnBarUpdate() {
    preUpdatePlots();
    updatePlots();
    postUpdatePlots();
    }
    Last edited by strategesis; 08-10-2015, 03:55 PM.

    #2
    Where are you declaring the RisingBrush, etc resources? And are they pre-defined brushes, or are you creating a new custom brush object?

    I could not compile your example, but you likely have declared a new custom brush resource without freezing it before you tried to use it.

    Please have a look on this topic under Creating a Solid Color Brush

    http://ninjatrader.com/support/helpG...us/brushes.htm

    For example, if you're doing something like I have written below, you'd get threading errors without first freezing the brush object as I have done in State.Configure

    Code:
    public class MyCustomIndicator : Indicator
    	{
    		SolidColorBrush myBrush;
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description					= @"Enter the description for your new custom Indicator here.";
    				Name						= "MyCustomIndicator";			
    				AddPlot(Brushes.Green, "myPlot");
    			}
    			else if (State == State.Configure)
    			{
    				myBrush = new SolidColorBrush(Colors.Blue);
    				// without freezing the brush, trying to use it later in OBU results in threading errors
    				myBrush.Freeze(); 
    			}
    		}
    
    		protected override void OnBarUpdate()
    		{
    			myPlot[0] = High[0];
    			
    			PlotBrushes[0][0] = myBrush;
    			//Add your custom indicator logic here.
    		}
    		
    		[Browsable(false)]
    		[XmlIgnore()]
    		public Series<double> myPlot
    		{
    			get { return Values[0]; }
    		}
    	}
    If you are in fact just using a plain old .NET predefined Brush, the error would be unexpected but I'd need more details from your code to reproduce.
    MatthewNinjaTrader Product Management

    Comment


      #3
      Aha. That fixed it. I missed that when perusing the documentation. As a programmer for more than three decades, I think I already know everything, and so tend to skim instead of reading completely and thoroughly :-)

      Suggestion: Add a section that provides a brief overview of the necessary (or recommended) differences between coding for NT7 and NT8 which result from the new multithreaded architecture for NT8. It mostly just needs to list each issue, and provide links to the various documentation pages which you already have (or will have) which discuss the details of each issue. And then link to the multithreading-issue overview section in the overview of the code-breaking changes for NT8.

      Comment


        #4
        Hello strategesis,

        Thanks for your suggestion. I have forward your suggestion as a feature request to Program Management for consideration.
        We appreciate the feedback/suggestions to help us improve the Ninjatrader 8 Product.
        Paul H.NinjaTrader Customer Service

        Comment


          #5
          In Matthew's example above, is it necessary to call Freeze() if we use a predefined brush instead of a custom brush? See my comments below.

          Thanks.

          SolidColorBrush myBrush;

          protected override void OnStateChange() {
          if (State == State.SetDefaults) {
          Description = @"Enter the description for your new custom Indicator here.";
          Name = "MyCustomIndicator";
          AddPlot(Brushes.Green, "myPlot");
          } else if (State == State.Configure) {
          myBrush = Brushes.Blue; // initiate it as a predefined brush instead
          myBrush.Freeze(); // do we need to freeze the brush here?
          }
          }

          protected override void OnBarUpdate() {
          myPlot[0] = High[0];
          PlotBrushes[0][0] = myBrush; //Add your custom indicator logic here.
          }
          ninZa
          NinjaTrader Ecosystem Vendor - Ninza

          Comment


            #6
            Following the link and reading the documentation:

            "Warning: If you do not call .Freeze() on a custom defined brush WILL eventually result in threading errors should you try to modify or access that brush after it is defined."

            I would say NO. It's not necessary. But then again - I haven't used a brush yet!

            Are you trying to change or modify it?

            Are you seeing differences calling Freeze or not?

            *I too will wait for official response on this.... too late to try testing here..

            Comment


              #7
              Originally posted by sledge View Post
              Following the link and reading the documentation:

              "Warning: If you do not call .Freeze() on a custom defined brush WILL eventually result in threading errors should you try to modify or access that brush after it is defined."

              I would say NO. It's not necessary. But then again - I haven't used a brush yet!

              Are you trying to change or modify it?

              Are you seeing differences calling Freeze or not?

              *I too will wait for official response on this.... too late to try testing here..
              My guess is also "No". But I have tried using Freeze() also.

              So far I have not seen any differences between calling and not calling Freeze() for predefined brush.

              We need an official response on this.
              ninZa
              NinjaTrader Ecosystem Vendor - Ninza

              Comment


                #8
                Hello,

                Thanks for your posts on this topic.

                Predefined brushes are static, cannot be modified and there is no need to Freeze() them.
                Paul H.NinjaTrader Customer Service

                Comment


                  #9
                  Hello,

                  To further assist, we have updated the NT8 helpguide documentation to clearly advise concerning predefined brushes.
                  Reference: http://ninjatrader.com/support/helpG...s/?brushes.htm (See first note in "Predefined brushes".

                  Thanks for your questions on this subject.
                  Paul H.NinjaTrader Customer Service

                  Comment


                    #10
                    Originally posted by NinjaTrader_Paul View Post
                    Hello,

                    To further assist, we have updated the NT8 helpguide documentation to clearly advise concerning predefined brushes.
                    Reference: http://ninjatrader.com/support/helpG...s/?brushes.htm (See first note in "Predefined brushes".

                    Thanks for your questions on this subject.
                    Got it
                    Thank you for your great info and being so quick in updating the documentation.
                    ninZa
                    NinjaTrader Ecosystem Vendor - Ninza

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by Arkadiy_B, Today, 06:43 AM
                    0 responses
                    2 views
                    0 likes
                    Last Post Arkadiy_B  
                    Started by leontancfa, Today, 06:09 AM
                    1 response
                    9 views
                    0 likes
                    Last Post NinjaTrader_PatrickG  
                    Started by soulfx, 12-01-2017, 08:44 AM
                    3 responses
                    1,019 views
                    0 likes
                    Last Post NinjaTrader_EricB  
                    Started by Parmenides48, 04-09-2019, 03:32 AM
                    10 responses
                    53 views
                    0 likes
                    Last Post NinjaTrader_PatrickG  
                    Started by NinjaCustomer, Today, 01:48 AM
                    1 response
                    13 views
                    0 likes
                    Last Post NinjaTrader_EricB  
                    Working...
                    X