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

Modifying the color of plot at each bar via FromArgb

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

    Modifying the color of plot at each bar via FromArgb

    I get the following error message if the included code is used modify the color of the plot per each bar. Please show the proper way of modifying the color of plot at each bar via FromArgb or SharpDX without going into OnRender portion of script.

    Color series exceeds the maximum number (65535) of unique brushes. Please adjust code to use fewer brushes.

    Code:
    if (State == State.SetDefaults)
    {
       AddPlot(new Stroke(Brushes.White, DashStyleHelper.Solid, 3f), PlotStyle.Line, "A50");
    }
    ...
    protected override void OnBarUpdate()
    {
    double cbe = 1 - btw1nd(Math.Abs(Close[i] - A50[i]) / (4 * bd_D[i]));
                        System.Windows.Media.Brush brush3 = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(colorByte(128 * cbe), colorByte(255 * cbe), colorByte(200 * cbe), 0));
                        brush3.Freeze();
                        PlotBrushes[10][i] = brush3;
    }

    #2
    i think, instead of

    System.Windows.Media.Brush brush3 = new System.Windows.Media.Solid ...

    you should use something like this:

    private SolidColorBrush brush3;
    .....
    .....
    brush3 = new BrushConverter().ConvertFromString("FF1122") as SolidColorBrush ;

    Plots[i].Brush = brush3;

    (you may need
    using System.Drawing; or
    using System.Windows.Media)
    Last edited by ttodua; 08-23-2017, 09:05 AM.

    Comment


      #3
      Hello bkinvent,

      Thanks for opening the thread.

      Please show the proper way of modifying the color of plot at each bar via FromArgb or SharpDX without going into OnRender portion of script.
      System.Windows.Media.Brushes must be frozen to be used properly when you create custom brushes. Since they cannot be unfrozen, I would not be able to advise a way to do this with these brushes or by avoiding custom rendering.

      You could do this with with custom rendering with SharpDX brushes, but these resources must be (re)created with every render target change so OnRenderTargetChanged() must be overridden to use these brushes efficiently. I would advise to take the OnRender() approach for custom rendering to maintain a consistent approach to our supported custom rendering system.

      I will provide links to examples and documentation demonstrating how to properly reuse SharpDX brushes.

      Chelsea's reusing SharpDX brush scripts - http://ninjatrader.com/support/forum...144#post509144

      SharpDX Brush Resources - https://ninjatrader.com/support/help...BrushResources

      SharpDX Best Practices - https://ninjatrader.com/support/help...arpDXResources

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

      Please let me know if you have any questions.
      JimNinjaTrader Customer Service

      Comment


        #4
        Dynamically color of a plot or Path Geometry on a bar by bar basis

        I've been able to achieve this using a new brush color and then drawing a new line segment for every bar, but I've noted that with this approach the lines are jagged and stroke styles are non-continuous. Is there an efficient way of modifying the color of a plot or Path Geometry on a bar by bar basis (use of script within the OnRender override included)?
        Code:
        dx4 = new SharpDX.Color4(0.3f, 0.3f, 0.3f, 0.3f);
        brushDXbid = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, dx4);
        SharpDX.Direct2D1.PathGeometry geo1 = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
        SharpDX.Direct2D1.GeometrySink sink1 = geo1.Open();
        sink1.BeginFigure(ap_bid0.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled);
        sink1.AddLines(vectors1);
        sink1.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
        sink1.Close();
        RenderTarget.FillGeometry(geo1, brushDXbid);
        geo1.Dispose();
        sink1.Dispose();
        brushDXbid.Dispose();

        Comment


          #5
          Hello bkinvent,

          I do not think using PathGeometry would be applicable for drawing lines in different colors when creating a figure since we use a Geometry Sink to define the shape of a figure, and then we fill it with FillGeometry().

          If you would like to create multiple line segments with different colors, I would suggest to use RenderTarget.DrawLine() instead. You could for example, loop through ChartBars.ToIndex and ChartBars.FromIndex for the visible bars, and then perform the RenderTarget.DrawLine() with the appropriate brush for the segment you wish to draw. Getting the X and Y coordinates may assist in creating continuous segments. ChartControl and ChartScale have GetXByBarIndex() and GetYByValue() methods available for this purpose.

          Although the application is different, the Fibonacci Clusters indicator (originally written by Harry) can provide an example for looping through visible bars, getting the pixel coordinates of bars that are looped through, and drawing lines. There may be better examples that can be referenced to do what you would like.

          Fibonacci Clusters - http://ninjatrader.com/support/forum...atid=7&lpage=1

          RenderTarget.DrawLine() (limited documentation) - https://ninjatrader.com/support/help...t_drawline.htm

          ChartBars - https://ninjatrader.com/support/help.../chartbars.htm

          GetXByBarIndex() - https://ninjatrader.com/support/help...bybarindex.htm

          GetYByValue() - https://ninjatrader.com/support/help...etybyvalue.htm

          Please let me know if I can be of further help.
          JimNinjaTrader Customer Service

          Comment


            #6
            Thank you for responding. I can draw line segments, however, the stroke styles are not continuous, can this be rectified in any way?

            Comment


              #7
              Hello bkinvent,

              There may have been some confusion surrounding my last reply.

              We do need a separate object (RenderTarget.DrawLine() or PathGeometry) to use a different color.

              I do not think using PathGeometry would be applicable for drawing lines in different colors when creating a figure since we use a Geometry Sink to define the shape of a figure, and then we fill it with FillGeometry().
              Actually, you may be able to do this by using separate PathGeometry's for each color and then leaving FigureEnd.Open when you close the figure.

              Here is a rough example my colleague Jesse put together:

              Code:
              for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex; idx++)
              {
              	SharpDX.Direct2D1.PathGeometry geometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);	
              	GeometrySink sink = geometry.Open();
              	var x = chartControl.GetXByBarIndex(ChartBars, idx);
              	var price = Bars.GetValueAt(idx);
              	var y = chartScale.GetYByValue(price);
              
              	var x2 = chartControl.GetXByBarIndex(ChartBars, idx+1);
              	var price2 = Bars.GetValueAt(idx+1);
              	var y2 = chartScale.GetYByValue(price2);
              
              	sink.BeginFigure(new Vector2(x, y), new FigureBegin());
              	sink.AddLine(new Vector2(x2,y2));
              	sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
              	sink.Close();
              
              	RenderTarget.DrawGeometry(geometry, idx % 2 == 0 ? Brushes.Red.ToDxBrush(RenderTarget) : Brushes.Blue.ToDxBrush(RenderTarget));
              	geometry.Dispose();
              }
              If you are looking into curving the segments, you may have luck using Bezier curves, but there is not any documentation that we have or any sample code I could share to demonstrate.

              Please let me know if there is anything I can do to assist further.
              JimNinjaTrader Customer Service

              Comment


                #8
                Is there any way to delete excess frozen brushes?

                Here I read that "The maximum number of brush objects you can create is 65,535"

                So, tried to collect each created brush and to delete all them on each bar, but still have same error message "Brush series exceeds the maximum number of unique brushes NinjaTrader"

                PHP Code:
                for( int b 0Wm_Brushes_To_Delete.Countb++ )
                {
                   
                Wm_Brushes_To_Delete[b] = null;
                }
                Wm_Brushes_To_Delete.Clear(); 
                Does the way to remove frozen brushes exists?
                Last edited by fx.practic; 11-05-2018, 01:21 AM.
                fx.practic
                NinjaTrader Ecosystem Vendor - fx.practic

                Comment


                  #9
                  Originally posted by fx.practic View Post
                  Is there any way to delete excess frozen brushes?
                  The problem is that you misunderstood the "objects" with "brushes". as said, you can have a max. of 65 000 objects (it's not the limit of arraysize of brushes as you see).
                  so, you have to delete the objects itself, not the brushes. Btw, you might need to create a brush only in the initialization and that will be enough, why you create brushes on every bar?

                  Comment


                    #10
                    Hello TazoTodua, thank for answer!
                    I need to create brushes on each bar to paint indicator plots in different colours.

                    I mean, WmBrush is object by itself.
                    If I set PlotBrushes[1][0] = Brushes.Transparent and set brush to null, it should free memory and "slots" it whatever arrays.

                    But, the core idea is just to paint price marker on each tick in proper (and different) colour.
                    fx.practic
                    NinjaTrader Ecosystem Vendor - fx.practic

                    Comment


                      #11
                      Hello fx.practic,

                      65,535 is the limit for custom WPF brushes that you can create. There isn't a good way to create new brushes and remove them to stay within this limit. The suggestion would be to create brushes that you can reuse.

                      Are you creating custom defined brushes with each bar and the colors of these brushes are not getting reused? If this is the case, I don't see a way to work around the issue without using custom rendering. SharpDX rendering could have brushes created based on Colors or RGBA values without using WPF brushes at all SharpDX also gives you better flexibility to dispose of these resources.

                      If you are making custom defined brushed that reuse the same colors, I would recommend creating those brushes ahead of time (perhaps in State.Configure or State.DataLoaded) and to use those predefined brushes as necessary throughout your code. This should avoid the WPF limitation.

                      Below is documentation reference for working with brushes which explains this limitation with WPF Brushes, offers some suggestions, and overviews SharpDX brush usage. If you wish to use SharpDX for your own customized rendering, I have included additional documentation for using SharpDX for custom rendering and for using SharpDX to override how plots are rendered. (This would involve custom rendering, and not calling base.OnRender() so the normal plot rendering is skipped.

                      Working with Brushes - https://ninjatrader.com/support/help...th_brushes.htm

                      Using SharpDX for Custom Rendering - https://ninjatrader.com/support/help..._rendering.htm

                      OnRender() (See "Using multiple SharpDX objects to override the default plot appearance") - https://ninjatrader.com/support/help...s/onrender.htm

                      You may also reference our Sample Custom Render indicator that comes with NinjaTrader 8 for more information.

                      Please let us know if there is anything else we can do to help.
                      JimNinjaTrader Customer Service

                      Comment


                        #12
                        Absolutely clear now.
                        Thank You, Jim
                        fx.practic
                        NinjaTrader Ecosystem Vendor - fx.practic

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by Jon17, Today, 04:33 PM
                        0 responses
                        1 view
                        0 likes
                        Last Post Jon17
                        by Jon17
                         
                        Started by Javierw.ok, Today, 04:12 PM
                        0 responses
                        4 views
                        0 likes
                        Last Post Javierw.ok  
                        Started by timmbbo, Today, 08:59 AM
                        2 responses
                        10 views
                        0 likes
                        Last Post bltdavid  
                        Started by alifarahani, Today, 09:40 AM
                        6 responses
                        41 views
                        0 likes
                        Last Post alifarahani  
                        Started by Waxavi, Today, 02:10 AM
                        1 response
                        19 views
                        0 likes
                        Last Post NinjaTrader_LuisH  
                        Working...
                        X