Die CBC_WS_RSI-Strategie ist eine High-Level-StockSharp-Implementierung des MQL5-Expertenberaters, der die Candlestick-Muster „Three White Soldiers“ und „Three Black Crows“ mit einer RSI-Bestätigung kombiniert. Die Strategie konzentriert sich auf die Identifizierung starker Multi-Candle-Umkehrungen und geht nur dann einen Handel ein, wenn die Marktdynamik, gemessen durch RSI, mit dem Muster übereinstimmt. Ausstiege werden durch Schwellenwertüberschreitungen von RSI und optionales Risikomanagement durch Stop-Loss- und Take-Profit-Schutz kontrolliert.
Die Strategie abonniert eine konfigurierbare Kerzenserie und verarbeitet ausschließlich Daten zu vollständig geformten Kerzen. Die gesamte Logik wird mithilfe des High-Level-API (SubscribeCandles().Bind(...)) von StockSharp ohne direkten Zugriff auf Indikatorpuffer implementiert.
Handelslogik
Lange Einrichtung
Erkennt drei aufeinanderfolgende bullische Kerzen, die das Three White Soldiers-Muster bilden:
Jede Kerze schließt über ihrem Eröffnungskurs.
Jeder Schlusskurs ist höher als der vorherige Schlusskurs.
Die zweite und dritte Kerze öffnen sich im Körper der vorherigen Kerze.
Bestätigt, dass der RSI-Wert der aktuellen Kerze unter oder gleich dem langen Bestätigungsniveau liegt (Standard 40).
Wenn das Konto flach ist, kauft die Strategie Volume Lots zum Marktwert. Wenn eine Short-Position besteht, wird diese abgedeckt, bevor eine neue Long-Position eröffnet wird.
Kurze Einrichtung
Erkennt drei aufeinanderfolgende bärische Kerzen, die das Muster Three Black Crows bilden:
Jede Kerze schließt unterhalb ihrer Eröffnung.
Jeder Schlusskurs ist niedriger als der vorherige Schlusskurs.
Die zweite und dritte Kerze öffnen sich im Körper der vorherigen Kerze.
Bestätigt, dass der RSI-Wert der aktuellen Kerze über oder gleich dem Short-Bestätigungsniveau liegt (Standard 60).
Wenn das Konto flach ist, verkauft die Strategie Volume Lose zum Marktwert. Wenn eine Long-Position besteht, wird diese geschlossen, bevor eine neue Short-Position eröffnet wird.
Ausgangsregeln
Long-Positionen schließen: RSI unterschreitet entweder das obere Ausgangsniveau (Standard 70) oder das untere Ausgangsniveau (Standard 30).
Shorts schließen: RSI überschreitet entweder die untere Ausgangsebene (Standard 30) oder die obere Ausgangsebene (Standard 70).
Schutz: Optionale Stop-Loss- und Take-Profit-Werte können als Prozentsätze des Einstiegspreises definiert werden. Wenn sie ungleich Null sind, werden sie über StartProtection verwaltet.
Alle Ausstiegsbedingungen verwenden die letzten beiden RSI-Werte, um einen Level-Crossover zu erkennen und sicherzustellen, dass Trades geschlossen werden, sobald das Momentum der aktiven Position widerspricht.
Parameter
Name
Beschreibung
Standard
CandleType
Kerzendatentyp und Zeitrahmen zum Abonnieren.
1-stündiger Zeitrahmen
RsiPeriod
RSI Zeitraum für die Bestätigung verwendet.
37
LongConfirmationLevel
Maximaler RSI-Wert, der eine lange Eingabe zulässt.
40
ShortConfirmationLevel
Mindestwert RSI, der eine kurze Eingabe zulässt.
60
LowerExitLevel
Das Niveau RSI wird verwendet, um eine Momentumumkehr in der Nähe des überverkauften Bereichs zu erkennen.
30
UpperExitLevel
Das Niveau RSI wird verwendet, um eine Momentumumkehr in der Nähe des überkauften Bereichs zu erkennen.
70
StopLossPercent
Optionaler Stop-Loss in Prozent; 0 deaktiviert den Schutz.
1
TakeProfitPercent
Optionaler Take-Profit in Prozent; 0 deaktiviert den Schutz.
2
Alle numerischen Parameter können dank SetCanOptimize(true) über den integrierten Optimierer optimiert werden.
Visualisierung
Wenn ein Diagrammbereich verfügbar ist, zeichnet die Strategie Folgendes:
Die ausgewählte Kerzenserie.
Der Indikator RSI.
Ausgeführte Trades erleichtern die Überprüfung von Mustererkennungen und -ausstiegen.
Nutzungshinweise
Stellen Sie sicher, dass Volume konfiguriert ist, bevor Sie mit der Strategie beginnen.
Funktioniert auf jedem Instrument, das OHLC Kerzendaten unterstützt.
Die Mustererkennungslogik filtert Doji-ähnliche Kerzen heraus, indem sie Kerzenkörper ungleich Null erfordert.
RSI-Bestätigungen schützen vor falschen Signalen bei schwachen Umkehrungen und halten die Strategie im Einklang mit der Dynamik.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// CBC WS RSI strategy: 3 Black Crows / 3 White Soldiers with RSI confirmation.
/// Buys after 3 bullish candles with RSI below 60, sells after 3 bearish with RSI above 40.
/// </summary>
public class CbcWsRsiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private int _bullCount;
private int _bearCount;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public CbcWsRsiStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_bullCount = 0;
_bearCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_bullCount = 0;
_bearCount = 0;
_candlesSinceTrade = SignalCooldownCandles;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (candle.ClosePrice > candle.OpenPrice)
{
_bullCount++;
_bearCount = 0;
}
else if (candle.ClosePrice < candle.OpenPrice)
{
_bearCount++;
_bullCount = 0;
}
else
{
_bullCount = 0;
_bearCount = 0;
}
// Exit on RSI extremes
if (Position > 0 && rsi > 75 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
else if (Position < 0 && rsi < 25 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
// Entry on pattern
if (_bullCount >= 3 && rsi < 60 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_bullCount = 0;
_candlesSinceTrade = 0;
}
else if (_bearCount >= 3 && rsi > 40 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_bearCount = 0;
_candlesSinceTrade = 0;
}
}
}
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 cbc_ws_rsi_strategy(Strategy):
def __init__(self):
super(cbc_ws_rsi_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators")
self._signal_cooldown = self.Param("SignalCooldownCandles", 6) \
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading")
self._rsi = None
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = 0
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def signal_cooldown(self):
return self._signal_cooldown.Value
def OnReseted(self):
super(cbc_ws_rsi_strategy, self).OnReseted()
self._rsi = None
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = self.signal_cooldown
def OnStarted2(self, time):
super(cbc_ws_rsi_strategy, self).OnStarted2(time)
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.rsi_period
self._bull_count = 0
self._bear_count = 0
self._candles_since_trade = self.signal_cooldown
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(60)))
subscription.Bind(self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._rsi.IsFormed:
return
rsi_val = float(rsi_value)
if self._candles_since_trade < self.signal_cooldown:
self._candles_since_trade += 1
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
if close > open_p:
self._bull_count += 1
self._bear_count = 0
elif close < open_p:
self._bear_count += 1
self._bull_count = 0
else:
self._bull_count = 0
self._bear_count = 0
if self.Position > 0 and rsi_val > 75.0 and self._candles_since_trade >= self.signal_cooldown:
self.SellMarket()
self._candles_since_trade = 0
elif self.Position < 0 and rsi_val < 25.0 and self._candles_since_trade >= self.signal_cooldown:
self.BuyMarket()
self._candles_since_trade = 0
if self._bull_count >= 3 and rsi_val < 60.0 and self.Position <= 0 and self._candles_since_trade >= self.signal_cooldown:
self.BuyMarket()
self._bull_count = 0
self._candles_since_trade = 0
elif self._bear_count >= 3 and rsi_val > 40.0 and self.Position >= 0 and self._candles_since_trade >= self.signal_cooldown:
self.SellMarket()
self._bear_count = 0
self._candles_since_trade = 0
def CreateClone(self):
return cbc_ws_rsi_strategy()