Открыть на GitHub

Стратегия Maximus vX Lite

Эта стратегия торгует прорывы краткосрочных зон консолидации. Она анализирует 15‑минутные свечи и определяет узкие диапазоны, после чего открывает сделки при выходе цены за пределы диапазона на заданное расстояние.

Логика стратегии

  1. Для каждой завершённой 15‑минутной свечи вычисляются максимум и минимум последних 40 свечей.
  2. Если расстояние между экстремумами меньше параметра Range, считается, что образована зона консолидации.
  3. После ожидания периода Delay Open без новых сделок, прорыв выше верхней границы плюс Distance пунктов открывает длинную позицию, а прорыв ниже нижней границы минус Distance пунктов открывает короткую позицию.
  4. После открытия позиции применяется фиксированный Stop Loss и трейлинг‑стоп величиной Trail пунктов.
  5. Границы консолидации сбрасываются спустя Period часов.

Параметры

  • DelayOpen – часы ожидания перед открытием новой сделки.
  • Distance – расстояние от границы консолидации в пунктах.
  • Period – часы до пересмотра уровней консолидации.
  • Range – максимальный размер зоны консолидации в пунктах.
  • StopLoss – начальный стоп‑лосс в пунктах.
  • Trail – дистанция трейлинг‑стопа в пунктах.

Примечания

Стратегия использует высокоуровневый API: свечи подписываются через SubscribeCandles, индикаторы привязываются с помощью Bind. Ордеры отправляются методами BuyMarket и SellMarket. Комментарии в исходном коде написаны на английском языке.

using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Breakout strategy based on consolidation zones.
/// </summary>
public class MaximusVxLiteStrategy : Strategy
{
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevHigh;
	private decimal _prevLow;
	private bool _hasPrev;

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

	public MaximusVxLiteStrategy()
	{
		_lookback = Param(nameof(Lookback), 20)
			.SetDisplay("Lookback", "Highest/Lowest lookback period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame for candles", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevHigh = 0;
		_prevLow = 0;
		_hasPrev = false;
	}

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

		var highest = new Highest { Length = Lookback };
		var lowest = new Lowest { Length = Lookback };

		SubscribeCandles(CandleType).Bind(highest, lowest, ProcessCandle).Start();
	}

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

		if (!_hasPrev)
		{
			_prevHigh = highest;
			_prevLow = lowest;
			_hasPrev = true;
			return;
		}

		var close = candle.ClosePrice;

		// Breakout above previous highest
		if (close > _prevHigh && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		// Breakout below previous lowest
		else if (close < _prevLow && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevHigh = highest;
		_prevLow = lowest;
	}
}