![]() |
This website will be down for maintenance from Friday May 24th at 6PM MDT until Sunday May 26th at 12PM MDT. We apologize for the inconvenience. If you need assistance during this time, please email sales@ninjatrader.com
|
|||||||
| Indicator Development Support for the development of custom indicators using NinjaScript. |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Senior Member
|
I would like to plot X according to time. On NT charts, X = time as:
07:30, 14:00, etc. Time[0] = mm/dd/yy hh:mm:ss. If I do ToTime(Time[0]) I get 73000, 140000, etc. Do I need to dig to a lower level and format to 07:30, 14:00 or is there some method/function available in NinjaScript to do this, or are NT charts smart enough to do the conversion. For instance: graphics.DrawString("myString", textFont, textBrush, Time[0], Close[0], stringFormat); I've tried the above, doesn't work, but I've tried this: protected override void OnBarUpdate() { if (CurrentBar == 0){ Plot0.Set(0); thisX = 0; thisY = 0; } else { Plot0.Set(Close[0]); } } public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { if (Bars == null) return; // Default plotting in base class. Uncomment if indicators holds at least one plot. base.Plot(graphics, bounds, min, max); // this var is needed for calc'ing height // we just need any text here to init height SizeF heightVal = graphics.MeasureString("Height", textFont); // stringFormat.Alignment = StringAlignment.Near; textBrush.Color = Color.Black; //thisX = bounds.X+90; //thisY = bounds.Y; thisX = ToTime(Time[0]); thisY = (float)Close[0]; // graphics.DrawString("hello", textFont, textBrush, thisX, thisY, stringFormat); } and I get the out of bounds error again... "Error on plotting indicator...Please check the 'Plot' method: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index" Hmm, please point me in the right direction.
Last edited by funk101; 05-23-2007 at 07:25 PM.
Reason: adjustment
|
|
|
|
|
|
#2 |
|
Administrator
Join Date: Nov 2004
Location: Denver, CO, USA
Posts: 11,163
Thanks: 6
Thanked 45 times in 32 posts
|
You can't access series data such as Time[] or Close[] etc... from the Plot() method. That's what is giving you the error. I realize you would not have known this partly because we do not currently provide support for overriding the Plot() method and it is not documented.
What you should do is create variables that are assigned in the OnBarUpdate() method and then access these variables within the Plot() method.
Ray
NinjaTrader Customer Service |
|
|
|
|
|
#3 |
|
Senior Member
|
I understand, and I'm not getting the error, and I've changed it to:
thisX = bounds.X and thisY = Plot0[0], which gives me the Close[0], however, Y is now 1530(ie: ES) and the indicator bounds.Y = 640, so it appears that "my" Y is WAAAAAAAY off the map. Hmm, can I tell the indicator to utilize the Price model for Y values somehow? or do I have to jump thru hoops to equate it? |
|
|
|
|
|
#4 |
|
Administrator
Join Date: Nov 2004
Location: Denver, CO, USA
Posts: 11,163
Thanks: 6
Thanked 45 times in 32 posts
|
You have to do some math...
int y = (int) ((bounds.Y + bounds.Height) - ((price - min) / (max - min)) * bounds.Height);
Ray
NinjaTrader Customer Service |
|
|
|
|
|
#5 |
|
Senior Member
|
Why am I getting this out of bounds error again?
"Error on calling 'OnBarUpdate' method for indicator, on bar0. Index was outside the bounds of the array." I don't understand, I thought I had the appropriate "checks" in place. Please check my code: protected override void OnBarUpdate() { if (CurrentBar == 0) { //Plot0.Set(0); Plot1.Set(0); vol.Set(0); Up.Set(0); Down.Set(0); Neutral.Set(0); } else { //Print("new "+newSlope+" old "+primary); newSlope = (Volume[0] - Volume[1]) / (ToTime(Time[0]) - ToTime(Time[1])); vol.Set(newSlope); study = SMA(vol, 6)[0]; primary = vol[1]+vol[0]; //Plot0.Set(primary); Plot1.Set(study); if (newSlope > primary) { Up.Set(primary); image = new Bitmap(imagePath+"thumbsUp.png"); myOperator = ">"; } else if (newSlope < primary) { Down.Set(primary); image = new Bitmap(imagePath+"thumbsDown.png"); myOperator = "<"; } Neutral.Set(primary); DrawHorizontalLine("L", Low[1], Color.Yellow); } } |
|
|
|
|
|
#6 |
|
Administrator
Join Date: Nov 2004
Location: Denver, CO, USA
Posts: 11,163
Thanks: 6
Thanked 45 times in 32 posts
|
Hi,
I don't see anything that pops out at me. You will have to debug it by adding some Print() statements to see where in the code the error is.
Ray
NinjaTrader Customer Service |
|
|
|
|
|
#7 |
|
Senior Member
|
I had it working after your first reply, I come back next day, and voila! Not working. I didn't change anything. It's just a calc of the slope of volume from one bar to next. It works when I don't try and paint the multi-colored MA. Green for up, Red for down, etc. If I just do Plot0/Plot1 (Plot0 is the actually raw values, which is a faster line, and Plot1 is an SMA(6) of Plot0's values, smoothed line).
And now I rewrote it using the wizard, and I'm getting this new error: Error on calling the 'OnBarUpdate' method for indicator ... on bar 2: Parameter is not valid. I've debugged, it's something I can't see! First of all, when I Print(CurrentBar) I *always* get 0. I guess, 'cause it's failing as soon as the indicator starts maybe? protected override void Initialize() { Add(new Plot(Color.Orange, PlotStyle.Line, "UpTick")); Add(new Plot(Color.Green, PlotStyle.Line, "DownTick")); Add(new Plot(Color.DarkViolet, PlotStyle.Line, "Neutral")); Add(new Plot(Color.Firebrick, PlotStyle.Line, "MovAvg")); CalculateOnBarClose = false; Overlay = false; PriceTypeSupported = false; vol = new DataSeries(this); } /// <summary> /// Called on each bar update event (incoming tick) /// </summary> protected override void OnBarUpdate() { Print(CurrentBar); if (CurrentBar == 0) { UpTick.Set(0); DownTick.Set(0); Neutral.Set(0); MovAvg.Set(0); } else { //Print("new "+newSlope+" old "+primary); newSlope = (Volume[0] - Volume[1]) / (ToTime(Time[0]) - ToTime(Time[1])); vol.Set(newSlope); Print(vol[0]); study = SMA(vol, 6)[0]; primary = vol[1]+vol[0]; MovAvg.Set(study); if (newSlope > primary) { UpTick.Set(primary); image = new Bitmap(imagePath+"thumbsUpTick.png"); myOperator = ">"; } else if (newSlope < primary) { DownTick.Set(primary); image = new Bitmap(imagePath+"thumbsDownTick.png"); myOperator = "<"; } else { Neutral.Set(primary); } DrawHorizontalLine("L", Low[1], Color.Yellow); } }
Last edited by funk101; 05-25-2007 at 01:10 AM.
|
|
|
|
|
|
#8 |
|
Senior Member
|
Now it's actually running, not Plotting any lines, getting the same error as previous post, but it's Printing where it's supposed to in the if/elseif/else conditions:
if (newSlope > primary) { Print("UP"); UpTick.Set(primary); image = new Bitmap(imagePath+"thumbsUpTick.png"); myOperator = ">"; } else if (newSlope < primary) { Print("DOWN"); DownTick.Set(primary); image = new Bitmap(imagePath+"thumbsDownTick.png"); myOperator = "<"; } else { Print("NEUTRAL"); Neutral.Set(primary); } That is a step forward, at least those Prints() are outputting, but still no plots, just a blank green panel. No name or anything. What doesn't help is the *vagueness* of the output to log. "...on bar 2: Parameter is not valid." What parameter?? Ya know?
Last edited by funk101; 05-25-2007 at 01:25 AM.
|
|
|
|
|
|
#9 |
|
Senior Member
|
It worked for a while then got this error.
Error on plotting indicator 'MyVolSlope'. Please check the 'Plot' method: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index This makes no sense to me. How could it work for a moment then just fail?? protected override void OnBarUpdate() { if (CurrentBar == 0) { MyVol.Set(0); Plot0.Set(0); } else { newSlope = (Volume[0] - Volume[1]) / (ToTime(Time[0]) - ToTime(Time[1])); MyVol.Set(newSlope); Plot0.Set(MyVol[0]); DrawHorizontalLine("L", Low[1], Color.Yellow); } } This works, it doesn't let me plot different colors for up tick, or down. Once I start testing -> if (MyVol[0] > MyVol[1])... That's what it doesn't like. It's basically saying "there is nothing in MyVol[1]" Oy, I'm about ready to put my fist thru the monitor
|
|
|
|
|
|
#10 |
|
Administrator
Join Date: Mar 2005
Location: Bamberg, Germany
Posts: 9,994
Thanks: 0
Thanked 6 times in 6 posts
|
- the problem is in the Plot method and not the OnBarUpdate method (see error message)
- we do not provide support for custom Plot() methods (as Ray pointed out below) - hint: I suggest applying try..catch.. blocks in the Plot() method to isolate the case of the trouble (see any C# language reference for details on try/catch)
Dierk
NinjaTrader Customer Service |
|
|
|
|
|
#11 |
|
Senior Member
|
Ok, thanks for the tip. It was, as usual, goofy and an oversight on my part. The try/catch blocks helped me to get there. Thanks for staying with me on this one
|
|
|
|
|
|
#12 |
|
Administrator
Join Date: Nov 2004
Location: Denver, CO, USA
Posts: 11,163
Thanks: 6
Thanked 45 times in 32 posts
|
Great, glad you were able to figure it out...
Ray
NinjaTrader Customer Service |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Time of Day and Price | Quicktrader10 | SuperDOM and other Order Entry Windows | 13 | 04-23-2010 04:54 AM |
| Price data on specific time frame. | The Shadow | Indicator Development | 4 | 03-17-2007 01:04 PM |
| How to get the the price of a bar by time | NinjaTrader_Ray | General Programming | 2 | 01-24-2007 04:35 AM |
| Plotting values on multi-time frame and instruments chart | SuzyG | Strategy Development | 1 | 01-19-2007 12:32 AM |
| Getting price and time on scale when move cursor | CJ888 | Charting | 1 | 07-17-2006 02:50 AM |