#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// The sample strategy Mattz's talked about in his webinar - https://nexusfi.com/webinars/jan15_2011/methodology/
/// </summary>
[Description("The sample strategy Mattz's talked about in his webinar - https://nexusfi.com/webinars/jan15_2011/methodology/")]
public class shMattzWebinar : Strategy
{
#region Parameter Variables
private int _stopLoss = 8; // Default setting for StopLoss
private int _profitTarget = 4; // Default setting for ProfitTarget
private int _pullback1 = 4; // Default setting for Pullback1
private int _pullback2 = 8; // Default setting for Pullback2
private int _lotSize = 1; // Default setting for LotSize
private int _consecutiveTrendBars = 3; // Default setting for ConsecutiveTrendBars
private int _emaPeriod = 20; // Default setting for EMAPeriod
private int _patience = 15; // Default setting for Patience
#endregion
#region Other Variables
const int UP = 1;
const int NEUTRAL = 0;
const int DOWN = -1;
const int LONG = 1;
const int SHORT = -1;
const int IGNORE = 0;
int _trigger = NEUTRAL;
int _consecutive = 0;
bool _inTrade = false;
IOrder _entry1;
EMA _ema;
#endregion
protected override void Initialize()
{
if (_emaPeriod > 0)
{
_ema = EMA(_emaPeriod);
Add(_ema);
}
CalculateOnBarClose = true;
}
protected override void OnBarUpdate()
{
if (CurrentBar <= _emaPeriod || CurrentBar <= _consecutiveTrendBars)
return;
if (Bars.FirstBarOfSession)
{
if (_entry1 != null)
CancelOrder(_entry1);
_entry1 = null;
_inTrade = false;
}
if (Flat && _inTrade)
{
_inTrade = false;
_entry1 = null;
}
if (Flat && !OrderPlaced)
{
int trade = LookForTrade();
string signal;
double entry;
if (trade == LONG)
{
signal = "B"+CurrentBar;
entry = High[0]-(_pullback1 * TickSize);
this.SetStopLoss(signal, CalculationMode.Ticks, _stopLoss, false);
this.SetProfitTarget(signal, CalculationMode.Ticks, _profitTarget);
_entry1 = this.EnterLongLimit(0, true, _lotSize, entry, signal);
this.DrawDiamond("di"+CurrentBar, true, 0, High[0] + TickSize, Color.Cyan);
P("Entered LONG at " + entry);
}
else if (trade == SHORT)
{
signal = "S"+CurrentBar;
entry = Low[0]+(_pullback1 * TickSize);
this.SetStopLoss(signal, CalculationMode.Ticks, _stopLoss, false);
this.SetProfitTarget(signal, CalculationMode.Ticks, _profitTarget);
_entry1 = this.EnterShortLimit(0, true, _lotSize, entry, signal);
this.DrawDiamond("di"+CurrentBar, true, 0, Low[0] - TickSize, Color.Magenta);
P("Entered SHORT at " + entry);
}
} if (!Flat)
{
_inTrade = true;
}
}
int LookForTrade()
{
int count = 0;
if (EMAPosition != SHORT)
{
for (int i=0; i < _consecutiveTrendBars-1; i++)
if (IsHH(i) && IsUpBar(i))
count++;
P("Long count = " + count);
if (count == _consecutiveTrendBars-1 && IsUpBar(_consecutiveTrendBars-1))
return LONG;
}
if (EMAPosition != LONG)
{
count = 0;
for (int i=0; i < _consecutiveTrendBars-1; i++)
if (IsLL(i) && IsDownBar(i))
count++;
P("Short count = " + count);
if (count == _consecutiveTrendBars-1 && IsDownBar(_consecutiveTrendBars-1))
return SHORT;
}
return IGNORE;
}
int EMAPosition
{
get
{
if (_emaPeriod > 0)
{
if (Close[0] > _ema[0])
return LONG;
else if (Close[0] < _ema[0])
return SHORT;
}
return IGNORE;
}
}
bool OrderPlaced { get { return _entry1 != null && _entry1.Filled == 0; } }
bool OrderFilled { get { return _entry1 != null && _entry1.Filled == _lotSize; } }
void P(string msg)
{
Print(Time[0].ToString() + "==> " + msg);
}
#region Price Action
bool UpBar { get { return Close[0] > Open[0]; } }
bool DownBar { get { return Close[0] < Open[0]; } }
bool Doji { get { return Close[0] == Open[0]; } }
bool HH { get { return High[0] > High[1]; } }
bool LL { get { return Low[0] < Low[1]; } }
bool IsUpBar(int bar) { return Close[bar] > Open[bar]; }
bool IsDownBar(int bar) { return Close[bar] < Open[bar]; }
bool IsDoji(int bar) { return Close[bar] == Open[bar]; }
bool IsHH(int bar) { return High[bar] > High[bar+1]; }
bool IsLL(int bar) { return Low[bar] < Low[bar+1]; }
#endregion
#region Position States
bool Long { get { return Position.MarketPosition == MarketPosition.Long; } }
bool Short { get { return Position.MarketPosition == MarketPosition.Short; } }
bool Flat { get { return Position.MarketPosition == MarketPosition.Flat; } }
#endregion
#region Properties
[Description("The number of ticks for the stop")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int StopLoss
{
get { return _stopLoss; }
set { _stopLoss = Math.Max(1, value); }
}
[Description("The number of ticks for the target")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int ProfitTarget
{
get { return _profitTarget; }
set { _profitTarget = Math.Max(1, value); }
}
[Description("The number of tick that represents the size of the pullback for entries on the first lot")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int Pullback1
{
get { return _pullback1; }
set { _pullback1 = Math.Max(1, value); }
}
[Description("The number of tick that represents the size of the pullback for entries on the 2nd lot, or use '0' if you don't want to trade a second lot")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int Pullback2
{
get { return _pullback2; }
set { _pullback2 = Math.Max(0, value); }
}
[Description("The number of contracts to trade per lot")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int LotSize
{
get { return _lotSize; }
set { _lotSize = Math.Max(1, value); }
}
[Description("The number of up HHs or down LLs to consider entering on a pullback")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int ConsecutiveTrendBars
{
get { return _consecutiveTrendBars; }
set { _consecutiveTrendBars = Math.Max(1, value); }
}
[Description("The period for the trend filtered EMA, or '0' if you don't want to use the EMA for filtering")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int EMAPeriod
{
get { return _emaPeriod; }
set { _emaPeriod = Math.Max(0, value); }
}
[Description("The number of minutes you expect a successful trade to succeed, after which the position will be closed if targets or stops are not reached. Or, enter '0' if you do not want to close out positions after a certain amount of time")]
#if NT7
[GridCategory("Parameters")]
#else
[Category("Parameters")]
#endif
public int Patience
{
get { return _patience; }
set { _patience = Math.Max(0, value); }
}
#endregion
}
}
|