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

MouseMove event

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

    #16
    Error on click when drawline code added

    Piersh,

    Code works well with MouseUp and the coordinates are displayed in the Output window successfully using the Print statement.

    I have tried to add the code (highlighted in bold) to the use these coordinates to draw a line between the clicked on areas, but this does not work - I get a "Ninja has detected a problem ..." error when I click. I have also tried to replace X and Y with static values and this also generates the same error. Do I have my drawline in the right place, Am I doing something stupid? Any suggestions would be most appreciated.

    void ChartControl_MouseMove (object sender, System.Windows.Forms.MouseEventArgs e)
    {
    eventCount ++;
    double right = _chartBounds.Right - this.ChartControl.BarMarginRight - this.ChartControl.BarWidth - this.ChartControl.BarSpace / 2;
    double bottom = _chartBounds.Bottom;

    double x = right - e.X;
    double y = bottom - e.Y;

    int iBar = this.LastVisibleBar + (int) Math.Round (x / this.ChartControl.BarSpace);
    double price = _min + y * (_max - _min) / _chartBounds.Height;

    if(eventCount == 1)
    {
    x1 = iBar;
    y1 = price; // y1-axis;
    }
    else if(eventCount == 2)
    {
    x2 = iBar;
    y2 = price; // y2-axis;
    eventCount = 0;
    }
    profitLine = Math.Max(y1, y2) - Math.Min(y1, y2);
    midPoint = Math.Min(y1, y2) + profitLine /2;
    string str = (profitLine * 10000).ToString("f0");

    Print(y1 + "::" + x1 + " , " + y2 + "::" + x2);
    if(Math.Min(y1,y2) > 0)
    {
    DrawLine("tag" + y1, 10, y1, 5, y2, Color.LimeGreen,DashStyle.Solid, 2);
    // DrawLine("tag" + y1, 10, 1.5090, 5, 1.4456, Color.LimeGreen,DashStyle.Solid, 2);
    // DrawText("tag2", str, 10, midPoint, Color.Black);
    }

    }
    Attached Files

    Comment


      #17
      Originally posted by traderT View Post
      I get a "Ninja has detected a problem ..." error when I click. I have also tried to replace X and Y with static values and this also generates the same error. Do I have my drawline in the right place, Am I doing something stupid?
      no, i got the same error:
      PHP Code:
       XYIndicator.DrawDot: bar out of valid range 0 through -1, was 75. 
      
      i think this is because NT leaves the Bars collection in an invalid state. i've poked around in the debugger, but everything throws exceptions during mouse events.

      there's a workaround, however.

      declare the following in your Indicator's class:


      PHP Code:
              delegate void Action ();
              Queue<Action> _rgPending = new Queue<Action> (); 
      
      then add pending operations to the queue in your ChartControl_MouseXXXX event handler. don't forget to refresh the control:
      PHP Code:
                  _rgPending.Enqueue (
                      delegate () {
                          this.DrawDot ("foo" + iBar, iBar, price, Color.Red);
                      }
                  );
      
                  this.ChartControl.Refresh (); 
      
      then, in Plot(), do the following:

      PHP Code:
                  foreach (Action pending in _rgPending)
                      pending (); 
      
      then you can waste a few minutes drawing silly lines on your charts ;-) like this:
      Attached Files

      Comment


        #18
        I found another way

        Found another way, not sure how good it will be, but it seems to work using a custom event (basically, wait for ALT to be pressed then do drawing thing)

        if(((Control.ModifierKeys & Keys.Alt) == Keys.Alt))
        {

        TriggerCustomEvent(new CustomEvent(MyCustomHandler), e);


        My only problem now is getting xx1 and xx2 to work properly, seems to convert from double to int32 and give a result of 0, no idea why yet.

        Anyway, the indicator below draws a line between 2 alt clicked points on the vertical access and tells you the points/distance. Tradestation has this tool, but NT doesn't.

        #region Using declarations
        using System;
        using System.ComponentModel;
        using System.Diagnostics;
        using System.Drawing;
        using System.Drawing.Drawing2D;
        using System.Xml.Serialization;
        using NinjaTrader.Cbi;
        using NinjaTrader.Data;
        using NinjaTrader.Gui.Chart;
        using System.Windows.Forms;
        #endregion

        // This namespace holds all indicators and is required. Do not change it.
        namespace NinjaTrader.Indicator
        {
        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        public class XYIndicator : Indicator
        {
        #region Variables
        // Wizard generated variables
        private int init1 = 1; // Default setting for Init1
        private int init2 = 1; // Default setting for Init2
        private bool _init = false;
        private bool click = false;
        private double _mouseOffset = 0;
        private int eventCount = 0;
        private double x1 = 0;
        private double y1 = 0;
        private double x2 = 0;
        private double y2 = 0;
        private int xx1 = 0;
        private int xx2 = 0;
        private double midPoint = 0;
        private double profitLine = 0;
        private string strProfitLine = "";
        private string str = "";
        private Font strFont;
        // private double _mouseOffset = 0;
        // private double _mouseOffset = 0;

        // User defined variables (add any user defined variables below)
        #endregion

        protected override void Initialize ()
        {
        strFont = new Font("Arial", 20);

        CalculateOnBarClose = false;
        PaintPriceMarkers = false;
        Overlay = true;
        PriceTypeSupported = false;
        PlotsConfigurable = false;
        }

        void ChartControl_MouseMove (object sender, System.Windows.Forms.MouseEventArgs e)
        {
        eventCount ++;
        double right = _chartBounds.Right - this.ChartControl.BarMarginRight - this.ChartControl.BarWidth - this.ChartControl.BarSpace / 2;
        double bottom = _chartBounds.Bottom;

        double x = right - e.X;
        double y = bottom - e.Y;

        int iBar = this.LastVisibleBar + (int) Math.Round (x / this.ChartControl.BarSpace);
        double price = _min + y * (_max - _min) / _chartBounds.Height;

        if(eventCount == 1)
        {
        x1 = iBar;
        y1 = price; // y1-axis;
        }
        else if(eventCount == 2)
        {
        x2 = iBar;
        y2 = price; // y2-axis;
        eventCount = 0;
        }
        profitLine = Math.Max(y1, y2) - Math.Min(y1, y2);
        midPoint = Math.Min(y1, y2) + profitLine /2;
        string str = (profitLine * 1000).ToString("f0");
        strProfitLine = str;
        int xx1 = Convert.ToInt32(x1);
        int xx2 = Convert.ToInt32(x2);

        //Print(y1 + "::" + x1 + " , " + y2 + "::" + x2);
        if(Math.Min(y1,y2) > 0)
        {
        if(((Control.ModifierKeys & Keys.Alt) == Keys.Alt))
        {

        TriggerCustomEvent(new CustomEvent(MyCustomHandler), e);

        }
        }

        }

        private void MyCustomHandler(object state)
        {
        // Print(midPoint + " : " + strProfitLine + " : " + x1 + " : " + x2 );
        DrawLine("tag1", xx2, y2, xx1, y1, Color.DarkGreen,DashStyle.Solid, 2);
        DrawText("tag3", strProfitLine, 2, midPoint, Color.Black, new Font("ArialBold", 20), StringAlignment.Center, Color.Transparent, Color.Transparent, 10 );
        }

        public override void Plot (Graphics graphics, Rectangle bounds, double min, double max)
        {
        base.Plot (graphics, bounds, min, max);

        _chartBounds = bounds;
        _min = min;
        _max = max;
        }

        public override void Dispose ()
        {
        base.Dispose ();
        if (_chartControl != null)
        _chartControl.ChartPanel.MouseUp -= new System.Windows.Forms.MouseEventHandler (ChartControl_MouseMove);
        }

        ChartControl _chartControl;
        Rectangle _chartBounds;
        double _min, _max;

        /// <summary>
        /// Called on each bar update event (incoming tick)
        /// </summary>
        protected override void OnBarUpdate ()
        {
        if (this.ChartControl != _chartControl)
        {

        if (_chartControl != null)
        _chartControl.ChartPanel.MouseUp -= new System.Windows.Forms.MouseEventHandler (ChartControl_MouseMove);

        _chartControl = this.ChartControl;

        if (_chartControl != null)
        _chartControl.ChartPanel.MouseUp += new System.Windows.Forms.MouseEventHandler (ChartControl_MouseMove);

        }
        }
        }
        }

        #region NinjaScript generated code. Neither change nor remove.
        // This namespace holds all indicators and is required. Do not change it.
        namespace NinjaTrader.Indicator
        {
        public partial class Indicator : IndicatorBase
        {
        private XYIndicator [] cacheXYIndicator = null;

        private static XYIndicator checkXYIndicator = new XYIndicator ();

        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        public XYIndicator XYIndicator ()
        {
        return XYIndicator (Input);
        }

        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        public XYIndicator XYIndicator (Data.IDataSeries input)
        {
        if (cacheXYIndicator != null)
        for (int idx = 0; idx < cacheXYIndicator.Length; idx++)
        if (cacheXYIndicator [idx].EqualsInput (input))
        return cacheXYIndicator [idx];

        XYIndicator indicator = new XYIndicator ();
        indicator.BarsRequired = BarsRequired;
        indicator.CalculateOnBarClose = CalculateOnBarClose;
        indicator.Input = input;
        indicator.SetUp ();

        XYIndicator [] tmp = new XYIndicator [cacheXYIndicator == null ? 1 : cacheXYIndicator.Length + 1];
        if (cacheXYIndicator != null)
        cacheXYIndicator.CopyTo (tmp, 0);
        tmp [tmp.Length - 1] = indicator;
        cacheXYIndicator = tmp;
        Indicators.Add (indicator);

        return indicator;
        }

        }
        }

        // This namespace holds all market analyzer column definitions and is required. Do not change it.
        namespace NinjaTrader.MarketAnalyzer
        {
        public partial class Column : ColumnBase
        {
        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition ("Indicator")]
        public Indicator.XYIndicator XYIndicator ()
        {
        return _indicator.XYIndicator (Input);
        }

        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        public Indicator.XYIndicator XYIndicator (Data.IDataSeries input)
        {
        return _indicator.XYIndicator (input);
        }

        }
        }

        // This namespace holds all strategies and is required. Do not change it.
        namespace NinjaTrader.Strategy
        {
        public partial class Strategy : StrategyBase
        {
        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition ("Indicator")]
        public Indicator.XYIndicator XYIndicator ()
        {
        return _indicator.XYIndicator (Input);
        }

        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        /// <returns></returns>
        public Indicator.XYIndicator XYIndicator (Data.IDataSeries input)
        {
        if (InInitialize && input == null)
        throw new ArgumentException ("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

        return _indicator.XYIndicator (input);
        }

        }
        }
        #endregion

        Comment


          #19
          nice. yeah TriggerCustomEvent is the way to go...

          Comment


            #20
            ok, here's what i have.

            Alt+right-click-drag to draw lines:
            Attached Files

            Comment


              #21
              Very nice

              Now you're just showing off ;-)

              Very good, will have a look at the code shortly and see if I can add an instrument modifier to convert the pips for different instruments as it does decimels for forex.

              Thanks again for the help. Attached is my current implementation.
              Attached Files

              Comment


                #22
                DragRange not working on 7

                Piersh - any idea how to get your code to work correctly on NT7 with second chart on panel.
                Ps works fine on a single lone chart
                Attached Files
                Last edited by Mindset; 01-11-2010, 05:32 AM.

                Comment


                  #23
                  Hoping someone could work this out

                  Well I have played with various things to sort this out but so far it has evaded me.
                  Looks simple using the new GetXByBarIdx(BarsArray[0],idx). But for the life of me I can't get m.X to convert to an idx.
                  I have spent so long looking at it now I am useless.

                  Comment


                    #24
                    Hello MindSet,

                    the Y value of the mouse can be in Panel 1 or Panel 2, so there is the ChartPanel[] Panel Property of ChartControl to find out.
                    I havnt' t done yet and please tell me your approach.


                    the X coordinate is easy:

                    I do:
                    privatevoid MouseClick(object state) {
                    System.Windows.Forms.MouseEventArgs e = ( System.Windows.Forms.MouseEventArgs) state;
                    MethodInfo mi=
                    this.ChartControl.GetType().GetMethod("GetTimeByX",BindingFlags.Instance|BindingFlags.NonPublic|Bind ingFlags.Public);
                    DateTime t=(DateTime) mi.Invoke(
                    this.ChartControl,newobject[]{e.X});

                    Print(
                    "Mouse("+e.X.ToString()+","+e.Y.ToString()+")"+ t.ToShortTimeString());
                    }


                    regards
                    Andreas

                    www.zweisteintrading.eu

                    NinjaTinyMobileTrader : control your NinjaTrader via a cell phone

                    Comment


                      #25
                      Y co ord

                      Code:
                      return (((((this.bounds.Y + this.bounds.Height) - y) * ChartControl.MaxMinusMin(this.max, this.min)) / ((double)this.bounds.Height)) + this.min);
                      This was my code before and it works on a single chart but not on multiple charts.

                      Your coding is way beyond my current learning but the mi line doesn't compile?
                      Code:
                      		private void myCustomEvent(object state)
                      		{
                      			MouseEventArgs m = (MouseEventArgs)state;
                      					
                      			int xpos = m.X;
                      			int ypos = m.Y;
                      		
                      MethodInfo mi=this.ChartControl.GetType().GetMethod("GetTimeByX",BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);
                      DateTime t=(DateTime) ;
                      mi.Invoke(this.ChartControl,newobject[]{e.X});// error at array start
                      Print("Mouse("+e.X.ToString()+","+e.Y.ToString()+")"+ t.ToShortTimeString());

                      Comment


                        #26
                        using System.Windows.Forms;
                        using System.Reflection;

                        also:

                        "new object" instead of "newobject"



                        keep me updated on the multiple Panel solutions


                        regards

                        Andreas

                        www.zweisteintrading.eu
                        NinjaTinyMobileTrader : control your NinjaTrader via a cell phone
                        Last edited by zweistein; 01-17-2010, 03:56 AM.

                        Comment


                          #27
                          Update

                          Thanks Zweistein.
                          It seems that multiple charts reside in 1 form - the Y co ord simply covers the whole no of charts - as far as I can tell.

                          I spent most of Sunday fiddling around with the mouse nos and realise that I just don't grasp the concepts of bounds and canvas, etc correctly.

                          On top of that do you use co ordinates or time/price values - so I have remained utterly confused. I am going back to the beginning to try and get what exactly bounds, etc is/does and how to use it to plot things.

                          What is so frustrating for me is that all my work still works perfectly on a single chart - the pragmatic trader in me says simply don't use multiple charts on one panel. The coder in me however says that would be surrendering and we don't do that!!

                          If I ever sort this out or find a solution I will post it here.

                          Comment


                            #28
                            Seem to have got Y co ords

                            Below is a new indicator that simply plots a line dissecting the selected bar ( via mouse).

                            I seem to have sorted out the Y value ( remarkably easy actually).
                            However my X co ord again still only works on a single chart and misplots on multiple charts within 1 panel.


                            NB THIS IS FOR NT7 BETA ONLY
                            Code:
                            #region Using declarations
                            using System;
                            using System.ComponentModel;
                            using System.Diagnostics;
                            using System.Drawing;
                            using System.Drawing.Drawing2D;
                            using System.Xml.Serialization;
                            using NinjaTrader.Cbi;
                            using NinjaTrader.Data;
                            using NinjaTrader.Gui.Chart;
                            using System.Reflection;
                            using System.Windows.Forms;
                            #endregion
                            
                            namespace NinjaTrader.Indicator
                            {
                            /// <summary>
                            /// Reveals a line along the axis of the selected bar
                            /// Produces wrong bar on multiple charts in single panel
                            /// Mindset Jan 18 2010
                            /// </summary>
                                [Description("Plots price on Mouse Click(Up)")]
                                public class mouseline : Indicator
                                {
                                    #region Variables
                            		private bool click = false;
                            		private bool IsOn = false;
                            		int bCount = 0;
                            		int barclick = 0;
                            		Font textFont1 = new Font("Verdana", 7F);
                            		public int TextOffset = 2;
                            		int xpos = 0;
                            		int myx = 0;
                            		internal double max;
                                    internal double min;
                            		#endregion
                            
                               
                                    protected override void Initialize()
                                    {
                                        CalculateOnBarClose	= false;
                                        Overlay				= true;
                                        PriceTypeSupported	= false;
                            			PlotsConfigurable = false;
                            			PaintPriceMarkers = false;
                                    }
                            
                            		private void myMouseEvents(object sender, MouseEventArgs e)
                            		{
                            		TriggerCustomEvent(new CustomEvent(myCustomEvent),e );
                            		}
                            		
                            		private void myCustomEvent(object state)
                            		{
                            			MouseEventArgs m = (MouseEventArgs)state;
                            			 
                            		//MethodInfo mi=this.ChartControl.GetType().GetMethod("GetTimeByX",BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);
                            		//DateTime t=(DateTime) mi.Invoke (this.ChartControl ,new object[] {m.X});
                            
                            		
                            			 xpos = m.X;
                            			int ypos = m.Y;
                            			int totalbars = this.ChartControl.BarsPainted - 1; //make it zero based
                            			bCount = Bars.Count - 1; //make it zero based
                            			int lastbarpainted = this.ChartControl.LastBarPainted;
                            			int firstbarpainted = this.ChartControl.FirstBarPainted;
                            			int barspace = this.ChartControl.BarSpace;
                            			 barclick = (int)(xpos/barspace);	//gets the bar, from the painted ones where the mouse is clicked
                            			if(IsOn == false)
                            			{
                            			//get rid of the free space on the left side if there are insufficient bars to fill the chartpanel
                            			if (totalbars > lastbarpainted)
                            			{
                            				barclick -= (totalbars - lastbarpainted);
                            			}
                            
                            			//finally get the actual barclick
                            			barclick += firstbarpainted -1;
                            			//make sure bar clicks is not less than 0 or greater than the total bars
                            			if (barclick > bCount)
                            			{
                            				barclick = bCount;
                            			}
                            			if (barclick < 0)
                            			{
                            				barclick = 0;
                            			}
                            			int mybarno = (bCount - barclick);
                            	
                            			IsOn = true;
                            			}
                            			
                            			else
                            				
                            			{
                            			IsOn = false;
                            			RemoveDrawObjects();
                            			}
                            		}
                            
                                    protected override void OnBarUpdate()
                                    {
                                     	if (!click)
                            			{
                            				click = true;
                            				this.ChartControl.ChartPanel.MouseUp += new MouseEventHandler(myMouseEvents);	
                            			}		
                                    }
                            				
                            		public override void Dispose()
                            		{
                            		if (this.ChartControl != null)
                            			{
                            				this.ChartControl.ChartPanel.MouseUp -= myMouseEvents;
                            			}
                            		base.Dispose();
                            				
                            		}
                            		
                            		public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
                                    {
                                     if(ChartControl != null)
                            		{this.min = min;
                            		this.max = max;
                            		bounds = ChartControl.Bounds;
                                         
                            			Pen linePen = new Pen(Color.Red);
                            			linePen.Width = 4;
                            			int pointX = ChartControl.GetXByBarIdx(BarsArray[0], barclick);
                            			int myhigh = ChartControl.GetYByValue(BarsArray[0],High[bCount - barclick] +TickSize * 2);
                            			int mylow = ChartControl.GetYByValue(BarsArray[0],Low[bCount - barclick]- TickSize * 2);
                            			double y1 = myhigh;
                            			double y2 = mylow;
                            			graphics.DrawLine(linePen,pointX,(float)y1,pointX,(float)y2);	
                            			linePen.Dispose();
                                    }
                            		}
                            		
                            	
                            
                                }
                            }
                            Last edited by Mindset; 01-18-2010, 07:56 AM.

                            Comment


                              #29
                              Get x and Get y

                              These 2 new methods in v7 are usefully outlined in the regression channel indicator.
                              GetXpos and GetYPos.

                              Again same problem - fine on single chart does NOT work on multi chart panel correctly.
                              here is the relevant section of code.
                              It is not a bug so this is the end of the road for me - I just don't see what is causing this behaviour.
                              Code:
                              public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
                               {
                                if(ChartControl != null)
                              {
                              this.min = min;
                              this.max = max;
                              bounds = ChartControl.Bounds;
                                  
                              Pen linePen = new Pen(Color.Red);
                              linePen.Width = 4;
                              int pointX = GetXPos(barsback);
                              double y1 = GetYPos(High[barsback]+(TickSize ),bounds,min,max);
                              double y2 = GetYPos(Low[barsback]-TickSize,bounds,min,max);
                              				
                              SmoothingMode oldSmoothingMode = graphics.SmoothingMode;		
                              graphics.SmoothingMode = SmoothingMode.AntiAlias;					
                              graphics.DrawLine(linePen,pointX,(float)y1,pointX,(float)y2);	
                              graphics.SmoothingMode = oldSmoothingMode;
                              linePen.Dispose();
                                 }
                              	}
                              		
                              
                              private int GetXPos(int barsback)//from regression channel
                              {
                              int idx = (Bars.Count - 1) + Math.Max(0, Bars.Count - 1 - ChartControl.LastBarPainted) - barsback;
                              return ChartControl.GetXByBarIdx(BarsArray[0], idx) + 1 ;//- ChartControl.ChartStyle.GetBarPaintWidth(Bars.BarsData.ChartStyle.BarWidthUI) / 2;
                              }
                              		
                              private int GetYPos(double price, Rectangle bounds, double min, double max)
                              {	
                              return ChartControl.GetYByValue(this, price);
                              }

                              Comment


                                #30
                                Trigger Custom Event

                                I notice that there is a new signature for the custom event in 7.
                                I am unsure if this would cause the behaviour I am seeing but I don't understand what barsinprogress refers to. (not BarsArray[0] or just plain int 0).

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by ashwania, 05-23-2020, 04:10 PM
                                3 responses
                                460 views
                                0 likes
                                Last Post yertle
                                by yertle
                                 
                                Started by kaywai, Yesterday, 07:09 AM
                                4 responses
                                16 views
                                0 likes
                                Last Post kaywai
                                by kaywai
                                 
                                Started by PrTester, 12-29-2008, 05:27 PM
                                131 responses
                                96,704 views
                                0 likes
                                Last Post diegomezhur  
                                Started by knowmad, 05-07-2024, 03:52 AM
                                6 responses
                                63 views
                                0 likes
                                Last Post knowmad
                                by knowmad
                                 
                                Started by xepher101, 05-10-2024, 12:19 PM
                                9 responses
                                115 views
                                0 likes
                                Last Post jeronymite  
                                Working...
                                X