Ver no GitHub

Alliheik Trader Strategy

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