La estrategia combina la reversión a la media del RSI con entradas de ruptura filtradas por ADX y una EMA de 200.
El sistema compra cuando el mercado está en rango y el RSI cae por debajo de RsiBuy en tendencia alcista de la EMA. Vende en corto cuando el RSI sube por encima de RsiSell en tendencia bajista. En régimen tendencial, entra en rupturas por encima/debajo de cierres recientes y rastrea la posición usando ATR.
Incluye un filtro de fecha de inicio y variables simples de panel para el último tipo de trade y dirección.
Detalles
Criterios de entrada: Señales de RSI en régimen de rango con sesgo de EMA, o rupturas por encima/debajo de los BreakoutLength cierres anteriores cuando ADX > AdxThreshold.
Largo/Corto: Ambos.
Criterios de salida: Los trades de RSI salen en RsiExit. Los trades de ruptura usan trailing stop ATR.
Stops: Trailing stop ATR para trades de ruptura.
Valores predeterminados:
AdxLength = 14
AdxThreshold = 20m
EmaLength = 200
RsiLength = 14
RsiBuy = 40m
RsiSell = 60m
RsiExit = 50m
BreakoutLength = 20
AtrLength = 14
AtrMultiplier = 2m
StartDate = 2017-01-01
CandleType = TimeSpan.FromMinutes(5)
Filtros:
Categoría: Tendencia, Reversión a la media
Dirección: Ambos
Indicadores: ADX, EMA, RSI, ATR, Highest/Lowest
Stops: Trailing
Complejidad: Moderado
Marco temporal: Intradía (5m)
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class HybridRsiBreakoutDashboardStrategy : Strategy
{
private readonly StrategyParam<int> _fastEmaPeriod;
private readonly StrategyParam<int> _slowEmaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFastEma;
private decimal _prevSlowEma;
public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public HybridRsiBreakoutDashboardStrategy()
{
_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnReseted()
{
base.OnReseted();
_prevFastEma = 0m;
_prevSlowEma = 0m;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fastEma, slowEma, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
{
if (candle.State != CandleStates.Finished) return;
if (_prevFastEma == 0m || _prevSlowEma == 0m)
{
_prevFastEma = fastEmaValue;
_prevSlowEma = slowEmaValue;
return;
}
if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
BuyMarket();
else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
SellMarket();
_prevFastEma = fastEmaValue;
_prevSlowEma = slowEmaValue;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class hybrid_rsi_breakout_dashboard_strategy(Strategy):
"""
EMA crossover strategy. Buys when fast EMA crosses above slow EMA,
sells when fast EMA crosses below slow EMA.
"""
def __init__(self):
super(hybrid_rsi_breakout_dashboard_strategy, self).__init__()
self._fast_ema_period = self.Param("FastEmaPeriod", 120) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_ema_period = self.Param("SlowEmaPeriod", 450) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(hybrid_rsi_breakout_dashboard_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
def OnStarted2(self, time):
super(hybrid_rsi_breakout_dashboard_strategy, self).OnStarted2(time)
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self._fast_ema_period.Value
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self._slow_ema_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ema, slow_ema, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
fast = float(fast_val)
slow = float(slow_val)
if self._prev_fast == 0.0 or self._prev_slow == 0.0:
self._prev_fast = fast
self._prev_slow = slow
return
if self._prev_fast <= self._prev_slow and fast > slow and self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast < slow and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return hybrid_rsi_breakout_dashboard_strategy()