// 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);
}