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
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).
Cálculo de momentum – el precio suavizado se compara con el valor de MomentumPeriod barras atrás para obtener el impulso de momentum.
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].
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
Agregar la estrategia a un proyecto StockSharp y asignar el instrumento que desea operar.
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.
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).
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;
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class exp_rsioma_v2_strategy(Strategy):
def __init__(self):
super(exp_rsioma_v2_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI calculation period", "Indicators")
self._overbought = self.Param("Overbought", 65.0) \
.SetDisplay("Overbought", "Overbought RSI level", "Levels")
self._oversold = self.Param("Oversold", 35.0) \
.SetDisplay("Oversold", "Oversold RSI level", "Levels")
self._prev_rsi = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@property
def Overbought(self):
return self._overbought.Value
@property
def Oversold(self):
return self._oversold.Value
def OnReseted(self):
super(exp_rsioma_v2_strategy, self).OnReseted()
self._prev_rsi = None
def OnStarted2(self, time):
super(exp_rsioma_v2_strategy, self).OnStarted2(time)
self._prev_rsi = None
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
ind_area = self.CreateChartArea()
if ind_area is not None:
self.DrawIndicator(ind_area, rsi)
def _on_process(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rv = float(rsi_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_rsi = rv
return
if self._prev_rsi is None:
self._prev_rsi = rv
return
ob = float(self.Overbought)
os_level = float(self.Oversold)
# RSI crosses above oversold
if self._prev_rsi <= os_level and rv > os_level and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# RSI crosses below overbought
elif self._prev_rsi >= ob and rv < ob and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rv
def CreateClone(self):
return exp_rsioma_v2_strategy()