La RSI Estrategia de alerta reproduce el comportamiento del asesor experto MetaTrader 5 "RSI Alerta" dentro del marco StockSharp. El robot original buscaba lecturas del índice de fuerza relativa (RSI) que cruzaran niveles profundamente de sobreventa (≤20) o sobrecompra (≥80) y enviaba inmediatamente notificaciones de alerta mientras abría posiciones en el mercado. La versión convertida mantiene esta filosofía basada en eventos: escucha las velas completadas, evalúa el RSI y automáticamente invierte la posición enviando órdenes de mercado cuando se alcanzan los umbrales configurados.
Lógica de trading
Suscríbase a la serie de velas configurada (predeterminado: período de tiempo de 1 minuto) e introduzca los precios de cierre en un indicador RelativeStrengthIndex.
Ignore las velas incompletas y espere hasta que el indicador RSI esté completamente formado. Esto refleja el experto MQL, que solo evaluó las condiciones una vez por nueva barra.
Generar señales comerciales:
Señal de compra – RSI ≤ OversoldLevel. La estrategia cierra cualquier exposición corta y abre una posición larga con el volumen configurado.
Señal de venta – RSI ≥ OverboughtLevel. La estrategia cierra cualquier exposición larga y abre una posición corta con el volumen configurado.
Las órdenes siempre se realizan con BuyMarket/SellMarket, por lo que no hay órdenes pendientes, niveles de stop-loss o take-profit. La implementación MetaTrader permitía entradas SL/TP opcionales, pero de forma predeterminada dependía de la gestión manual. El puerto StockSharp se centra en la conversión de alerta a operación y deja la gestión de riesgos a módulos externos (por ejemplo, StartProtection() o controles a nivel de cartera).
La estrategia se mantiene plana entre señales. Cuando aparece un disparador opuesto, invierte la posición agregando suficiente volumen para aplanar la exposición existente antes de entrar en la nueva dirección, exactamente como lo hizo el EA original al disparar alertas consecutivas.
Parámetros
Parámetro
Predeterminado
Descripción
OrderVolume
0,01
Tamaño comercial para órdenes de mercado. Al revertir, la estrategia agrega la cantidad requerida para cubrir la posición existente antes de volver a ingresar.
RsiPeriod
30
RSI período promedio. Debe ser un número entero positivo.
OverboughtLevel
80
RSI umbral que emite una señal de venta. Se puede optimizar para ajustar la agresividad.
OversoldLevel
20
RSI umbral que emite una señal de compra.
CandleType
1 minuto TimeFrameCandle
Fuente de datos de velas utilizada para el cálculo de RSI. Cámbielo para analizar marcos de tiempo más altos.
Todos los parámetros se exponen a través de StrategyParam<T> para que aparezcan en el diseñador StockSharp, se puedan guardar en ajustes preestablecidos XML y admitan escenarios de optimización.
Notas de implementación
El StockSharp API de alto nivel se utiliza en todo momento: las velas se obtienen a través de SubscribeCandles() y el RSI se actualiza a través de subscription.Bind(indicator, callback). No se requiere manipulación manual del búfer ni copia histórica.
La propiedad base Strategy.Volume está sincronizada con el parámetro OrderVolume para que la inversión de posición funcione correctamente incluso si el usuario cambia el tamaño del lote en tiempo de ejecución.
Los comentarios en línea y la documentación XML están escritos en inglés para cumplir con los requisitos del proyecto.
La salida del gráfico es opcional pero compatible: cuando la estrategia se ejecuta dentro del diseñador, traza las velas de precios, las operaciones ejecutadas y los valores del indicador RSI.
Consejos de uso
Combine la estrategia con módulos externos de stop-loss/take-profit si es necesario un control de riesgos automatizado.
Optimice los umbrales de RSI al adaptarse a mercados con diferentes regímenes de volatilidad.
Aumente el marco de tiempo de la vela para las configuraciones de swing o mantenga la serie predeterminada de 1 minuto para alertas de estilo especulación, como en el script original.
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>
/// RSI alert strategy converted from the original MetaTrader expert advisor.
/// Buys when RSI drops below the oversold threshold and sells when RSI rises above the overbought threshold.
/// </summary>
public class RsiAlertStrategy : Strategy
{
private readonly StrategyParam<decimal> _orderVolume;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<decimal> _oversoldLevel;
private readonly StrategyParam<DataType> _candleType;
private RelativeStrengthIndex _rsi;
/// <summary>
/// Order volume used for market trades.
/// </summary>
public decimal OrderVolume
{
get => _orderVolume.Value;
set
{
_orderVolume.Value = value;
Volume = value; // Keep the base strategy volume aligned with the parameter value.
}
}
/// <summary>
/// RSI averaging period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// RSI level that triggers short trades.
/// </summary>
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
/// <summary>
/// RSI level that triggers long trades.
/// </summary>
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
/// <summary>
/// Candle type supplying prices to the RSI indicator.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="RsiAlertStrategy"/> with default parameters.
/// </summary>
public RsiAlertStrategy()
{
_orderVolume = Param(nameof(OrderVolume), 0.01m)
.SetGreaterThanZero()
.SetDisplay("Order Volume", "Order size used for market trades", "Trading")
;
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Number of bars for RSI calculation", "Indicator")
;
_overboughtLevel = Param(nameof(OverboughtLevel), 70m)
.SetDisplay("Overbought Level", "RSI threshold that triggers short signals", "Indicator")
;
_oversoldLevel = Param(nameof(OversoldLevel), 30m)
.SetDisplay("Oversold Level", "RSI threshold that triggers long signals", "Indicator")
;
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles that feed the RSI", "General");
Volume = OrderVolume;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_rsi = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
Volume = OrderVolume; // Ensure the strategy uses the configured volume on each start.
_rsi = new RelativeStrengthIndex
{
Length = RsiPeriod
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_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, _rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
var buySignal = rsiValue <= OversoldLevel;
var sellSignal = rsiValue >= OverboughtLevel;
if (buySignal && Position == 0)
{
BuyMarket();
}
else if (sellSignal && Position == 0)
{
SellMarket();
}
}
}