Estrategia que opera basándose en el Índice de Fuerza Relativa (RSI) al cruzar un valor central.
La idea es observar cuando el RSI cruza por encima o por debajo de un nivel configurable (por defecto 50). Cuando el indicador se mueve de abajo hacia arriba de este nivel se abre una posición larga. Cuando cruza de vuelta hacia abajo se abre una posición corta. Las posiciones existentes se cierran en el cruce opuesto. Stop-loss opcional, take-profit y trailing stop protegen la operación.
Detalles
Criterios de entrada: Comprar cuando RSI cruza por encima del nivel. Vender cuando RSI cruza por debajo.
Largo/Corto: Ambas direcciones.
Criterios de salida: Cruce opuesto o trailing stop.
Stops: Stop-loss fijo opcional, take-profit y trailing stop.
Valores predeterminados:
RsiPeriod = 14
RsiLevel = 50
StopLoss = 100
TakeProfit = 200
TrailingStop = 0
CandleType = TimeSpan.FromMinutes(5)
Filtros:
Categoría: Oscilador
Dirección: Ambos
Indicadores: RSI
Stops: Sí
Complejidad: Básico
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;
/// <summary>
/// RSI level crossing strategy.
/// </summary>
public class RsiValueStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private bool _hasPrev;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiLevel { get => _rsiLevel.Value; set => _rsiLevel.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public RsiValueStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiLevel = Param(nameof(RsiLevel), 50m)
.SetDisplay("RSI Level", "RSI crossing level", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
SubscribeCandles(CandleType)
.Bind(rsi, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevRsi = rsiVal;
_hasPrev = true;
return;
}
var crossUp = _prevRsi <= RsiLevel && rsiVal > RsiLevel;
var crossDown = _prevRsi >= RsiLevel && rsiVal < RsiLevel;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevRsi = rsiVal;
}
}