Estrategia Rsi Supertrend
Estrategia basada en los indicadores RSI y Supertrend. Entra largo cuando el RSI está en sobrevendido (< RsiOversold) y el precio está por encima de Supertrend. Entra corto cuando el RSI está en sobrecomprado (> RsiOverbought) y el precio está por debajo de Supertrend.
Las pruebas indican un retorno anual promedio de aproximadamente 112%. Funciona mejor en el mercado forex.
El oscilador RSI define los extremos de momentum mientras Supertrend apunta a la dirección predominante. Las operaciones ocurren cuando el RSI se alinea con el color de Supertrend.
Funciona para traders que aprecian una salida estilo trailing stop. La configuración ATR del propio Supertrend da forma a esa línea de seguimiento.
Detalles
- Criterios de entrada:
- Largo:
RSI < RsiOversold && Close > Supertrend
- Corto:
RSI > RsiOverbought && Close < Supertrend
- Largo/Corto: Ambos
- Criterios de salida: Cambio de Supertrend
- Stops: Trailing con Supertrend
- Valores predeterminados:
RsiPeriod = 14
SupertrendPeriod = 10
SupertrendMultiplier = 3.0m
RsiOversold = 40
RsiOverbought = 60
CandleType = TimeSpan.FromMinutes(5).TimeFrame()
En velas de cinco minutos el RSI casi nunca llega a 30 con el precio por encima del Supertrend (ni a 70 por debajo): el archivo de BTC de marzo de 2024 no tiene ni una vela así. Por eso los niveles son parámetros con valores 40 y 60, que siguen marcando un retroceso contra la tendencia y operan en ambos sentidos. Un largo se cierra cuando el Supertrend gira a la baja y un corto cuando gira al alza. Una señal de entrada contra una posición abierta la invierte.
- Filtros:
- Categoría: Reversión a la media
- Dirección: Ambos
- Indicadores: RSI, Supertrend
- Stops: Sí
- Complejidad: Intermedio
- Marco temporal: Medio plazo
- 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;
/// <summary>
/// RSI Supertrend strategy.
/// A close above the Supertrend line with RSI below RsiOversold goes long and a close below it with RSI above RsiOverbought goes short,
/// reversing an opposite position. The Supertrend line is the trailing stop: a long closes when Supertrend flips down and a short
/// when it flips up.
/// </summary>
public class RsiSupertrendStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _supertrendPeriod;
private readonly StrategyParam<decimal> _supertrendMultiplier;
private readonly StrategyParam<decimal> _rsiOversold;
private readonly StrategyParam<decimal> _rsiOverbought;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Period of RSI.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// ATR period of Supertrend.
/// </summary>
public int SupertrendPeriod
{
get => _supertrendPeriod.Value;
set => _supertrendPeriod.Value = value;
}
/// <summary>
/// ATR multiplier of Supertrend.
/// </summary>
public decimal SupertrendMultiplier
{
get => _supertrendMultiplier.Value;
set => _supertrendMultiplier.Value = value;
}
/// <summary>
/// RSI level for longs.
/// </summary>
public decimal RsiOversold
{
get => _rsiOversold.Value;
set => _rsiOversold.Value = value;
}
/// <summary>
/// RSI level for shorts.
/// </summary>
public decimal RsiOverbought
{
get => _rsiOverbought.Value;
set => _rsiOverbought.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public RsiSupertrendStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Period of RSI", "RSI");
_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Supertrend Period", "ATR period of Supertrend", "Supertrend");
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3m)
.SetGreaterThanZero()
.SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Supertrend");
_rsiOversold = Param(nameof(RsiOversold), 40m)
.SetDisplay("RSI Oversold", "RSI level for longs", "RSI");
_rsiOverbought = Param(nameof(RsiOverbought), 60m)
.SetDisplay("RSI Overbought", "RSI level for shorts", "RSI");
_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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
var supertrend = new SuperTrend { Length = SupertrendPeriod, Multiplier = SupertrendMultiplier };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(supertrend, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, supertrend);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, rsi);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue supertrendValue, IIndicatorValue rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!supertrendValue.IsFormed || !rsiValue.IsFormed || supertrendValue is not SuperTrendIndicatorValue trend)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var line = trend.Value;
var isUpTrend = trend.IsUpTrend;
var rsi = rsiValue.GetValue<decimal>();
var close = candle.ClosePrice;
if (close > line && rsi < RsiOversold && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (close < line && rsi > RsiOverbought && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
else if (Position > 0 && !isUpTrend)
SellMarket(Position);
else if (Position < 0 && isUpTrend)
BuyMarket(-Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SuperTrend, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class rsi_supertrend_strategy(Strategy):
"""
RSI Supertrend strategy.
A close above the Supertrend line with RSI below RsiOversold goes long and a close below it with RSI above RsiOverbought goes short,
reversing an opposite position. The Supertrend line is the trailing stop: a long closes when Supertrend flips down and a short
when it flips up.
"""
def __init__(self):
super(rsi_supertrend_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14).SetGreaterThanZero().SetDisplay("RSI Period", "Period of RSI", "RSI")
self._supertrend_period = self.Param("SupertrendPeriod", 10).SetGreaterThanZero().SetDisplay("Supertrend Period", "ATR period of Supertrend", "Supertrend")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0).SetGreaterThanZero().SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Supertrend")
self._rsi_oversold = self.Param("RsiOversold", 40.0).SetDisplay("RSI Oversold", "RSI level for longs", "RSI")
self._rsi_overbought = self.Param("RsiOverbought", 60.0).SetDisplay("RSI Overbought", "RSI level for shorts", "RSI")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(rsi_supertrend_strategy, self).OnStarted2(time)
supertrend = SuperTrend()
supertrend.Length = self._supertrend_period.Value
supertrend.Multiplier = Decimal(self._supertrend_multiplier.Value)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(supertrend, rsi, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
def _process_candle(self, candle, supertrend_value, rsi_value):
if candle.State != CandleStates.Finished:
return
if not supertrend_value.IsFormed or not rsi_value.IsFormed:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
line = supertrend_value.Value
is_up_trend = supertrend_value.IsUpTrend
rsi = rsi_value.GetValue[Decimal](None)
close = candle.ClosePrice
if close > line and rsi < Decimal(self._rsi_oversold.Value) and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif close < line and rsi > Decimal(self._rsi_overbought.Value) and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and not is_up_trend:
self.SellMarket(self.Position)
elif self.Position < 0 and is_up_trend:
self.BuyMarket(-self.Position)
def CreateClone(self):
return rsi_supertrend_strategy()