DT RSI EXP1 Strategie
Dieser Port repliziert den MT4 Expert Advisor DT-RSI-EXP1. Die Strategie scannt 15-minütige RSI-Schwünge, um Double-Tops oder Double-Bottoms um die 60/40-Level herum zu erkennen. Ein Long-Trade wird abgeschlossen, wenn die jüngsten RSI-Höchstwerte zurückgehen, ohne dass es zu Tiefstständen unter 40 kommt, während der 4-Stunden-Trendfilter nach unten zeigt. Shorts spiegeln die Logik mit Tiefstständen über 60 und einem Filter für steigende Trends wider. Mit jeder Position sind ein fester Stop-Loss und ein Take-Profit verbunden, und ein optionaler Trailing-Stop schützt die Gewinne. Positionen werden zwangsweise geschlossen, wenn RSI extreme 70/30-Werte erreicht, wodurch das ursprüngliche Ausstiegsverhalten kopiert wird.
Einzelheiten
- Eintrittskriterien:
- Long: zwei zinsbullische RSI-Höchststände, wobei der zweite über 60 liegt, keine rückläufigen Tiefststände unter 40 dazwischen, 4 Stunden EMA unter dem vorherigen Schlusskurs, RSI(1) Überschreitung der prognostizierten Nackenlinie, RSI(2) immer noch darunter, RSI(2) < 50 und RSI(0) < 55.
- Short: zwei rückläufige RSI-Tiefststände, wobei der zweite unter 40 liegt, keine zinsbullischen Spitzen über 60 dazwischen, 4 Stunden EMA über dem vorherigen Schlusskurs, RSI(1) Kreuzung unter der prognostizierten Nackenlinie, RSI(2) > 50 und RSI(0) > 47.
- Lang/Kurz: Beide Richtungen.
- Ausstiegskriterien:
- RSI Extreme (RSI > 70 für Long-Positionen, RSI < 30 für Short-Positionen).
- Aus Preisschritten berechnete Stop-Loss-/Take-Profit-Ziele.
- Optionaler Trailing-Stop, der Gewinne sperrt, sobald sich der Preis um
TrailingStopPoints bewegt.
- Stops: Fester Stop-Loss und Take-Profit, optionaler Trailing-Stop.
- Standardwerte:
CandleType = 15-Minuten-Kerzen.
TrendCandleType = 240-Minuten-Kerzen (Trendfilter EMA).
RsiPeriod = 47.
StopLossPoints = 26.
TakeProfitPoints = 76.
TrailingStopPoints = 0 (deaktiviert).
- Filter:
- Kategorie: Trendfolgende Einträge zu RSI-Strukturen.
- Richtung: Beide.
- Indikatoren: RSI, EMA Trendfilter.
- Stoppt: Ja.
- Komplexität: Mittelschwer (Multi-Constraint-Swing-Erkennung).
- Zeitrahmen: Intraday (M15 mit H4-Filter).
- Saisonalität: Nein.
- Neuronale Netze: Nein.
- Divergenz: Nein.
- Risikostufe: Mittel.
Parameter
| Name |
Standard |
Beschreibung |
Optimierbar |
CandleType |
15 Minuten |
Primäre Kerzenserie zur Berechnung von RSI und Signalen. |
Ja |
TrendCandleType |
240 Minuten |
Höherer Zeitrahmen, der vom Trendfilter EMA verwendet wird (Ersatz für den MT4 RFTL-Indikator). |
Ja |
RsiPeriod |
47 |
RSI Länge, angewendet auf die Primärkerzen. |
Ja |
StopLossPoints |
26 |
Abstand zum Stop-Loss in Preisschritten. |
Ja |
TakeProfitPoints |
76 |
Abstand zum Take-Profit in Preisschritten. |
Ja |
TrailingStopPoints |
0 |
Trailing-Stop-Offset in Preisschritten (0 deaktiviert das Trailing). |
Ja |
Notizen
- Der benutzerdefinierte Indikator MetaTrader
RFTL wird durch einen 10-Perioden-EMA im 240-Minuten-Zeitrahmen angenähert. Passen Sie den längeren Zeitrahmen oder die Länge von EMA an, um sie besser an die ursprüngliche Umgebung anzupassen.
- Stellen Sie sicher, dass
PriceStep und StepPrice des Instruments so konfiguriert sind, dass punktbasierte Stopps mit der Tick-Größe des Brokers übereinstimmen.
- Der Trailing Stop wird erst aktiviert, wenn der Preis um mehr als
TrailingStopPoints vom Einstiegspreis steigt, und lockert sich nie über den ursprünglichen Stop hinaus.
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>
/// DT RSI EXP1 strategy - RSI overbought/oversold with EMA trend filter.
/// Buys when RSI crosses above oversold level while above EMA trend.
/// Sells when RSI crosses below overbought level while below EMA trend.
/// </summary>
public class DtRsiExp1Strategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _oversold;
private readonly StrategyParam<decimal> _overbought;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private bool _hasPrev;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public DtRsiExp1Strategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI period", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
_oversold = Param(nameof(Oversold), 30m)
.SetDisplay("Oversold", "RSI oversold level", "Indicators");
_overbought = Param(nameof(Overbought), 70m)
.SetDisplay("Overbought", "RSI overbought level", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevRsi = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ema, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
}
private void ProcessCandle(ICandleMessage candle, decimal rsi, decimal ema)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevRsi = rsi;
_hasPrev = true;
return;
}
// RSI crosses above oversold + bullish trend
if (_prevRsi <= Oversold && rsi > Oversold && close > ema && Position == 0)
{
BuyMarket();
}
// RSI crosses below overbought + bearish trend
else if (_prevRsi >= Overbought && rsi < Overbought && close < ema && Position == 0)
{
SellMarket();
}
_prevRsi = rsi;
}
}
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, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from StockSharp.Messages import Unit, UnitTypes
class dt_rsi_exp1_strategy(Strategy):
def __init__(self):
super(dt_rsi_exp1_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators")
self._oversold = self.Param("Oversold", 30.0) \
.SetDisplay("Oversold", "RSI oversold level", "Indicators")
self._overbought = self.Param("Overbought", 70.0) \
.SetDisplay("Overbought", "RSI overbought level", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_rsi = 0.0
self._has_prev = False
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def ema_period(self):
return self._ema_period.Value
@property
def oversold(self):
return self._oversold.Value
@property
def overbought(self):
return self._overbought.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(dt_rsi_exp1_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(dt_rsi_exp1_strategy, self).OnStarted2(time)
self._has_prev = False
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, ema, self.process_candle).Start()
self.StartProtection(
takeProfit=Unit(2, UnitTypes.Percent),
stopLoss=Unit(1, UnitTypes.Percent)
)
def process_candle(self, candle, rsi, ema):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
rsi_val = float(rsi)
ema_val = float(ema)
if not self._has_prev:
self._prev_rsi = rsi_val
self._has_prev = True
return
if self._prev_rsi <= self.oversold and rsi_val > self.oversold and close > ema_val and self.Position == 0:
self.BuyMarket()
elif self._prev_rsi >= self.overbought and rsi_val < self.overbought and close < ema_val and self.Position == 0:
self.SellMarket()
self._prev_rsi = rsi_val
def CreateClone(self):
return dt_rsi_exp1_strategy()