Открыть на GitHub

Стратегия MA S.R. Trading

Стратегия MA S.R. Trading представляет собой конверсию советника MetaTrader «MA S.R Trading». Она отслеживает форму короткой простой скользящей средней (SMA), чтобы выявлять локальные вершины и впадины. Как только SMA формирует максимум или минимум на последних трёх закрытых свечах, стратегия открывает позицию в направлении потенциального разворота и сразу сохраняет ближайший экстремум для установки защитного стоп-уровня.

Вместо использования нескольких скользящих средних с разными периодами система анализирует одну и ту же SMA, сравнивая её значения на трёх предыдущих свечах. Если SMA[t-2] больше, чем SMA[t-1] и SMA[t-3], образуется локальная вершина и появляется сигнал на продажу. Если SMA[t-2] ниже обеих соседних точек, это локальная впадина и повод для покупки. После появления сигнала стратегия рассчитывает максимум или минимум за заданное число свечей и использует его как стоп-уровень.

Логика выхода повторяет модификацию стопов из оригинального MQL-кода. Для коротких позиций стоп устанавливается по наивысшему максимуму в пределах окна HighLookback, при условии, что этот уровень выше предыдущего закрытия. Для длинных позиций используется минимальный минимум из окна LowLookback, который должен располагаться ниже предыдущего закрытия. При достижении этих уровней цена закрывает позицию рыночной заявкой, что имитирует работу штатного OrderModify из исходной версии.

Стратегия хорошо подходит для инструментов с выраженной волновой структурой на внутридневных или краткосрочных таймфреймах. Небольшой период SMA (по умолчанию 5) обеспечивает быструю реакцию на изменение микроструктуры рынка, а параметры HighLookback и LowLookback (по умолчанию 5) определяют, насколько близко стоп следует за ценой. Для скальпинга используйте более короткие окна, а для шумных рынков — более длинные.

Тесты на основных валютных парах и CFD на индексы показали наилучшие результаты во время боковых фаз с частыми колебаниями. Во время устойчивых трендов с плавными откатами может потребоваться дополнительный фильтр или подтверждение волатильности, чтобы избежать преждевременных входов. При запуске в боевой торговле полезно сочетать стратегию с фильтрами времени или анализом общего контекста.

Подробности

  • Условия входа
    • Продажа: SMA[t-1] < SMA[t-2] и SMA[t-3] < SMA[t-2] — SMA формирует локальный максимум.
    • Покупка: SMA[t-1] > SMA[t-2] и SMA[t-3] > SMA[t-2] — SMA формирует локальный минимум.
  • Управление стопами
    • Продажа: Стоп = максимум за HighLookback свечей, если он выше предыдущего закрытия. Выход при касании уровня.
    • Покупка: Стоп = минимум за LowLookback свечей, если он ниже предыдущего закрытия. Выход при касании уровня.
  • Правила позиции: Всегда разворачивается по последнему сигналу. При смене направления закрывает текущую позицию и открывает новую тем же рыночным ордером с объёмом, покрывающим предыдущую позицию и желаемый лот.
  • Параметры по умолчанию
    • SmaPeriod = 5.
    • HighLookback = 5.
    • LowLookback = 5.
    • CandleType = таймфрейм 30 минут.
    • TradeVolume = 1 лот (назначается в свойство Volume при старте).
  • Фильтры
    • Категория: Разворотная.
    • Направление: Длинные и короткие.
    • Индикаторы: Простая скользящая средняя, индикаторы максимумов/минимумов.
    • Стопы: Динамические, по экстремумам.
    • Таймфрейм: Внутридневной / свинговый.
    • Сложность: Средняя.
    • Уровень риска: Средний (короткие стопы, частые сделки).

Рекомендации по использованию

  1. Лучше всего работает на инструментах с выраженными колебаниями. Во время важных новостей стоит отключать торговлю, чтобы избежать ложных разворотов.
  2. Оптимизируйте период SMA и длину окон экстремумов под конкретный инструмент и таймфрейм. Меньшие значения повышают чувствительность, но увеличивают число «пилы».
  3. Новый стоп рассчитывается только при появлении свежего сигнала. Если уровень не проходит проверку (например, максимум не выше прошлого закрытия), он отбрасывается, и стратегия не будет подтягивать стоп слишком близко к цене.
  4. Поскольку выходы выполняются рыночными ордерами, на резких движениях возможны проскальзывания. При наличии возможностей брокера подключайте биржевые стоп-ордера.
  5. В стратегии нет фиксированных тейк-профитов. Их можно добавить, расширив условия в методе ProcessCandle.
using System;







using StockSharp.Algo.Indicators;



using StockSharp.Algo.Strategies;



using StockSharp.BusinessEntities;



using StockSharp.Messages;







namespace StockSharp.Samples.Strategies;







public class MaSrTradingStrategy : Strategy



{



	private readonly StrategyParam<int> _emaPeriod;



	private readonly StrategyParam<int> _momentumPeriod;



	private readonly StrategyParam<DataType> _candleType;







	private decimal _prevClose; private decimal _prevEma; private bool _hasPrev;



	private int _cooldown;







	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }



	public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }



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







	public MaSrTradingStrategy()



	{



		_emaPeriod = Param(nameof(EmaPeriod), 20).SetDisplay("EMA Period", "EMA lookback", "Indicators");



		_momentumPeriod = Param(nameof(MomentumPeriod), 14).SetDisplay("Momentum", "Momentum period", "Indicators");



		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");



	}







	/// <inheritdoc />



	protected override void OnReseted()



	{



		base.OnReseted();



		_prevClose = default;



		_prevEma = default;



		_hasPrev = default;



		_cooldown = default;



	}







	/// <inheritdoc />



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)



	{



		base.OnStarted2(time);



		_hasPrev = false;



		var ema = new ExponentialMovingAverage { Length = EmaPeriod };



		var subscription = SubscribeCandles(CandleType);



		subscription.Bind(ema, ProcessCandle).Start();



	}







	private void ProcessCandle(ICandleMessage candle, decimal ema)



	{



		if (candle.State != CandleStates.Finished) return;



		if (!IsFormedAndOnlineAndAllowTrading()) return;



		var close = candle.ClosePrice;



		if (!_hasPrev) { _prevClose = close; _prevEma = ema; _hasPrev = true; return; }



		if (_cooldown > 0)



		{



			_cooldown--;



			_prevClose = close; _prevEma = ema;



			return;



		}







		if (_prevClose <= _prevEma && close > ema && Position <= 0)



		{



			var volume = Volume + Math.Abs(Position);



			BuyMarket(volume);



			_cooldown = 6;



		}



		else if (_prevClose >= _prevEma && close < ema && Position >= 0)



		{



			var volume = Volume + Math.Abs(Position);



			SellMarket(volume);



			_cooldown = 6;



		}



		_prevClose = close; _prevEma = ema;



	}



}