Открыть на GitHub

Стратегия Bands Pending Breakout

Стратегия переносит эксперта MetaTrader «Bands 2» на платформу StockSharp. Она отслеживает завершённые свечи, проверяет, что текущее время попадает в заданный торговый интервал и что цена находится внутри канала Боллинджера. Когда условия выполняются, роботу выставляется симметричная сетка из трёх отложенных покупок Stop и трёх продаж Stop вокруг границ канала. Каждый ордер получает собственные уровни стоп-лосса и тейк-профита; при срабатывании одного сигнала остальные заявки удаляются.

Алгоритм ориентирован на пробой диапазона Боллинджера. Режим стоп-лосса переключается между противоположной границей индикатора и центральной скользящей средней. Дополнительно реализован трейлинг, который подтягивает защитный стоп при развитии прибыли на заданную величину шага.

Подробности

  • Рыночные данные: Работает на любом инструменте/таймфрейме, доступном через StockSharp.
  • Торговые часы: Параметры HourStart и HourEnd ограничивают постановку новых отложенных ордеров; на каждой завершённой свече внутри окна заявки переустанавливаются.
  • Логика входа:
    • Ожидать свечу со статусом Finished, у которой цена закрытия строго между смещёнными верхней и нижней полосой Боллинджера.
    • Удалить отложенные ордера, оставшиеся от предыдущего бара, и выставить сетку из трёх buy stop выше верхней полосы и трёх sell stop ниже нижней.
    • Расстояние между уровнями определяется StepPips (пересчитывается в шаги цены).
  • Режимы стоп-лосса:
    • BollingerBands: стоп ставится на противоположную полоску плюс шаг StepPips.
    • MovingAverage: стоп рассчитывается от значения скользящей средней, с учётом смещения MaShift и выбранного типа цены.
    • None: начальный стоп не выставляется, но трейлинг может включиться позже.
  • Тейк-профит:
    • Первый уровень использует FirstTakeProfitPips для покупок и продаж.
    • Второй и третий ордера на покупку применяют Second/Third тейк-профиты, а продажи повторяют оригинальную логику MQL и всегда используют первый тейк.
  • Управление ордерами:
    • При выполнении любой заявки остальные отложенные ордера отменяются, а для объёма позиции создаются защитные stop и limit ордера.
    • Модуль трейлинга переносит стоп ближе к рынку, когда цена проходит TrailingStopPips + TrailingStepPips от входа.
    • Защитные ордера автоматически снимаются при закрытии позиции.
  • Нормализация цены: Все уровни округляются к шагу цены инструмента, а перевод «пунктов» повторяет логику оригинала для 3/5 знаков после запятой.

Параметры

Параметр Описание
OrderVolume Объём каждой отложенной заявки.
CandleType Таймфрейм/тип данных для расчётов индикаторов.
HourStart, HourEnd Часы (0–24), в течение которых разрешена установка новых ордеров. HourEnd должен быть строго больше HourStart.
StopLossModes Способ расчёта первоначального стоп-лосса (BollingerBands, MovingAverage, None).
FirstTakeProfitPips, SecondTakeProfitPips, ThirdTakeProfitPips Дистанции тейк-профитов в пунктах для трёх уровней сетки.
TrailingStopPips, TrailingStepPips Размер трейлинг-стопа и дополнительный шаг для его активации (0 отключает трейлинг).
StepPips Расстояние между соседними уровнями сетки.
MaPeriod, MaShift, MaMethod, MaPriceType Настройки скользящей средней (длина, смещение, метод сглаживания и тип цены). Смещение повторяет поведение эксперта MetaTrader.
BandsPeriod, BandsShift, BandsDeviation, BandsPriceType Параметры полос Боллинджера (период, смещение, множитель и тип цены).

Сценарий работы

  1. Подписка на свечи выбранного таймфрейма.
  2. На каждой завершённой свече внутри торгового окна пересчитываются полосы Боллинджера и скользящая средняя с учётом смещения.
  3. Если цена закрытия находится внутри канала, формируется сетка buy/sell stop ордеров с соответствующими стопами и тейками.
  4. При исполнении одного из ордеров остальные отменяются, создаются защитные заявки и запускается трейлинг.
  5. После закрытия позиции защитные ордера снимаются, стратегия готова к следующему сигналу.
namespace StockSharp.Samples.Strategies;

using System;

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

/// <summary>
/// Bands Pending Breakout strategy (simplified).
/// Buys when price closes above the upper Bollinger Band.
/// Sells when price closes below the lower Bollinger Band.
/// </summary>
public class BandsPendingBreakoutStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _bbPeriod;

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

	public int BbPeriod
	{
		get => _bbPeriod.Value;
		set => _bbPeriod.Value = value;
	}

	public BandsPendingBreakoutStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Source candles", "General");

		_bbPeriod = Param(nameof(BbPeriod), 15)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var bb = new BollingerBands { Length = BbPeriod, Width = 1m };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(bb, (ICandleMessage candle, IIndicatorValue bbValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var bbTyped = (BollingerBandsValue)bbValue;
				if (bbTyped.UpBand is not decimal upper || bbTyped.LowBand is not decimal lower)
					return;

				// Buy on breakout above upper band
				if (candle.ClosePrice > upper && Position <= 0)
				{
					BuyMarket();
				}
				// Sell on breakdown below lower band
				else if (candle.ClosePrice < lower && Position >= 0)
				{
					SellMarket();
				}
			})
			.Start();

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