Открыть на GitHub

Стратегия Combo EA4 FSF R Updated 5

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

Эта стратегия представляет собой перенос MetaTrader-советника «Combo_EA4FSFrUpdated5» на платформу StockSharp. Решение объединяет пять модулей технического анализа — скользящие средние, RSI, стохастик, параболик SAR и нулевое запаздывание MACD. Сделка открывается только тогда, когда все включённые модули подтверждают одно и то же направление, что полностью воспроизводит консенсусную фильтрацию оригинального советника. Дополнительно сохранены опциональный трейлинг-стоп, автоматическое закрытие по сигналам и возможность мгновенного переворота после закрытия позиции.

Набор индикаторов

  • Скользящие средние — три настраиваемых средних (MA1, MA2, MA3) с ATR-буферами, уменьшающими число ложных пересечений. Поддерживаются все пять режимов MA_MODE из исходного кода.
  • RSI — четыре режима подтверждения: зоны перекупленности/перепроданности, анализ наклона, комбинированный вариант и проверка зон.
  • Стохастический осциллятор — параметры %K/%D и замедление, при желании накладываются пороги StochasticHigh/StochasticLow.
  • Параболик SAR — сравнивает значение SAR с закрытием предыдущей свечи.
  • Zero-lag MACD — реализован через нулевые экспоненциальные средние, что повторяет индикатор ZeroLag_MACD.mq4; доступны режимы «тренд», «пересечение нуля» и комбинированный.
  • ATR — рассчитывает стопы и тейки, а также служит буфером для пересечения скользящих средних.

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

Вход в позицию

  1. Стратегия дожидается формирования всех требуемых индикаторов.
  2. Для каждого активного модуля вычисляется направление в соответствии с выбранным режимом:
    • MA — сравнение MA1/MA2/MA3 с учётом ATR-буфера.
    • RSI — пороговая логика, анализ наклона, комбинированный режим или зоны.
    • Стохастик — пересечение %K/%D с дополнительными фильтрами по уровням.
    • Parabolic SAR — цена должна находиться выше/ниже SAR предыдущей свечи.
    • Zero-lag MACD — проверка структуры гистограммы или пересечения сигнальной линии около нулевой оси.
  3. Если все модули выдают сигнал «Buy», открывается длинная позиция; если все выдают «Sell», открывается короткая позиция. В остальных случаях сделка не совершается.

Выход из позиции

  • Закрытие по сигналам — при AutoClose = true выполняется аналогичный консенсусный анализ с использованием параметров блока «Closing». Длинная позиция закрывается, когда все выбранные выходные модули показывают «Sell», короткая — при общем сигнале «Buy». Если OpenOppositeAfterClose = true, заявка на противоположную позицию ставится сразу после исполнения закрывающего ордера.
  • Стоп-уровни — начальные стоп-лосс и тейк-профит рассчитываются как ATR × AtrMultiplier с поправкой на минимальный шаг цены (имитация Point*MyPoint). Для длинных позиций стоп = ATR × мультипликатор − буфер, тейк = ATR × мультипликатор + буфер (для коротких зеркально).
  • Трейлинг-стоп — при включенном UseTrailingStop цена стоп-лосса обновляется на каждом завершённом баре согласно параметру TrailingStop (в пунктах).
  • Жёсткие выходы — срабатывание стопа или тейка приводит к немедленному закрытию позиции без последующего переворота.

Управление объёмом

  • Фиксированный объём — при UseStaticVolume = true используется значение StaticVolume.
  • Динамический объём — в противном случае объём оценивается по текущей стоимости портфеля и параметру RiskPercent. Если данные недоступны, применяется базовый Volume стратегии.

Параметры

