Открыть на GitHub

Стратегия Potential Entries

Обзор

Potential Entries Strategy воспроизводит алгоритм советника EA_PotentialEntries.mq5. Стратегия анализирует пары последних завершённых свечей и ищет паттерны разворота или наращивания импульса. Торговля ведётся только в одном направлении за раз (бычьем или медвежьем), режим задаётся параметром Pattern Side. После открытия позиции рассчитывается защитный уровень на экстремумах анализируемой пары свечей, что повторяет логику исходного эксперта MetaTrader.

Реализация использует высокоуровневый API StockSharp: подписка на выбранный тип свечей, обработка данных в ProcessCandle, открытие позиций через BuyMarket/SellMarket и закрытие сделок рыночными ордерами при срабатывании внутреннего стоп-уровня. На график выводятся свечи и собственные сделки для визуального контроля.

Данные и параметры

Группа Название Описание
General Pattern Side Направление поиска паттернов: Bullish — поиск бычьих сигналов, Bearish — медвежьих.
Trading Trade Volume Объём рыночной заявки при входе. Перед открытием длинной/короткой позиции стратегия закрывает встречную.
General Candle Type Тип свечей, используемых для распознавания паттернов (по умолчанию часовые).

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

Стратегия анализирует текущую завершённую свечу (C1) и предыдущую (C2). Все значения тел и теней рассчитываются в ценовых единицах.

Бычий режим

При Pattern Side = Bullish выполняются следующие условия для входа в лонг:

  1. Hammer (молот)
    • C1 закрывается выше открытия, C2 — медвежья.
    • Нижняя тень C1 минимум вдвое длиннее тела и более чем втрое длиннее верхней тени.
    • Открывается длинная позиция. Стоп устанавливается на минимуме из Low свечей C1 и C2.
  2. Inverted Hammer (перевёрнутый молот)
    • C1 бычья, C2 медвежья.
    • Верхняя тень C1 минимум вдвое длиннее тела и минимум втрое длиннее нижней тени.
    • Используется та же схема открытия и выставления стопа.
  3. Building Momentum (рост импульса)
    • C1 и C2 бычьи.
    • Диапазон C1 больше диапазона C2, тело C1 как минимум вдвое больше тела C2.
    • Покупка с переносом стопа под минимальный минимум пары свечей.

Медвежий режим

При Pattern Side = Bearish выполняются условия для коротких позиций:

  1. Shooting Star (падающая звезда)
    • C1 закрывается ниже открытия, C2 — бычья.
    • Верхняя тень C1 минимум вдвое длиннее тела и минимум втрое длиннее нижней тени.
    • Открывается шорт и фиксируется стоп над максимальным максимумом C1 и C2.
  2. Hanging Man (повешенный)
    • C1 медвежья, C2 бычья.
    • Нижняя тень C1 минимум вдвое длиннее тела и более чем втрое длиннее верхней тени.
    • Вход в короткую позицию с тем же правилом стопа, что и для падающей звезды.
  3. Building Momentum (рост импульса вниз)
    • C1 и C2 медвежьи.
    • Тело C1 больше тела C2, а диапазон C1 не меньше двойного диапазона C2.
    • Продажа со стопом над максимальным максимумом анализируемых свечей.

Управление стопами и позицией

  • Активен только один режим. Перед открытием новой сделки стратегия закрывает позицию противоположного знака.
  • После входа фиксируется стоп-уровень на экстремумах свечной пары. Каждая новая завершённая свеча проверяет пробой: при уходе цены ниже стопа для лонга или выше стопа для шорта позиция закрывается рыночным ордером.
  • При отсутствии позиции запомненный стоп сбрасывается, что исключает повторное использование старых уровней.

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

  • Выбирайте режим Bullish или Bearish в зависимости от желаемого направления торговли.
  • Тип свечей можно заменить на любой доступный агрегатор, если требуется другой таймфрейм.
  • Python-версии, как и отдельной папки PY, намеренно нет — реализована только C#-стратегия.
  • Стратегия не выставляет тейк-профит. Выход осуществляется по стопу либо вручную.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Potential Entries strategy: two-candle reversal patterns with RSI confirmation.
/// Detects bullish/bearish reversals and trades with RSI filter.
/// </summary>
public class PotentialEntriesStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private readonly List<ICandleMessage> _candles = new();
	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 PotentialEntriesStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candles.Clear();
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candles.Clear();
		_candlesSinceTrade = SignalCooldownCandles;
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(rsi, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		_candles.Add(candle);
		if (_candles.Count > 5)
			_candles.RemoveAt(0);

		if (_candles.Count >= 2)
		{
			var curr = _candles[^1];
			var prev = _candles[^2];

			// Bullish reversal: prev bearish, curr bullish with higher close
			var bullish = prev.OpenPrice > prev.ClosePrice
				&& curr.ClosePrice > curr.OpenPrice
				&& curr.ClosePrice > prev.OpenPrice;

			// Bearish reversal: prev bullish, curr bearish with lower close
			var bearish = prev.ClosePrice > prev.OpenPrice
				&& curr.OpenPrice > curr.ClosePrice
				&& curr.ClosePrice < prev.OpenPrice;

			if (bullish && rsiValue < 50 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (bearish && rsiValue > 50 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}
	}
}