Открыть на GitHub

Стратегия MACD Sample Hedging Grid

Обзор

Стратегия представляет собой портирование советника MetaTrader "MACD Sample Hedging Grid" на StockSharp. Она объединяет краткосрочные пересечения MACD, фильтр наклона EMA и подтверждения со старших таймфреймов. При совпадении условий строится сетка позиций по направлению сигнала с наращиванием объёма по заданному множителю.

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

  • Базовый таймфрейм: задаётся параметром (по умолчанию 5-минутные свечи).
  • Фильтр тренда: EMA (по умолчанию 26 периодов) должна расти для покупок и снижаться для продаж.
  • Сигнал MACD: быстрая линия MACD пересекает сигнальную на базовом таймфрейме и превышает минимальный модуль (в шагах цены).
  • Подтверждение моментума: модуль отклонения индикатора Momentum от нейтрального уровня 100 на старшем таймфрейме должен превысить пороги для лонгов и шортов. Анализируются три последних свечи старшего таймфрейма — как в исходном советнике.
  • Долгосрочное подтверждение: MACD на ещё более крупном таймфрейме (по умолчанию месячном) должен поддерживать выбранное направление (MACD выше сигнальной линии при бычьем сценарии и ниже — при медвежьем).

Когда сигнал формируется, стратегия либо открывает новую сетку в выбранном направлении, либо добавляет позицию, пока не достигнут лимит входов.

Управление позицией

  • Масштабирование сетки: каждый дополнительный вход умножает стартовый объём на LotExponent (по умолчанию 1.44). Счётчик сбрасывается при смене направления или закрытии позиции.
  • Ограничение рисков: опциональные тейк-профит и стоп-лосс переводятся в защитные заявки StockSharp и задаются в шагах цены.
  • Смена направления: при обратном сигнале текущая позиция закрывается перед открытием сетки в противоположную сторону.

Параметры

Название Описание Значение по умолчанию
CandleType Основной таймфрейм для расчёта MACD и EMA. 5 минут
MomentumCandleType Старший таймфрейм для расчёта Momentum. 30 минут
TrendCandleType Долгий таймфрейм для трендового фильтра MACD. 30 дней
FastMaPeriod Период быстрой EMA в MACD. 12
SlowMaPeriod Период медленной EMA в MACD. 26
SignalPeriod Период сигнальной SMA MACD. 9
TrendMaPeriod Период EMA для локального фильтра. 26
MomentumPeriod Период индикатора Momentum. 14
MacdOpenLevel Минимальный модуль MACD (в шагах цены) для входа. 3
MomentumBuyThreshold Минимальное отклонение Momentum от 100 для покупок. 0.3
MomentumSellThreshold Минимальное отклонение Momentum от 100 для продаж. 0.3
MaxTrades Максимум входов в одном направлении. 10
LotExponent Множитель объёма для каждого следующего входа. 1.44
StopLossSteps Размер стоп-лосса в шагах цены. 20
TakeProfitSteps Размер тейк-профита в шагах цены. 50

Примечания

  • В исходном советнике присутствовали денежный трейлинг, перевод в безубыток и контроль просадки по капиталу. Эти функции требуют брокерских данных о счёте и ручного управления заявками, поэтому в высокоуровневой реализации StockSharp они не включены.
  • Подписки на свечи, индикаторы и торговые операции реализованы через рекомендованный высокоуровневый API.
  • Перед запуском убедитесь, что для выбранного инструмента доступны исторические данные всех указанных таймфреймов.
namespace StockSharp.Samples.Strategies;

using System;

using Ecng.Common;

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

/// <summary>
/// MACD Sample Hedging Grid: MACD crossover with grid-like position management.
/// </summary>
public class MacdSampleHedgingGridStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

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

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

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

		var macd = new MovingAverageConvergenceDivergence();

		decimal? prevMacd = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(macd, (candle, macdLine) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevMacd.HasValue)
				{
					if (prevMacd.Value <= 0 && macdLine > 0 && Position <= 0)
						BuyMarket();
					else if (prevMacd.Value >= 0 && macdLine < 0 && Position >= 0)
						SellMarket();
				}

				prevMacd = macdLine;
			})
			.Start();

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