La estrategia AMS ES RSI replica el comportamiento del MetaTrader experto Expert_AMS_ES_RSI dentro de StockSharp. Combina formaciones de velas de estrella matutina y vespertina con un filtro de confirmación del índice de fuerza relativa (RSI). Las operaciones largas se abren cuando aparece una estrella de la mañana alcista, mientras que RSI indica condiciones de sobreventa. Se realizan operaciones cortas cuando se forma una estrella vespertina bajista junto con una sobrecompra RSI. Las posiciones se cierran cuando RSI vuelve a cruzar los niveles de umbral configurables.
Supuestos del mercado
Funciona en cualquier instrumento que produzca velas OHLC regulares. Los futuros sobre índices y divisas al contado fueron los objetivos originales del experto MQL.
La estrategia espera una acción del precio fluida donde los patrones de velas japonesas sean significativos. Es posible que los gráficos de ticks extremadamente ruidosos no produzcan señales confiables.
Lógica de entrada
Suscríbase al período de tiempo configurado (predeterminado: 1 hora) y espere tres velas completamente cerradas.
Calcule el tamaño corporal promedio en las últimas velas BodyAveragePeriod (predeterminado: 3).
Detecta una estrella de la mañana cuando:
La vela 3 es fuertemente bajista (Open - Close más grande que el tamaño promedio del cuerpo).
La vela 2 tiene un cuerpo real pequeño (menos de la mitad del promedio) y huecos por debajo de la vela 3.
La vela 1 cierra por encima del punto medio de la vela 3.
Detecte una estrella vespertina con condiciones bajistas simétricas.
Confirme las entradas largas cuando el valor actual de RSI esté por debajo de LongEntryRsi (predeterminado: 40). Confirme las entradas cortas cuando RSI esté por encima de ShortEntryRsi (predeterminado: 60).
Ejecutar órdenes de mercado utilizando la estrategia Volume.
Salir de la lógica
Cierre posiciones largas cuando RSI cruce hacia abajo a través de UpperExitRsi (predeterminado: 70) o LowerExitRsi (predeterminado: 30).
Cierre posiciones cortas cuando RSI cruce hacia arriba por los mismos niveles.
No se aplica ningún límite de pérdidas ni toma de ganancias estricto. La gestión de riesgos debe realizarse externamente o ajustando los umbrales.
Parámetros
Nombre
Descripción
Predeterminado
Rango
CandleType
Tipo de datos que representa la serie de velas a suscribir.
plazo de 1 hora
Cualquier tipo de vela admitida
RsiPeriod
RSI longitud del cálculo.
47
Optimizable (10–70)
BodyAveragePeriod
Número de velas utilizadas para calcular el tamaño corporal promedio requerido para la validación del patrón.
3
Optimizable (2–6)
LongEntryRsi
Valor máximo RSI que permite entradas largas.
40
Optimizable (20–50)
ShortEntryRsi
Valor mínimo de RSI que permite entradas cortas.
60
Optimizable (50–80)
LowerExitRsi
Límite inferior que desencadena salidas cuando se cruza hacia arriba.
30
Optimizable (20–40)
UpperExitRsi
Límite superior que desencadena salidas cuando se cruza hacia abajo.
70
Optimizable (60–80)
Notas de implementación
Utiliza la API de alto nivel de StockSharp con suscripciones automáticas de velas.
Se basa únicamente en los valores de los indicadores proporcionados por Bind, evitando llamadas manuales a GetValue de acuerdo con las pautas del proyecto.
Mantiene solo un historial mínimo en memoria (tres velas recientes) para la validación del patrón.
La estrategia llama automáticamente a StartProtection() al iniciarse para habilitar mecanismos de seguridad integrados.
Consejos de uso
Adjunte la estrategia a un par de instrumento/cartera y asegúrese de que la serie de velas esté disponible en su conector.
Ajuste los niveles de RSI según la volatilidad de los activos. Los umbrales más amplios reducen el número de operaciones pero aumentan la calidad de la confirmación.
Combínelo con módulos de dimensionamiento de posiciones externos (por ejemplo, volumen basado en riesgo) para emular el comportamiento del lote fijo del EA original.
Al realizar una prueba retrospectiva, asegúrese de que los datos de las velas contengan espacios para que los patrones de estrellas puedan identificarse correctamente.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Morning/Evening Star + RSI strategy.
/// Buys on morning star with low RSI, sells on evening star with high RSI.
/// </summary>
public class AmsEsRsiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiLow;
private readonly StrategyParam<decimal> _rsiHigh;
private ICandleMessage _prevCandle;
private ICandleMessage _prevPrevCandle;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiLow { get => _rsiLow.Value; set => _rsiLow.Value = value; }
public decimal RsiHigh { get => _rsiHigh.Value; set => _rsiHigh.Value = value; }
public AmsEsRsiStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiLow = Param(nameof(RsiLow), 40m)
.SetDisplay("RSI Low", "RSI oversold threshold", "Signals");
_rsiHigh = Param(nameof(RsiHigh), 60m)
.SetDisplay("RSI High", "RSI overbought threshold", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCandle = null;
_prevPrevCandle = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCandle = null;
_prevPrevCandle = null;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) return;
if (_prevCandle != null && _prevPrevCandle != null)
{
var prevBody = Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice);
var prevRange = _prevCandle.HighPrice - _prevCandle.LowPrice;
var isSmallBody = prevRange > 0 && prevBody < prevRange * 0.3m;
var firstBearish = _prevPrevCandle.OpenPrice > _prevPrevCandle.ClosePrice;
var currBullish = candle.ClosePrice > candle.OpenPrice;
var isMorningStar = firstBearish && isSmallBody && currBullish;
var firstBullish = _prevPrevCandle.ClosePrice > _prevPrevCandle.OpenPrice;
var currBearish = candle.OpenPrice > candle.ClosePrice;
var isEveningStar = firstBullish && isSmallBody && currBearish;
if (isMorningStar && rsiValue < RsiLow && Position <= 0)
BuyMarket();
else if (isEveningStar && rsiValue > RsiHigh && Position >= 0)
SellMarket();
}
_prevPrevCandle = _prevCandle;
_prevCandle = candle;
}
}
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 ams_es_rsi_strategy(Strategy):
def __init__(self):
super(ams_es_rsi_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._rsi_low = self.Param("RsiLow", 40.0)
self._rsi_high = self.Param("RsiHigh", 60.0)
self._prev_candle = None
self._prev_prev_candle = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def RsiLow(self):
return self._rsi_low.Value
@RsiLow.setter
def RsiLow(self, value):
self._rsi_low.Value = value
@property
def RsiHigh(self):
return self._rsi_high.Value
@RsiHigh.setter
def RsiHigh(self, value):
self._rsi_high.Value = value
def OnReseted(self):
super(ams_es_rsi_strategy, self).OnReseted()
self._prev_candle = None
self._prev_prev_candle = None
def OnStarted2(self, time):
super(ams_es_rsi_strategy, self).OnStarted2(time)
self._prev_candle = None
self._prev_prev_candle = None
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
if self._prev_candle is not None and self._prev_prev_candle is not None:
prev_body = abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))
prev_range = float(self._prev_candle.HighPrice) - float(self._prev_candle.LowPrice)
is_small_body = prev_range > 0 and prev_body < prev_range * 0.3
first_bearish = float(self._prev_prev_candle.OpenPrice) > float(self._prev_prev_candle.ClosePrice)
curr_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
is_morning_star = first_bearish and is_small_body and curr_bullish
first_bullish = float(self._prev_prev_candle.ClosePrice) > float(self._prev_prev_candle.OpenPrice)
curr_bearish = float(candle.OpenPrice) > float(candle.ClosePrice)
is_evening_star = first_bullish and is_small_body and curr_bearish
if is_morning_star and rsi_val < self.RsiLow and self.Position <= 0:
self.BuyMarket()
elif is_evening_star and rsi_val > self.RsiHigh and self.Position >= 0:
self.SellMarket()
self._prev_prev_candle = self._prev_candle
self._prev_candle = candle
def CreateClone(self):
return ams_es_rsi_strategy()