Открыть на GitHub

Стратегия Absolutely No Lag LWMA

Общее описание

Стратегия повторяет логику советника MetaTrader Exp_AbsolutelyNoLagLwma. Для выбранных свечей выполняется двойное сглаживание линейной взвешенной средней (LWMA), после чего направление наклона классифицируется цветами: 2 — восходящее движение, 1 — нейтральное состояние, 0 — нисходящее движение. Смена цвета генерирует торговые сигналы. Реализация в StockSharp использует высокоуровневый API: стратегия подписывается на свечи заданного таймфрейма и выставляет рыночные заявки в соответствии с сигналами.

Логика работы

Индикаторная часть

  1. Источник цены выбирается параметром Price Type.
  2. К выбранной цене применяется LWMA длиной LWMA Length.
  3. Результат дополнительно сглаживается второй LWMA той же длины.
  4. Текущее значение сравнивается с предыдущим:
    • 2 (рост) — текущее значение выше предыдущего.
    • 1 (флэт) — значения равны.
    • 0 (падение) — текущее значение ниже предыдущего.

Формирование сигналов

  • Обрабатываются только завершенные свечи. Параметр Signal Bar задает смещение относительно последней завершенной свечи (1 — последняя, 2 — предпоследняя и т.д.). Дополнительно запоминается цвет предыдущей свечи, чтобы не генерировать повторные входы.
  • Бычий переход: выбранная свеча имеет цвет 2, а предыдущая — не 2. При включенном разрешении открываются длинные позиции и закрываются активные короткие.
  • Медвежий переход: выбранная свеча имеет цвет 0, а предыдущая — не 0. При включенном разрешении открываются короткие позиции и закрываются активные длинные.

Управление позициями

  • Сделки совершаются рыночными заявками. При развороте направление позиции меняется объемом Volume + |Position|, что гарантирует закрытие противоположной позиции.
  • Разрешения на входы и выходы по лонгам/шортам настраиваются отдельно, что позволяет использовать стратегию только для входов либо только для выходов.
  • В методе OnStarted вызывается StartProtection(), чтобы активировать стандартную защиту StockSharp.

Параметры

  • LWMA Length — длина обеих LWMA.
  • Price Type — тип цены для расчета индикатора (Close, Open, High, Low, Median, Typical, Weighted, Simpl, Quarter, варианты TrendFollow и Demark).
  • Signal Bar — количество завершенных свечей назад для оценки сигнала.
  • Enable Long Entries — разрешение на открытие длинных позиций.
  • Enable Short Entries — разрешение на открытие коротких позиций.
  • Enable Long Exits — закрытие длинных позиций при появлении медвежьего сигнала.
  • Enable Short Exits — закрытие коротких позиций при появлении бычьего сигнала.
  • Candle Type — таймфрейм свечей, используемых индикатором.
  • Volume — стандартный параметр стратегии, определяющий объем сделок при открытии.

Дополнительные сведения

  • По умолчанию используется таймфрейм 4 часа, как в оригинальном советнике, но его можно изменить через параметр Candle Type.
  • Стратегия не выставляет стоп-лоссы и тейк-профиты; при необходимости подключайте дополнительные модули риск-менеджмента StockSharp.
  • По требованию Python-версия не создавалась.
namespace StockSharp.Samples.Strategies;

using System;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Absolutely No Lag LWMA strategy (simplified).
/// Uses two EMAs of different periods to detect trend direction changes.
/// </summary>
public class AbsolutelyNoLagLwmaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public AbsolutelyNoLagLwmaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Source candles", "General");

		_fastPeriod = Param(nameof(FastPeriod), 9)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 21)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };

		decimal prevFast = 0, prevSlow = 0;
		bool hasPrev = false;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!hasPrev)
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					hasPrev = true;
					return;
				}

				if (!IsFormedAndOnlineAndAllowTrading())
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					return;
				}

				if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
				{
					BuyMarket();
				}
				else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
				{
					SellMarket();
				}

				prevFast = fastValue;
				prevSlow = slowValue;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}
}