Открыть на GitHub

More Orders After BreakEven (порт для StockSharp)

Папка содержит перевод советника MetaTrader 4 «More Orders After BreakEven» (MQL источник 35609) на C# под платформу StockSharp. Оригинальная стратегия постоянно добавляет новые длинные позиции после того, как предыдущие сделки переведены в безубыток. Порт сохраняет поведение работы с отдельными тикетами и использует высокоуровневый API StockSharp.

Краткое описание стратегии

  • Тип сделок – только покупки. Каждая заявка отправляется как рыночный ордер на основной инструмент стратегии.
  • Основная идея – пока количество сделок без защиты безубытком меньше MaximumOrders, стратегия открывает новый ордер. Когда цена проходит расстояние BreakEvenPips, стоп переносится в точку входа, и позиция перестаёт ограничивать добавление новых сделок.
  • Управление выходом – для каждой позиции сохраняются собственные уровни стоп-лосса и тейк-профита. При достижении триггера безубытка стоп поднимается к цене открытия; при касании стопа или тейка по бид-цене отправляется рыночный ордер на закрытие соответствующего объёма.
  • Обработка тиков – в MQL логика работала в OnTick. В порте используется поток Level1 (лучшая покупка/продажа), что позволяет воспроизвести тот же порядок действий при каждом обновлении котировки.

Параметры

Имя Описание Значение по умолчанию
MaximumOrders Максимальное число длинных сделок, которые ещё не переведены в безубыток. Пока значение меньше порога, стратегия может открыть новый ордер. 1
TakeProfitPips Расстояние от цены входа до тейк-профита в метатрейдеровских пунктах. 0 отключает тейк. 100
StopLossPips Начальное расстояние до стоп-лосса в пунктах. 0 оставляет позицию без стартового стопа. 200
BreakEvenPips Прибыль в пунктах, после которой стоп переносится в безубыток. 0 означает перенос сразу после перехода цены выше точки входа. 10
TradeVolume Объём каждой новой рыночной покупки. 0.01
DebugMode Включает подробные сообщения в лог, аналог функции Comment() в MetaTrader. true

Все параметры в пунктах автоматически корректируются под 4/2- и 5/3-значные котировки, повторяя расчёт коэффициента points из оригинала.

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

  1. Подписка на Level1 – стратегия подписывается на лучшие bid/ask. Как только обе цены известны, вызывается процедура ProcessPrices, имитирующая цикл OnTick.
  2. Подсчёт ордеров – до открытия новой сделки проводится подсчёт активных позиций без безубытка (аналог OrdersCounter() в MQL).
  3. Открытие – при выполнении условия отправляется рыночная покупка объёмом TradeVolume. После исполнения сохраняются цена входа и уровни защиты для тикета.
  4. Перевод в безубыток – при достижении бидом значения Entry + BreakEvenPips стоп-лосс переносится на цену входа, что снимает ограничение на открытие новых сделок.
  5. Выход – при касании бидом тейка или стопа формируется рыночный ордер на продажу оставшегося объёма данного тикета.
  6. Учёт позиций – обработчик OnOwnTradeReceived поддерживает список сделок в порядке FIFO, чтобы точно повторять тиковый учёт MetaTrader при суммарной позиции в StockSharp.

Отличия от оригинала

  • Реализованы только длинные входы, поскольку исходный советник не открывал короткие позиции.
  • Стопы и тейки исполняются силами стратегии через рыночные заявки, так как высокоуровневый API StockSharp не управляет индивидуальными стоп-заявками автоматически.
  • Сообщения диагностики пишутся в журнал StockSharp вместо вывода Comment() на графике.

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

  1. Подключите стратегию к коннектору, который передаёт поток Level1 по выбранному инструменту.
  2. Настройте параметры в пунктах под требования брокера и желаемую тактику управления рисками.
  3. Включите DebugMode на этапе тестирования, чтобы проверить корректность счётчиков и перевода в безубыток; отключите для промышленной эксплуатации.
  4. Убедитесь, что на счёте достаточно средств для открытия дополнительных сделок, которые могут появляться после активации безубытка.

Исходные файлы

  • Оригинальный MQL4: MQL/35609/More Orders After BreakEven.mq4.
  • Конвертированная стратегия: CS/MoreOrdersAfterBreakEvenStrategy.cs.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// More Orders After BreakEven strategy: TEMA crossover.
/// Buys when price crosses above TEMA, sells when price crosses below TEMA.
/// </summary>
public class MoreOrdersAfterBreakEvenStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;

	private decimal _prevClose;
	private decimal _prevTema;
	private bool _hasPrev;

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

	public MoreOrdersAfterBreakEvenStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_period = Param(nameof(Period), 50)
			.SetGreaterThanZero()
			.SetDisplay("Period", "TEMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevTema = 0;
		_hasPrev = false;
		var tema = new ExponentialMovingAverage { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(tema, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevClose <= _prevTema && candle.ClosePrice > temaValue && Position <= 0)
				BuyMarket();
			else if (_prevClose >= _prevTema && candle.ClosePrice < temaValue && Position >= 0)
				SellMarket();
		}

		_prevClose = candle.ClosePrice;
		_prevTema = temaValue;
		_hasPrev = true;
	}
}