Estrategia de Supertrend RSI Divergence
La estrategia Supertrend RSI Divergence utiliza el indicador Supertrend junto con la divergencia RSI para identificar oportunidades de trading.
Las pruebas indican un rendimiento anual promedio de aproximadamente el 67%. Funciona mejor en el mercado de acciones.
Las señales se activan cuando Divergence confirma configuraciones de divergencia en datos intradía (15m). Este método es adecuado para operadores activos.
Los stops se basan en múltiplos de ATR y factores como SupertrendPeriod, SupertrendMultiplier. Ajuste estos valores predeterminados para equilibrar el riesgo y la recompensa.
Detalles
- Criterios de entrada: ver implementación para condiciones de indicadores.
- Largo/Corto: Ambos direcciones.
- Criterios de salida: señal opuesta o lógica de stop.
- Stops: Sí, usando cálculos basados en indicadores.
- Valores predeterminados:
SupertrendPeriod = 10SupertrendMultiplier = 3.0mRsiPeriod = 14CandleType = TimeSpan.FromMinutes(15).TimeFrame()
- Filtros:
- Categoría: Seguimiento de tendencia
- Dirección: Ambos
- Indicadores: Divergence
- Stops: Sí
- Complejidad: Intermedio
- Marco temporal: Intradía (15m)
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: Sí
- Nivel de riesgo: Medio
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that uses Supertrend indicator along with RSI divergence to identify trading opportunities.
/// </summary>
public class SupertrendRsiDivergenceStrategy : Strategy
{
private readonly StrategyParam<int> _supertrendPeriod;
private readonly StrategyParam<decimal> _supertrendMultiplier;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<DataType> _candleType;
private SuperTrend _supertrend;
private RelativeStrengthIndex _rsi;
// Data for divergence detection
private readonly SynchronizedList<decimal> _prices = [];
private readonly SynchronizedList<decimal> _rsiValues = [];
// Supertrend state tracking
private decimal _supertrendValue;
private TrendDirections _trendDirection = TrendDirections.None;
/// <summary>
/// Supertrend period.
/// </summary>
public int SupertrendPeriod
{
get => _supertrendPeriod.Value;
set => _supertrendPeriod.Value = value;
}
/// <summary>
/// Supertrend multiplier.
/// </summary>
public decimal SupertrendMultiplier
{
get => _supertrendMultiplier.Value;
set => _supertrendMultiplier.Value = value;
}
/// <summary>
/// RSI period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// Candle type to use for the strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="SupertrendRsiDivergenceStrategy"/>.
/// </summary>
public SupertrendRsiDivergenceStrategy()
{
_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
.SetDisplay("Supertrend Period", "Supertrend ATR period", "Supertrend")
.SetOptimize(5, 20, 1);
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3.0m)
.SetDisplay("Supertrend Multiplier", "Supertrend ATR multiplier", "Supertrend")
.SetOptimize(2.0m, 5.0m, 0.5m);
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI period for divergence detection", "RSI")
.SetOptimize(8, 20, 2);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prices.Clear();
_rsiValues.Clear();
_trendDirection = TrendDirections.None;
_supertrendValue = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_supertrend = new SuperTrend
{
Length = SupertrendPeriod,
Multiplier = SupertrendMultiplier
};
_rsi = new RelativeStrengthIndex
{
Length = RsiPeriod
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_supertrend, _rsi, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent));
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _supertrend);
DrawIndicator(area, _rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal supertrendValue, decimal rsiValue)
{
// Skip unfinished candles
if (candle.State != CandleStates.Finished)
return;
// Extract values from indicators
_supertrendValue = supertrendValue;
decimal rsi = rsiValue;
// Store values for divergence calculation
_prices.Add(candle.ClosePrice);
_rsiValues.Add(rsi);
// Keep reasonable history
while (_prices.Count > 50)
{
_prices.RemoveAt(0);
_rsiValues.RemoveAt(0);
}
// Determine Supertrend trend direction
TrendDirections previousDirection = _trendDirection;
if (candle.ClosePrice > _supertrendValue)
_trendDirection = TrendDirections.Up;
else if (candle.ClosePrice < _supertrendValue)
_trendDirection = TrendDirections.Down;
// Check for trend direction change
bool trendDirectionChanged = previousDirection != TrendDirections.None && previousDirection != _trendDirection;
// Check for divergence
bool bullishDivergence = CheckBullishDivergence();
bool bearishDivergence = CheckBearishDivergence();
if (Position != 0)
return;
// Bullish setup - price above Supertrend with RSI not overbought
if (candle.ClosePrice > _supertrendValue && rsi < 60m)
BuyMarket();
// Bearish setup - price below Supertrend with RSI not oversold
else if (candle.ClosePrice < _supertrendValue && rsi > 40m)
SellMarket();
}
private bool CheckBullishDivergence()
{
// Need at least a few candles for divergence check
if (_prices.Count < 5 || _rsiValues.Count < 5)
return false;
// Check for bullish divergence: price making lower lows while RSI making higher lows
// Look at the last 5 candles for a simple check
decimal currentPrice = _prices[_prices.Count - 1];
decimal previousPrice = _prices[_prices.Count - 2];
decimal currentRsi = _rsiValues[_rsiValues.Count - 1];
decimal previousRsi = _rsiValues[_rsiValues.Count - 2];
// Bullish divergence: price lower but RSI higher
bool divergence = currentPrice < previousPrice && currentRsi > previousRsi;
if (divergence)
{
LogInfo($"Bullish Divergence Detected: Price {previousPrice:F2}->{currentPrice:F2}, RSI {previousRsi:F2}->{currentRsi:F2}");
}
return divergence;
}
private bool CheckBearishDivergence()
{
// Need at least a few candles for divergence check
if (_prices.Count < 5 || _rsiValues.Count < 5)
return false;
// Check for bearish divergence: price making higher highs while RSI making lower highs
// Look at the last 5 candles for a simple check
decimal currentPrice = _prices[_prices.Count - 1];
decimal previousPrice = _prices[_prices.Count - 2];
decimal currentRsi = _rsiValues[_rsiValues.Count - 1];
decimal previousRsi = _rsiValues[_rsiValues.Count - 2];
// Bearish divergence: price higher but RSI lower
bool divergence = currentPrice > previousPrice && currentRsi < previousRsi;
if (divergence)
{
LogInfo($"Bearish Divergence Detected: Price {previousPrice:F2}->{currentPrice:F2}, RSI {previousRsi:F2}->{currentRsi:F2}");
}
return divergence;
}
// Trend direction enum for tracking Supertrend state
private enum TrendDirections
{
None,
Up,
Down
}
}
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, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import SuperTrend, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class supertrend_rsi_divergence_strategy(Strategy):
"""
Strategy that uses Supertrend indicator along with RSI divergence to identify trading opportunities.
"""
def __init__(self):
super(supertrend_rsi_divergence_strategy, self).__init__()
self._supertrend_period = self.Param("SupertrendPeriod", 10) \
.SetDisplay("Supertrend Period", "Supertrend ATR period", "Supertrend")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0) \
.SetDisplay("Supertrend Multiplier", "Supertrend ATR multiplier", "Supertrend")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period for divergence detection", "RSI")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prices = []
self._rsi_values = []
self._supertrend_val = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(supertrend_rsi_divergence_strategy, self).OnReseted()
self._prices = []
self._rsi_values = []
self._supertrend_val = 0.0
def OnStarted2(self, time):
super(supertrend_rsi_divergence_strategy, self).OnStarted2(time)
supertrend = SuperTrend()
supertrend.Length = int(self._supertrend_period.Value)
supertrend.Multiplier = Decimal(self._supertrend_multiplier.Value)
rsi = RelativeStrengthIndex()
rsi.Length = int(self._rsi_period.Value)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(supertrend, rsi, self._process_candle).Start()
self.StartProtection(
Unit(2, UnitTypes.Percent),
Unit(1, UnitTypes.Percent)
)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawIndicator(area, rsi)
self.DrawOwnTrades(area)
def _process_candle(self, candle, supertrend_value, rsi_value):
if candle.State != CandleStates.Finished:
return
self._supertrend_val = float(supertrend_value)
rsi = float(rsi_value)
close_price = float(candle.ClosePrice)
self._prices.append(close_price)
self._rsi_values.append(rsi)
while len(self._prices) > 50:
self._prices.pop(0)
self._rsi_values.pop(0)
if self.Position != 0:
return
if close_price > self._supertrend_val and rsi < 60.0:
self.BuyMarket()
elif close_price < self._supertrend_val and rsi > 40.0:
self.SellMarket()
def CreateClone(self):
return supertrend_rsi_divergence_strategy()