Die AML RSI Meeting Lines Strategy ist eine StockSharp-Portierung des MetaTrader 5-Expertenberaters Expert_AML_RSI.mq5. Das ursprüngliche System kombiniert die Erkennung japanischer Candlestick-Muster mit dem Relative Strength Index (RSI), um bullische und bärische „Meeting Lines“-Umkehrungen zu handeln. Diese Konvertierung behält die Kernhandelslogik bei und passt sie gleichzeitig an StockSharps High-Level-API mit Kerzenabonnements und integrierten Indikatoren an.
Handelslogik
Abonniert einen konfigurierbaren Kerzentyp und verarbeitet nur fertige Kerzen.
Berechnet einen einfachen gleitenden Durchschnitt der Kerzenkörpergrößen, um „lange“ Kerzen zu erkennen, die Meeting-Lines-Muster bilden.
Verfolgt RSI-Werte der beiden zuletzt abgeschlossenen Kerzen für Bestätigungs- und Ausstiegssignale.
Bulnisches Setup: Die Umkehrung der Meeting Lines mit zwei Kursstäben und RSI unter der bullischen Schwelle löst Long-Einstiege aus.
Bearisches Setup: Ein gespiegeltes Muster mit RSI über der bärischen Schwelle löst Short-Einstiege aus.
Positionsausstiege: RSI Crossovers durch konfigurierbare untere und obere Ebenen schließen offene Trades in die entgegengesetzte Richtung.
Verwendet die Helfer BuyMarket, SellMarket und ClosePosition, um die Belichtung zu verwalten, und ändert die Positionsgröße automatisch, wenn ein gegenteiliges Signal auftritt.
Parameter
Name
Beschreibung
Standard
CandleType
Zeitrahmen zur Bewertung von Candlestick-Mustern.
Zeitrahmen 1 Stunde
RsiPeriod
RSI Lookback-Länge.
11
BodyAveragePeriod
Anzahl der Kerzen für die durchschnittliche Körpergröße.
3
BullishRsiLevel
Maximum RSI, das bullische Meeting-Linien bestätigt.
40
BearishRsiLevel
Minimum RSI, das die rückläufigen Meeting-Linien bestätigt.
60
LowerExitLevel
RSI-Level, das Shorts bei Aufwärtskreuzen schließt.
30
UpperExitLevel
RSI-Level, das Long-Positionen bei Abwärtskreuzungen schließt.
70
Alle Parameter werden als StrategyParam<T>-Objekte angezeigt, sodass sie im StockSharp-Designer optimiert werden können.
Risikomanagement
StartProtection() wird in OnStarted aufgerufen, um die integrierte Positionsüberwachung des Frameworks zu aktivieren.
Die Strategie schließt das bestehende Risiko immer dann, wenn RSI die konfigurierten Exit-Grenzen überschreitet, bevor neue Signale berücksichtigt werden.
Marktaufträge kehren die Position automatisch um, indem sie den absoluten Wert des aktuellen Engagements zum konfigurierten Volumen addieren.
Konvertierungshinweise
Bei der Candlestick-Mittelung wird SimpleMovingAverage mit absoluten Kerzenkörpern gespeist, was den AvgBody-Helfer aus der MQL5-Quelle widerspiegelt.
Die RSI-Bestätigung basiert auf den Werten der beiden vorherigen Kerzen und reproduziert die RSI(1)- und RSI(2)-Prüfungen des ursprünglichen Experten.
Alle Kommentare im Code wurden in Englisch umgeschrieben und die Struktur folgt den Repository-Anforderungen von dateibezogenen Namespaces mit Tabulatoreinzug.
Nutzung
Hängen Sie die Strategie an ein Wertpapier in StockSharp an und wählen Sie den gewünschten Kerzentyp aus.
Konfigurieren Sie RSI und Ausstiegsschwellenwerte, um sie an den Handelsplatz oder die Volatilität des Instruments anzupassen.
Führen Sie die Strategie zunächst im Papierhandel aus, um die Mustererkennung zu validieren, bevor Sie zum Live-Handel oder zur Optimierung übergehen.
Verwenden Sie die bereitgestellten Parameter während der Optimierung, um die RSI-Werte und die durchschnittliche Körperlänge für verschiedene Märkte zu optimieren.
Haftungsausschluss
Diese Strategie dient ausschließlich Bildungszwecken. Testen Sie gründlich anhand historischer Daten und in simulierten Umgebungen, bevor Sie es in Live-Kapital einsetzen.
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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class aml_rsi_meeting_lines_strategy(Strategy):
def __init__(self):
super(aml_rsi_meeting_lines_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._rsi_low = self.Param("RsiLow", 40.0)
self._rsi_high = self.Param("RsiHigh", 60.0)
self._prev_candle = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def RsiLow(self):
return self._rsi_low.Value
@RsiLow.setter
def RsiLow(self, value):
self._rsi_low.Value = value
@property
def RsiHigh(self):
return self._rsi_high.Value
@RsiHigh.setter
def RsiHigh(self, value):
self._rsi_high.Value = value
def OnReseted(self):
super(aml_rsi_meeting_lines_strategy, self).OnReseted()
self._prev_candle = None
def OnStarted2(self, time):
super(aml_rsi_meeting_lines_strategy, self).OnStarted2(time)
self._prev_candle = None
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
if self._prev_candle is not None:
avg_body = (abs(float(candle.ClosePrice) - float(candle.OpenPrice))
+ abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))) / 2.0
if avg_body > 0:
prev_bearish = float(self._prev_candle.OpenPrice) > float(self._prev_candle.ClosePrice)
curr_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
closes_near = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bearish and curr_bullish and closes_near and rsi_val < self.RsiLow and self.Position <= 0:
self.BuyMarket()
prev_bullish = float(self._prev_candle.ClosePrice) > float(self._prev_candle.OpenPrice)
curr_bearish = float(candle.OpenPrice) > float(candle.ClosePrice)
closes_near2 = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bullish and curr_bearish and closes_near2 and rsi_val > self.RsiHigh and self.Position >= 0:
self.SellMarket()
self._prev_candle = candle
def CreateClone(self):
return aml_rsi_meeting_lines_strategy()