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

Is it possible to create GDI objects in any pane other than Pane 1?

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

    Is it possible to create GDI objects in any pane other than Pane 1?

    When I override the Plot Method the "bounds" parameter only encompasses the area in Pane 1.

    Is there an index on the ChartControl Object or some other way I can get a graphics object on Pane 2?

    I'm trying to paint circles with DrawEllipse & FillPath but they dissapear with the Indicator is put in Pane 2. So all suggestions welcome.

    #2
    David Lean, thanks for the post - unfortunately overriding the Plot method is stepping outside of our supported scope - have you tried setting DrawOnPricePanel to false for this?

    BertrandNinjaTrader Customer Service

    Comment


      #3
      Solved - sort of.

      "have you tried setting DrawOnPricePanel to false for this?"

      I played with this some more. If you are reading this thread for insight I found with "DrawOnPricePanel = false", you do get a Graphics context of the current pane in the PLOT event. (so a good thing to do)

      The coordinate system seems to change based on the Y-Axis scale. I moved my pane to almost full screen & saw my indicators (which are normally drawn at the bottom of the screen, up the top. ) They drifted down the screen as I made the window bigger. I realise that Y=0 is at the top of the screen & suspect that Y=0 is still at the top of Pane1 & not limited to your Pane. (However anything you render is clipped by the other panes.)

      So my conclusion is that rendering with GDI+ is possible & any bugs you have are likely to be related to the coordinate system.
      I'm unclear if WPF objects are supported will check on that later.

      I hope this helps you.

      Comment


        #4
        David, thanks for the feedback and reply - if you have a reproducible scenario outlining what you believe might be a bug, I'm happy to test and look into - please contact me at support at ninjatrader dot com Attn Bertrand if you like to follow up, thanks
        BertrandNinjaTrader Customer Service

        Comment


          #5
          Solution to both drawing GDI & using Ninja Drawing Methods. Part 1/2

          Using Ninja Drawing Methods (like DrawRegion)
          Advantage: It is supported. It is heaps simpler & you don't need to worry about the Z-Order as is just draws behind the price bars.
          Disadvantage: The DrawOnPricePanel property controls where your methods will draw, you can't draw in both at the same time, as you might need if you were drawing divergence lines.
          Tip: If you want your Draw methods to display in the window where the indicator is displayed set DrawOnPricePanel = false. Even if your indicator is in Panel 1, the price panel, it will still draw correctly.

          Comment


            #6
            Solution to both drawing GDI & using Ninja Drawing Methods. Part 2/2

            Using GDI+ methods to draw anything.
            Step 1: Grab one of the indicators from this forum & use their code as a template. This is not a complete article
            Step 2: When you override the Plot event eg:
            publicoverridevoid Plot(Graphics graphics, Rectangle bounds, double min, double max)
            Step 3. The "bounds" parameter gives you the area of the Panel that your indicator is displayed in. Most useful is bounds.Top & bounds.Height.
            These coordinates are relative to the entire area that all the indicators are displayed in; ie ChartControl.Top & ChartControl.Height.
            So if your indicator ranges from 0 to 100, you'll need to :-
            1st. Remember that Y=0 is the top of the screen so flip it by subtracting the value from 100 (or whatever you max is) eg: 100-myValue.
            2nd. Multiply it by bounds.Height to scale it up to the full height of the panel. ie: (100 - myValue) * bounds.Height
            3rd. Add bounds.Top to the result. This moves it down the screen so it displays in the correct panel.
            Done.
            Tip 2: Be careful about doing anything other than drawing in the Plot event. If you calculate values or set global variables you risk confusing the "CalculateBarOnClose" property. As you will be "CalculatingStateWheneverTheScreenIsRefreshed" , which might be less frequently than every tick, but more often than every bar. This could be OK, or may cause errors in your logic.

            Tip 3:
            The BarWidth Property you configure on the chart, is not identical to the ChartControl.Barwidth property. The latter is determined by your screen resolution. You can convert it using

            int barWidth = ChartControl.ChartStyle.GetBarPaintWidth(ChartControl.BarWidth);








            Tip 4: To find the locations of each bar the ChartControl offers a variety of methods to assist. eg:
            a) .FirstBarPainted & .LastBarPainted tells you what bars are visible on the screen.
            b) Note: Bar 0 is the LeftMost or oldest bar & increased by 1 for every bar to the most recent. This is exactly the opposite of the indexing you use for a dataseries, where Close[0] is the Rightmost or most recent bar. So you need to use CurrentBar to find the number of the RightMost bar.
            c) ChartControl.GetXByBarIdx lets you find where to plot relative to each bar. (I don't know if it is more or less efficient than the commmon alternative of doing the maths the ChartControl methods. Given that they are loop invarient if you made them variables & set them prior to the loop it might be faster to do the following :-
            int x = (int) (ChartControl.CanvasRight - ChartControl.BarMarginRight - barWidth / 2 - (ChartControl.BarsPainted - 1) * ChartControl.BarSpace + count * ChartControl.BarSpace) + 1;
            I think the following was easier to read, so the choice is yours






            Code Example
            for(int cntBar = ChartControl.FirstBarPainted; cntBar <= ChartControl.LastBarPainted; cntBar++) {

            seriesvalue = Stochastics(periodD, periodK, smooth)[CurrentBar - cntBar];

            if (seriesvalue == 0)
            continue;
            int x = ChartControl.GetXByBarIdx(cntBar);
            int y = (int) (((100.0 - seriesvalue) * (double)bounds.Height)/100.0) + bounds.Top;
            if (lastX >= 0) {

            path.AddLine(lastX - plot.Pen.Width /
            2, lastY, x - plot.Pen.Width / 2, y);

            }
            lastX = x;
            lastY = y;
            }
            I hope you find this useful.

            Dave

            Comment


              #7
              David, thanks for sharing those tips!
              BertrandNinjaTrader Customer Service

              Comment


                #8
                David,

                I came across this post after eDanny recommended it from here.



                We hope you stick around!


                Thanks,

                Comment


                  #9
                  Code Example

                  David
                  First let me say thanks for this.
                  I really struggle to get the concept of bounds and coords right - and I am still not getting it.
                  My coding skills are relatively basic in these areas but I couldn't get your example code to run.
                  Could you provide a complete idiots version?

                  Comment


                    #10
                    simplified solution

                    For beginners or lazy programmers: I have found that it is just easier to switch between indicator and price panel for drawing divergence lines.
                    This code will be in stochastics:

                    PHP Code:
                    if( bDivergence )
                    {
                    DrawOnPricePanel false;
                    DrawLinestrDivTagfalsebagoEx1K1bagoEx0K0minidivLineColorDashStyle.Solid 5);
                    DrawDot"MDDOT" + (CurrentBar-bagoEx0).ToString(), falsebagoEx0K[bagoEx0], minidivDotColor);
                    DrawDot"MDDOT" + (CurrentBar-bagoEx1).ToString(), falsebagoEx1K[bagoEx1], minidivDotColor);
                     
                    DrawOnPricePanel true;
                    DrawLine"PR"+strDivTagfalsebagoEx1P1bagoEx0P0,minidivLineColorDashStyle.Solid 5);
                    DrawDot"MDDOTPR" + (CurrentBar-bagoEx0).ToString(), falsebagoEx0P0minidivDotColor);
                    DrawDot"MDDOTPR" + (CurrentBar-bagoEx1).ToString(), falsebagoEx1P1minidivDotColor);

                    Just play with :
                    DrawOnPricePanel = true; or DrawOnPricePanel = false;

                    Comment


                      #11
                      Originally posted by David Lean View Post
                      int y = (int) (((100.0 - seriesvalue) * (double)bounds.Height)/100.0) + bounds.Top;
                      havent read the whole stuff, but to draw in different pane make sure,

                      bounds.Y + bounds.Height

                      Comment


                        #12
                        very neat

                        I am sure programmers will be pulling their hair out - but that is a very simple and neat solution dimkdimk.

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by Irukandji, Today, 05:50 AM
                        0 responses
                        5 views
                        0 likes
                        Last Post Irukandji  
                        Started by ageeholdings, Today, 05:22 AM
                        0 responses
                        9 views
                        0 likes
                        Last Post ageeholdings  
                        Started by llanqui, 04-28-2024, 10:32 AM
                        2 responses
                        19 views
                        0 likes
                        Last Post llanqui
                        by llanqui
                         
                        Started by DroneBlackCa, Today, 05:17 AM
                        0 responses
                        6 views
                        0 likes
                        Last Post DroneBlackCa  
                        Started by tradingnasdaqprueba, 04-09-2024, 09:52 AM
                        7 responses
                        50 views
                        0 likes
                        Last Post NinjaTrader_Gaby  
                        Working...
                        X