Открыть на GitHub

Стратегия Full Damp

Общее описание

Full Damp — это контртрендовая стратегия, использующая три набора полос Боллинджера и фильтр на основе RSI. Система ищет выбросы цены за пределы самых широких полос, чтобы обнаружить возможное истощение движения. После фиксации экстремума проверяется, попадал ли RSI в зону перепроданности или перекупленности в пределах последних LookbackBars свечей. Вход осуществляется, когда цена возвращается внутрь средней полосы. Управление позицией включает частичную фиксацию прибыли, перенос стоп-ордера и выход по сигналу полос Боллинджера.

Торговая логика

  1. Определение сигнала
    • Лонг сигнал формируется, когда минимум свечи закрывается ниже нижней полосы Боллинджера с шириной 3. Шорт сигнал возникает при закрытии максимума выше верхней полосы того же набора.
    • В течение последних LookbackBars завершённых свечей RSI должен достигнуть значения ниже 30 (для покупки) или выше 70 (для продажи). Каждый новый экстремум обновляет таймер.
  2. Точка входа
    • Покупка выполняется после закрытия цены выше нижней полосы набора с шириной 2 и при отсутствии открытой длинной позиции.
    • Продажа инициируется, когда цена закрывается ниже верхней полосы среднего набора.
    • Начальный стоп-лосс устанавливается на минимуме (для покупок) или максимуме (для продаж), зарегистрированном после появления сигнальной свечи, и расширяется на заданное количество пунктов.
  3. Сопровождение позиции
    • При достижении прибыли, равной первоначальному риску, половина позиции закрывается, а стоп переносится в точку входа.
    • Оставшаяся часть закрывается, если максимум (для покупок) или минимум (для продаж) пересекает среднюю полосу Боллинджера в противоположную сторону.
    • Если цена раньше доходит до стоп-уровня, позиция закрывается полностью.

Параметры

Параметр Описание Значение по умолчанию
CandleType Тип свечей, используемых для расчётов и торговли. Часовые свечи
BollingerPeriod1 Период узких полос Боллинджера (ширина = 1). 20
BollingerPeriod2 Период средних полос Боллинджера (ширина = 2). 20
BollingerPeriod3 Период широких полос Боллинджера (ширина = 3). 20
RsiPeriod Период RSI для фильтрации сигналов. 14
LookbackBars Количество свечей для поиска экстремальных значений RSI. 6
StopOffsetPoints Дополнительный зазор в пунктах для расчёта стоп-лосса. 10
Volume Объём заявки, задаётся базовым классом. 1

Примечания

  • Пороговые значения RSI фиксированы на уровнях 30 и 70, чтобы соответствовать оригинальному советнику MQL.
  • Стратегия использует высокоуровневый API StockSharp: индикаторы подключаются через Bind, ордера исполняются по рынку, логика стопов и частичных выходов управляется внутри стратегии.
  • Все решения принимаются по закрытию свечи, что исключает реакции на незавершённые данные.
using System;



using StockSharp.Algo.Indicators;

using StockSharp.Algo.Strategies;

using StockSharp.BusinessEntities;

using StockSharp.Messages;



namespace StockSharp.Samples.Strategies;



public class FullDampStrategy : Strategy

{

	private readonly StrategyParam<int> _rsiPeriod;

	private readonly StrategyParam<DataType> _candleType;



	private decimal _prevRsi; private bool _hasPrev;

	private int _cooldown;



	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }

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



	public FullDampStrategy()

	{

		_rsiPeriod = Param(nameof(RsiPeriod), 14).SetDisplay("RSI Period", "RSI lookback", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");

	}



	/// <inheritdoc />

	protected override void OnReseted()

	{

		base.OnReseted();

		_prevRsi = default;

		_hasPrev = default;

		_cooldown = default;

	}



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)

	{

		base.OnStarted2(time);

		_hasPrev = false;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(rsi, ProcessCandle).Start();

	}



	private void ProcessCandle(ICandleMessage candle, decimal rsi)

	{

		if (candle.State != CandleStates.Finished) return;

		if (!IsFormedAndOnlineAndAllowTrading()) return;

		if (!_hasPrev) { _prevRsi = rsi; _hasPrev = true; return; }

		if (_cooldown > 0)

		{

			_cooldown--;

			_prevRsi = rsi;

			return;

		}



		if (_prevRsi <= 30 && rsi > 30 && Position <= 0)

		{

			var volume = Volume + Math.Abs(Position);

			BuyMarket(volume);

			_cooldown = 2;

		}

		else if (_prevRsi >= 70 && rsi < 70 && Position >= 0)

		{

			var volume = Volume + Math.Abs(Position);

			SellMarket(volume);

			_cooldown = 2;

		}

		_prevRsi = rsi;

	}

}