Conversion of the MetaTrader 4 expert advisor alliheik.mq4. The strategy combines a double-smoothed Heiken Ashi candle body with the forward-shifted Alligator "jaw" moving average. Entries occur when the Heiken Ashi buffers cross after the smoothing process. Exits rely on a jaw crossover filter, optional fixed targets, and a price-based trailing stop.
Trading Logic
Heiken Ashi construction
Smooth raw open, high, low, and close prices with PreSmoothMethod / PreSmoothPeriod.
Build classic Heiken Ashi candles from the smoothed prices.
Swap the high/low buffers depending on candle color (bullish keeps low/high order, bearish reverses them).
Apply a second smoothing pass (PostSmoothMethod / PostSmoothPeriod) to the conditional buffers. These are the values compared in the signal rules.
Signal definition
Long: the current lower buffer is below the upper buffer while the previous bar had the opposite or equal relationship.
Short: the current lower buffer is above the upper buffer while the previous bar had the opposite or equal relationship.
Jaw filter and trailing
The Alligator jaw is a moving average of JawsPeriod bars, shifted JawsShift bars forward and fed with JawsPrice.
Close[6] (six bars ago) must cross the jaw before the position can be closed automatically.
Once the difference between Close[6] and the jaw reaches eight points and reverses through the jaw, the position is closed.
If TrailingStopPoints is greater than zero, the stop price follows Close[6] once that candle is on the profitable side of the jaw.
Stops and targets
StopLossPoints and TakeProfitPoints are optional fixed distances applied on entry.
Trailing logic overwrites the protective stop once it moves in favor of the trade.
Default Parameters
Parameter
Default
Description
CandleType
TimeSpan.FromHours(1).TimeFrame()
Time frame used for all calculations.
JawsPeriod
144
Length of the Alligator jaw moving average.
JawsShift
8
Forward displacement of the jaw (number of bars).
JawsMethod
Simple
Moving average type for the jaw (Simple, Exponential, Smoothed, Weighted).
JawsPrice
Close
Price component supplied to the jaw (Close/Open/High/Low/Median/Typical/Weighted).
PreSmoothMethod
Exponential
Moving average used to smooth raw OHLC values before computing Heiken Ashi.
PreSmoothPeriod
21
Period of the pre-smoothing averages.
PostSmoothMethod
Weighted
Moving average applied to the conditional Heiken Ashi buffers.
PostSmoothPeriod
1
Period of the post-smoothing averages (1 keeps the original buffers).
StopLossPoints
0
Fixed stop distance in points (0 disables).
TrailingStopPoints
0
Trailing stop distance based on Close[6] (0 disables).
TakeProfitPoints
225
Take-profit distance in points (0 disables).
OrderVolume
0.1
Lot size for entries.
Indicators Used
Pre-smoothing MAs (four parallel series for open, high, low, close).
Heiken Ashi reconstruction driven by the smoothed prices.
Post-smoothing MAs of the conditional buffers that form the entry signal.
Alligator jaw moving average with adjustable type, shift, and applied price.
Entry and Exit Summary
Enter Long when the smoothed lower buffer crosses below the upper buffer and the previous bar was not bullish (crossing condition described above).
Exit Long when:
Close[6] falls back below the jaw after previously being above it and the distance reached ≥ 8 points; or
TakeProfitPoints target is reached; or
StopLossPoints/TrailingStopPoints stop is hit.
Enter Short when the smoothed lower buffer crosses above the upper buffer and the previous bar was not bearish.
Exit Short when:
Close[6] rises back above the jaw after previously being below it and the distance reached ≥ 8 points; or
TakeProfitPoints target is reached; or
StopLossPoints/TrailingStopPoints stop is hit.
Conversion Notes
The strategy enforces one trade per bar, mirroring the isOrderAllowed() check in the original EA.
Protective stops and targets are simulated internally because StockSharp strategies cannot rely on broker-side MT4 orders.
The jaw moving average stores historical values so that the forward shift replicates iMA behaviour with ma_shift = JawsShift.
All computations use decimal arithmetic and indicator bindings consistent with StockSharp high-level API requirements.
Risk and Usage
Designed for both long and short trading on the same instrument.
Works best on trending markets where the jaw shift and Heiken Ashi smoothing can highlight medium-term swings.
Consider adjusting TrailingStopPoints and TakeProfitPoints to match instrument volatility.
Always backtest and forward test on paper accounts before live deployment.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alliheik Trader: uses smoothed Heiken Ashi candles (EMA of OHLC)
/// with Alligator jaw (long SMA) as trend filter.
/// Entry on HA color change above/below jaw, exit on reversal.
/// </summary>
public class AlliheikTraderStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smoothPeriod;
private readonly StrategyParam<int> _jawPeriod;
private decimal _prevHaOpen;
private decimal _prevHaClose;
private bool _prevBullish;
private bool _hasPrev;
private decimal _entryPrice;
public AlliheikTraderStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_smoothPeriod = Param(nameof(SmoothPeriod), 6)
.SetDisplay("Smooth Period", "EMA period for HA smoothing.", "Indicators");
_jawPeriod = Param(nameof(JawPeriod), 144)
.SetDisplay("Jaw Period", "SMA period for Alligator jaw.", "Indicators");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int SmoothPeriod
{
get => _smoothPeriod.Value;
set => _smoothPeriod.Value = value;
}
public int JawPeriod
{
get => _jawPeriod.Value;
set => _jawPeriod.Value = value;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHaOpen = 0;
_prevHaClose = 0;
_prevBullish = false;
_hasPrev = false;
_entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHaOpen = 0;
_prevHaClose = 0;
_prevBullish = false;
_hasPrev = false;
_entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = SmoothPeriod };
var jaw = new SimpleMovingAverage { Length = JawPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, jaw, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, jaw);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal jawVal)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
// Compute smoothed Heiken Ashi
var haClose = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + close) / 4m;
var haOpen = _prevHaOpen == 0
? (candle.OpenPrice + close) / 2m
: (_prevHaOpen + _prevHaClose) / 2m;
var bullish = haClose > haOpen;
if (!_hasPrev)
{
_prevHaOpen = haOpen;
_prevHaClose = haClose;
_prevBullish = bullish;
_hasPrev = true;
return;
}
var colorChange = bullish != _prevBullish;
// Exit on color change
if (Position > 0 && colorChange && !bullish)
{
SellMarket();
_entryPrice = 0;
}
else if (Position < 0 && colorChange && bullish)
{
BuyMarket();
_entryPrice = 0;
}
// Entry on color change confirmed by jaw filter
if (Position == 0 && colorChange)
{
if (bullish && close > jawVal)
{
_entryPrice = close;
BuyMarket();
}
else if (!bullish && close < jawVal)
{
_entryPrice = close;
SellMarket();
}
}
_prevHaOpen = haOpen;
_prevHaClose = haClose;
_prevBullish = bullish;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class alliheik_trader_strategy(Strategy):
"""
Alliheik Trader: uses smoothed Heiken Ashi candles (EMA of OHLC)
with Alligator jaw (long SMA) as trend filter.
Entry on HA color change above/below jaw, exit on reversal.
"""
def __init__(self):
super(alliheik_trader_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._smooth_period = self.Param("SmoothPeriod", 6) \
.SetDisplay("Smooth Period", "EMA period for HA smoothing.", "Indicators")
self._jaw_period = self.Param("JawPeriod", 144) \
.SetDisplay("Jaw Period", "SMA period for Alligator jaw.", "Indicators")
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
@property
def SmoothPeriod(self): return self._smooth_period.Value
@SmoothPeriod.setter
def SmoothPeriod(self, v): self._smooth_period.Value = v
@property
def JawPeriod(self): return self._jaw_period.Value
@JawPeriod.setter
def JawPeriod(self, v): self._jaw_period.Value = v
def OnReseted(self):
super(alliheik_trader_strategy, self).OnReseted()
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
def OnStarted2(self, time):
super(alliheik_trader_strategy, self).OnStarted2(time)
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
ema = ExponentialMovingAverage()
ema.Length = self.SmoothPeriod
jaw = SimpleMovingAverage()
jaw.Length = self.JawPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, jaw, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, jaw)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_val, jaw_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
o = float(candle.OpenPrice)
h = float(candle.HighPrice)
l = float(candle.LowPrice)
# Compute smoothed Heiken Ashi
ha_close = (o + h + l + close) / 4.0
if self._prev_ha_open == 0:
ha_open = (o + close) / 2.0
else:
ha_open = (self._prev_ha_open + self._prev_ha_close) / 2.0
bullish = ha_close > ha_open
if not self._has_prev:
self._prev_ha_open = ha_open
self._prev_ha_close = ha_close
self._prev_bullish = bullish
self._has_prev = True
return
color_change = bullish != self._prev_bullish
# Exit on color change
if self.Position > 0 and color_change and not bullish:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0 and color_change and bullish:
self.BuyMarket()
self._entry_price = 0.0
# Entry on color change confirmed by jaw filter
if self.Position == 0 and color_change:
if bullish and close > jaw_val:
self._entry_price = close
self.BuyMarket()
elif not bullish and close < jaw_val:
self._entry_price = close
self.SellMarket()
self._prev_ha_open = ha_open
self._prev_ha_close = ha_close
self._prev_bullish = bullish
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return alliheik_trader_strategy()