Ver en GitHub

Estrategia Exp RSIOMA V2

Descripción general

Exp RSIOMA V2 es una conversión del asesor experto original de MetaTrader 5 que opera en el oscilador RSIOMA (Índice de Fuerza Relativa de la Media Móvil). La estrategia reproduce las mismas ideas dentro de la API de alto nivel de StockSharp: los datos de precio se suavizan, se convierten en una serie de momentum y se alimentan en un acumulador estilo RSI. Las decisiones de trading se toman cuando el oscilador cambia de dirección o cruza zonas predefinidas.

Lógica de trading

  1. Preprocesamiento de precio – el precio de vela seleccionado (cierre por defecto) se suaviza con una de cuatro familias de medias móviles (simple, exponencial, suavizada o lineal ponderada).
  2. Cálculo de momentum – el precio suavizado se compara con el valor de MomentumPeriod barras atrás para obtener el impulso de momentum.
  3. Computación RSIOMA – los componentes de momentum positivo y negativo se acumulan con un suavizado exponencial de longitud RsiomaLength, produciendo el valor RSIOMA en el rango [0; 100].
  4. Evaluación de señales – las velas cerradas más recientes se inspeccionan según el Mode elegido:
    • Breakdown – reacciona cuando RSIOMA abandona los niveles de tendencia principal (MainTrendLong / MainTrendShort). Cuando el oscilador sale de la zona superior, los cortos se cierran y se permiten entradas largas; salir de la zona inferior realiza la acción opuesta.
    • Twist – busca puntos de giro. Una compra ocurre cuando la pendiente de RSIOMA cambia de descendente a ascendente, mientras que las ventas reaccionan a una transición de ascendente a descendente.
    • CloudTwist – emula la lógica de nube coloreada del indicador MT5. Los trades se abren cuando RSIOMA regresa de extremos de sobrecompra/sobreventa de vuelta dentro del canal, y las posiciones opuestas se cierran al mismo tiempo.

Las señales se evalúan en la barra especificada por SignalBar (por defecto: la vela completamente cerrada anterior), asegurando que solo se usen datos confirmados.

Parámetros

Nombre Descripción Valor predeterminado
OrderVolume Volumen de orden predeterminado utilizado por las órdenes de mercado. 1
CandleType Serie de datos de velas procesada por la estrategia. Marco temporal de 4 horas
EnableLongEntries / EnableShortEntries Permitir la apertura de nuevas posiciones largas/cortas. true
EnableLongExits / EnableShortExits Permitir el cierre de posiciones largas/cortas existentes. true
Mode Lógica de trading (Breakdown, Twist o CloudTwist). Breakdown
PriceSmoothing Media móvil aplicada al precio antes de RSIOMA. Exponential
RsiomaLength Período de promediado RSIOMA. 14
MomentumPeriod Retraso entre muestras al computar momentum. 1
AppliedPrice Precio de vela usado para el oscilador (cierre, apertura, mediana, DeMark, etc.). Close
MainTrendLong / MainTrendShort Niveles RSIOMA que definen zonas de sobrecompra/sobreventa. 60 / 40
SignalBar Número de barras cerradas atrás que deben analizarse. 1

Notas de implementación

  • Solo se admiten las familias de suavizado disponibles en StockSharp (simple, exponencial, suavizada y lineal ponderada). Los modos avanzados de la versión MT5 (JJMA, VIDYA, AMA, …) no están incluidos.
  • Los promedios RSI se inicializan usando los primeros RsiomaLength valores de momentum para reflejar la inicialización de MetaTrader. Después se aplica una actualización exponencial, coincidiendo con el comportamiento del asesor experto original.
  • Las posiciones siempre se cierran antes de emitir una entrada opuesta. Los permisos de entrada (EnableLongEntries, EnableShortEntries) y los permisos de salida (EnableLongExits, EnableShortExits) proporcionan control total sobre las direcciones permitidas.
  • SignalBar = 0 se puede usar para reaccionar a la vela finalizada actual; valores más altos reproducen la capacidad de MT5 de esperar varias barras antes de actuar.

Uso

  1. Agregar la estrategia a un proyecto StockSharp y asignar el instrumento que desea operar.
  2. Configurar la suscripción de velas a través de CandleType (por defecto velas de 4 horas) y ajustar umbrales si el símbolo usa características de volatilidad diferentes.
  3. Seleccionar el modo de señal preferido dependiendo de si desea entradas estilo ruptura (Breakdown), giros de momentum (Twist) o cambios de color de nube (CloudTwist).
  4. Iniciar la estrategia. Durante la ejecución la estrategia se suscribe a la serie de velas elegida, computa la cadena RSIOMA y emite órdenes de mercado cuando se satisfacen las condiciones.
using System;
using System.Collections.Generic;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// RSIOMA strategy using RSI with overbought/oversold levels.
/// Buys when RSI crosses above oversold, sells when crosses below overbought.
/// </summary>
public class ExpRsiomaV2Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _overbought;
	private readonly StrategyParam<decimal> _oversold;

	private decimal? _prevRsi;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public decimal Overbought
	{
		get => _overbought.Value;
		set => _overbought.Value = value;
	}

	public decimal Oversold
	{
		get => _oversold.Value;
		set => _oversold.Value = value;
	}

	public ExpRsiomaV2Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI calculation period", "Indicators");

		_overbought = Param(nameof(Overbought), 65m)
			.SetDisplay("Overbought", "Overbought RSI level", "Levels");

		_oversold = Param(nameof(Oversold), 35m)
			.SetDisplay("Oversold", "Oversold RSI level", "Levels");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevRsi = null;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}

		var indArea = CreateChartArea();
		if (indArea != null)
		{
			DrawIndicator(indArea, rsi);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevRsi = rsiValue;
			return;
		}

		if (_prevRsi == null)
		{
			_prevRsi = rsiValue;
			return;
		}

		// RSI crosses above oversold → buy signal
		if (_prevRsi.Value <= Oversold && rsiValue > Oversold && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// RSI crosses below overbought → sell signal
		else if (_prevRsi.Value >= Overbought && rsiValue < Overbought && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevRsi = rsiValue;
	}
}