Группа Параметр Назначение
Entries UseMa Включить подтверждение скользящими средними.
Entries MaMode Режим комбинирования MA (быстрая/средняя, средняя/медленная, комбинированные варианты).
Indicators Ma1Period, Ma2Period, Ma3Period Периоды трёх средних.
Indicators Ma1BufferPeriod, Ma2BufferPeriod Периоды ATR для буферов пересечения.
Indicators Ma1Method, Ma2Method, Ma3Method Типы скользящих (SMA, EMA, SMMA, LWMA).
Indicators Ma1Price, Ma2Price, Ma3Price Используемый тип цены.
Entries UseRsi Включить подтверждение RSI.
Indicators RsiPeriod Период RSI.
Entries RsiMode Режим анализа RSI.
Entries RsiBuyLevel, RsiSellLevel Пороговые уровни для зоны перепроданности/перекупленности.
Entries RsiBuyZone, RsiSellZone Границы зон для режима 4.
Entries UseStochastic Включить стохастик.
Indicators StochasticK, StochasticD, StochasticSlowing Параметры стохастика.
Entries UseStochasticHighLow Требовать выхода за уровни StochasticHigh/Low.
Entries StochasticHigh, StochasticLow Верхний и нижний пороги стохастика.
Entries UseSar Включить Parabolic SAR.
Indicators SarStep, SarMax Настройки ускорения SAR.
Entries UseMacd Включить нулевой MACD.
Indicators MacdFast, MacdSlow, MacdSignal Параметры MACD.
Indicators MacdPrice Тип цены для MACD.
Entries MacdMode Режим сигналов MACD.
Risk UseTrailingStop, TrailingStop Включить трейлинг и задать расстояние (в пунктах).
Risk UseStaticVolume, StaticVolume, RiskPercent Управление объёмом.
Risk AtrPeriod, AtrMultiplier Настройки ATR для управления рисками.
Exits AutoClose Включить автоматическое закрытие по сигналам.
Exits OpenOppositeAfterClose Переворачиваться после сигналового выхода.
Exits UseMaClosing, MaModeClosing Настройки выхода по MA.
Exits UseMacdClosing, MacdModeClosing Настройки выхода по MACD.
Exits UseRsiClosing, RsiModeClosing Настройки выхода по RSI.
Exits UseStochasticClosing Включить стохастик для выхода.
Exits UseSarClosing Включить SAR для выхода.
General CandleType Основной таймфрейм (по умолчанию 5-минутные свечи).

Дополнительные замечания

  • Стратегия ведёт только одну совокупную позицию, что упрощает управление и повторяет ограничение «Max_same_orders» оригинального советника.
  • Переворот выполняется только после закрытия по сигналу; если позиция закрыта стопом или тейком, новая сделка не инициируется автоматически.
  • Из-за различий в брокерских требованиях к марже динамическое вычисление объёма носит приблизительный характер — перед использованием на реальном счёте проверьте фактический размер заявки.
  • Как и в MetaTrader-версии, для корректной работы нулевого MACD и ATR необходим достаточный прогрев историческими данными.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Combo EA: Triple EMA confirmation with RSI filter and ATR stops.
/// </summary>
public class ComboEa4FsfrUpdated5Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;

	public ComboEa4FsfrUpdated5Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastEmaLength = Param(nameof(FastEmaLength), 8)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowEmaLength = Param(nameof(SlowEmaLength), 21)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int FastEmaLength
	{
		get => _fastEmaLength.Value;
		set => _fastEmaLength.Value = value;
	}

	public int SlowEmaLength
	{
		get => _slowEmaLength.Value;
		set => _slowEmaLength.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;
	}

		protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;

		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, rsi, atr, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevFast == 0 || _prevSlow == 0 || atrVal <= 0)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (fastVal < slowVal && _prevFast >= _prevSlow)
			{
				SellMarket();
				_entryPrice = 0;
			}
			else if (close <= _entryPrice - atrVal * 2m)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (fastVal > slowVal && _prevFast <= _prevSlow)
			{
				BuyMarket();
				_entryPrice = 0;
			}
			else if (close >= _entryPrice + atrVal * 2m)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (fastVal > slowVal && _prevFast <= _prevSlow && rsiVal > 50)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (fastVal < slowVal && _prevFast >= _prevSlow && rsiVal < 50)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}