Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Custom Chart: Multiple indicator slots per bar

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

    Custom Chart: Multiple indicator slots per bar

    Greetings

    The attached image is a type of a custom chart that I would like to create. I know that this will require quite a bit of custom render development. However before I delve too deeply into such an effort, I would like to know if this type of a chart is even possible in NT8.

    The attached drawing depicts a regular 5 minute OHLC chart. However the twist is that each bar has spaces for three indicator slots in the indicator pane, as to opposed to the usual one. There is the typical indicator slot in the middle which at is aligned to OHLC price bar. Then there is an indicator slot to the left and another slot to the right.

    I suppose one approach is to take a NT8 minute chart template and some how create additional spaces or slots to the right and left of the bar. However I'm not confident if this is possible let alone feasible.

    So the questions are:

    1) Is the creation of this type of chart/indicator possible with NT8?
    2) If so, what is best approach to take?

    Thanks in advance for any help, hint or suggestions.

    Click image for larger version

Name:	IMG_20210317_094935.jpg
Views:	351
Size:	205.7 KB
ID:	1147046

    #2
    Hello svrz,

    Thank you for your post.

    There's a couple ways you could try approaching this.

    Depending on the time frame, you could put another data series on that is 1/3 of primary, make it invisible, and then use that data series for plotting.

    Depending on the values you want shown, you could consider using a block style plot with different colors. If you only need indication and not a value or can tie value to a color, you could take this approach of using x plots (4 in the attached blockstyleplotexample).

    You could also go the custom rendering approach and get the variables for bar spacing, etc, and divvy it up as you like.

    It sounds somewhat like the custom rendering approach would be what you'd want, but if you can provide more detail about what the values are that you're trying to have plotted around the bar would be we can give a more definitive answer.

    Please let us know if we may be of further assistance to you.
    Attached Files
    Last edited by NinjaTrader_Kate; 03-17-2021, 12:33 PM.

    Comment


      #3
      Hi Kate

      Thank you very much for the prompt reply and for the example that you attached. I will carefully look at it when I have a moment.

      To answer your question, yes, the bars below the price pane will have values just like any other indicator. Think of it as similar to the MACD indicator which has 3 components. The difference will be that these components will have to be plotted next to one another in the column style.

      I suppose the pseudo data structure can look something like this:

      {
      DateTime
      Open,
      High,
      Low,
      Close,
      Indicator1,
      Indicator2,
      Indicator3
      }

      So the OHLC will be plotted as it normally would. However on the indicator pane, Indicator1 will be plotted to the left of price bar, Indicator2 at the center (exactly below the price bar) and finally Indicator3 to the right of the price bar. The crude drawing that I attached to original post best represents this idea.

      The 5 minute timeframe will be the most used timeframe for this type of an indicator or chart.

      Thanks again for your assistance.

      Comment


        #4
        Hello svrz,

        Thank you for your reply.

        In that case, I would recommend the custom rendering approach. You'd need to figure out the bar width of the primary bars and divvy that up. Here's an example from our User App Share that renders candlestick type bars like a chart would that gets the bar width and uses that to plot - you could certainly use this as a jumping off point:

        https://ninjatraderecosystem.com/use...cators-sample/

        I'd also recommend reviewing this section of our help guide on custom rendering using SharpDX:

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

        Please let us know if we may be of further assistance to you.

        The NinjaTrader Ecosystem website is for educational and informational purposes only and should not be considered a solicitation to buy or sell a futures contract or make any other type of investment decision. The add-ons listed on this website are not to be considered a recommendation and it is the reader's responsibility to evaluate any product, service, or company. NinjaTrader Ecosystem LLC is not responsible for the accuracy or content of any product, service or company linked to on this website.

        Comment


          #5
          Hello Kate

          Once again thanks for the prompt reply and including a sample.

          As I study the image that was attached to the sample, I'm not sure if this particular example can be helpful.

          In essence, I need to create two empty slots on a 5 minute OHLC chart, one to the left of the bar and one to the right. Furthermore, these slots must be carried over to the indicator pane which will have two column bars on either side of the principal bar. Please refer to image that is attached to this post.

          Perhaps a better example would be having a volume indicator pane but instead of one bar corresponding to the OHLC bar, there would be two additional bars on either side of the center volume bar. All three bars would correspond to one OHLC bar. I see your point in regards to bar spacing but I'm not sure if this would address the issue of allowing more than one indicator bar to correspond to one OHLC bar.

          I apologize if I misunderstand your suggestions.

          Take careClick image for larger version

