Auf GitHub ansehen

RSI Expert Ausbruch-Strategie

Übersicht

  • Port der MetaTrader 5 "RSI_Expert"-Strategie, die RSI-Schwellenwert-Ausbrüche handelt.
  • Verwendet einen einzigen RSI-Indikator, um Momentum-Umkehrungen in der Nähe von überverkauften/überkauften Bereichen zu erkennen.
  • Implementiert das ursprüngliche feste Take-Profit-, Stop-Loss- und Trailing-Stop-Management in Pips.

Strategie-Logik

  1. RSI auf der ausgewählten Kerzenserie aufbauen (Standardperiode: 14).
  2. Die zwei zuletzt abgeschlossenen RSI-Werte verfolgen.
  3. Long gehen, wenn der RSI nach vorherigem Unterschreiten wieder über den unteren Schwellenwert steigt (Standard 20).
  4. Short gehen, wenn der RSI nach vorherigem Überschreiten wieder unter den oberen Schwellenwert fällt (Standard 60).
  5. Jede entgegengesetzte Exposition schließen, bevor eine neue Position eröffnet wird, um netto-direktional zu bleiben.
  6. Offene Trades mit optionalen Stop-Loss-, Take-Profit- und Trailing-Stop-Abständen in Pips verwalten.

Parameter

Name Beschreibung Standard
CandleType Zeitrahmen für die Kerzenaggregation. 1-Stunden-Kerzen
TradeVolume Ordergröße für Einstiege. 0.1
RsiPeriod RSI-Lookback-Länge. 14
RsiUpperLevel RSI-Schwellenwert, der eine bärische Umkehr signalisiert. 60
RsiLowerLevel RSI-Schwellenwert, der eine bullische Umkehr signalisiert. 20
TakeProfitPips Take-Profit-Abstand in Pips (0 deaktiviert). 60
StopLossPips Stop-Loss-Abstand in Pips (0 deaktiviert). 0
TrailingStopPips Trailing-Stop-Abstand in Pips (0 deaktiviert Trailing). 15
TrailingStepPips Mindestpreisverbesserung, bevor der Trailing-Stop erneut verschoben wird. 5

Pip-Interpretation: Im StockSharp-Port entspricht ein "Pip" einem Security.PriceStep. Bei FX-Symbolen mit fraktionierter Quotierung sicherstellen, dass der Preisschritt mit der Pip-Konvention des Instruments übereinstimmt, andernfalls die Eingangsabstände entsprechend anpassen.

Risikomanagement

  • Take-Profit und Stop-Loss werden bei jeder abgeschlossenen Kerze anhand des letzten durchschnittlichen Positionspreises ausgewertet.
  • Der Trailing-Stop aktiviert sich erst, nachdem die Bewegung TrailingStopPips + TrailingStepPips überschreitet, und folgt dann dem Close um TrailingStopPips, wenn der Preis vorrückt.
  • Stop-Überprüfungen verwenden Kerzen-Hochs/Tiefs, um Intrabar-Trigger zu emulieren; bei Auslösung wird die Position zum Marktpreis geschlossen.

Konvertierungshinweise

  • Die High-Level-API wird verwendet (SubscribeCandles + Bind), und RSI-Werte werden direkt aus dem Binding-Callback verarbeitet ohne manuelle Indikatorbuffer.
  • Die Trailing-Stop-Logik reproduziert die MQL-Bedingungen, einschließlich des Schrittschwellenwerts vor jeder Anpassung.
  • Die Strategie setzt den Trailing-Status zurück, wenn die Exposition wechselt oder schließt, um veraltete Niveaus in einen neuen Trade zu verhindern.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// RSI Expert Breakout strategy. Trades RSI threshold crossovers.
/// </summary>
public class RsiExpertBreakoutStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _rsiUpper;
	private readonly StrategyParam<decimal> _rsiLower;

	private decimal? _prevRsi;

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

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

	public decimal RsiUpper
	{
		get => _rsiUpper.Value;
		set => _rsiUpper.Value = value;
	}

	public decimal RsiLower
	{
		get => _rsiLower.Value;
		set => _rsiLower.Value = value;
	}

	public RsiExpertBreakoutStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

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

		_rsiUpper = Param(nameof(RsiUpper), 70m)
			.SetDisplay("RSI Upper", "Overbought threshold", "Indicators");

		_rsiLower = Param(nameof(RsiLower), 30m)
			.SetDisplay("RSI Lower", "Oversold threshold", "Indicators");
	}

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

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

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

		_prevRsi = null;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			var rsiArea = CreateChartArea();
			if (rsiArea != null)
				DrawIndicator(rsiArea, rsi);
			DrawOwnTrades(area);
		}
	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevRsi = rsiVal;
			return;
		}

		if (_prevRsi == null)
		{
			_prevRsi = rsiVal;
			return;
		}

		// RSI crosses above lower level from below → buy
		if (_prevRsi.Value < RsiLower && rsiVal >= RsiLower && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// RSI crosses below upper level from above → sell
		else if (_prevRsi.Value > RsiUpper && rsiVal <= RsiUpper && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevRsi = rsiVal;
	}
}