RRS-Impulsstrategie
Die RRS Impulse Strategy ist eine High-Level-StockSharp-Portierung des MetaTrader-Expertenberaters „RRS Impulse“. Der ursprüngliche Roboter
kombinierte RSI-, Stochastic- und Bollinger-Bandfilter, rotiert zwischen mehreren Signalstärkemodi und verwendete Schutzstopps und
virtuelle Trailing-Exits. Diese C#-Version behält das gleiche Verhalten bei, verlässt sich jedoch ausschließlich auf die StockSharp High-Level-Kerze API:
Abonnements füttern die Indikatoren, während BuyMarket, SellMarket und ClosePosition die Aufträge ausführen.
Handelslogik
- Anzeigemodi – Wählen Sie zwischen vier Optionen:
Rsi: Handeln Sie mit dem Oszillator, wenn er die überkaufte/überverkaufte Zone verlässt.
Stochastic: erfordern, dass sowohl %K als auch %D über/unter den konfigurierten Werten liegen.
BollingerBands: Reagieren Sie auf Schlusskurse oberhalb des oberen Bandes oder unterhalb des unteren Bandes.
RsiStochasticBollinger: wird nur ausgelöst, wenn alle drei Filter die gleiche Richtung bestätigen.
- Handelsrichtung –
Trend folgt dem Indikator (überkauft führt zu Short-Positionen, überverkauft zu Long-Positionen). CounterTrend blendet das aus
Bewegung (überkauft löst Long-Positionen aus, überverkauft löst Short-Positionen aus).
- Signalstärke – Steuert, wie viele Zeitrahmen übereinstimmen müssen, bevor ein Handel abgeschlossen wird:
SingleTimeFrame: Verwenden Sie nur den von CandleType bereitgestellten Basiszeitrahmen.
MultiTimeFrame: erfordert eine Ausrichtung über die Kerzen M1, M5, M15, M30, H1 und H4.
Strong: Konzentrieren Sie sich auf das Intraday-Momentum, indem Sie M1, M5, M15 und M30 überprüfen.
VeryStrong: Bestätigung von der vollständigen Leiter M1 … H4 anfordern. Wenn der kombinierte Anzeigemodus in jedem Zeitrahmen aktiviert ist
muss alle drei Filter erfüllen.
- Risikomanagement – Jede Position verfolgt den durchschnittlichen Ausführungspreis und überwacht drei Ausstiegsbedingungen:
- feste Stop-Loss-Distanz in Pips;
- feste Take-Profit-Distanz in Pips;
- Trailing Stop wird aktiviert, sobald der Gewinn
TrailingStartPips übersteigt, und wird von TrailingGapPips beibehalten.
Immer wenn die Richtung umkehrt, ruft die Strategie zuerst ClosePosition() auf, um abzuflachen, und eröffnet erst danach den entgegengesetzten Handel
das nächste Bestätigungshäkchen.
Parameter
| Gruppe |
Name |
Beschreibung |
| Daten |
CandleType |
Basiskerzenserien, die für Handelsentscheidungen verarbeitet werden. |
| Bestellungen |
TradeVolume |
Beim Versenden von Marktaufträgen verwendetes Volumen. |
| Risiko |
StopLossPips, TakeProfitPips, TrailingStartPips, TrailingGapPips |
Virtuelle Schutzausgänge, ausgedrückt in Pips. |
| Signale |
IndicatorMode, TradeDirection, SignalStrength |
Verhaltensschalter, die aus dem Eingabeblock MQL kopiert wurden. |
| RSI |
RsiPeriod, RsiUpperLevel, RsiLowerLevel |
RSI-Konfiguration zur Erkennung von Überkauft/Überverkauft. |
| Stochastic |
StochasticKPeriod, StochasticDPeriod, StochasticSlowing, StochasticUpperLevel, StochasticLowerLevel |
Langsame stochastische Oszillatoreinstellungen. |
| Bollinger |
BollingerPeriod, BollingerDeviation |
Bollinger Bands-Rückblick und Abweichungsmultiplikator. |
Alle Parameter unterstützen Optimierungsbereiche, die mit der MetaTrader-Version identisch sind, wo es sinnvoll war (z. B. Stoppen und Distanzen nehmen).
oder Oszillatorschwellen).
Datenanforderungen
Die Strategie benötigt winzige Kerzen für die Bestätigungsleiter. Wenn SignalStrength zusätzliche Zeitrahmen für die Strategie anfordert
fügt automatisch die erforderlichen Abonnements hinzu (GetWorkingSecurities kündigt sie der Suchmaschine an). Anführungszeichen der Stufe 1 werden nicht verwendet;
Nur die Schlusskurse fertiger Kerzen steuern Ein- und Ausstiege. Die Schutzlogik bildet somit den „virtuellen“ Stopp/Ziel nach
Verhalten des ursprünglichen Roboters.
Hinweise zur Konvertierung
- Die zufällige Symbolrotation von EA wurde absichtlich entfernt. StockSharp-Strategien funktionieren mit einem einzigen
Security, also
port konzentriert sich auf die Abstimmung der Indikatorlogik und des Risikomanagements und überlässt die Instrumentenrotation dem Benutzer.
- Die Auftragsverwaltung erfolgt marktbasiert: Wenn sich die Richtung ändert oder eine Schutzbedingung auslöst, wird
ClosePosition() aufgerufen.
Spiegelung der MetaTrader-Schleifen, die Tickets durchlaufen haben.
- Bei der Konvertierung werden alle Kommentare auf Englisch beibehalten und Tabulatoren zum Einrücken verwendet, um den Repository-Richtlinien zu entsprechen.
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using StockSharp.Algo;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// RRS Impulse strategy.
/// Combines RSI, Stochastic and Bollinger Bands for counter-trend entries.
/// </summary>
public class RrsImpulseStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiUpperLevel;
private readonly StrategyParam<decimal> _rsiLowerLevel;
private readonly StrategyParam<int> _stochasticKPeriod;
private readonly StrategyParam<int> _stochasticDPeriod;
private readonly StrategyParam<decimal> _stochasticUpperLevel;
private readonly StrategyParam<decimal> _stochasticLowerLevel;
private readonly StrategyParam<int> _bollingerPeriod;
private readonly StrategyParam<decimal> _bollingerDeviation;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiUpperLevel { get => _rsiUpperLevel.Value; set => _rsiUpperLevel.Value = value; }
public decimal RsiLowerLevel { get => _rsiLowerLevel.Value; set => _rsiLowerLevel.Value = value; }
public int StochasticKPeriod { get => _stochasticKPeriod.Value; set => _stochasticKPeriod.Value = value; }
public int StochasticDPeriod { get => _stochasticDPeriod.Value; set => _stochasticDPeriod.Value = value; }
public decimal StochasticUpperLevel { get => _stochasticUpperLevel.Value; set => _stochasticUpperLevel.Value = value; }
public decimal StochasticLowerLevel { get => _stochasticLowerLevel.Value; set => _stochasticLowerLevel.Value = value; }
public int BollingerPeriod { get => _bollingerPeriod.Value; set => _bollingerPeriod.Value = value; }
public decimal BollingerDeviation { get => _bollingerDeviation.Value; set => _bollingerDeviation.Value = value; }
public RrsImpulseStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI length", "RSI");
_rsiUpperLevel = Param(nameof(RsiUpperLevel), 65m)
.SetDisplay("RSI Upper", "Overbought", "RSI");
_rsiLowerLevel = Param(nameof(RsiLowerLevel), 35m)
.SetDisplay("RSI Lower", "Oversold", "RSI");
_stochasticKPeriod = Param(nameof(StochasticKPeriod), 10)
.SetDisplay("Stochastic %K", "%K period", "Stochastic");
_stochasticDPeriod = Param(nameof(StochasticDPeriod), 3)
.SetDisplay("Stochastic %D", "%D period", "Stochastic");
_stochasticUpperLevel = Param(nameof(StochasticUpperLevel), 70m)
.SetDisplay("Stochastic Upper", "Overbought", "Stochastic");
_stochasticLowerLevel = Param(nameof(StochasticLowerLevel), 30m)
.SetDisplay("Stochastic Lower", "Oversold", "Stochastic");
_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
.SetDisplay("Bollinger Period", "BB length", "Bollinger");
_bollingerDeviation = Param(nameof(BollingerDeviation), 2m)
.SetDisplay("Bollinger Deviation", "BB deviation", "Bollinger");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var stochastic = new StochasticOscillator();
stochastic.K.Length = StochasticKPeriod;
stochastic.D.Length = StochasticDPeriod;
var bollinger = new BollingerBands { Length = BollingerPeriod, Width = BollingerDeviation };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(rsi, stochastic, bollinger, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bollinger);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue rsiVal, IIndicatorValue stochVal, IIndicatorValue bbVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!rsiVal.IsFinal || !stochVal.IsFinal || !bbVal.IsFinal)
return;
if (!rsiVal.IsFormed || !stochVal.IsFormed || !bbVal.IsFormed)
return;
var rsi = rsiVal.GetValue<decimal>();
var stoch = (StochasticOscillatorValue)stochVal;
var stochK = stoch.K ?? 50m;
var bb = (BollingerBandsValue)bbVal;
var bbUpper = bb.UpBand ?? candle.ClosePrice;
var bbLower = bb.LowBand ?? candle.ClosePrice;
var close = candle.ClosePrice;
// Count how many indicators signal overbought/oversold
var obSignals = 0;
var osSignals = 0;
if (rsi >= RsiUpperLevel) obSignals++;
if (rsi <= RsiLowerLevel) osSignals++;
if (stochK >= StochasticUpperLevel) obSignals++;
if (stochK <= StochasticLowerLevel) osSignals++;
if (close >= bbUpper) obSignals++;
if (close <= bbLower) osSignals++;
// Counter-trend: need at least 2 of 3 indicators confirming
if (osSignals >= 2 && Position <= 0)
{
BuyMarket();
}
else if (obSignals >= 2 && Position >= 0)
{
SellMarket();
}
// Exit long when RSI and stoch neutralize
else if (Position > 0 && rsi > 50m && stochK > 50m)
{
SellMarket();
}
// Exit short when RSI and stoch neutralize
else if (Position < 0 && rsi < 50m && stochK < 50m)
{
BuyMarket();
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import BollingerBands, RelativeStrengthIndex, StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class rrs_impulse_strategy(Strategy):
"""RSI + Stochastic + Bollinger Bands counter-trend strategy."""
def __init__(self):
super(rrs_impulse_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("RSI Period", "RSI length", "RSI")
self._rsi_upper_level = self.Param("RsiUpperLevel", 65.0) \
.SetDisplay("RSI Upper", "Overbought", "RSI")
self._rsi_lower_level = self.Param("RsiLowerLevel", 35.0) \
.SetDisplay("RSI Lower", "Oversold", "RSI")
self._stochastic_k_period = self.Param("StochasticKPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Stochastic %K", "%K period", "Stochastic")
self._stochastic_d_period = self.Param("StochasticDPeriod", 3) \
.SetGreaterThanZero() \
.SetDisplay("Stochastic %D", "%D period", "Stochastic")
self._stochastic_upper_level = self.Param("StochasticUpperLevel", 70.0) \
.SetDisplay("Stochastic Upper", "Overbought", "Stochastic")
self._stochastic_lower_level = self.Param("StochasticLowerLevel", 30.0) \
.SetDisplay("Stochastic Lower", "Oversold", "Stochastic")
self._bollinger_period = self.Param("BollingerPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("Bollinger Period", "BB length", "Bollinger")
self._bollinger_deviation = self.Param("BollingerDeviation", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("Bollinger Deviation", "BB deviation", "Bollinger")
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(rrs_impulse_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
stochastic = StochasticOscillator()
stochastic.K.Length = self._stochastic_k_period.Value
stochastic.D.Length = self._stochastic_d_period.Value
bollinger = BollingerBands()
bollinger.Length = self._bollinger_period.Value
bollinger.Width = self._bollinger_deviation.Value
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(rsi, stochastic, bollinger, self._process_candle).Start()
def _process_candle(self, candle, rsi_val, stoch_val, bb_val):
if candle.State != CandleStates.Finished:
return
if not rsi_val.IsFinal or not stoch_val.IsFinal or not bb_val.IsFinal:
return
if not rsi_val.IsFormed or not stoch_val.IsFormed or not bb_val.IsFormed:
return
rsi = float(rsi_val)
stoch_k = float(stoch_val.K) if stoch_val.K is not None else 50.0
bb_upper = bb_val.UpBand
bb_lower = bb_val.LowBand
upper = float(bb_upper) if bb_upper is not None else float(candle.ClosePrice)
lower = float(bb_lower) if bb_lower is not None else float(candle.ClosePrice)
close = float(candle.ClosePrice)
ob_signals = 0
os_signals = 0
if rsi >= float(self._rsi_upper_level.Value):
ob_signals += 1
if rsi <= float(self._rsi_lower_level.Value):
os_signals += 1
if stoch_k >= float(self._stochastic_upper_level.Value):
ob_signals += 1
if stoch_k <= float(self._stochastic_lower_level.Value):
os_signals += 1
if close >= upper:
ob_signals += 1
if close <= lower:
os_signals += 1
if os_signals >= 2 and self.Position <= 0:
self.BuyMarket()
elif ob_signals >= 2 and self.Position >= 0:
self.SellMarket()
elif self.Position > 0 and rsi > 50.0 and stoch_k > 50.0:
self.SellMarket()
elif self.Position < 0 and rsi < 50.0 and stoch_k < 50.0:
self.BuyMarket()
def CreateClone(self):
return rrs_impulse_strategy()