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.
Der schnelle EMA war kleiner oder gleich dem langsamen EMA der vorherigen Signalkerze.
Der schnelle EMA liegt über dem langsamen EMA der aktuellen Signalkerze.
RSI auf derselben Kerze ist unbedingt größer als 50.
Bearisches Setup
Der schnelle EMA lag über oder gleich dem langsamen EMA der vorherigen Signalkerze.
Der schnelle EMA liegt unter dem langsamen EMA der aktuellen Signalkerze.
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;
}
}