Открыть на GitHub

Стратегия XIT Three MA Cross

Эта стратегия повторяет эксперта MetaTrader 5 XIT_THREE_MA_CROSS.mq5 на платформе StockSharp. Алгоритм синхронизирует три скользящих средних, проверяет расхождение линий MACD и рассчитывает объём сделки на основе ATR. Получается трендовая методика с подтверждением импульса, рассчитанная на среднесрочные движения ликвидных валютных пар или индексов.

Общие сведения

  • Тип рынка: Наиболее эффективна на инструментах, которые формируют устойчивые движения в рамках выбранного таймфрейма.
  • Используемые индикаторы:
    • Медленная, промежуточная и быстрая скользящие средние (тип выбирается пользователем) на основном таймфрейме.
    • MACD (на EMA) для оценки направления импульса и разницы между линией и сигналом.
    • Два индикатора ATR одинаковой длины на независимых таймфреймах для вычисления стоп-лосса и тейк-профита.
  • Направление торгов: Двусторонняя торговля, возможны длинные и короткие позиции.
  • Размер позиции: Рассчитывается из заданного процента риска и дистанции стопа по ATR. Если у инструмента нет полной информации о тиках, стратегия возвращается к стандартному значению Volume.

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

Вход в покупку

Длинная позиция открывается на закрытой свече, когда одновременно выполняются условия:

  1. Значение MACD растёт относительно предыдущей свечи (MACD[t] > MACD[t-1]).
  2. Сигнальная линия MACD также растёт.
  3. Разница между MACD и сигналом превышает MacdTriggerPoints * PriceStep.
  4. Промежуточная скользящая средняя увеличилась по сравнению с прошлым значением.
  5. Быстрая скользящая средняя увеличилась.
  6. Промежуточная средняя находится выше медленной.
  7. Быстрая средняя выше промежуточной.
  8. Оба значения ATR доступны для расчёта стопа и цели.

Вход в продажу

Короткий вход является зеркальным отражением длинного сценария:

  1. Линия MACD уменьшается относительно прошлой свечи.
  2. Сигнальная линия MACD уменьшается.
  3. Сигнальная линия превышает MACD минимум на MacdTriggerPoints * PriceStep.
  4. Промежуточная средняя снижается относительно предыдущего значения.
  5. Быстрая средняя снижается.
  6. Промежуточная средняя ниже медленной.
  7. Быстрая средняя ниже промежуточной.
  8. ATR на обоих таймфреймах сформированы.

Выход

  • Длинная позиция закрывается при пересечении: быстрая средняя уходит ниже промежуточной, либо цена достигает ATR-стопа/тейк-профита.
  • Короткая позиция закрывается, когда быстрая средняя поднимается выше промежуточной, либо при касании ценой уровней ATR.
  • После фиксации позиции стратегия дожидается следующей свечи, что повторяет поведение исходного советника.

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

  • Стоп-лосс: Дистанция равна значению ATR с таймфрейма AtrStopCandleType. Для покупок стоп = Entry - ATR, для продаж = Entry + ATR.
  • Тейк-профит: Расстояние равно ATR с таймфрейма AtrTakeCandleType, уровни зеркально расположены относительно цены входа.
  • Процент риска: Денежная потеря на единицу позиции оценивается по расстоянию до стопа. Если заданы PriceStep и PriceStepCost, используется стоимость тика. Иначе применяется чистая ценовая дистанция. Размер позиции = RiskPercent% от текущей стоимости портфеля, делённые на риск на единицу и округлённые вниз до шага объёма.

Параметры

Параметр Описание Значение по умолчанию
CandleType Таймфрейм, на котором рассчитываются скользящие средние и MACD. Свечи 1 час
SlowMaLength / IntermediateMaLength / FastMaLength Периоды скользящих средних. 60 / 14 / 4
SlowMaType, IntermediateMaType, FastMaType Типы средних (Simple, Exponential, Smoothed, Weighted). Simple
MacdFastLength, MacdSlowLength, MacdSignalLength Быстрый, медленный и сигнальный периоды MACD. 12 / 26 / 9
MacdTriggerPoints Минимальная дистанция между MACD и сигналом в пунктах инструмента. Конвертируется через PriceStep. 7
AtrLength Период обоих ATR. 14
AtrTakeCandleType / AtrStopCandleType Таймфреймы ATR для тейк-профита и стоп-лосса. Свечи 4 часа
RiskPercent Доля портфеля, которую допускается потерять в одной сделке. 10%

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

  1. Подключайте стратегию к инструментам с корректными параметрами PriceStep, PriceStepCost и VolumeStep, чтобы позиционирование рассчитывалось точно.
  2. Загрузите историю для всех таймфреймов подписки (CandleType, AtrTakeCandleType, AtrStopCandleType). При отсутствии ATR входы откладываются.
  3. Алгоритм работает по закрытым свечам и игнорирует внутрисвечные колебания, аналогично исходному советнику, который считывает текущие и предыдущие буферы индикаторов.
  4. При необходимости адаптируйте типы скользящих средних под специфику торгуемого рынка.

Файлы

  • CS/XitThreeMaCrossStrategy.cs – C#-реализация на высокоуровневом API StockSharp с подписками ATR и управлением риском.
  • README.md – английская версия описания.
  • README_zh.md – китайский перевод документации.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Triple MA alignment strategy.
/// </summary>
public class XitThreeMaCrossStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _midPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal? _prevFast;
	private decimal? _prevMid;

	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 XitThreeMaCrossStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

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

		_midPeriod = Param(nameof(MidPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("Mid Period", "Medium MA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow MA (trend filter)", "Indicators");

		Volume = 0.1m;
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevMid = null;
	}

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

		_prevFast = null;
		_prevMid = null;

		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var mid = new SimpleMovingAverage { Length = MidPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, mid, slow, ProcessCandle)
			.Start();

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

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

		if (_prevFast == null || _prevMid == null)
		{
			_prevFast = fastVal;
			_prevMid = midVal;
			return;
		}

		var buySignal = fastVal > midVal && midVal > slowVal;
		var sellSignal = fastVal < midVal && midVal < slowVal;

		if (buySignal && Position <= 0)
		{
			if (Position < 0)
				BuyMarket(Math.Abs(Position));

			BuyMarket(Volume);
		}
		else if (sellSignal && Position >= 0)
		{
			if (Position > 0)
				SellMarket(Position);

			SellMarket(Volume);
		}

		_prevFast = fastVal;
		_prevMid = midVal;
	}
}