Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Backcolorall stops working

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

    Backcolorall stops working

    Hi,

    Based on some rules, I'm creating a score and setting the back colour on the chart. I want to do different shades of green and red, so I'm setting is like this

    if (score > 0)
    {
    //Print("Green brush");
    Brush newBrush = myBrushG.Clone();
    newBrush.Opacity = .10 * multiplier + .10;
    newBrush.Freeze();
    BackBrushAll = newBrush;
    } else if (score < 0 ){
    //Print("Red brush");
    Brush newBrush = myBrushR.Clone();
    newBrush.Opacity = .10 * multiplier + .10;
    newBrush.Freeze();
    BackBrushAll = newBrush;
    } else {
    BackBrushAll = null;
    }

    The problem is, after a while, during live play, it stays green! I've veridied the code in the score <0 is running with 'print' statements.

    In my global variables I have

    Brush myBrushG;
    Brush myBrushR;

    and in stateconfigure I set them like this

    myBrushG = Brushes.Green;
    myBrushR = Brushes.Red;
    myBrushG.Freeze();
    myBrushR.Freeze();

    I am setting the BrushBackAll in OnBarUpdate, which is set to run on price change, in case that is relevant.

    What am I doing wrong? Why does the brush stop working?

    Thanks.
    Last edited by pjsmith; 10-13-2016, 08:57 AM.

    #2
    Hello pjsmith, and thank you for your question. I would like to simplify the question to help us narrow in on an answer. Please refactor your brush creation and reuse so that we can test it independently from your score variable. I would recommend the following :

    Code:
    [FONT=Courier New]private Brush GreenBrush(Brush myBrushG)
    {
        if (myBrushG == null || myGreenBrush == null)
        {
    [/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]         if (myBrushG == null)
            {[/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]
                myGreenBrush = this.myBrushG.Clone();[/FONT][/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]
    [/FONT]        }
            else[/FONT][/FONT][/FONT]
            {[/FONT][FONT=Courier New][FONT=Courier New]
                myGreenBrush = myBrushG.Clone();
            }
    [/FONT][/FONT]        myGreenBrush.Opacity = .10 * multiplier + .10;
            myGreenBrush.Freeze();[/FONT][/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New]
    [/FONT]    }
        return myGreenBrush;
    }
    private Brush myGreenBrush = null;
    
    
    private Brush RedBrush(Brush myBrushR)
    {[/FONT][FONT=Courier New]
        if (myBrushR == null || myRedBrush == null)
        {
    [/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]         if (myBrushR == null)
            {[/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]
                myRedBrush = this.myBrushR.Clone();[/FONT][/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New][FONT=Courier New]
    [/FONT]        }
            else[/FONT][/FONT][/FONT]
            {[/FONT][FONT=Courier New][FONT=Courier New]
                myRedBrush = myBrushR.Clone();
            }
    [/FONT][/FONT]        myRedBrush.Opacity = .10 * multiplier + .10;
            myRedBrush.Freeze();[/FONT][/FONT][/FONT][/FONT][/FONT][FONT=Courier New][FONT=Courier New]
    [/FONT]    }
    [/FONT][FONT=Courier New]     return myRedBrush;
    }
    private Brush myRedBrush = null;[/FONT]
    This suggestion will allow you to pass a null into the methods GreenBrush and RedBrush, to preserve the way your script already runs (re-cloning every bar), and will otherwise allow you to pass in your existing myBrushR and MyBrushG members to preserve brush instances between bars. This is necessary to give us enough flexibility to track down what is occurring.

    If you act on the above suggestion, and add an additional trace so that we may observe what is happening, your code could be refactored like so :

    Code:
    [FONT=Courier New]if (score > 0)
                    {
        Log(Time[0].ToString() + " Green brush " + score, LogLevel.Information);
        BackBrushAll = GreenBrush(myBrushG);
                    } else if (score < 0 ){
        Log(Time[0].ToString() + " Red brush " + score, LogLevel.Information);
        BackBrushAll = RedBrush(myBrushR);
                    } else {
        Log(Time[0].ToString() + "Score zero", LogLevel.Information);
        BackBrushAll = null;
                    }    [/FONT]
    While the above are recommendations, please add some logging code with

    Log("message", LogLevel.Information)

    And then please provide as complete a code sample as possible along with your logs after running your code. If you would prefer to send this information privately, please send an e-mail with this information attached as separate files to platformsupport[at]ninjatrader[dot]com , referencing attn:ninjatrader_jessicap and 1587624 in the subject line of your e-mail.

    I look forward to assisting further.
    Last edited by NinjaTrader_JessicaP; 10-13-2016, 09:14 AM.
    Jessica P.NinjaTrader Customer Service

    Comment


      #3
      Many thanks for that. I will test some more, but it would appear that using the functions to return the brush has certainly improved things.

      The only thing I slightly changes was to also pass the 'muliplier' variable so that the opacity would work.

      So I have this now


      private Brush GreenBrush(Brush myBrushG, double multiplier)
      {
      if (myBrushG == null || myGreenBrush == null)
      {
      if (myBrushG == null)
      {
      myGreenBrush = this.myBrushG.Clone();
      }
      else
      {
      myGreenBrush = myBrushG.Clone();
      }
      myGreenBrush.Opacity = .10 * multiplier + .10;
      myGreenBrush.Freeze();
      }
      return myGreenBrush;
      }
      private Brush myGreenBrush = null;


      private Brush RedBrush(Brush myBrushR, double multiplier)
      {
      if (myBrushR == null || myRedBrush == null)
      {
      if (myBrushR == null)
      {
      myRedBrush = this.myBrushR.Clone();
      }
      else
      {
      myRedBrush = myBrushR.Clone();
      }
      myRedBrush.Opacity = .10 * multiplier + .10;
      myRedBrush.Freeze();
      }
      return myRedBrush;
      }
      private Brush myRedBrush = null;


      for the score and paint


      SCORE[0] = score;
      int multiplier = score;
      if (multiplier <0 ) multiplier = multiplier * -1;

      if (score > 0)
      {
      Log(Time[0].ToString() + " Green brush " + score + " / " + multiplier, LogLevel.Information);
      BackBrushAll = GreenBrush(myBrushG,multiplier);
      } else if (score < 0 ){
      Log(Time[0].ToString() + " Red brush " + score + " / " + multiplier, LogLevel.Information);
      BackBrushAll = RedBrush(myBrushR,multiplier);
      } else {
      Log(Time[0].ToString() + "Score zero", LogLevel.Information);
      BackBrushAll = null;
      }

      score is always a number between -5 and +5 (but - number gets converted to pos per above before used by opacity)

      I added to the logging to log the multiplier also


      So, my colours now appear to work, but my opacity does not.

      See any issue?

      I am getting the following from my log statement

      2016-10-13 17:53:08:913|1|16|13/10/2016 17:51:17 Green brush 3 / 3
      2016-10-13 17:53:08:914|1|16|13/10/2016 17:51:17 Green brush 3 / 3
      2016-10-13 17:53:08:914|1|16|13/10/2016 17:51:17 Green brush 3 / 3
      2016-10-13 17:53:08:915|1|16|13/10/2016 17:51:17 Green brush 3 / 3
      2016-10-13 17:53:08:916|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:917|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:917|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:917|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:917|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:918|1|16|13/10/2016 17:51:42 Green brush 3 / 3
      2016-10-13 17:53:08:918|1|16|13/10/2016 17:51:42 Green brush 2 / 2
      2016-10-13 17:53:08:919|1|16|13/10/2016 17:51:42 Green brush 2 / 2

      Comment


        #4
        I am glad the above code helps. I did some research into freezable objects at this publicly available MSDN C# link,

        Learn how to use and create freezable objects in Windows Presentation Foundation (WPF) applications.


        It looks like we can change the method you created just slightly to get opacity working properly. You would want to make equivalent changes for red.

        Code:
        [FONT=Courier New]
        private Brush GreenBrush(Brush myBrushG, double multiplier)
        {
            // force cloning from this.myBrushG
            if (myBrushG == null)
            {
                myGreenBrush = this.myBrushG.Clone();
            }
        
            // we have not yet initialized
            else [/FONT][FONT=Courier New][FONT=Courier New]if (myGreenBrush == null)[/FONT]
            {
                myGreenBrush = myBrushG.Clone();
            }
        
            // thaw to change the multiplier
            else if (multiplier != 0)
            {
                myGreenBrush = myGreenBrush.Clone();
            }
        
            // configure
            myGreenBrush.Opacity = .10 * multiplier + .10;
        
            // freeze and return
            myGreenBrush.Freeze();
            return myGreenBrush;
        }
        private Brush myGreenBrush = null;[/FONT]
        Please let us know if this is not the case or if we can help any other way
        Jessica P.NinjaTrader Customer Service

        Comment


          #5
          Sounds like the issue of creating more than 65535, or whatever the limit is, brushes through cloning. This is an issue I had also with bar brushes and was made worse with Tick Replay. Eventually the color changes stop and stays fixed on the last brush created.
          Last edited by eDanny; 10-13-2016, 11:24 AM.
          eDanny
          NinjaTrader Ecosystem Vendor - Integrity Traders

          Comment


            #6
            Using that new method solves the opacity problem to start, but as eDanny (thank you) suggested, it stops working By the time it has rendered 3 days on 1500 tick, is all green again

            I tried limiting the use of the brushes by only changing them when the score changes, rather than on every onbarupdate, but still an issue.

            I checked the amount of times the backcolour is changed. 78,628, and the 65k number looks like it would correspond to where it stops working. It looks like this may have been my original and current problem.

            If this is a none ninjatrader issue, then given I only have 10 variations in each brush, I will try to setup an array containing the brushes, pre set for each and use them that way. Long winded, by probably more efficient anyway?

            Unless you have a workaround?

            Many thanks for the assistance.

            Comment


              #7
              Thank you very much eDanny for informing us of the 0xFFFF limit to number of brushes, I was unaware of this limit myself.

              pjsmith, while this does appear to be a C# limitation we are working against, I believe I can still provide some more assistance.

              The very first thing I would try, would be to eliminate all freezing and cloning (which I called "thawing") in my comment altogether, just using myBrushG and myBrushR throughout.

              If we discover that we need to be working with frozen brushes, I would then like to recommend that we create two dictionaries with 100 frozen brushes in each - one brush with each opacity 1-100 for the colors red and green - and then pull from this dictionary as needed. I am including some documentation for C# dictionaries.



              While developing such a method is beyond the scope of the support we may provide, should you decide to implement such a solution and any questions come up, please feel free to ask and I will be happy to assist further.
              Jessica P.NinjaTrader Customer Service

              Comment


                #8
                I thught the array solution might work. I thought I'd come up with a neat/clever solution, but I get no colours at all!

                Code:
                        private Brush[] myBrushG = new Brush[15];
                        private Brush[] myBrushR = new Brush[15];
                
                                myBrushG[0] = Brushes.Green;
                                myBrushG[0].Freeze();
                                int i = 0;
                                for (i=1; i<11; i++)
                                {
                                    myBrushG[i] = myBrushG[i-1].Clone();
                                    myBrushG[i].Opacity = i / 10;
                                    myBrushG[i].Freeze();
                                }
                                myBrushR[0] = Brushes.Red;
                                myBrushR[0].Freeze();
                                for (i=1; i<11; i++)
                                {
                                    myBrushR[i] = myBrushR[i-1].Clone();
                                    myBrushR[i].Opacity = i / 10;
                                    myBrushR[i].Freeze();
                                }    
                
                
                                SCORE[0] = score;
                                int multiplier = score;
                                if (multiplier <0 ) multiplier = multiplier * -1;
                
                                if (score != LastScore)
                                {
                                    counter++;
                                    if (score > 0 )
                                    {
                                        BackBrushAll = myBrushG[multiplier];
                                    } else if (score < 0 ){
                                        BackBrushAll = myBrushR[multiplier];
                                    } else {
                                        BackBrushAll = null;
                                    }    
                                } else {
                                    LastScore = score;
                                }
                Stumped!

                Maybe I need to use a dictionary as you suggested, instead of an array of brushes. I only saw your comment after I posted this.

                Comment


                  #9
                  I believe an array will be sufficient, I believe I skipped reading that the first time I read your post.

                  Your code does look correct to me. I would recommend testing just the myBrushG[10] and myBrushR[10] members immediately after you create them to see if these are getting loaded. If these are null I would recommend just testing the myBrushG[0] and myBrushR[0] members to make sure they were initialized properly.

                  Otherwise the only possibility that is jumping out at me is to set

                  myBrushG[0] = Brushes.Green.Clone();
                  Jessica P.NinjaTrader Customer Service

                  Comment


                    #10
                    Thanks again

                    Tried a few things.

                    Setting text on chart and the background to specific colours in the array.

                    So, Brush[0], the default brush works. Brush[10], a brush populated by cloning in the array works.

                    The only thing is these two brushes both have an opacity of 1.

                    All the other brushes when used plot no colour at all.

                    So this works and prints red ok

                    BackBrushAll = myBrushR[0];

                    as does this

                    BackBrushAll = myBrushR[10];

                    but not this

                    BackBrushAll = myBrushR[5];

                    Prints no colour. All are set though

                    myBrushR[0] = Brushes.Red.Clone();
                    myBrushR[0].Freeze();
                    for (i=1; i<11; i++)
                    {
                    myBrushR[i] = myBrushR[i-1].Clone();
                    myBrushR[i].Opacity = i / 10;
                    myBrushR[i].Freeze();
                    }

                    Opacity is a number between 0 and 1 as it should be. Brushes must be cloned correctly for myBrush[10] to work.

                    So it seems the brushes with an opacity set have no colour any more.

                    I also tried this, just in case

                    myBrushR[0] = Brushes.Red.Clone();
                    myBrushR[0].Freeze();
                    for (i=1; i<11; i++)
                    {
                    myBrushR[i] = Brushes.Red.Clone();
                    myBrushR[i].Opacity = i / 10;
                    myBrushR[i].Freeze();
                    }

                    Comment


                      #11
                      Does the same thing occur when you create and configure brushes in one loop, and then freeze them in a separate loop?
                      Jessica P.NinjaTrader Customer Service

                      Comment


                        #12
                        I would seem so

                        I just tried this

                        Code:
                                        myBrushR[0] = Brushes.Red.Clone();
                                        myBrushR[0].Freeze();
                                        for (i=1; i<11; i++)
                                        {
                                            myBrushR[i] = Brushes.Red.Clone();
                                            myBrushR[i].Opacity = i / 10;
                                            //myBrushR[i].Freeze();
                                        }                
                                        Draw.TextFixed(this,"tagTEST2",  "GREEN5",TextPosition.TopLeft,ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, myBrushG[5], myBrushG[5], 0);
                                        for (i=1; i<11; i++)
                                        {
                                            myBrushG[i].Freeze();            
                                            myBrushR[i].Freeze();
                                        }
                        Only brushes [0] and [10] plot any colour. Most strange.

                        Comment


                          #13
                          Ahh, the Opacity thingy. I was told to create enough brushes for the colors needed on an OnStateChange(), probably in State.Configure, and then use them as you nrrd them without cloning or creating any more. My code breaks when doing that if I add Opacity too.
                          eDanny
                          NinjaTrader Ecosystem Vendor - Integrity Traders

                          Comment


                            #14
                            Well, that sucks.

                            To verify, I simply removed the .opacity setting from the last code. ALL the cloned brushes in the array now plot either green or red. Add the opacity setting, they stop except 0 and 10 with an opacity of 1.

                            So, is this a NT or .net issue?

                            Comment


                              #15
                              OK, this gets weirder. I found a solution, but I do not understand why it works. I think something outside of my control is screwy!

                              this does not work, but I believe it should

                              Code:
                                              myBrushR[0] = Brushes.Red.Clone();
                                              myBrushR[0].Freeze();
                                              for (i=1; i<11; i++)
                                              {
                                                  myBrushR[i] = Brushes.Red.Clone();
                                                  myBrushR[i].Opacity = i / 10;
                                                  myBrushR[i].Freeze();
                                              }
                              All brushes that have an opacity other than 1 do not work - no colour

                              This does not work

                              myBrushR[i].Opacity = i / 10;

                              where i is a number from 1 to 10.Always producing a valid number.

                              This works in the same loop

                              myBrushR[i].Opacity = .5;

                              But obviously with a fixed opacity for each brush.

                              Having found that, I tried this

                              double o = i / 10;
                              myBrushR[i].Opacity = o;

                              does not work.

                              So, I tried this

                              Code:
                                              myBrushG[0] = Brushes.Green.Clone();
                                              myBrushG[0].Freeze();
                                              int i = 0;
                                              for (i=1; i<11; i++)
                                              {
                                                  myBrushG[i] = Brushes.Green.Clone();
                                                  if (i == 1) myBrushG[i].Opacity = .1;
                                                  if (i == 2) myBrushG[i].Opacity = .2;                
                                                  if (i == 3) myBrushG[i].Opacity = .3;
                                                  if (i == 4) myBrushG[i].Opacity = .4;
                                                  if (i == 5) myBrushG[i].Opacity = .5;
                                                  if (i == 6) myBrushG[i].Opacity = .6;
                                                  if (i == 7) myBrushG[i].Opacity = .7;
                                                  if (i == 8) myBrushG[i].Opacity = .8;
                                                  if (i == 9) myBrushG[i].Opacity = .9;
                                                  if (i == 10) myBrushG[i].Opacity = 1;
                                                  myBrushG[i].Freeze();
                                              }
                              Stupid long way to do it, but what do you know, it works!

                              So, it seems the opacity issue is related to passing the opacity as a variable or calculation. If you pass it as a fixed number, it works! According to MSDN, the number to be passed is a simple double. Don't see why I had a problem, but this appears to be a workaround.

                              I am creating the brushes in State.Configure, in the array, per the previous posts. I tested with more bars than before and did not encounter the issue again. I will test further real-time and update the post if further issues detected.

                              Thanks for both your assistance.

                              Paul

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Stanfillirenfro, Yesterday, 09:19 AM
                              7 responses
                              51 views
                              0 likes
                              Last Post NinjaTrader_Gaby  
                              Started by TraderCro, 04-12-2024, 11:36 AM
                              4 responses
                              69 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Mindset, Yesterday, 02:04 AM
                              1 response
                              15 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by agclub, 04-21-2024, 08:57 PM
                              4 responses
                              18 views
                              0 likes
                              Last Post NinjaTrader_Gaby  
                              Started by Irukandji, Today, 04:58 AM
                              0 responses
                              6 views
                              0 likes
                              Last Post Irukandji  
                              Working...
                              X