Die RSI MA auf RSI Dual-Strategie erstellt den MetaTrader-Expertenberater „RSI_MAonRSI_Dual“ innerhalb von StockSharp neu. Es überwacht zwei Relative-Stärke-Indizes mit unterschiedlichen Lookback-Zeiträumen und wendet einen gemeinsamen gleitenden Durchschnitt über jedem RSI-Stream an. Handelsentscheidungen werden getroffen, wenn die geglätteten RSI-Linien einander kreuzen und dabei auf der gleichen Seite eines konfigurierbaren neutralen Niveaus bleiben.
Die Konvertierung behält das Verhalten des ursprünglichen Roboters bei, einschließlich Zeitfilterung und der Möglichkeit, die Handelsrichtung einzuschränken oder die Signallogik umzukehren.
Indikatoren
Schnell RSI – Relative-Stärke-Index mit konfigurierbarem Zeitraum.
Langsam RSI – Relative-Stärke-Index mit eigener Periode.
Gleitender Durchschnitt auf RSI – Einfacher gleitender Durchschnitt, der über jedem RSI-Wertstrom berechnet wird. Beide RSIs verwenden die gleiche Glättungslänge.
Für alle drei Indikatoren gilt der gleiche angewandte Preis (standardmäßig Schlusskurs). Die beiden geglätteten RSI-Linien werden zur Überwachung in ein spezielles Diagrammfeld gezeichnet.
Einreisebestimmungen
Warten Sie, bis sich beide geglätteten RSI-Werte auf dem aktuell abgeschlossenen Balken gebildet haben.
Lange Einrichtung
Der schnell geglättete RSI kreuzt oberhalb den langsam geglätteten RSI (aktueller Wert oben, vorheriger Wert unten).
Beide geglätteten RSIs liegen unterhalb des neutralen Niveaus (standardmäßig 50).
Kurze Einrichtung
Der schnell geglättete RSI kreuzt unterhalb den langsam geglätteten RSI (aktueller Wert unten, vorheriger Wert oben).
Beide geglätteten RSIs liegen über dem neutralen Niveau.
Optional können Sie die Signalrichtungen mithilfe des Parameters ReverseSignals umkehren.
Signale, die auf demselben Balken erzeugt werden, werden ignoriert (ein Eintrag pro Balken).
Positionsmanagement
AllowLong und AllowShort steuern, ob die Strategie Positionen in jede Richtung eröffnen darf.
CloseOpposite schließt eine bestehende Position, bevor die Gegenseite betreten wird, und repliziert dabei die ursprüngliche EA-Logik.
OnlyOnePosition verbietet die Eröffnung einer neuen Position, wenn eine Position bereits aktiv ist.
Marktaufträge werden mit der Strategie Volume erteilt.
Zeitfilter
Aktivieren oder deaktivieren Sie den Handelssitzungsfilter mit UseTimeFilter. Wenn diese Option aktiviert ist, sind Trades nur zwischen SessionStart und SessionEnd zulässig. Sitzungen, die über Mitternacht hinausgehen, werden unterstützt. Die Zeitstempel werden in der Börsenzeitzone ausgewertet, die durch die eingehenden Kerzennachrichten bereitgestellt wird.
Parameter
Name
Beschreibung
CandleType
Von der Strategie analysierte Kerzenserie.
FastRsiPeriod
Zeitraum des Fastens RSI.
SlowRsiPeriod
Zeitraum der langsamen RSI.
MaPeriod
Länge des gleitenden Durchschnitts, die zum Glätten beider RSI-Streams verwendet wird.
AppliedPrice
Preistyp, der in die RSI-Berechnungen weitergeleitet wird.
NeutralLevel
RSI Schwellenwert, der bullische und bärische Zonen trennt.
AllowLong / AllowShort
Handelsrichtung aktivieren oder deaktivieren.
ReverseSignals
Tauschen Sie Long- und Short-Signale aus.
CloseOpposite
Schließen Sie die gegenüberliegende Position, bevor Sie eine neue eingeben.
OnlyOnePosition
Erlauben Sie höchstens eine offene Stelle.
UseTimeFilter
Aktivieren Sie den Handelssitzungsfilter.
SessionStart / SessionEnd
Grenzen des Handelsfensters.
Unterschiede zum Original EA
Money-Management-, Stop-Loss- und Trailing-Stop-Blöcke des ursprünglichen MQL5-Codes werden nicht reproduziert. Die StockSharp-Strategie platziert Marktaufträge mithilfe des festen Volume, der für die Strategie konfiguriert ist.
Alle Protokollierungs- und Diagnosewarnungen wurden entfernt; Bei Bedarf sollte stattdessen die StockSharp-Protokollierung verwendet werden.
Die plattformspezifische Transaktionsverfolgung wird durch StockSharp Bestellstatusereignisse ersetzt.
Trotz dieser Unterschiede stimmen die Kerneintragslogik und die Richtungsfilter mit denen des Quellen-Expertenberaters überein.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Dual moving averages calculated on top of RSI values.
/// Fast RSI MA crossing slow RSI MA generates entry signals.
/// </summary>
public class RsiMaOnRsiDualStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastRsiPeriod;
private readonly StrategyParam<int> _slowRsiPeriod;
private readonly StrategyParam<int> _maPeriod;
private RelativeStrengthIndex _fastRsi;
private RelativeStrengthIndex _slowRsi;
private readonly Queue<decimal> _fastRsiHistory = new();
private readonly Queue<decimal> _slowRsiHistory = new();
private decimal? _previousFastMa;
private decimal? _previousSlowMa;
public RsiMaOnRsiDualStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle type", "Candles processed by the strategy.", "General");
_fastRsiPeriod = Param(nameof(FastRsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("Fast RSI period", "Length of the fast RSI smoothing window.", "Indicators");
_slowRsiPeriod = Param(nameof(SlowRsiPeriod), 28)
.SetGreaterThanZero()
.SetDisplay("Slow RSI period", "Length of the slow RSI smoothing window.", "Indicators");
_maPeriod = Param(nameof(MaPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("MA period", "Number of RSI values averaged by the smoothing moving average.", "Indicators");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastRsiPeriod
{
get => _fastRsiPeriod.Value;
set => _fastRsiPeriod.Value = value;
}
public int SlowRsiPeriod
{
get => _slowRsiPeriod.Value;
set => _slowRsiPeriod.Value = value;
}
public int MaPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousFastMa = null;
_previousSlowMa = null;
_fastRsiHistory.Clear();
_slowRsiHistory.Clear();
_fastRsi = null!;
_slowRsi = null!;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousFastMa = null;
_previousSlowMa = null;
_fastRsiHistory.Clear();
_slowRsiHistory.Clear();
_fastRsi = new RelativeStrengthIndex { Length = FastRsiPeriod };
_slowRsi = new RelativeStrengthIndex { Length = SlowRsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_fastRsi, _slowRsi, ProcessCandle)
.Start();
var priceArea = CreateChartArea();
if (priceArea != null)
{
DrawCandles(priceArea, subscription);
DrawOwnTrades(priceArea);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastRsiValue, decimal slowRsiValue)
{
if (candle.State != CandleStates.Finished)
return;
_fastRsiHistory.Enqueue(fastRsiValue);
_slowRsiHistory.Enqueue(slowRsiValue);
while (_fastRsiHistory.Count > MaPeriod)
_fastRsiHistory.Dequeue();
while (_slowRsiHistory.Count > MaPeriod)
_slowRsiHistory.Dequeue();
if (!_fastRsi.IsFormed || !_slowRsi.IsFormed)
return;
if (_fastRsiHistory.Count < MaPeriod || _slowRsiHistory.Count < MaPeriod)
return;
// Calculate SMA of each RSI
var fastSum = 0m;
var fastHistory = _fastRsiHistory.ToArray();
foreach (var v in fastHistory)
fastSum += v;
var fastMa = fastSum / MaPeriod;
var slowSum = 0m;
var slowHistory = _slowRsiHistory.ToArray();
foreach (var v in slowHistory)
slowSum += v;
var slowMa = slowSum / MaPeriod;
if (_previousFastMa is null || _previousSlowMa is null)
{
_previousFastMa = fastMa;
_previousSlowMa = slowMa;
return;
}
var crossUp = _previousFastMa < _previousSlowMa && fastMa > slowMa;
var crossDown = _previousFastMa > _previousSlowMa && fastMa < slowMa;
var volume = Volume;
if (volume <= 0)
volume = 1;
if (crossUp)
{
if (Position <= 0)
BuyMarket(volume);
}
else if (crossDown)
{
if (Position >= 0)
SellMarket(volume);
}
_previousFastMa = fastMa;
_previousSlowMa = slowMa;
}
}