Открыть на GitHub

Стратегия AML RSI Meeting Lines

Обзор

AML RSI Meeting Lines Strategy — порт на StockSharp советника MetaTrader 5 Expert_AML_RSI.mq5. Исходная система сочетает распознавание японских свечных моделей «Meeting Lines» и индикатор RSI. В процессе конвертации сохранены ключевые торговые правила, а выполнение перенесено на высокоуровневый API StockSharp с подписками на свечи и встроенными индикаторами.

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

  • Подписка на выбранный тип свечей и обработка только завершённых баров.
  • Расчёт скользящего среднего по размерам тел свечей позволяет определить «длинные» свечи, необходимые для модели Meeting Lines.
  • Хранение значений RSI на двух предыдущих свечах обеспечивает подтверждение и выход из позиции.
  • Бычий сигнал: две свечи формируют модель Meeting Lines, а RSI ниже порогового уровня — открывается длинная позиция.
  • Медвежий сигнал: зеркальная конфигурация и RSI выше порога — открывается короткая позиция.
  • Выход: пересечение RSI настроенных уровней 30 и 70 в противоположную сторону закрывает текущую позицию.
  • Для сделок используются методы BuyMarket, SellMarket и ClosePosition, что позволяет автоматически переворачиваться при появлении противоположного сигнала.

Параметры

Имя Назначение Значение по умолчанию
CandleType Таймфрейм для анализа свечных моделей. Часовые свечи
RsiPeriod Период расчёта RSI. 11
BodyAveragePeriod Количество свечей для усреднения тел. 3
BullishRsiLevel Максимальное значение RSI для подтверждения бычьей модели. 40
BearishRsiLevel Минимальное значение RSI для подтверждения медвежьей модели. 60
LowerExitLevel Уровень RSI, при пробое вверх закрывающий шорты. 30
UpperExitLevel Уровень RSI, при пробое вниз закрывающий лонги. 70

Все параметры реализованы через StrategyParam<T> и доступны для оптимизации в дизайнере StockSharp.

Управление рисками

  • В OnStarted вызывается StartProtection(), что задействует встроенный мониторинг позиций.
  • Перед открытием новой сделки стратегия проверяет, не требуется ли закрытие текущей позиции по сигналам RSI.
  • Рыночные ордера учитывают текущий объём позиции, чтобы переворот выполнялся одним вызовом.

Особенности конвертации

  • Усреднение тел свечей реализовано индикатором SimpleMovingAverage, который получает модуль разницы Open и Close, аналогично функции AvgBody в MQL5.
  • Проверка RSI повторяет оригинальные условия RSI(1) и RSI(2) — используются значения двух предыдущих свечей.
  • Комментарии переписаны на английском языке, а код оформлен в соответствии с требованиями репозитория (tab-отступы и file-scoped namespace).

Как использовать

  1. Запустите стратегию на нужном инструменте и выберите соответствующий тип свечей.
  2. При необходимости скорректируйте уровни RSI и период усреднения под специфику рынка.
  3. Перед реальной торговлей протестируйте стратегию на истории и в симуляции.
  4. Для тонкой настройки используйте оптимизацию параметров в Designer или в бэктестере StockSharp.

Дисклеймер

Стратегия предоставляется исключительно в учебных целях. Перед использованием на реальном счёте необходимо провести всестороннее тестирование.

namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Meeting Lines + RSI strategy.
/// Buys on bullish meeting lines with low RSI, sells on bearish meeting lines with high RSI.
/// </summary>
public class AmlRsiMeetingLinesStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _rsiLow;
	private readonly StrategyParam<decimal> _rsiHigh;

	private ICandleMessage _prevCandle;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public decimal RsiLow { get => _rsiLow.Value; set => _rsiLow.Value = value; }
	public decimal RsiHigh { get => _rsiHigh.Value; set => _rsiHigh.Value = value; }

	public AmlRsiMeetingLinesStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
		_rsiLow = Param(nameof(RsiLow), 40m)
			.SetDisplay("RSI Low", "RSI level for bullish entry", "Signals");
		_rsiHigh = Param(nameof(RsiHigh), 60m)
			.SetDisplay("RSI High", "RSI level for bearish entry", "Signals");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevCandle = null;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevCandle = null;
		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 (_prevCandle != null)
		{
			var avgBody = (Math.Abs(candle.ClosePrice - candle.OpenPrice) +
						   Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice)) / 2m;

			if (avgBody > 0)
			{
				var prevBearish = _prevCandle.OpenPrice > _prevCandle.ClosePrice;
				var currBullish = candle.ClosePrice > candle.OpenPrice;
				var closesNear = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;

				if (prevBearish && currBullish && closesNear && rsiValue < RsiLow && Position <= 0)
					BuyMarket();

				var prevBullish = _prevCandle.ClosePrice > _prevCandle.OpenPrice;
				var currBearish = candle.OpenPrice > candle.ClosePrice;
				var closesNear2 = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;

				if (prevBullish && currBearish && closesNear2 && rsiValue > RsiHigh && Position >= 0)
					SellMarket();
			}
		}

		_prevCandle = candle;
	}
}