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

Make Draw Object Delete Itself

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

    Make Draw Object Delete Itself

    Hi there,

    I made a custom drawing tool that is a global horizontal line.
    What would be the way to destroy/remove that draw object if for example in its OnRender code it detected that the last price was above the line.
    Basically I'd like a way to trigger the code that runs if the user removes the line themselves.

    In the draw tool's code I have tried finding the object in the IChartObjects list and removing it, but the draw object stays on the chart.

    This method seemed to work before in testing when I was doing the same thing via a charttrader button added by an addon.

    Telling where the global chart objects are stored on disk would also be another way, then I could delete the line ref in that text file and set the horizontal line to locked and paint transparent, making it seemingly deleted. Then on next startup those global lines would really be gone.

    Thanks for your assistance

    #2
    Hello anon84,
    Thanks for your post.

    I would expect that method to work as well. Can we see how you are adding and removing the object from the chart?
    Josh G.NinjaTrader Customer Service

    Comment


      #3
      A correction of sorts: 'This method seemed to work before in testing when I was doing the same thing via a charttrader button added by an addon'

      I've just tried to recreate my earlier tests and it no longer removes the lines from the chart via the button. I've deleted the test code so I have no idea how I made it work before.

      Button removal code:

      Code:
          for(int i = CurrentChartControl.ChartObjects.Count-1; i >=0; i--)
          {
              if(CurrentChartControl.ChartObjects[i].GetType() == typeof(NinjaTrader.NinjaScript.DrawingTools.CustomLine))
              {
                  Print("removing");
                  CurrentChartControl.ChartObjects.RemoveAt(i);
              }          
          }
      Similar thing in the draw tool's code:

      Code:
                      IList<Gui.NinjaScript.IChartObject> myObjects = CurrentChartControl.ChartObjects;
      
                      for(int i = myObjects.Count-1; i >= 0; i--)
                      {
                          if(myObjects[i] == this)
                          {
                              Print("removed from list");
                              myObjects.RemoveAt(i);
                              break;
                          }
                      }
      *oh you also asked how I was creating the lines. I drew them from the draw tool menu. Maybe I had drawn them via TryStartChartDrawing() before. Will test if that works. If I don't edit this then it means it didn't work.
      Last edited by anon84; 05-10-2019, 11:26 AM.

      Comment


        #4
        anon84,
        Thanks for your note.

        There is not currently a supported way to remove a manually drawn object through NinjaScript. We are tracking demand for this functionality through feature request SFT-356, so I went ahead and added a vote on your behalf. Please reference this internal tracking number if you ever have questions regarding this feature request.

        That said, If you wanted to draw your custom line through NinjaScript than it would be possible to remove it through NinjaScript.
        Josh G.NinjaTrader Customer Service

        Comment


          #5
          Thanks.

          This thread got a lot of views quite fast, so maybe there are many people wondering how to do this.

          For those people I will say that I found a hacky way to do it via SendKeys sending a delete keypress.
          I tried 2 'WPF' ways to simulate input but they strangely didn't affect any draw objects, even though the delete command was confirmed working. As evidenced by typing letters to change symbol and seeing they were getting deleted.

          You'll need to use Win Forms and sort out any ambiguous reference errors, but it works perfectly. I'm sure there are some unforeseen problems with this but I am just taking the win. It even works when the chart is not the active window, and even if another draw object is selected the delete keypress only affects my line as intended. I guess the keypress is somehow getting sent to itself (the line) so it's surprisingly perfect.

          Just for testing purposes you can test it out by putting this inside the OnRender of your drawing tool:

          if(AttachedTo.Instrument.MarketData.Last.Price > EndAnchor.Price)
          SendKeys.Send("{DEL}");

          *UPDATE

          I have found the 'official' way of doing this via an NT method. The method is hidden but can be executed via reflection like so:

          Code:
          using System.Reflection;
          
          typeof(ChartControl).GetMethod("RemoveDrawingTool")
             .Invoke(ChartControlOfDrawObject, new Object[] { DrawingObjectToDelete, false, false });
          God knows why NT are afraid and would hide such a method.

          Note: If using the built-in ninjascript editor the reflection methods (ie GetMethod) may not show up in intellisense, so you'll just have to trust they exist and type them manually. All methods show up if editing via Visual Studio.

          *Edit: The intellisense shows up in NT if using the format: [variable].GetType().[Get Method etc.]

          Not sure what the 2 boolean parameters are for. Possibly for warnings if deleting a draw object from an indicator or strategy.


          Last edited by anon84; 05-19-2019, 04:11 PM. Reason: Intellisense discovery

          Comment


            #6
            Anon, thanks for posting this, I was looking for a way to delete an indicator drawn object as the RemoveDrawObject method doesn;t meet my requirements as the object that was removed keeps re-appearing.

            Could the ninjatrader rep on this thread please confirm that Anon's code is correct?

            Thanks
            Last edited by b16_aln; 08-22-2019, 03:46 AM.

            Comment


              #7
              Hello b16_aln,

              The code anon84 provided can be used at your own discretion, as this is not documented/supported code we can't confirm that will work in all cases. You can certainly test this code in what you are developing to see if it works for the intended purpose. If you have found this to work for the use case, that will be a good temporary workaround until a real method for NinjaScript is exposed.

              Using C# reflection is outside of documented NinjaScript because this is just a part of C#, if you want to use reflection to explore undocumented methods in NinjaScript you can do that. It is not generally suggested to do this because there can be unintended side effects in some situations, this is generally why the method/property is hidden in the first place. I am not saying the above code has any specific problems only that you should be cautious and make sure to test undocumented code if you plan to use it in your script.


              Please let me know if I may be of further assistance.
              JesseNinjaTrader Customer Service

              Comment


                #8
                I would also like to add a vote to SFT-356 so that it can be removed via supported method

                Comment


                  #9
                  Code:
                  using System.Reflection;
                  
                  typeof(ChartControl).GetMethod("RemoveDrawingTool")
                  .Invoke(ChartControlOfDrawObject, new Object[] { DrawingObjectToDelete, false, false });

                  If the above code does not work work for you try the code below.


                  Code:
                  using System.Reflection;
                  private NinjaTrader.NinjaScript.DrawingTools.Dot d1; 
                  
                          //Find manually drawn dot.  
                          d1 = null; 
                          foreach (Gui.NinjaScript.IChartObject thisObject in ChartPanel.ChartObjects)
                            {
                            if(thisObject is NinjaTrader.NinjaScript.DrawingTools.Dot)
                            {
                              d1 = thisObject as NinjaTrader.NinjaScript.DrawingTools.Dot;  
                              break; 
                            }
                          }
                  
                       // Delete it 
                       BindingFlags bfObject = BindingFlags.Instance | BindingFlags.NonPublic;
                       MethodInfo methodNT = typeof(ChartControl).GetMethod("RemoveDrawingTool", bfObject);
                       methodNT.Invoke(ChartControl, new Object [] { d1, false, false });

                  Comment


                    #10
                    Hello Bidder,
                    Thank you for the codes to remove manual drawn objects. For my testing on the Path drawingtool using these codes (DrawingTools.Dot sample), the results and side effects are as follows:
                    1. After executing the codes, the manual drawn Path objects are no longer visible on the chart but the drawing objects are still shown on the “Drawing Objects” dialog.
                    2. The Start Time of the Path object is changed to 1800-01-01 12:00:01 AM and Start Y changed to 0. This is similar to other occasions, when a workspace is crashed by a bad indicator.
                    3. The Start Time of 1800-01-01 12:00:01 caused error “Failed to call OnRender for 'Path': 'The added or subtracted value results in an un-representable DateTime. Parameter name: value' ”
                    4. The error was traced to the Path codes inside IsVisibleOnChart(...), statement: DateTime leftWidthTime = chartControl.GetTimeByX((int)minX);
                    5. Basically the Start Time of 1800-01-01 12:00:01 caused an error in the call to chartControl.GetTimeByX((int)minX);

                      On another note, for the Path drawingtool, it is rather surprising that NinjaTrader would not handle or filter errors due to out of range numbers, which could be caused by a corrupted workspace.
                    Last edited by kkc2015; 09-29-2020, 03:03 PM.

                    Comment


                      #11
                      Thanks anon84 and Bidder.

                      It would be very useful to have an officially supported method by NinjaTrader to delete user drawn drawings. Meanwhile your code is very helpful.
                      ASCENDO Trading
                      NinjaTrader Ecosystem Vendor - ASCENDO Trading

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by xiinteractive, 04-09-2024, 08:08 AM
                      3 responses
                      11 views
                      0 likes
                      Last Post NinjaTrader_Erick  
                      Started by Johnny Santiago, 10-11-2019, 09:21 AM
                      95 responses
                      6,193 views
                      0 likes
                      Last Post xiinteractive  
                      Started by Irukandji, Today, 09:34 AM
                      1 response
                      3 views
                      0 likes
                      Last Post NinjaTrader_Clayton  
                      Started by RubenCazorla, Today, 09:07 AM
                      1 response
                      6 views
                      0 likes
                      Last Post RubenCazorla  
                      Started by TraderBCL, Today, 04:38 AM
                      3 responses
                      26 views
                      0 likes
                      Last Post NinjaTrader_Jesse  
                      Working...
                      X