// SMI Candle Paintbar
// Modified by Prospectus (readtheprospectus@yahoo.com)
// This indicator paints the candles to match the same colors as the SMI.
// Also contains an audio alert and signal arrows.
//
// Author: Mathew Wyatt (mathew.wyatt at gmail.com)
// This indicator is the Stochastic Momentum Index by William Blau. Formula for the indicator was found - http://www.purebytes.com/archives/metastock/1998/msg06283.html.
//
#region Using declarations
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Xml.Serialization;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion
// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
[Description("The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.")]
public class SMI: Indicator
{
#region Variables
private int range = 13;
private int emaperiod1 = 25;
private int emaperiod2 = 1;
private int smiemaperiod = 25;
private DataSeries sms;
private DataSeries hls;
private DataSeries smis;
private Color dnColor = Color.Gold;
private Color upColor = Color.Lime;
#endregion
///
/// This method is used to configure the indicator and is called once before any bar data is loaded.
///
protected override void Initialize()
{
Add(new Line(Color.DarkGray, 0, "Zero line"));
Add(new Plot(Color.Green, PlotStyle.Line, "SMI"));
Add(new Plot(Color.Orange, "SMIEMA"));
Plots[0].Pen.Width = 2;
//stochastic momentums
sms = new DataSeries(this);
//high low diffs
hls = new DataSeries(this);
//stochastic momentum indexes
smis = new DataSeries(this);
//CalculateOnBarClose = false;
}
///
/// Calculates the indicator value(s) at the current index.
///
protected override void OnBarUpdate()
{
if (( CurrentBar < emaperiod2) | ( CurrentBar < emaperiod1)) {
return;
}
//Stochastic Momentum = SM {distance of close - midpoint}
sms.Set(Close[0] - 0.5 * ((MAX(High, range)[0] + MIN(Low, range)[0])));
//High low diffs
hls.Set(MAX(High, range)[0] - MIN(Low, range)[0]);
//Stochastic Momentum Index = SMI
double denom = 0.5*EMA(EMA(hls,emaperiod1),emaperiod2)[0];
smis.Set(100*(EMA(EMA(sms,emaperiod1),emaperiod2))[0] / (denom ==0 ? 1 : denom ));
//Set the current SMI line value
smi.Set(smis[0]);
//*************************************************************************************
double smiVal = (smis[0]);
if (Falling(smis))
{
DrawOnPricePanel = false;
DrawDot(CurrentBar.ToString(),true,0,smiVal,DnColor);
}
if (Rising(smis))
{
DrawOnPricePanel = false;
DrawDot(CurrentBar.ToString(),true,0,smiVal,UpColor);
}
//*****************************************************************************
//Set the line value for the SMIEMA by taking the EMA of the SMI
SMIEMA.Set(EMA(smis, smiemaperiod)[0]);
//Print("SMI: " + EMA(smis, smiemaperiod)[0].ToString());
}
#region Properties
///
/// Gets the fast D value.
///
[Browsable(false)]
[XmlIgnore()]
public DataSeries smi
{
get { return Values[0]; }
}
///
/// Gets the fast K value.
///
[Browsable(false)]
[XmlIgnore()]
public DataSeries SMIEMA
{
get { return Values[1]; }
}
///
///
[Description("Range for momentum calculation. ( Q )")]
[Category("Parameters")]
public int Range
{
get { return range; }
set { range = Math.Max(1, value); }
}
///
///
[Description("1st ema smothing period. ( R )")]
[Category("Parameters")]
public int EMAPeriod1
{
get { return emaperiod1; }
set { emaperiod1 = Math.Max(1, value); }
}
///
///
[Description("2nd ema smoothing period. ( S )")]
[Category("Parameters")]
public int EMAPeriod2
{
get { return emaperiod2; }
set { emaperiod2 = Math.Max(1, value); }
}
///
///
[Description("SMI EMA smoothing period.")]
[Category("Parameters")]
public int SMIEMAPeriod
{
get { return smiemaperiod; }
set { smiemaperiod = Math.Max(1, value); }
}
// Create our user definable color input
[Description("Color for painted region")]
[Category("Parameters")]
public Color UpColor
{
get { return upColor; }
set { upColor = value; }
}
// Serialize our Color object
[Browsable(false)]
public string UpColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(upColor); }
set { upColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
// Create our user definable color input
[Description("Color for painted region")]
[Category("Parameters")]
public Color DnColor
{
get { return dnColor; }
set {dnColor = value; }
}
// Serialize our Color object
[Browsable(false)]
public string DnColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(dnColor); }
set { dnColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
#endregion
}
}
#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 SMI[] cacheSMI = null;
private static SMI checkSMI = new SMI();
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
public SMI SMI(Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
return SMI(Input, dnColor, eMAPeriod1, eMAPeriod2, range, sMIEMAPeriod, upColor);
}
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
public SMI SMI(Data.IDataSeries input, Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
if (cacheSMI != null)
for (int idx = 0; idx < cacheSMI.Length; idx++)
if (cacheSMI[idx].DnColor == dnColor && cacheSMI[idx].EMAPeriod1 == eMAPeriod1 && cacheSMI[idx].EMAPeriod2 == eMAPeriod2 && cacheSMI[idx].Range == range && cacheSMI[idx].SMIEMAPeriod == sMIEMAPeriod && cacheSMI[idx].UpColor == upColor && cacheSMI[idx].EqualsInput(input))
return cacheSMI[idx];
lock (checkSMI)
{
checkSMI.DnColor = dnColor;
dnColor = checkSMI.DnColor;
checkSMI.EMAPeriod1 = eMAPeriod1;
eMAPeriod1 = checkSMI.EMAPeriod1;
checkSMI.EMAPeriod2 = eMAPeriod2;
eMAPeriod2 = checkSMI.EMAPeriod2;
checkSMI.Range = range;
range = checkSMI.Range;
checkSMI.SMIEMAPeriod = sMIEMAPeriod;
sMIEMAPeriod = checkSMI.SMIEMAPeriod;
checkSMI.UpColor = upColor;
upColor = checkSMI.UpColor;
if (cacheSMI != null)
for (int idx = 0; idx < cacheSMI.Length; idx++)
if (cacheSMI[idx].DnColor == dnColor && cacheSMI[idx].EMAPeriod1 == eMAPeriod1 && cacheSMI[idx].EMAPeriod2 == eMAPeriod2 && cacheSMI[idx].Range == range && cacheSMI[idx].SMIEMAPeriod == sMIEMAPeriod && cacheSMI[idx].UpColor == upColor && cacheSMI[idx].EqualsInput(input))
return cacheSMI[idx];
SMI indicator = new SMI();
indicator.BarsRequired = BarsRequired;
indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
indicator.Input = input;
indicator.DnColor = dnColor;
indicator.EMAPeriod1 = eMAPeriod1;
indicator.EMAPeriod2 = eMAPeriod2;
indicator.Range = range;
indicator.SMIEMAPeriod = sMIEMAPeriod;
indicator.UpColor = upColor;
Indicators.Add(indicator);
indicator.SetUp();
SMI[] tmp = new SMI[cacheSMI == null ? 1 : cacheSMI.Length + 1];
if (cacheSMI != null)
cacheSMI.CopyTo(tmp, 0);
tmp[tmp.Length - 1] = indicator;
cacheSMI = tmp;
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
{
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
[Gui.Design.WizardCondition("Indicator")]
public Indicator.SMI SMI(Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
return _indicator.SMI(Input, dnColor, eMAPeriod1, eMAPeriod2, range, sMIEMAPeriod, upColor);
}
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
public Indicator.SMI SMI(Data.IDataSeries input, Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
return _indicator.SMI(input, dnColor, eMAPeriod1, eMAPeriod2, range, sMIEMAPeriod, upColor);
}
}
}
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
public partial class Strategy : StrategyBase
{
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
[Gui.Design.WizardCondition("Indicator")]
public Indicator.SMI SMI(Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
return _indicator.SMI(Input, dnColor, eMAPeriod1, eMAPeriod2, range, sMIEMAPeriod, upColor);
}
///
/// The Stochastic Momentum Index is made up of two lines that oscillate between a vertical scale of -100 to 100.
///
///
public Indicator.SMI SMI(Data.IDataSeries input, Color dnColor, int eMAPeriod1, int eMAPeriod2, int range, int sMIEMAPeriod, Color upColor)
{
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.SMI(input, dnColor, eMAPeriod1, eMAPeriod2, range, sMIEMAPeriod, upColor);
}
}
}
#endregion