Name:	IMG_20210317_094935B.jpg
Views:	295
Size:	213.8 KB
ID:	1147135

          Comment


            #6
            Hello svrz,

            Thank you for your reply.

            The second example in my previous reply would give you a jumping off point to custom render multiple bars. We don't have an example of this, but that should give you the information you would need to get the bar width, divide that into thirds, and then render your custom bars.

            You could do your custom rendering in either the primary chart or an indicator panel, but that would be the route to take.

            Please let us know if we may be of further assistance to you.

            Comment


              #7
              Hello Kate

              Thanks to your help, we are almost there.

              As you can see from the attached image, the scaling is a problem. In the candle example that you referred me to, I did not see any code to handle scaling. I was under the impression that NT would automatically handle this but apparently this assumption was incorrect.

              Here is the code taken directly from the help files that I hoped would resolve the issue but unfortunately it did not:

              Code:
              public override void OnCalculateMinMax()
              {
              int tmpMin = int.MaxValue;
              int tmpMax = int.MinValue;
              
              for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex; idx++)
              {
              
              //There are two volume based series
              int plotValue1 = VolSeries1.GetValueAt(idx);
              int plotValue2 = VolSeries2.GetValueAt(idx);
              
              //Get the max value of these two series
              int plotValue = Math.Max(plotValue1, plotValue2);
              
              // return min/max of volume value
              tmpMin = Math.Min(tmpMin, plotValue);
              tmpMax = Math.Max(tmpMax, plotValue);
              }
              
              
              MinValue = tmpMin - 50;
              MaxValue = tmpMax + 50;
              }
              Furthermore, I'm not sue why the y-axis label is on the left side.

              Please advise.

              Thanks

              Attached Files
              Last edited by svrz; 03-29-2021, 09:40 PM.

              Comment


                #8
                Hello svrz,

                Thank you for your reply.

                Is IsAutoScale set to true in State.SetDefaults?

                What is ScaleJustification set to in State.SetDefaults? If this is set to NinjaTrader.Gui.Chart.ScaleJustification.Left; we would expect the scale to be seen on the left side.

                Thanks in advance; I look forward to assisting you further.

                Comment


                  #9
                  Hi Kate

                  The ScaleJustfication issue was resolved by setting it to Right in the chart settings. Thanks for that.

                  To answer your question, 'IsAutoScale' is set to True in 'State.SetDefaults.'

                  Through VS debugging, I can see 'VolSeries1' and 'VolSeries2' being set to correct values in the OnBarUpdate method.

                  It may be that I'm misunderstanding something. 'VolSeries1' and 'VolSeries2' are 'Series<int>' types. As I mentioned the values for these arrays are being set in 'OnBarUpdate.' I'm using the values from these arrays to draw the bars (via FillRectangle) in the 'OnRender' method. Here are the snippets of this code:

                  Code:
                  protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                  {
                  int barWidth = (int)ChartBars.Properties.ChartStyle.BarWidth;
                  
                  for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex; idx++)
                  {
                  if (idx < BarsRequiredToPlot) return;
                  
                  int x = chartControl.GetXByBarIndex(ChartBars, idx);
                  List<float> lf = GetBarDistance(idx);
                  
                  float barDist = (lf[1] - lf[0]) / 2;
                  
                  CreateBar(VolSeries1.GetValueAt(idx), lf[0], lf[0] + barDist, SharpDX.Color.Red);
                  CreateBar(VolSeries2.GetValueAt(idx), lf[0] + barDist, lf[1], SharpDX.Color.Black);
                  
                  }
                  }
                  
                  private void CreateBar(float value, float x1, float x2, SharpDX.Color clr)
                  {
                  int barWidth = (int)ChartBars.Properties.ChartStyle.BarWidth;
                  float y0 = ChartPanel.Y + ChartPanel.H;
                  float y1 = y0 - value;
                  SharpDX.Vector2 startPoint = new SharpDX.Vector2(x1, y0);
                  SharpDX.Vector2 endPoint = new SharpDX.Vector2(x2, y1);
                  
                  // calculate the desired width and heigh of the rectangle
                  float width = endPoint.X - startPoint.X;
                  float height = endPoint.Y - startPoint.Y;
                  
                  // construct the rectangleF struct to describe the with position and size the drawing
                  SharpDX.RectangleF rect = new SharpDX.RectangleF(startPoint.X, startPoint.Y, width, height);
                  
                  // define the brush used in the rectangle
                  SharpDX.Direct2D1.SolidColorBrush customDXBrush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, clr);
                  
                  // execute the render target fill rectangle with desired values
                  RenderTarget.FillRectangle(rect, customDXBrush);
                  
                  // always dispose of a brush when finished
                  customDXBrush.Dispose();
                  }
                  I hope I have provided enough information.

                  Thanks again for your assistance.

                  Comment


                    #10
                    Hello svrz,

                    Thank you for your reply.

                    It looks like the X scaling is working correctly from your screenshot, but the y scaling is the issue, correct?

                    What I would recommend to troubleshoot would be to print the MinValue and MaxValue after these are set, and print the price values the for the series those rendered objects are rendered on, so your VolSeries1 and VolSeries2 values, so we can see what values are being set for those and whether CalculateOnMinMax is being called appropriately.

                    What do you see printing those values?

                    Thanks in advance; I look forward to assisting you further.

                    Comment


                      #11
                      Hi Kate

                      Thanks again for your assistance.

                      To answer your question, yes, the Y scaling is the problem.

                      The indicator is volume based so it has nothing to do with price.

                      Here is an image of the NT's output window.

                      Click image for larger version

