Ver en GitHub

Range Breakout Strategy

The strategy measures the highest and lowest prices within the last RangePeriod candles. When the candle closes outside of this range and the total width of the range is narrower than MaxRangePoints, the strategy enters in the breakout direction.

Entry Rules

  • Long: Candle close >= highest high of the lookback range AND range in points <= MaxRangePoints AND no open position.
  • Short: Candle close <= lowest low of the lookback range AND range in points <= MaxRangePoints AND no open position.

Exit Rules

  • Protective stop loss and take profit are applied immediately after the position is opened.
  • No additional exit rules are used; the position stays open until protection closes it.

Parameters

  • RangePeriod – number of candles for highest/lowest calculation.
  • MaxRangePoints – maximum width of the range in points to allow trading.
  • CandleType – timeframe of candles used for analysis and trading.
  • Volume – market order volume.
  • StopLossPoints – stop loss distance in points.
  • TakeProfitPoints – take profit distance in points.

Indicators

  • Highest
  • Lowest
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Range Breakout strategy: Highest/Lowest channel breakout.
/// Buys when close >= highest. Sells when close <= lowest.
/// </summary>
public class RangeBreakoutStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _channelPeriod;

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

	public int ChannelPeriod
	{
		get => _channelPeriod.Value;
		set => _channelPeriod.Value = value;
	}

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

		_channelPeriod = Param(nameof(ChannelPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Channel Period", "Lookback period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var high = new Highest { Length = ChannelPeriod };
		var low = new Lowest { Length = ChannelPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(high, low, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (candle.ClosePrice >= high && Position <= 0)
			BuyMarket();
		else if (candle.ClosePrice <= low && Position >= 0)
			SellMarket();
	}
}