Alexander Elder- come into my trading room
The Impulse System is based on two indicators, a 13-day exponential moving average and the MACD-Histogram. The moving average identifies the trend, while the MACD-Histogram measures momentum. As a result, the Impulse System combines trend following and momentum to identify tradable impulses. This unique indicator combination is color coded into the price bars for easy reference.
public class shElderImpulse : Strategy
{
private bool _usesHigherTimeFrame;
private MACD _htfMacd, _macd;
private EMA _htfEma, _ema;
private bool _initialized = false;
private const int TREND_UP = 1;
private const int TREND_NONE = 0;
private const int TREND_DOWN = -1;
private int _htfTrend = TREND_NONE;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"The Elder Impulse System";
Name = "shElderImpulse";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.Standard;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 20;
#region Variables
Contracts = 1;
HTFType = 0;
HTFPeriod = 0;
TradeTimeBegin = 0;
TradeTimeEnd = 0;
#endregion
}
else if (State == State.Configure)
{
if (HTFPeriod > 0)
{
_usesHigherTimeFrame = true;
switch (HTFType)
{
case 1: AddDataSeries(BarsPeriodType.Second, HTFPeriod); break;
case 2: AddDataSeries(BarsPeriodType.Minute, HTFPeriod); break;
case 3: AddDataSeries(BarsPeriodType.Day, HTFPeriod); break;
case 4: AddDataSeries(BarsPeriodType.Week, HTFPeriod); break;
case 5: AddDataSeries(BarsPeriodType.Month, HTFPeriod); break;
case 6: AddDataSeries(BarsPeriodType.Year, HTFPeriod); break;
case 7: AddDataSeries(BarsPeriodType.Tick, HTFPeriod); break;
case 8: AddDataSeries(BarsPeriodType.Range, HTFPeriod); break;
case 9: AddDataSeries(BarsPeriodType.Volume, HTFPeriod); break;
default: _usesHigherTimeFrame = false; break;
}
}
_ema = EMA(13);
_macd = MACD(12,26,9);
AddChartIndicator(_ema);
AddChartIndicator(_macd);
}
}
private void MyInitialize()
{
if (_usesHigherTimeFrame)
{
_htfMacd = MACD(BarsArray[1],12,26,9);
_htfEma = EMA(BarsArray[1],26);
}
_initialized = true;
}
protected override void OnBarUpdate()
{
//Add your custom strategy logic here.
if (!_initialized) MyInitialize();
if (TimeToTrade)
{
DoPlots();
if (!InPosition)
if (CurrentBar > 0)
LookForTrade();
if (InPosition)
ManagePosition();
}
else if (InPosition)
FlattenPosition();
}
private void DoPlots()
{
if (BarsInProgress == 0 && _usesHigherTimeFrame)
{
if (_htfTrend == TREND_UP)
BackBrush = Brushes.LightGreen;
else if (_htfTrend == TREND_DOWN)
BackBrush = Brushes.LightPink;
else
BackBrush = Brushes.LightYellow;
}
}
private void LookForTrade()
{
if (_usesHigherTimeFrame)
{
if (BarsInProgress == 1)
{
if (_htfEma[0] > _htfEma[1] && _htfMacd.Diff[0] > _htfMacd.Diff[1])
_htfTrend = TREND_UP;
else if (_htfEma[0] < _htfEma[1] && _htfMacd.Diff[0] < _htfMacd.Diff[1])
_htfTrend = TREND_DOWN;
else
_htfTrend = TREND_NONE;
PrintDebug("HTF trend is " + _htfTrend);
}
}
if (BarsInProgress == 0)
{
if (_ema[0] > _ema[1] && _macd.Diff[0] > _macd.Diff[1])
{
bool buy = true;
if (_usesHigherTimeFrame &&_htfTrend != TREND_UP)
buy = false;
if (buy)
EnterLong(Contracts);
}
if (_ema[0] < _ema[1] && _macd.Diff[0] < _macd.Diff[1])
{
bool sell = true;
if (_usesHigherTimeFrame &&_htfTrend != TREND_DOWN)
sell = false;
if (sell)
EnterShort(Contracts);
}
}
}
private void ManagePosition()
{
if (InLong)
{
if (_ema[0] < _ema[1] || _macd.Diff[0] < _macd.Diff[1])
ExitLong();
}
if (InShort)
{
if (_ema[0] > _ema[1] || _macd.Diff[0] > _macd.Diff[1])
ExitShort();
}
}
private void PrintDebug(string msg) { Print(Time[0].ToString() + "::" + msg); }
private bool InPosition { get { return Position.MarketPosition != MarketPosition.Flat; } }
private bool InLong { get { return Position.MarketPosition == MarketPosition.Long; } }
private bool InShort { get { return Position.MarketPosition == MarketPosition.Short; } }
private void FlattenPosition()
{
if (Position.MarketPosition == MarketPosition.Long)
ExitLong();
else if (Position.MarketPosition == MarketPosition.Short)
ExitShort();
}
private bool TimeToTrade
{
get
{
if (TradeTimeBegin == 0 || TradeTimeEnd == 0)
return true;
else
{
if (TradeTimeBegin > TradeTimeEnd) // sessions that begin previous day and end next day
return ToTime(Time[0]) >= TradeTimeBegin*100 || ToTime(Time[0]) <= TradeTimeEnd*100;
else
return ToTime(Time[0]) >= TradeTimeBegin*100 && ToTime(Time[0]) <= TradeTimeEnd*100;
}
}
}