La estrategia CBC_WS_RSI es una implementación StockSharp de alto nivel del asesor experto MQL5 que combina los patrones de velas "Tres soldados blancos" y "Tres cuervos negros" con confirmación RSI. La estrategia se centra en identificar fuertes reversiones de múltiples velas y solo ingresa a una operación cuando el impulso del mercado, medido por RSI, concuerda con el patrón. Las salidas están controladas por cruces de umbrales RSI y gestión de riesgos opcional a través de protecciones de limitación de pérdidas y toma de ganancias.
La estrategia se suscribe a una serie de velas configurables y procesa datos exclusivamente en velas completamente formadas. Toda la lógica se implementa utilizando API (SubscribeCandles().Bind(...)) de alto nivel de StockSharp sin acceso directo a los buffers de indicador.
Lógica de trading
Configuración larga
Detecta tres velas alcistas consecutivas que forman el patrón Tres Soldados Blancos:
Cada vela se cierra por encima de su apertura.
Cada cierre es mayor que el cierre anterior.
La segunda y tercera vela se abren dentro del cuerpo de la vela anterior.
Confirma que el valor RSI de la vela actual está por debajo o igual al nivel de confirmación larga (predeterminado 40).
Si la cuenta es plana, la estrategia compra Volume lotes en el mercado. Si existe una posición corta, se cubre antes de abrir una nueva posición larga.
Configuración corta
Detecta tres velas bajistas consecutivas que forman el patrón Tres Cuervos Negros:
Cada vela cierra por debajo de su apertura.
Cada cierre es más bajo que el cierre anterior.
La segunda y tercera vela se abren dentro del cuerpo de la vela anterior.
Confirma que el valor RSI de la vela actual está por encima o igual al nivel de confirmación corta (predeterminado 60).
Si la cuenta es plana, la estrategia vende Volume lotes en el mercado. Si existe una posición larga, se cierra antes de abrir una nueva posición corta.
Reglas de salida
Cerrar posiciones largas: RSI cruza por debajo del nivel de salida superior (predeterminado 70) o del nivel de salida inferior (predeterminado 30).
Cerrar cortos: RSI cruza por encima del nivel de salida inferior (predeterminado 30) o del nivel de salida superior (predeterminado 70).
Protección: Los valores opcionales de stop-loss y take-profit se pueden definir como porcentajes del precio de entrada. Cuando son distintos de cero, se administran a través de StartProtection.
Todas las condiciones de salida utilizan los dos valores RSI más recientes para detectar un cruce de niveles, lo que garantiza que las operaciones se cierren tan pronto como el impulso contradiga la posición activa.
Parámetros
Nombre
Descripción
Predeterminado
CandleType
Tipo de datos de vela y período de tiempo al que suscribirse.
plazo de 1 hora
RsiPeriod
RSI período utilizado para la confirmación.
37
LongConfirmationLevel
Valor máximo RSI que permite una entrada larga.
40
ShortConfirmationLevel
Valor mínimo RSI que permite una entrada corta.
60
LowerExitLevel
Nivel RSI utilizado para detectar una reversión del impulso cerca del territorio de sobreventa.
30
UpperExitLevel
Nivel RSI utilizado para detectar una reversión del impulso cerca del territorio de sobrecompra.
70
StopLossPercent
Stop-loss opcional en porcentaje; 0 desactiva la protección.
1
TakeProfitPercent
Toma de ganancias opcional en porcentaje; 0 desactiva la protección.
2
Todos los parámetros numéricos se pueden optimizar a través del optimizador integrado gracias a SetCanOptimize(true).
Visualización
Cuando un área del gráfico está disponible, la estrategia dibuja:
La serie de velas seleccionada.
El indicador RSI.
Operaciones ejecutadas, lo que facilita la inspección de detecciones y salidas de patrones.
Notas de uso
Asegúrese de que Volume esté configurado antes de iniciar la estrategia.
Funciona en cualquier instrumento que admita OHLC datos de velas.
La lógica de detección de patrones filtra las velas tipo doji al requerir cuerpos de vela distintos de cero.
Las confirmaciones RSI protegen contra señales falsas durante reversiones débiles, manteniendo la estrategia alineada con el impulso.
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()