Auf GitHub ansehen

Sidus EMA RSI Strategie

Diese Strategie ist eine StockSharp-Portierung des MetaTrader 4 Expert Advisors Exp_Sidus.mq4. Es reproduziert die ursprüngliche Logik kombiniert einen schnellen/langsamen EMA-Crossover mit einem 50-stufigen RSI-Filter. Signale werden nur für abgeschlossene Kerzen ausgewertet, und jede Kerze kann dies tun spawnen höchstens eine Reihenfolge, entsprechend der Timing-Disziplin des Quellroboters.

Handelslogik

  • Indikatorstapel
    • Schneller exponentieller gleitender Durchschnitt (Standardzeitraum 5)
    • Langsamer exponentieller gleitender Durchschnitt (Standardzeitraum 12)
    • Relative-Stärke-Index (Standardzeitraum 21)
  • Bulles Setup
    1. Der schnelle EMA war kleiner oder gleich dem langsamen EMA der vorherigen Signalkerze.
    2. Der schnelle EMA liegt über dem langsamen EMA der aktuellen Signalkerze.
    3. RSI auf derselben Kerze ist unbedingt größer als 50.
  • Bearisches Setup
    1. Der schnelle EMA lag über oder gleich dem langsamen EMA der vorherigen Signalkerze.
    2. Der schnelle EMA liegt unter dem langsamen EMA der aktuellen Signalkerze.
    3. RSI auf derselben Kerze ist unbedingt kleiner als 50.
  • Signalverschiebung – der Parameter SignalShift (Standard 1) definiert, welche geschlossene Kerze als „aktueller“ Signalbalken gilt. Ein Wert von 1 verwendet die letzte geschlossene Kerze, 0 verwendet die gerade geschlossene Kerze, 2 blickt zwei Balken zurück und so weiter. Der Vorherige Kerze für die Crossover-Erkennung wird automatisch als SignalShift + 1 berechnet.
  • Doppelter Schutz – die Strategie speichert die Öffnungszeit der Signalkerze und eröffnet nie eine andere damit verbundene Position Dieselbe Leiste, die den LastTime-Check im Original EA originalgetreu nachahmt.

Positionsmanagement

  • Es existiert immer nur eine Position.
  • Wenn ein entgegengesetztes Signal erscheint, während eine Position offen ist, schließt die Strategie zunächst die bestehende Position und wartet dann auf das nächsten Verarbeitungsdurchgang, um einen Trade in die neue Richtung zu eröffnen, genau wie die Version MQL.
  • StartProtection fügt optionale Take-Profit- und Stop-Loss-Klammern hinzu, ausgedrückt in Preispunkten (Preisschritten). Entfernungen sind abgeleitet aus den Eingaben der ursprünglichen EA: Standard-Take-Profit-80-Punkte und Stop-Loss-20-Punkte.

Parameter

Name Beschreibung Standard Notizen
TakeProfitPoints Take-Profit-Distanz in Preisschritten. 80 Legen Sie 0 fest, um das Ziel zu deaktivieren.
StopLossPoints Stop-Loss-Distanz in Preisschritten. 20 Legen Sie 0 fest, um den Schutz zu deaktivieren.
TradeVolume Auftragsvolumen (Lose/Verträge). 0.1 Wird beim Start der Basiseigenschaft Volume zugewiesen.
FastPeriod Schnelle Länge von EMA. 5 Optimierbar.
SlowPeriod Langsame Länge von EMA. 12 Optimierbar.
RsiPeriod RSI Länge. 21 Optimierbar.
SignalShift Anzahl der geschlossenen Kerzen, die für Signalberechnungen verwendet werden. 1 Spiegelt die shif-Eingabe des MT4 EA.
CandleType Kerzenquelle für das Abonnement. 1h Zeitrahmen Kann auf jedes von der Umgebung unterstützte DataType eingestellt werden.

Implementierungshinweise

  • Kerzendaten werden über SubscribeCandles(CandleType) abonniert und in ProcessCandle erst verarbeitet, nachdem die Kerze erreicht ist der Finished-Zustand.
  • Die Indikatorwerte werden in einer kurzen Warteschlange zwischengespeichert, sodass die Strategie auf die aktuellen und vorherigen von angegebenen Balken zugreifen kann SignalShift, ohne Indikatormethoden wie GetValue aufzurufen, unter Einhaltung der Repository-Richtlinien.
  • Die Handelsausführung verwendet BuyMarket/SellMarket, sobald die Strategie flach ist; wenn eine Position in der entgegengesetzten Richtung existiert, ClosePosition wird zuerst ausgegeben, sodass der Bestellablauf mit dem des ursprünglichen Roboters identisch bleibt.
  • Alle Laufzeitprotokolle sind auf Englisch verfasst, um einen klaren Prüfpfad zu gewährleisten.

Konvertierungshinweise

  • Die Take-Profit- und Stop-Loss-Abstände vervielfachen das Instrument PriceStep und reproduzieren das Verhalten von MetaTrader Point.
  • Die Lautstärke ist standardmäßig auf 0.1 eingestellt, genau wie die Eingabe Lots in der Quelle MQL.
  • RSI-Schwellenwerte sind bei 50 fest codiert, um die ursprüngliche Implementierung widerzuspiegeln.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Sidus EMA + RSI strategy: fast EMA crosses slow EMA confirmed by RSI above/below 50.
/// </summary>
public class SidusEmaRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;

	public SidusEmaRsiStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 12)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

		_rsiPeriod = Param(nameof(RsiPeriod), 21)
			.SetDisplay("RSI Period", "RSI period.", "Indicators");
	}

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevFast = 0;
		_prevSlow = 0;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

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

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

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

		if (_prevFast == 0 || _prevSlow == 0)
		{
			_prevFast = fastValue;
			_prevSlow = slowValue;
			return;
		}

		var bullishCross = _prevFast <= _prevSlow && fastValue > slowValue;
		var bearishCross = _prevFast >= _prevSlow && fastValue < slowValue;

		// Exit existing positions on opposite cross
		if (Position > 0 && bearishCross)
		{
			SellMarket();
		}
		else if (Position < 0 && bullishCross)
		{
			BuyMarket();
		}

		// Entry on crossover confirmed by RSI
		if (Position == 0)
		{
			if (bullishCross && rsiValue > 50)
			{
				BuyMarket();
			}
			else if (bearishCross && rsiValue < 50)
			{
				SellMarket();
			}
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
	}
}