Name:	table.jpg
Views:	293
Size:	98.2 KB
ID:	1149529I
                      ​​​​​​I'm not sure why the plot shows a scale of 0 -> 120k. At one point in the series there may have been a value of 120K but as you can see not one single value reaches that number in the chart's visible area.

                      Thanks again.

                      Comment


                        #12
                        Hello Svrz,

                        Thank you for your reply.

                        My colleague Jim thought this was an interesting idea and would make a good example script, so he's made an example that would be a good starting point for you. This will appropriately scale the bars created in OnRender.

                        I'd advise taking a look at this script and comparing to yours to see what may be different between the two.

                        Please let us know if we may be of further assistance to you.

                        Attached Files

                        Comment


                          #13
                          Hi Kate

                          This is simply fantastic! I express my immense gratitude to you and your colleague Jim. Without your help, this type of a plot would not have been possible.

                          Best wishes.

                          Comment


                            #14
                            Kate

                            If I may ask you or your colleague Jim one more question:

                            The brushes are initialized in the constructor as such:

                            Code:
                            for(int i = 0; i < PlotWMBrushes.Length; i++)
                            PlotWMBrushes[i] = Brushes.Red;
                            
                            PlotWMBrushes[0] = Brushes.Red;
                            PlotWMBrushes[1] = Brushes.Green;
                            PlotWMBrushes[2] = Brushes.Blue;
                            PlotWMBrushes[3] = Brushes.Orange;
                            If I wanted to dynamically change the respective brushes at run time in such a way:

                            Code:
                            protected override void OnBarUpdate()
                            {
                                 if (something)
                                 {
                                      PlotWMBrushes[0] = Brushes.Black;
                                      PlotWMBrushes[1] = Brushes.Red;
                                 }
                                 else
                                 {
                                    PlotWMBrushes[0] = Brushes.Red;
                                    PlotWMBrushes[1] = Brushes.Black;
                                 }
                            }
                            I see that the changes do not take place which simply means the colors remain Red and Green respectively. I removed the initialization code in the constructor which resulted in the colors being changed the first time they are assigned but not after that. That is the respective brushes remained Black and Red with no other changes taking place.

                            So the question is can the brush colors be changed dynamically? I apologize if the question is rudimentary. Unfortunately my knowledge of SharpDX and MS' DirectX programming is minimal at best.

                            Thanks again for your assistance.


                            Comment


                              #15
                              Hello svrz,

                              I thought the example would be useful for others and a good personal challenge so I used some of my free time to put it together. I'm glad you found it helpful.

                              The SharpDX brushes and the Windows Media brushes are separate and the SharpDX brushes would need to be updated from OnRender or OnRederTargetChange. If we are to change the brushes depending on conditions using logic from OnBarUpdate, you could do something similar to the SetOpacity helper method I left so you can update the appropriate Windows Media brush, and then signal that the DX brush needs to be updated. OnRender will then check PlotBrushNeedsUpdate on the next render pass and update any brushes needed.

                              This would change the color for the plot and not a specific bar since all of that is handled in OnRender. If you want to change specific bars to show specific colors, I suggest creating another set of brush arrays like I have with PlotDXBrushes and PlotWMBrushes, so you can have 2 different kinds of brushes prepared for each plot (or as many as you want,) and then you can use logic in OnRender to draw bars with different brushes.

                              We look forward to assisting.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                              0 responses
                              606 views
                              0 likes
                              Last Post Geovanny Suaza  
                              Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                              0 responses
                              353 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by Mindset, 02-09-2026, 11:44 AM
                              0 responses
                              105 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                              0 responses
                              560 views
                              1 like
                              Last Post Geovanny Suaza  
                              Started by RFrosty, 01-28-2026, 06:49 PM
                              0 responses
                              561 views
                              1 like
                              Last Post RFrosty
                              by RFrosty
                               
                              Working...
                              X