PDA

View Full Version : Generic Indicator Overlay on price


monpere
12-25-2007, 07:45 AM
I've altered the Plot method originally from user 'Josh' s Stochastic and RSI Overlay code, to be more generic. Just add the following code to your favorite indicator to overlay it on top of price

//[Gui.Design.DisplayName(".Test")]
//Add the following method under the 'NinjaTrader.Indicator' namespace
//to override the 'Plot' method to draw the indicator overlayed on the price chart
public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
{
// Add the following variables to Initialize() method
// AutoScale = false;
// Overlay = true;
//
// The following variables can be moved out to '#region Variables'
// and corresponding '#region Properties' entries added to make these
// variables user selectable from the indicator properties sheet
// Example: for scaleHigh:
//
// Delete the scaleHigh variable from this routine.
// In '#region Variables' add the following:
// private double scaleHigh = 100;
//
// In '#region Properties' add the following:
// [Description("Scale High")]
// [Category("Parameters")]
// [Gui.Design.DisplayName("Scale High")]
// public double Scale_High
// {
// get { return scaleHigh; }
// set { scaleHigh = value; }
// }
bool drawscale = true; // Limited scale marks
double scaleHigh = 200; // Max value of indicator (100 for Stochastic, +400 for CCI, etc.)
double scaleLow = -200; // Min value of indicator (0 for Stochastic, -400 for CCI, etc.)
double upperline = 175; // Optional horizontal line 1 (80 for Stochastic)
double lowerline = -175; // Optional horizontal line 2 (20 for Stochastic)
Color uppercolor = Color.Green; // Color for line 1
Color lowercolor = Color.Green; // Color for line 2

//Draw Scale
StringFormat stringFormat = new StringFormat();
SolidBrush textBrush = new SolidBrush(Color.Black);
System.Drawing.Font textFont = new Font("Arial", 8);
double scaleRange = (scaleHigh - scaleLow);
double scaleShift = ( scaleLow < 0 ) ? -scaleLow : 0;
if(drawscale)
{
//Upper line
double line = ((upperline+scaleShift)/scaleRange)*100;
graphics.DrawLine(new Pen(uppercolor,2),bounds.X,(float)((bounds.Bottom-bounds.Y)*(1-((double)line/100))),bounds.X+bounds.Width,(float)((bounds.Botto m-bounds.Y)*(1-((double)line/100))));
graphics.DrawString(upperline.ToString(), textFont, textBrush, bounds.X, (float)((bounds.Bottom-bounds.Y)*(1-((double)line/100))),stringFormat);

//1/4 up the scale
line = (scaleRange*.75)+scaleLow;
graphics.DrawString(line.ToString(), textFont, textBrush, bounds.X, (float)((bounds.Bottom-bounds.Y)*(1-0.75)),stringFormat);

//Center Line
line = ((scaleRange/2)+scaleLow)*100;
graphics.DrawLine(new Pen(Color.DarkGray,2),bounds.X,(float)((bounds.Bot tom-bounds.Y)*0.50),bounds.X+bounds.Width,(float)((bou nds.Bottom-bounds.Y)*0.50));
graphics.DrawString(((scaleRange/2)+scaleLow).ToString(), textFont, textBrush, bounds.X, (float)((bounds.Bottom-bounds.Y)*(1-0.50)),stringFormat);

//3/4 up the scale
line = (scaleRange*.25)+scaleLow;
graphics.DrawString(line.ToString(), textFont, textBrush, bounds.X, (float)((bounds.Bottom-bounds.Y)*(1-0.25)),stringFormat);

//Lower line
line = ((lowerline+scaleShift)/scaleRange)*100;
graphics.DrawLine(new Pen(lowercolor,2),bounds.X,(float)((bounds.Bottom-bounds.Y)*(1-((double)line/100))),bounds.X+bounds.Width,(float)((bounds.Botto m-bounds.Y)*(1-((double)line/100))));
graphics.DrawString(lowerline.ToString(), textFont, textBrush, bounds.X, (float)((bounds.Bottom-bounds.Y)*(1-((double)line/100))),stringFormat);
}

//Plot Indicator
int barWidth = ChartControl.ChartStyle.GetBarPaintWidth(ChartCont rol.BarWidth);
SmoothingMode oldSmoothingMode = graphics.SmoothingMode;
GraphicsPath dpath = new GraphicsPath();
int lastX = -1;
int lastY = -1;
DataSeries series = (DataSeries) Values[0];
double seriesvalue = 0;
Gui.Chart.Plot plot = Plots[0];
for(int count = 0; count < ChartControl.BarsPainted; count++)
{
int idx = ChartControl.LastBarPainted - ChartControl.BarsPainted + 1 + count;
if (idx < 0 || idx >= Input.Count || (!ChartControl.ShowBarsRequired && idx < BarsRequired))
continue;

seriesvalue = ((series.Get(idx))+scaleShift)/scaleRange;
if (seriesvalue == 0)
continue;

int x = (int) (ChartControl.CanvasRight - ChartControl.BarMarginRight - barWidth / 2 - (ChartControl.BarsPainted - 1) * ChartControl.BarSpace + count * ChartControl.BarSpace) + 1;
int y = (int) ((bounds.Bottom-bounds.Y)*(1-seriesvalue));

if (lastX >= 0)
{
dpath.AddLine(lastX - plot.Pen.Width / 2, lastY, x - plot.Pen.Width / 2, y);
}

lastX = x;
lastY = y;
}
dpath.Reverse();

graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.DrawPath(Plots[0].Pen, dpath);
graphics.SmoothingMode = oldSmoothingMode;
}

NinjaTrader_Josh
12-25-2007, 01:17 PM
Awesome monpere. Thanks!:D

sbgtrading
12-29-2007, 04:57 PM
Excellent! Thank you!

sbgtrading
12-29-2007, 05:06 PM
Hmmm...can you give us an example of exactly where to paste your code in? I've been unable to find the right location...keep getting compile errors.

NinjaTrader_Josh
12-29-2007, 05:29 PM
It would go outside of the OnBarUpdate(), but inside the Indicator namespace.

sbgtrading
12-29-2007, 07:14 PM
Hmmm...still having trouble. Can someone check the posted code to see if it's missing a "}"...or has too many of them perhaps? If not, then can someone post a test indicator that has this new code in there correctly? Thanks!


It would go outside of the OnBarUpdate(), but inside the Indicator namespace.

NinjaTrader_Josh
12-29-2007, 09:27 PM
What you probably experienced was some weirdness in the formatting when you copy and paste the code. Extra white space was added between variable names so that caused errors.

MichaelB
04-13-2008, 06:33 AM
Hi Josh,
Is this a possible starting area to create a MACD Line overlay on price chart indicator?
ie, instead of having the "Diff" option set to Histogram , instead it is selected to Line to represent the value above and below the horizontal zero line ?
Thanks
Michael b

NinjaTrader_Josh
04-13-2008, 02:02 PM
For sure MichaelB, but this is beyond the level of support we can offer. Feel free to play around with the code though. I believe that is the reason why monpere released it :D.

MichaelB
04-17-2008, 05:26 AM
Hi Josh,
Thanks
cheers
Michael B