Открыть на GitHub

Стратегия Ronz Auto SLTP

Описание

Ronz Auto SLTP — это порт MetaTrader 5 советника Ronz Auto SLTP на C#. Стратегия выступает менеджером открытых позиций: автоматически выставляет защитные стопы и тейки, при достижении заданной прибыли подтягивает стоп для фиксации части результата и запускает один из трех вариантов трейлинг-стопа. Реализация построена на высокоуровневом API StockSharp и умеет контролировать как один инструмент, так и весь портфель.

Основные возможности:

  • Переключение между серверными стопами и виртуальным (клиентским) закрытием через параметр UseServerStops.
  • Расчет стартовых уровней SL/TP в «метатрейдеровских» пунктах с учетом минимального допустимого расстояния брокера.
  • Логика фиксации прибыли: после достижения LockProfitAfterPips стоп переносится за цену входа на ProfitLockPips пунктов.
  • Полная поддержка режимов Classic, StepDistance и StepByStep, аналогичных оригинальному советнику.
  • Опция ManageAllSecurities позволяет отслеживать все позиции портфеля, автоматически подписываясь на Level1 для нужных инструментов.
  • Виртуальный режим может выводить сообщения в лог при закрытии сделок.

Параметры

Параметр Значение по умолчанию Описание
ManageAllSecurities true Контролировать все позиции в портфеле. Если false, стратегия управляет только инструментом, указанным в свойстве Security.
TakeProfitPips 550 Расстояние от цены входа до тейк-профита в пунктах (плюс минимальное расстояние брокера).
StopLossPips 350 Расстояние от цены входа до стоп-лосса в пунктах (плюс минимальное расстояние брокера).
UseServerStops true true — выставлять реальные стоп/лимит заявки, false — закрывать позицию рыночным ордером при срабатывании виртуальных уровней.
EnableLockProfit true Включает перенос стопа в прибыльную область.
LockProfitAfterPips 100 Объем прибыли (в пунктах), после которого активируется блокировка прибыли. 0 — блокировка пропускается и сразу включается трейлинг.
ProfitLockPips 60 Сколько пунктов фиксированной прибыли сохраняет стоп после срабатывания блокировки.
TrailingStopMode Classic Режим трейлинг-стопа: None, Classic, StepDistance, StepByStep.
TrailingStopPips 50 Базовое расстояние трейлинг-стопа в пунктах.
TrailingStepPips 10 Шаг, используемый ступенчатыми режимами.
EnableAlerts false Записывать ли уведомления в лог при виртуальном закрытии позиций.

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

  1. Начальные уровни. При появлении позиции вычисляются цены SL и TP, исходя из цены входа, шага цены и минимального стоп-уровня биржи/брокера. Если задано UseServerStops = true, отправляются соответствующие заявки. В противном случае значения сохраняются как виртуальные пороги.
  2. Фиксация прибыли. Как только текущая прибыль по позиции превышает LockProfitAfterPips, стоп переносится на расстояние ProfitLockPips пунктов в прибыльную область (для коротких позиций — ниже цены входа). Если фиксация отключена, этот шаг пропускается.
  3. Трейлинг-стоп:
    • Classic — стоп следует за ценой на фиксированном расстоянии TrailingStopPips.
    • StepDistance — расстояние сокращается на TrailingStepPips, когда цена проходит достаточное количество пунктов.
    • StepByStep — стоп перемещается дискретно, каждый раз на TrailingStepPips, после прохождения очередного интервала TrailingStopPips.
    • Если LockProfitAfterPips = 0, трейлинг активируется сразу, иначе — после превышения LockProfitAfterPips + TrailingStopPips.
  4. Виртуальный режим. При UseServerStops = false стратегия не выставляет дополнительных заявок, а закрывает позицию рыночным ордером, когда фактическая цена пересекает расчетный стоп или тейк. При включенном EnableAlerts соответствующее событие фиксируется в журнале.
  5. Поддержка нескольких инструментов. Для каждого инструмента хранится собственное состояние (цены стопа/тейка, направление позиции, параметры трейлинга). Это позволяет одновременно контролировать разнонаправленные позиции по разным инструментам.

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

  • Убедитесь, что коннектор поставляет Level1-данные (Bid/Ask) по всем торгуемым инструментам — именно они используются для пересчета пунктов и определения прибыли.
  • Если брокер предъявляет жесткие требования к минимальным расстояниям, выбирайте более крупные значения StopLossPips/TakeProfitPips.
  • В условиях тестирования или при торговле на площадках без поддержки серверных стопов переключайтесь в виртуальный режим (UseServerStops = false).
  • StockSharp работает с чистой позицией по инструменту. Если на счете есть несколько хеджирующих сделок, стратегия управляет их суммарным результатом.

Отличия от MQ5-версии

  • В MetaTrader каждая позиция (тикет) обрабатывается отдельно. В StockSharp используется агрегированная позиция по инструменту.
  • Встроенная в исходный скрипт функция тестовых сделок (автоматическое открытие сделок в тестере) не перенесена.
  • Уведомления реализованы через систему логирования StockSharp и не показываются всплывающими окнами.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Ronz Auto SLTP strategy: SMA crossover with ATR-based risk management.
/// Buys when fast SMA crosses above slow SMA, sells on cross below.
/// </summary>
public class RonzAutoSltpStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public RonzAutoSltpStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}