![]() |
|
|||||||
| General Programming General NinjaScript programming questions. |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#16 |
|
Member
Join Date: Nov 2008
Location: London
Posts: 53
Thanks: 0
Thanked 0 times in 0 posts
|
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); } } |
|
|
|
|
|
#17 | |
|
Member
Join Date: Jun 2009
Posts: 41
Thanks: 0
Thanked 0 times in 0 posts
|
Quote:
PHP Code:
there's a workaround, however. declare the following in your Indicator's class: PHP Code:
PHP Code:
PHP Code:
|
|
|
|
|
|
|
#18 |
|
Member
Join Date: Nov 2008
Location: London
Posts: 53
Thanks: 0
Thanked 0 times in 0 posts
|
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 |
|
|
|
|
|
#19 |
|
Member
Join Date: Jun 2009
Posts: 41
Thanks: 0
Thanked 0 times in 0 posts
|
nice. yeah TriggerCustomEvent is the way to go...
|
|
|
|
|
|
#20 |
|
Member
Join Date: Jun 2009
Posts: 41
Thanks: 0
Thanked 0 times in 0 posts
|
ok, here's what i have.
Alt+right-click-drag to draw lines: |
|
|
|
|
|
#21 |
|
Member
Join Date: Nov 2008
Location: London
Posts: 53
Thanks: 0
Thanked 0 times in 0 posts
|
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. |
|
|
|
|
|
#22 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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
Last edited by Mindset; 01-11-2010 at 04:32 AM.
|
|
|
|
|
|
#23 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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. |
|
|
|
|
|
#24 |
|
Senior Member
Join Date: Jan 2009
Posts: 584
Thanks: 2
Thanked 21 times in 12 posts
|
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 |
|
|
|
|
|
#25 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
Code:
return (((((this.bounds.Y + this.bounds.Height) - y) * ChartControl.MaxMinusMin(this.max, this.min)) / ((double)this.bounds.Height)) + this.min); 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());
|
|
|
|
|
|
#26 |
|
Senior Member
Join Date: Jan 2009
Posts: 584
Thanks: 2
Thanked 21 times in 12 posts
|
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 at 02:56 AM.
|
|
|
|
|
|
#27 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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. |
|
|
|
|
|
#28 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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 at 06:56 AM.
|
|
|
|
|
|
#29 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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);
}
|
|
|
|
|
|
#30 |
|
Senior Member
Join Date: Mar 2008
Location: UK West Sussex
Posts: 667
Thanks: 10
Thanked 11 times in 8 posts
|
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). |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| event-driven methods? | mktrend | General Programming | 8 | 04-29-2008 06:17 AM |
| Order Event Warning | Moda1 | Miscellaneous Support | 4 | 02-14-2008 09:44 AM |
| Live Events - Seen After the Event | jstockman | Miscellaneous Support | 3 | 09-26-2007 04:37 PM |
| Strategy Start/Stop Event | Json | Strategy Development | 1 | 05-01-2007 03:55 AM |
| Chaining strategy and event | afifio | ATM Strategies (Discretionary Trading) | 6 | 06-26-2005 01:52 PM |