// Scalper v0.1 by Gumphrie, inspired by John Carter's TTMScalper // v0.2 - removed the period parameter as pretty much useless and changed all the high/low calaculations to be one bar ahead // v0.3 - fixed possible plotting error // v0.4 - additional check for highest and lowest // v0.5 - reduced cpu usage & added trigger bar alert arrows #region Using declarations using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.ComponentModel; using System.Xml.Serialization; using System.Text; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.Design; #endregion // This namespace holds all indicators and is required. Do not change it. namespace NinjaTrader.Indicator { /// /// Scalper /// [Description("Scalper")] [Gui.Design.DisplayName("Scalper")] public class Scalper : Indicator { #region Variables private SolidBrush ScalpBarBrush = new SolidBrush(Color.Lavender); private int counter = 0; private int ExtremeBar = 0; private int lastBar=0; private bool HighPainted = false; private bool LowPainted = true; private bool showTriggers = false; private double ExtremeBarHigh = 0; private double TriggerBarLow = 0; private double ExtremeBarLow = 0; private double TriggerBarHigh = 0; private int TriggerBarLowNo=0; private int TriggerBarHighNo=0; private DataSeries scalpSeries; private DataSeries open; private DataSeries high; private DataSeries low; private DataSeries close; #endregion /// /// This method is used to configure the indicator and is called once before any bar data is loaded. /// protected override void Initialize() { Overlay = true; scalpSeries = new DataSeries(this); open = new DataSeries(this); high = new DataSeries(this); low = new DataSeries(this); close = new DataSeries(this); CalculateOnBarClose = true; } /// /// Called on each bar update event (incoming tick) /// protected override void OnBarUpdate() { open.Set(Open[0]); high.Set(High[0]); low.Set(Low[0]); close.Set(Close[0]); if (CurrentBar <= 4) { scalpSeries.Set(0); } else { //Up if (HighPainted==false) { if ((High[1] < High[2]) && (0==ExtremeBar)) //if ((High[1] < High[2]) && (2 == Bars.HighestBar(3)) && (0==ExtremeBar)) { ExtremeBar = 2; ExtremeBarHigh = High[2]; TriggerBarLow = Low[1]; TriggerBarLowNo = CurrentBar-1; // if (ExtremeBarLow > High[4]) ExtremeBar = 4; } if (High[0] > ExtremeBarHigh) { ExtremeBar = 0; ExtremeBarHigh = 0; TriggerBarLow = 0; TriggerBarLowNo = 0; counter=-1; } if (0!=ExtremeBar) counter++; if ((Close[0] < TriggerBarLow) && (0!=ExtremeBar)) { ExtremeBar = ExtremeBar + counter; HighPainted = true; counter=-1; scalpSeries.Set(CurrentBar-ExtremeBar); ExtremeBar=0; } } //Down if (HighPainted==true) { if ((Low[1] > Low[2]) && (0==ExtremeBar)) //if ((Low[1] > Low[2]) && (2 == Bars.LowestBar(3)) && (0==ExtremeBar)) { ExtremeBar = 2; ExtremeBarLow = Low[2]; TriggerBarHigh = High[1]; TriggerBarHighNo = CurrentBar-1; // if (ExtremeBarLow > Low[4]) ExtremeBar = 4; } if (Low[0] < ExtremeBarLow) { ExtremeBar = 0; ExtremeBarLow = 0; TriggerBarHigh = 0; TriggerBarHighNo = 0; counter=-1; } if (0!=ExtremeBar) counter++; if ((Close[0] > TriggerBarHigh) && (0!=ExtremeBar)) { ExtremeBar = ExtremeBar + counter; HighPainted = false; counter=-1; scalpSeries.Set(CurrentBar-ExtremeBar); ExtremeBar=0; } } // else scalpSeries.Set(0); } lastBar=CurrentBar; } public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { // Default plotting in base class. //base.Plot(graphics, bounds, min, max); if (base.Bars == null) return; if (ChartControl.ChartStyleType.ToString()=="LineOnClose") return; int index = -1; Exception caughtException; int barPaintWidth = ChartControl.ChartStyle.GetBarPaintWidth(ChartControl.BarWidth); int bars = ChartControl.BarsPainted; while (bars >= 0) { index = ((ChartControl.LastBarPainted - ChartControl.BarsPainted) + 1) + bars; if (ChartControl.ShowBarsRequired || ((index - Displacement) >= BarsRequired)) { try { bool ScalpBar=false; for (int scalpBar=index;scalpBar<=lastBar;scalpBar++) { if (scalpSeries.Get(scalpBar)==index) { ScalpBar=true; break; } } if (ScalpBar) { int x1 = (((ChartControl.CanvasRight - ChartControl.BarMarginRight) - (barPaintWidth / 2)) - ((ChartControl.BarsPainted - 1) * ChartControl.BarSpace)) + (bars * ChartControl.BarSpace); int y1 = (bounds.Y + bounds.Height) - ((int) (((high.Get(index) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); int y2 = (bounds.Y + bounds.Height) - ((int) (((close.Get(index) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); int y3 = (bounds.Y + bounds.Height) - ((int) (((open.Get(index) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); int y4 = (bounds.Y + bounds.Height) - ((int) (((low.Get(index) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); if (ChartControl.ChartStyleType.ToString()=="OHLC") graphics.DrawLine(new Pen(ScalpBarBrush.Color,(int)((((double)ChartControl.BarWidth)/3)*2)),x1,y1,x1,y4); else if (ChartControl.ChartStyleType.ToString()=="HiLoBars") graphics.DrawLine(new Pen(ScalpBarBrush.Color,ChartControl.BarWidth),x1,y1,x1,y4); else { byte bRed = (byte)~(ChartControl.BackColor.R); byte bGreen = (byte)~(ChartControl.BackColor.G); byte bBlue = (byte)~(ChartControl.BackColor.B); Pen pen = new Pen(Color.FromArgb(bRed,bGreen,bBlue), 1); graphics.FillRectangle(ScalpBarBrush,x1-(barPaintWidth/2)+1,y1,barPaintWidth-2,y4-y1); if (y2>y3) { graphics.DrawLine(pen,x1,y1,x1,y3); graphics.DrawLine(pen,x1,y2,x1,y4); } else { graphics.DrawLine(pen,x1,y1,x1,y2); graphics.DrawLine(pen,x1,y3,x1,y4); } graphics.DrawLine(pen,x1-(barPaintWidth/2)+1,y3,x1+(barPaintWidth/2)-2,y3); graphics.DrawLine(pen,x1-(barPaintWidth/2),y2,x1+(barPaintWidth/2),y2); graphics.DrawLine(pen,x1-(barPaintWidth/2),y2,x1-(barPaintWidth/2),y3); graphics.DrawLine(pen,x1+(barPaintWidth/2),y2,x1+(barPaintWidth/2),y3); } } else if (showTriggers) { if ((TriggerBarLowNo>0) && (TriggerBarLowNo==index)) { int x1 = (((ChartControl.CanvasRight - ChartControl.BarMarginRight) - (barPaintWidth / 2)) - ((ChartControl.BarsPainted - 1) * ChartControl.BarSpace)) + (bars * ChartControl.BarSpace); int y1 = (bounds.Y + bounds.Height) - ((int) ((((high.Get(index)+(2*TickSize)) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); DrawArrow((barPaintWidth/5)*4, graphics,x1,y1,ScalpBarBrush,false); } if ((TriggerBarHighNo>0) && (TriggerBarHighNo==index)) { int x1 = (((ChartControl.CanvasRight - ChartControl.BarMarginRight) - (barPaintWidth / 2)) - ((ChartControl.BarsPainted - 1) * ChartControl.BarSpace)) + (bars * ChartControl.BarSpace); int y1 = (bounds.Y + bounds.Height) - ((int) ((((low.Get(index)-(2*TickSize)) - min) / ChartControl.MaxMinusMin(max, min)) * bounds.Height)); DrawArrow((barPaintWidth/5)*4, graphics,x1,y1,ScalpBarBrush,true); } } } catch (Exception exception) { caughtException = exception; } } bars--; } } private void DrawArrow(int arrowSize, Graphics graphics, int x, int y, SolidBrush brush, bool up) { Point[] points; int halfSize = (int) Math.Floor((double) (((double) arrowSize) / 2)); Point[] upPoints = new Point[] { new Point(0, 0), new Point(arrowSize, arrowSize), new Point(halfSize, arrowSize), new Point(halfSize, arrowSize * 2), new Point(-halfSize, arrowSize * 2), new Point(-halfSize, arrowSize), new Point(-arrowSize, arrowSize), new Point(0, 0) }; //Point[] dnPoints = new Point[] { new Point(-halfSize, -arrowSize * 2), new Point(halfSize, -arrowSize * 2), new Point(halfSize, -arrowSize), new Point(arrowSize, -arrowSize), new Point(0, 0), new Point(-arrowSize, -arrowSize), new Point(-halfSize, -arrowSize), new Point(-halfSize, -arrowSize * 2) }; //Point[] upPoints = new Point[] { new Point(0, -arrowSize), new Point(arrowSize, arrowSize), new Point(0, arrowSize/2), new Point(-arrowSize, arrowSize), new Point(0, -arrowSize) }; Point[] dnPoints = new Point[] { new Point(-halfSize, -arrowSize * 2), new Point(halfSize, -arrowSize * 2), new Point(halfSize, -arrowSize), new Point(arrowSize, -arrowSize), new Point(0, 0), new Point(-arrowSize, -arrowSize), new Point(-halfSize, -arrowSize), new Point(-halfSize, -arrowSize * 2) }; if (up) { points = upPoints; } else { points = dnPoints; } for (int i = 0; i < points.Length; i++) { points[i].Offset(x, y); } byte bRed = (byte)~(base.ChartControl.BackColor.R); byte bGreen = (byte)~(base.ChartControl.BackColor.G); byte bBlue = (byte)~(base.ChartControl.BackColor.B); graphics.FillPolygon(brush, points); graphics.DrawPolygon(new Pen(Color.FromArgb(bRed,bGreen,bBlue)), points); }