Открыть на GitHub

Стратегия X MAN

Обзор

Стратегия X MAN переносит логику советника MetaTrader X_MAN.mq4 на высокоуровневый API StockSharp. Система торгует пробои, опираясь на комбинацию быстрой и медленной линейно-взвешенных скользящих средних (LWMA), фильтрует сигналы по импульсу старшего таймфрейма и подтверждает направление линиями MACD, рассчитанными на месячных свечах. Цель стратегии — подключаться к продолжению тренда, когда структура цены и импульс согласованы.

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

  1. Фильтр тренда — быстрая LWMA на основном таймфрейме должна находиться выше медленной (для покупок) или ниже (для продаж) как минимум на величину параметра DistancePoints.
  2. Импульс старшего таймфрейма — стратегия подписывается на свечи более высокого периода и измеряет отклонение импульса от нейтрального уровня 100. За последние три значения должно появиться отклонение, превышающее MomentumBuyThreshold или MomentumSellThreshold в зависимости от направления сделки.
  3. Подтверждение MACD — на месячных свечах считается стандартный MACD (12, 26, 9). Для покупок линия MACD должна быть выше сигнальной, для продаж — ниже.
  4. Исполнение сделок — при выполнении всех фильтров открываются рыночные ордера. Позиция может быть перевёрнута только если появляется противоположный сигнал.

Параметры

Параметр Описание
CandleType Основной таймфрейм для LWMA.
HigherCandleType Таймфрейм для импульсного фильтра.
MacdCandleType Таймфрейм для MACD (по умолчанию месяц).
FastMaPeriod Период быстрой LWMA.
SlowMaPeriod Период медленной LWMA.
MomentumPeriod Период расчёта импульса.
MomentumBuyThreshold Минимальное отклонение импульса для покупок.
MomentumSellThreshold Минимальное отклонение импульса для продаж.
DistancePoints Минимальная разница между LWMA в пунктах.
TakeProfitPoints Дистанция тейк-профита в пунктах (опция).
StopLossPoints Дистанция стоп-лосса в пунктах (опция).

Все параметры реализованы через StrategyParam<T>, поэтому их можно оптимизировать или настраивать в Designer.

Управление рисками

Если заданы положительные значения TakeProfitPoints или StopLossPoints, активируется встроенный защитный модуль StockSharp с рыночными выходами. Дополнительные алгоритмы безубыточности и трейлинга из исходного советника пока не перенесены.

Отличия от оригинала

  • В MetaTrader-версии присутствовали эквити-стопы, перенос в безубыток и расширенные схемы управления объёмом. В адаптации оставлена только ключевая логика входа.
  • Подбор объёма позиций возлагается на окружение запуска; ступенчатое увеличение лота не реализовано.
  • Отправка писем, уведомлений и ручное сопровождение ордеров отсутствуют.

Такой подход делает стратегию компактной и лучше интегрированной с инфраструктурой StockSharp, сохраняя при этом исходную идею торговли по импульсу и тренду.

namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// X-MAN strategy: Stochastic + SMA trend filter.
/// </summary>
public class XManStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _smaPeriod;

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

	public XManStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_smaPeriod = Param(nameof(SmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("SMA Period", "SMA period", "Indicators");
	}

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

		var sma = new SimpleMovingAverage { Length = SmaPeriod };
		var rsi = new RelativeStrengthIndex { Length = 14 };

		decimal? prevClose = null;
		decimal? prevSma = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(sma, rsi, (candle, smaVal, rsiVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;

				if (prevClose.HasValue && prevSma.HasValue)
				{
					var crossUp = prevClose.Value <= prevSma.Value && close > smaVal;
					var crossDown = prevClose.Value >= prevSma.Value && close < smaVal;

					if (crossUp && rsiVal < 70 && Position <= 0)
						BuyMarket();
					else if (crossDown && rsiVal > 30 && Position >= 0)
						SellMarket();
				}

				prevClose = close;
				prevSma = smaVal;
			})
			.Start();

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