Открыть на GitHub

Стратегия Alliheik Trader

Конвертация советника MetaTrader 4 alliheik.mq4. Стратегия сочетает двойное сглаживание свечей Heiken Ashi с линией челюсти аллигатора, смещённой вперёд. Входы формируются на пересечении сглаженных буферов Heiken Ashi, а выходы зависят от пересечения цены с челюстью, фиксированных целей и трейлинг-стопа.

Логика торговли

  • Построение Heiken Ashi
    • Сглаживаем исходные значения Open/High/Low/Close с помощью параметров PreSmoothMethod / PreSmoothPeriod.
    • Формируем классические свечи Heiken Ashi по сглаженным данным.
    • В зависимости от цвета свечи меняем местами буферы High/Low (бычьи свечи сохраняют Low/High, медвежьи — High/Low).
    • Применяем второе сглаживание (PostSmoothMethod / PostSmoothPeriod) к условным буферам. Именно эти значения сравниваются в правилах сигналов.
  • Определение сигналов
    • Покупка: текущий нижний буфер находится ниже верхнего, а на предыдущем баре соотношение было противоположным или равным.
    • Продажа: текущий нижний буфер находится выше верхнего, а на предыдущем баре соотношение было противоположным или равным.
  • Фильтр челюсти и трейлинг
    • Челюсть аллигатора — скользящая средняя длиной JawsPeriod, смещённая вперёд на JawsShift баров и построенная по цене JawsPrice.
    • Значение Close[6] (шесть баров назад) должно пересечь челюсть, прежде чем позицию можно автоматически закрыть.
    • Когда расстояние между Close[6] и челюстью достигает восьми пунктов и цена возвращается через челюсть, позиция закрывается.
    • При TrailingStopPoints > 0 стоп подтягивается за Close[6], если соответствующая свеча находится по прибыльную сторону от челюсти.
  • Стопы и цели
    • StopLossPoints и TakeProfitPoints — необязательные фиксированные расстояния в пунктах, задаваемые при входе.
    • Трейлинг-стоп при необходимости заменяет исходный стоп-лосс, как только цена продвинулась в прибыль.

Параметры по умолчанию

Параметр Значение Описание
CandleType TimeSpan.FromHours(1).TimeFrame() Таймфрейм для расчётов.
JawsPeriod 144 Длина скользящей средней челюсти.
JawsShift 8 Смещение челюсти вперёд (в барах).
JawsMethod Simple Тип скользящей средней для челюсти (Simple, Exponential, Smoothed, Weighted).
JawsPrice Close Цена, подаваемая в расчёт челюсти (Close/Open/High/Low/Median/Typical/Weighted).
PreSmoothMethod Exponential Тип сглаживания исходных цен OHLC перед построением Heiken Ashi.
PreSmoothPeriod 21 Период сглаживающих средних.
PostSmoothMethod Weighted Тип сглаживания условных буферов Heiken Ashi.
PostSmoothPeriod 1 Период второго сглаживания (1 оставляет значения без изменений).
StopLossPoints 0 Фиксированный стоп-лосс в пунктах (0 — без стопа).
TrailingStopPoints 0 Дистанция трейлинг-стопа на основе Close[6] (0 — отключено).
TakeProfitPoints 225 Фиксированная цель в пунктах (0 — без цели).
OrderVolume 0.1 Лотность при входах.

Используемые индикаторы

  • Сглаженные MA для каждой из серий Open/High/Low/Close.
  • Конструкция Heiken Ashi на основе сглаженных цен.
  • Дополнительное сглаживание условных буферов, формирующих сигналы.
  • Скользящая средняя челюсти аллигатора с настраиваемым типом, смещением и ценой.

Правила входа и выхода

  • Вход в лонг — нижний буфер пересекает верхний снизу вверх, а на предыдущем баре пересечения не было в пользу быков.
  • Выход из лонга при выполнении одного из условий:
    • Close[6] возвращается ниже челюсти после нахождения выше неё, а расстояние достигло ≥ 8 пунктов;
    • срабатывает TakeProfitPoints;
    • цена достигает StopLossPoints или трейлинг-стопа.
  • Вход в шорт — нижний буфер пересекает верхний сверху вниз, а на предыдущем баре условия для медведей не выполнялись.
  • Выход из шорта при выполнении одного из условий:
    • Close[6] возвращается выше челюсти после нахождения ниже неё, а расстояние достигло ≥ 8 пунктов;
    • срабатывает TakeProfitPoints;
    • цена достигает StopLossPoints или трейлинг-стопа.

Особенности конвертации

  • За счёт хранения времени последней сделки стратегия разрешает только один вход на бар, повторяя поведение isOrderAllowed() из оригинала.
  • Стопы и тейки моделируются внутри стратегии, поскольку в StockSharp нельзя полагаться на серверные заявки MT4.
  • История значений челюсти хранится с учётом смещения, чтобы воспроизвести работу iMA с параметром ma_shift = JawsShift.
  • Используются типовые индикаторы StockSharp и работа через high-level API в соответствии с требованиями проекта.

Рекомендации по применению

  • Стратегия работает в обе стороны (лонг/шорт) по одному инструменту.
  • Наиболее эффективно на трендовых участках, где сглаженные свечи и смещённая челюсть помогают фильтровать шум.
  • Подбирайте TrailingStopPoints и TakeProfitPoints в соответствии с волатильностью инструмента.
  • Перед использованием на реальном счёте выполните полноценное тестирование и прогон на демо.
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;
	}
}