Открыть на GitHub

Стратегия TrendManager TM Plus

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

TrendManager TM Plus — это конвертированная версия советника MetaTrader 5 Exp_TrendManager_Tm_Plus.mq5. В основе стратегии лежит индикатор TrendManager, сравнивающий две сглаженные скользящие средние и измеряющий расстояние между ними. При превышении заданного порога стратегия открывает позиции по направлению тренда, а при смене направления или срабатывании защитных условий закрывает сделки.

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

  1. На выбранном типе свечей строятся две скользящие средние. Для каждой линии можно указать собственный метод сглаживания и длину.
  2. Вычисляется разница между быстрой и медленной средними. Если она больше или равна пороговому значению — фиксируется восходящий тренд; если меньше или равна отрицательному порогу — нисходящий. В остальных случаях сигнал отсутствует.
  3. Состояния цвета (0 — рост, 1 — падение, 3 — нейтрально) сохраняются в короткой истории. Параметр SignalBar определяет, сколько закрытых баров назад анализируется смена цвета, что соответствует оригинальному алгоритму MQL.
  4. При появлении нового «зелёного» сигнала стратегия по желанию закрывает существующие короткие позиции и, если разрешено, открывает длинную. Аналогично «магентовый» сигнал закрывает лонги и может открыть шорт.
  5. Дополнительно могут применяться выходы по времени и по цене: позиция закрывается, когда её возраст превышает MaxPositionAge, цена уходит за StopLossDistance или достигает TakeProfitDistance.

Параметры

  • Candle Type — таймфрейм для построения сигналов (по умолчанию H4, как в исходном советнике).
  • Fast/Slow MA Method — методы сглаживания для быстрой и медленной средних. Доступны Simple, Exponential, Smoothed, Weighted, Jurik и Kaufman Adaptive.
  • Fast/Slow Length — периоды скользящих средних.
  • Distance Threshold (DvLimit) — минимальная абсолютная разница между средними для фиксации тренда. Чтобы перенести значения из MT5, преобразуйте пункты в цену (например, 70 пунктов для пятизнака ≈ 0.00070).
  • Signal Bar — число баров назад для подтверждения свежего сигнала (значение 1 воспроизводит стандартное поведение).
  • Allow Long/Short Entries — включение открытия длинных и коротких позиций.
  • Close Long/Short on Opposite Signal — немедленное закрытие позиции при сигнале противоположного направления.
  • Use Time Exit / Max Position Age — активация выхода по времени и максимальная длительность удержания позиции.
  • Order Volume — фиксированный объём рыночных ордеров, заменяющий блок управления капиталом в MT5.
  • Stop Loss Distance / Take Profit Distance — опциональные защитные и целевые уровни в ценовых единицах (0 отключает).

Особенности реализации

  • Используются стандартные индикаторы StockSharp. Экзотические методы сглаживания из MT5 при отсутствии прямого аналога заменяются ближайшей доступной реализацией.
  • Для соблюдения логики SignalBar хранится небольшой буфер предыдущих цветов.
  • Stop Loss и Take Profit проверяются по минимумам/максимумам закрытых свечей, что имитирует срабатывания внутри бара.
  • Параметры MT5 вроде Deviation и режимов маржи заменены на настройки, совместимые со StockSharp.

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

  1. Выберите таймфрейм свечей в соответствии с желаемым горизонтом торговли. Для полной идентичности оставьте H4.
  2. Настройте порог DvLimit под волатильность инструмента: чем выше волатильность, тем больше значение порога.
  3. Сочетайте выход по времени со стоп- и тейк-уровнями, чтобы воспроизвести систему управления рисками оригинального советника.
  4. Для торговли в обе стороны держите активными оба направления и включайте автоматическое закрытие при противоположном сигнале.

Отличия от оригинального советника

  • Объём сделок задаётся параметром OrderVolume, вместо сложного расчёта по балансу и марже.
  • Защитные ордера моделируются на основе данных свечей и не отправляются в торговую систему заранее.
  • Используются встроенные скользящие средние StockSharp, часть методов отображена напрямую, остальные заменены близкими по поведению.
  • Выход по времени реализован через MaxPositionAge типа TimeSpan, что удобнее для .NET-экосистемы.

Документ содержит всю необходимую информацию для настройки и эксплуатации стратегии TrendManager TM Plus в среде StockSharp.

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>
/// TrendManager TM Plus strategy. Uses fast/slow EMA crossover with distance threshold.
/// </summary>
public class TrendManagerTmPlusStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private decimal? _prevFast;
	private decimal? _prevSlow;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }

	public TrendManagerTmPlusStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_fastLength = Param(nameof(FastLength), 10).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowLength = Param(nameof(SlowLength), 30).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

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

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = null; _prevSlow = null;
		var fast = new ExponentialMovingAverage { Length = FastLength };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
		if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fast > slow;
		_prevFast = fast; _prevSlow = slow;
		if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
	}
}