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

Drawing thext next to the rectangle

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

    Drawing thext next to the rectangle

    Hello!
    I am looking for a way to draw a text next to my rectangle.
    I can draw the rectangle successfully. The problem comes when I have to draw my text. The text should be drawn right to the rectangle and should not be a fixed text, since the rectangle is drawn dynamically too. That means, when a new bar is formed, the rectangle increases in the length and the text therefore has to move so that the space between the rectangle and the text remains.
    I have used the following function to dray the rectangle:

    HTML Code:
    Draw.Rectangle(NinjaScriptBase owner, string tag, DateTime startTime, double startY, DateTime endTime, double endY, Brush brush)
    The constructor was surcharged here among others with the DateTime startTime and DateTime endTime.
    The following function could be appropriate to draw the text:

    HTML Code:
    Draw.Text(NinjaScriptBase owner, string tag, bool isAutoScale, string text, DateTime time, double y, int yPixelOffset, Brush textBrush, SimpleFont font, TextAlignment alignment, Brush outlineBrush, Brush areaBrush, int areaOpacity)
    Also here, I have in the constructor among others the argument DateTime startTime. But if I use this function, the startTime for the rectangle would overlap with that of the text. Since it is not possible to have the time for Bar[-x] for example (x!=0), I am failing here to solve this problem.

    Any help would be welcome.

    Thanks
    Last edited by Stanfillirenfro; 08-01-2022, 05:09 AM.

    #2
    Hello Stanfillirenfro,

    Drawing text next to the rectangle would require making a custom draw object that does that action or using OnRender instead of drawing tools.

    The bounds of the rectangle are controlled by the start and end bars ago or dates being used. When you call the rectangle to update it you would have to do the same for the text to supply new barsago/times for it to be moved. A Text object can be placed using barsago/dates as well but that won't correspond to the rectangle at all so it may be on the line of the rectangle or inside it or overlap.

    To do this without any overlapping between the objects or to maintain a fixed position in relation to the rectangle would require that the drawing object code draws that text in addition to the rectangle. You could make a copy of the existing rectangle drawing tool and add text into its OnRender logic if you wanted to do that. Alternatively you would have to use the indicators OnRender override to render your own rectangle and text using x/y coordinates.

    JesseNinjaTrader Customer Service

    Comment


      #3
      Many thanks Jesse for your reply.
      I am proceeding smoothly with the programmation you know, since I do not have strong skills yet.
      Please what do you mean with
      You could make a copy of the existing rectangle drawing tool and add text into its OnRender logic
      ? Do you mean the function I have used above to draw the rectangle?
      If yes, the constructor of Draw.Text does not accept something related to text or am I misunderstanding?

      Thanks!

      Comment


        #4
        Hello Stanfillirenfro,

        You can view the code for the drawing tools in the NinjaScript editor, you can also make your own drawing tools. Because text is not a feature of the rectangle tool by default you could make a new drawing object and re use the existing code for Draw.Rectangle as a starting point. That is a little more difficult than just using OnRender directly from your indicator to render rectangles/text because you have to worry about making a whole new drawing tool. This is the only way to be able to use the same general code that you are or Draw.MyCustomRectangle to be able to have text and rectangle linked.

        The problem here is that both the rectangle and text are separate drawing tools with specific ways they render, they don't know about each other to be placed a distance away from each other. To make a combination of text and rectangle requires OnRender. OnRender is used in both the rectangle drawing tool and the text tool so the code is already there but in separate scripts. A new drawing tool could make use of those individual drawing objects OnRender code to make a combination tool that draws both a rectangle and text.

        There are a couple of simplified examples of rectangles and text from OnRender in the following link:


        JesseNinjaTrader Customer Service

        Comment


          #5
          Many thanks Jesse for the help.

          I think I can start something with the link you have provided me. I will for sure revert to you very soon (maybe tomorrow) for feedback.

          Thanks again.

          Comment


            #6
            NinjaTrader_Jesse

            I am still facing a problem to complete my code.
            I have the following code, but with error message.
            HTML Code:
            SharpDX.RectangleF rectangleF = new SharpDX.RectangleF(startPoint.X+Time[5], startPoint.Y+Time[0], ChartPanel.W+High[0], ChartPanel.H+Low[0]);
            The error message mentions that I can not used a float with DateTime.

            Could you pleaee advise how to fix this problem?

            Thanks!

            Comment


              #7
              Hello Stanfillirenfro,

              You have a few issues in the provided code. The main issues are the way you have used the series and also that you are trying to mix times and Y values which are not the same.

              To get an X value you can use a time but you need to convert the time to an X value.

              https://ninjatrader.com/support/help...getxbytime.htm

              Because you are using OnRender BarsAgo don't apply so Time[0] wouldn't be valid. You would need to specify the index for the bar you wanted, 0 bars ago is the current bar so that would be Bars.Count - 1 for the index.

              In OnRender you can't access bar related series like you would in OnBarUpdate, you need to use the GetValueAt method:

              https://ninjatrader.com/support/help...sub=getvalueat

              Combining these details you would end up with the following syntax to get the current bars index:

              Code:
              double x = chartControl.GetXByTime(Time.GetValueAt(Bars.Count - 1));
              Alternatively you can get a bar by its index without involving the time: https://ninjatrader.com/support/help...ightsub=getxby

              Code:
              double x = chartControl.GetXByBarIndex(ChartBars, Bars.Count - 1);
              To get Y coordinates you need to specify a Price and convert it to a Y:

              https://ninjatrader.com/support/help...ightsub=getyby

              Code:
               int yByValue = chartScale.GetYByValue(Bars.GetHigh(Bars.Count - 1));
              The width and height you are using are also not valid, ChartPanel.W+High[0], ChartPanel.H+Low[0]

              You are adding a price to a Time by using W+High, you need to specify a width across the X axis so a price would not be used here. You could specify another bar but you would have to convert that bar index to an X value first. This is also the panel width so adding to this value would be outside the panel.
              https://ninjatrader.com/support/help...b=ChartPanel.W

              The H can have a price because that's the vertical or Y scale but ChartPanel.H is the height of the panel so adding more to that will be outside the panel. https://ninjatrader.com/support/help...b=ChartPanel.H

              Last edited by NinjaTrader_Jesse; 08-10-2022, 09:15 AM.
              JesseNinjaTrader Customer Service

              Comment


                #8
                Hello NinjaTrader_Jesse and many thanks for your reply.
                Please allow me to ask some questions here.
                In the following code,
                HTML Code:
                SharpDX.RectangleF rectangleF = new SharpDX.RectangleF(startPoint.X, startPoint.Y, ChartPanel.W, ChartPanel.H);
                if I understand properly, startPoint.X would be the X value and startPoint.Y the Y value correct? If yes, replacing these value by
                HTML Code:
                double x = chartControl.GetXByTime(Time.GetValueAt(Bars.Count - 1));
                for X value and
                HTML Code:
                int yByValue = chartScale.GetYByValue(Bars.GetHigh(Bars.Count - 1));
                for Y value pups up error messages.
                Since it is confusing for me here, could you please advise in which function the X and Y values have to be converted and replaced?
                Because after replacement I have the following functions:

                HTML Code:
                SharpDX.Vector2 startPoint = new SharpDX.Vector2(x, y);
                with x and y as above declared.

                When I use the following:
                HTML Code:
                SharpDX.Vector2 startPoint = new SharpDX.Vector2(ChartPanel.X, ChartPanel.Y);
                I have my text on the upper left corner of the window.

                Thanks!
                Last edited by Stanfillirenfro; 08-11-2022, 04:18 AM.

                Comment


                  #9
                  Hello Stanfillirenfro,

                  In the code you provided for RectangleF that would be the format of X,Y,Width,Height as its parameters.

                  X and Y are the location of the top left of the rectangle. The width and height are the amount of pixels wide and high that you want the rectangle to be.

                  What error are you seeing for the Y value code?

                  You will need to convert any bar related data to X and Y when using OnRender. OnRender does not use chart values it uses the rendering system which uses Pixels. Times would need converted to an X or horizontal value. Price would need converted to a Y or vertical value.

                  The ChartPanel.X and Y are its location, that's generally 0,0 for X,Y. That is suggested to be used in place of 0,0 to account for the platforms panel placement options. If you wanted something to fill the panel that would be:

                  Code:
                  ChartPanel.X, ChartPanel.Y, ChartPanel.W, ChartPanel.H for the X,Y,W,H of a rectangle.
                  If you wanted something on the right side of the chart you need to use math for that X value:

                  Code:
                  double panelWidth = ChartPanel.X + ChartPanel.W;
                  double xOffsetFromRight = panelWidth - 300;
                  Just as an example this offsets the starting X point 300 pixels from the right of the chart. If your text was more than 300 pixels wide you would subtract more than 300 to show the whole text.



                  Its helpful to look at the pictures provided in the help guide for these objects:









                  JesseNinjaTrader Customer Service

                  Comment


                    #10
                    Hello NinjaTrader_Jesse and many thanks for your help.

                    I am moving forward, but very slowly.

                    I have finally the follwoing codes:
                    HTML Code:
                    float XCoordinate = chartControl.GetXByTime(Time.GetValueAt(Bars.Count-1));
                    float YCoordinate = chartScale.GetYByValue(Bars.GetHigh(Bars.Count-1));
                    float highValue = chartScale.GetYByValue(Bars.GetHigh(Bars.Count-1));
                    float lowValue = chartScale.GetYByValue(Bars.GetHigh(Bars.Count-1));
                    float center = highValue-(highValue-lowValue)/2;
                    The problem here is that I can use only the float. No double or int.

                    HTML Code:
                    SharpDX.Vector2 startPoint = new SharpDX.Vector2(ChartPanel.X+XCoordinate+5, ChartPanel.Y+YCoordinate);
                    SharpDX.DirectWrite.TextFormat textFormat = new SharpDX.DirectWrite.TextFormat(Core.Globals.DirectWriteFactory, "Arial", 12);
                    SharpDX.RectangleF rectangleF = new SharpDX.RectangleF(startPoint.X, startPoint.Y, ChartPanel.W, ChartPanel.H+center);
                    SharpDX.Direct2D1.SolidColorBrush customDXBrush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.DodgerBlue);
                    RenderTarget.DrawText("myText", textFormat, rectangleF, customDXBrush);
                    At the end, I can have some text, but it moves everytime a new high of a bar is formed. It is really weird!!! When the prices form a bearsih bar, the text remains only at the open of the bar.
                    I also have the text right to the bar, what is good for me.

                    Could you please advise how to get the text fixed on the Y coordinate?

                    Thanks!
                    Last edited by Stanfillirenfro; 08-12-2022, 10:45 AM.

                    Comment


                      #11
                      Hello Stanfillirenfro,

                      Converting a type in C# is a called casting, you can cast a double to a float or a float to a double.

                      Code:
                      double a = (double)myFloat; 
                      float b = (float)myDouble;

                      At the end, I can have some text, but it moves everytime a new high of a bar is formed. It is really weird!!! When the prices form a bearsih bar, the text remains only at the open of the bar.
                      You are using the current bar index by using Bars.Count-1, that means each time a new bar is generated the index increases.

                      If you want fixed text based on the panel you need to avoid using bars or times for the X coordinate and instead use the ChartPanel.X to know the left of the panel or the ChartPanel.W to know the right of the panel.

                      The same with Y values, fixed Y values are based on the charts Y and H values to know the top and bottom of the panel.

                      This works just like a mathematic graph which uses X/Y values. You have a starting point of 0,0 and you can increase the value of either X or Y to move through the graph. At this level you don't need to know anything about bars or prices since you are just working with the rendering engine in X and Y coordinates.




                      JesseNinjaTrader Customer Service

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by Jonafare, 12-06-2012, 03:48 PM
                      5 responses
                      3,984 views
                      0 likes
                      Last Post rene69851  
                      Started by Fitspressorest, Today, 01:38 PM
                      0 responses
                      2 views
                      0 likes
                      Last Post Fitspressorest  
                      Started by Jonker, Today, 01:19 PM
                      0 responses
                      2 views
                      0 likes
                      Last Post Jonker
                      by Jonker
                       
                      Started by futtrader, Today, 01:16 PM
                      0 responses
                      7 views
                      0 likes
                      Last Post futtrader  
                      Started by Segwin, 05-07-2018, 02:15 PM
                      14 responses
                      1,791 views
                      0 likes
                      Last Post aligator  
                      Working...
                      X