Открыть на GitHub

Стратегия CBC_WS_RSI

Обзор

CBC_WS_RSI — реализация на StockSharp высокого уровня оригинального советника MQL5. Стратегия объединяет свечные модели «Три белых солдата» и «Три черные вороны» с подтверждением по RSI. Вход выполняется только тогда, когда много-свечная разворотная конфигурация совпадает с направлением импульса. Обработка ведётся исключительно по сформированным свечам, а все подписки реализованы через SubscribeCandles().Bind(...) без ручной работы с буферами индикаторов.

Логика торговли

Условия для покупки

  1. Обнаружена фигура «Три белых солдата»:
    • Три подряд бычьи свечи с закрытием выше открытия.
    • Каждое закрытие выше закрытия предыдущей свечи.
    • Вторая и третья свечи открываются внутри тела предыдущей.
  2. RSI текущей свечи не превышает уровня подтверждения лонга (по умолчанию 40).
  3. При отсутствии позиции выполняется покупка Volume по рынку. При наличии короткой позиции она закрывается и только затем открывается длинная.

Условия для продажи

  1. Обнаружена фигура «Три черные вороны»:
    • Три подряд медвежьи свечи с закрытием ниже открытия.
    • Каждое закрытие ниже закрытия предыдущей свечи.
    • Вторая и третья свечи открываются внутри тела предыдущей.
  2. RSI текущей свечи не ниже уровня подтверждения шорта (по умолчанию 60).
  3. При отсутствии позиции выполняется продажа Volume по рынку. При наличии длинной позиции она закрывается и только затем открывается короткая.

Правила выхода

  • Закрытие лонга: RSI пересекает сверху вниз верхний (70) или нижний (30) уровни выхода.
  • Закрытие шорта: RSI пересекает снизу вверх нижний (30) или верхний (70) уровни выхода.
  • Защита позиций: Параметры стоп-лосса и тейк-профита задаются в процентах. Если значения больше нуля, защита активируется через StartProtection.

Стратегия отслеживает два последних значения RSI и фиксирует позицию при первом же пересечении критических уровней, что позволяет быстро реагировать на изменение импульса.

Параметры

Имя Описание Значение по умолчанию
CandleType Тип и таймфрейм свечей для подписки. Свечи 1 часа
RsiPeriod Период расчёта RSI. 37
LongConfirmationLevel Максимальный RSI для входа в лонг. 40
ShortConfirmationLevel Минимальный RSI для входа в шорт. 60
LowerExitLevel Нижний уровень RSI для закрытия позиций. 30
UpperExitLevel Верхний уровень RSI для закрытия позиций. 70
StopLossPercent Стоп-лосс в процентах (0 отключает). 1
TakeProfitPercent Тейк-профит в процентах (0 отключает). 2

Все числовые параметры помечены SetCanOptimize(true) и могут участвовать в оптимизации.

Визуализация

При наличии области графика стратегия отображает:

  • выбранную свечную серию;
  • линию RSI;
  • совершённые сделки, что помогает оценить точность распознавания моделей.

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

  • Перед запуском установите желаемый объём Volume.
  • Стратегия подходит для любых инструментов с данными OHLC.
  • Свечи с нулевым телом игнорируются, что уменьшает влияние дожи.
  • Подтверждение RSI снижает количество ложных сигналов при слабых разворотах.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// CBC WS RSI strategy: 3 Black Crows / 3 White Soldiers with RSI confirmation.
/// Buys after 3 bullish candles with RSI below 60, sells after 3 bearish with RSI above 40.
/// </summary>
public class CbcWsRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private int _bullCount;
	private int _bearCount;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public CbcWsRsiStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_bullCount = 0;
		_bearCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_bullCount = 0;
		_bearCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		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 (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (candle.ClosePrice > candle.OpenPrice)
		{
			_bullCount++;
			_bearCount = 0;
		}
		else if (candle.ClosePrice < candle.OpenPrice)
		{
			_bearCount++;
			_bullCount = 0;
		}
		else
		{
			_bullCount = 0;
			_bearCount = 0;
		}

		// Exit on RSI extremes
		if (Position > 0 && rsi > 75 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
		else if (Position < 0 && rsi < 25 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}

		// Entry on pattern
		if (_bullCount >= 3 && rsi < 60 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_bullCount = 0;
			_candlesSinceTrade = 0;
		}
		else if (_bearCount >= 3 && rsi > 40 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_bearCount = 0;
			_candlesSinceTrade = 0;
		}
	}
}