Открыть на GitHub

Стратегия Test MACD

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

Test MACD — это точная конвертация советника MetaTrader TestMACD на платформу StockSharp с использованием высокоуровневого API. Стратегия применяет индикатор MACD для отслеживания смены импульса и совершает сделки, когда основная линия MACD пересекает сигнальную на закрытии свечи. Инструмент и таймфрейм задаются параметром CandleType.

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

  1. Подписаться на свечные данные типа CandleType и рассчитать индикатор MACD с настраиваемыми периодами быстрой, медленной и сигнальной EMA.
  2. На каждой завершённой свече анализировать разницу между значениями MACD и сигнальной линии.
  3. При переходе разницы из неположительной области в положительную открыть длинную позицию: это означает, что MACD пересёк сигнальную линию снизу вверх. Перед открытием лонга ликвидируются активные короткие позиции.
  4. При переходе разницы из неотрицательной области в отрицательную открыть короткую позицию: MACD пересёк сигнальную линию сверху вниз. Перед открытием шорта закрываются все лонги.
  5. Заявки отправляются по рынку фиксированным объёмом, который задаётся параметром TradeVolume.
  6. Для каждой сделки автоматически выставляются стоп-лосс и тейк-профит в шагах цены, что воспроизводит точечную систему управления риском исходного советника.

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

  • Дистанции стоп-лосса и тейк-профита задаются в шагах цены. Если у инструмента нет данных PriceStep, стратегия использует MinPriceStep или единицу в качестве множителя и работает с абсолютными значениями.
  • Защита активируется один раз при запуске стратегии через StartProtection, поэтому все последующие сделки автоматически используют те же настройки.

Параметры

Параметр Описание Значение по умолчанию
FastPeriod Период быстрой EMA в MACD. 12
SlowPeriod Период медленной EMA в MACD. 24
SignalPeriod Период сигнальной EMA в MACD. 9
StopLossPoints Расстояние стоп-лосса в шагах цены. 90
TakeProfitPoints Расстояние тейк-профита в шагах цены. 110
TradeVolume Фиксированный объём заявок. 1
CandleType Тип и таймфрейм свечей для расчётов. 30-минутный таймфрейм

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

  • Перед запуском привяжите стратегию к конкретному инструменту, чтобы были доступны PriceStep и MinPriceStep.
  • Убедитесь в наличии данных по выбранному CandleType; без них индикатор MACD не сформируется и торговля не начнётся.
  • В журнале фиксируются все события пересечения, что помогает анализировать решения стратегии при тестировании.

Особенности конвертации

  • Классы MetaTrader CSignalMACD, CTrailingNone и CMoneyFixedLot заменены механизмами подписки на индикаторы StockSharp и защитой через StartProtection.
  • Функция ExtStateMACD, определявшая момент пересечения линий MACD, преобразована в проверку смены знака разницы между значениями на соседних закрытых свечах.
  • Управление капиталом сведено к фиксированному объёму, что наиболее близко к поведению CMoneyFixedLot без процентной надстройки.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Test MACD strategy: MACD histogram zero-cross.
/// Buys when MACD histogram crosses above zero.
/// Sells when MACD histogram crosses below zero.
/// </summary>
public class TestMacdStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

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

	public TestMacdStrategy()
	{
		_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 MovingAverageConvergenceDivergenceSignal
		{
			Macd = { ShortMa = { Length = 12 }, LongMa = { Length = 26 } },
			SignalMa = { Length = 9 }
		};

		decimal? prevHistogram = null;

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

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (macdVal.IsEmpty)
					return;

				var v = (MovingAverageConvergenceDivergenceSignalValue)macdVal;
				if (v.Macd is not decimal macdDec || v.Signal is not decimal signalDec)
					return;

				var histogram = macdDec - signalDec;

				if (prevHistogram.HasValue)
				{
					if (prevHistogram.Value <= 0m && histogram > 0m && Position <= 0)
						BuyMarket();
					else if (prevHistogram.Value >= 0m && histogram < 0m && Position >= 0)
						SellMarket();
				}

				prevHistogram = histogram;
			})
			.Start();

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