Открыть на GitHub

Стратегия Smart Forex System

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

Smart Forex System — это порт советника MetaTrader на платформу StockSharp. Стратегия сочетает фильтр моментума на основе последней свечи и усредняющую сетку с увеличением объёмов. Первый ордер открывается, когда предыдущая свеча закрылась в направлении тренда и текущее закрытие достаточно отклоняется от опорной цены. Дополнительные сделки добавляются через фиксированный шаг в пунктах против текущей позиции, при этом объём умножается на заданный коэффициент. Выход осуществляется по усреднённым целям take-profit и страховочному stop-loss относительно последнего ордера сетки.

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

  • Генерация сигналов
    • Анализируется последняя завершённая свеча на выбранном таймфрейме.
    • Рассчитывается импульс: (текущее закрытие − предыдущее закрытие) / предыдущее закрытие * 10 000.
    • Если предыдущая свеча медвежья и импульс ниже отрицательного порога, разрешается запуск длинной сетки.
    • Если предыдущая свеча бычья и импульс превышает положительный порог, запускается короткая сетка.
    • Параметр «Режим торговли» позволяет ограничить работу только лонгами, только шортами, обоими направлениями либо полностью отключить торговлю.
  • Расширение сетки
    • При наличии открытой сетки новый ордер добавляется, когда цена проходит против позиции минимум Grid Step пунктов от цены последнего ордера.
    • Объём каждого следующего ордера умножается на Lot Multiplier, но ограничивается биржевыми лимитами и параметром Max Volume.
    • Сетка перестаёт расширяться при достижении Max Trades ордеров в одном направлении.
  • Управление выходами
    • Жёсткий стоп-лосс рассчитывается от цены последнего ордера на расстояние Stop Loss пунктов. Пробой уровня закрывает всю сетку.
    • Цель take-profit зависит от размера сетки:
      • Для единственного ордера используется First Take Profit пунктов от средневзвешенной цены входа.
      • Для нескольких ордеров применяется Grid Take Profit пунктов от той же средней цены.
    • Все проверки выполняются на завершённых свечах, что обеспечивает стабильность расчётов.

Замечания по рискам

  • Мартингейл-подход быстро увеличивает объём позиции в затяжных трендах. Используйте консервативные множители и ограничивайте размер сетки на волатильных инструментах.

  • Базовый стоп-лосс (400 пунктов) повторяет настройки оригинального советника и достаточно широк. При необходимости уменьшения просадки адаптируйте его под волатильность инструмента.

  • Сеточная торговля требует значительного маржинального обеспечения. Проверьте соответствие параметров Start Volume, кредитного плеча и спецификаций брокера.

Параметры

Название Описание Значение по умолчанию
Trading Mode Разрешённое направление торговли (лонг, шорт, оба, выключено). Long & Short
Momentum Threshold Минимальный импульс в условных пунктах для открытия сетки. 1
Start Volume Объём первого ордера в новой сетке. 0.01
Max Volume Максимальный объём одной заявки. 2
Lot Multiplier Множитель объёмов для последующих ордеров. 1.5
Grid Step Минимальный шаг цены в пунктах между усреднениями. 26
Max Trades Максимальное число ордеров в одном направлении. 12
First Take Profit Расстояние до цели, если открыт один ордер. 30
Grid Take Profit Расстояние до цели при нескольких ордерах. 7
Stop Loss Расстояние стоп-лосса от последнего ордера. 400
Candle Type Таймфрейм расчёта сигналов. Свечи 1 час

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

  1. Подключайте стратегию к ликвидной валютной паре с предсказуемым спредом.
  2. Настройте Candle Type под желаемый торговый горизонт (по умолчанию H1, как в оригинале).
  3. Перед реальной торговлей оптимизируйте шаг сетки, множитель объёмов и фильтр моментума на исторических данных.
  4. Контролируйте загрузку маржи: сетка может быстро нарастить позицию, поэтому полезно использовать дополнительные механизмы защиты капитала.
  5. Избегайте одновременного запуска нескольких сеточных стратегий на одном инструменте, чтобы не суммировать просадки.

Отличия от версии MetaTrader

  • В портированной версии расчёты выполняются на завершённых свечах, что снижает шум и делает результаты воспроизводимыми.
  • Объёмы заявок приводятся к ограничениям инструмента через свойства StockSharp (минимальный/максимальный объём и шаг лота).
  • Управление стопами и целями реализовано внутри стратегии, без постоянной модификации заявок для каждой ступени сетки.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Smart Forex System strategy: Triple EMA alignment.
/// Enters when fast > mid > slow (buy) or fast < mid < slow (sell).
/// </summary>
public class SmartForexSystemStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _midPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private bool _wasBullishAlignment;
	private bool _hasPrevAlignment;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int MidPeriod { get => _midPeriod.Value; set => _midPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public SmartForexSystemStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_midPeriod = Param(nameof(MidPeriod), 25)
			.SetGreaterThanZero()
			.SetDisplay("Mid EMA", "Mid EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_wasBullishAlignment = false;
		_hasPrevAlignment = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_wasBullishAlignment = false;
		_hasPrevAlignment = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var mid = new ExponentialMovingAverage { Length = MidPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, mid, slow, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal midValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;

		var bullishAlignment = fastValue > midValue && midValue > slowValue;
		var bearishAlignment = fastValue < midValue && midValue < slowValue;
		var crossedUp = bullishAlignment && (!_hasPrevAlignment || !_wasBullishAlignment);
		var crossedDown = bearishAlignment && (!_hasPrevAlignment || _wasBullishAlignment);

		if (crossedUp && Position <= 0)
			BuyMarket();
		else if (crossedDown && Position >= 0)
			SellMarket();

		if (bullishAlignment || bearishAlignment)
		{
			_wasBullishAlignment = bullishAlignment;
			_hasPrevAlignment = true;
		}
	}
}