Ver en GitHub

Estrategia Two MA One RSI

Esta estrategia porta el experto de MetaTrader 5 "Two MA one RSI" a StockSharp. Combina el cruce de una media móvil rápida y lenta con una confirmación RSI evaluada en la vela cerrada anterior. Interruptores flexibles permiten convertir cada comparación en una regla "mayor que" o "menor que", de modo que la configuración puede invertirse sin tocar el código.

Detalles

  • Criterios de entrada:
    • Las señales largas requieren que la MA rápida esté por debajo de la MA lenta hace dos barras, que la MA rápida esté por encima de la MA lenta en la barra cerrada más reciente, y que el RSI de la barra anterior esté por encima del umbral superior. Cada comparación puede invertirse mediante parámetros booleanos.
    • Las señales cortas reflejan la lógica y comprueban las relaciones MA opuestas junto con el RSI cayendo por debajo del umbral inferior.
    • Ambas MAs usan el mismo tipo de promedio; el período lento siempre es FastMaPeriod * SlowPeriodMultiplier. Los desplazamientos horizontales opcionales reproducen el comportamiento de MT5 donde los valores del indicador se leen varias velas atrás.
  • Largo/Corto: La estrategia puede abrir posiciones en ambas direcciones. CloseOppositePositions controla si una nueva señal fuerza el cierre del lado opuesto antes de entrar.
  • Criterios de salida:
    • Stop-loss y take-profit configurables en pips.
    • Trailing stop opcional que solo se mueve después de que el precio avanza al menos TrailingStopPips + TrailingStepPips más allá de la entrada.
    • ProfitClose monitoriza el P&L flotante (usando el precio de paso del instrumento) y cierra todas las posiciones una vez alcanzado el importe objetivo en divisa.
  • Stops: Cuando StopLossPips es cero, la estrategia depende puramente del módulo de trailing stop (si está habilitado). TrailingStopPips requiere un TrailingStepPips positivo, coincidiendo con la validación del experto original.
  • Valores predeterminados:
    • FastMaPeriod = 10, SlowPeriodMultiplier = 2.
    • FastMaShift = 3, SlowMaShift = 0.
    • RsiPeriod = 10, RsiUpperLevel = 70, RsiLowerLevel = 30.
    • StopLossPips = 50, TakeProfitPips = 150, TrailingStopPips = 15, TrailingStepPips = 5.
    • MaxPositions = 10, ProfitClose = 100, TradeVolume = 1.
  • Filtros: Seis interruptores booleanos (BuyPreviousFastBelowSlow, BuyCurrentFastAboveSlow, BuyRequiresRsiAboveUpper, SellPreviousFastAboveSlow, SellCurrentFastBelowSlow, SellRequiresRsiBelowLower) permiten al usuario cambiar instantáneamente el sentido de cada comparación.

Parámetros

Nombre Descripción
CandleType Marco temporal (u otro tipo de vela) utilizado para el análisis.
MaType Familia de medias móviles (simple, exponencial, suavizada, ponderada, ponderada por volumen).
FastMaPeriod Período de la MA rápida.
SlowPeriodMultiplier Multiplicador de período de la MA lenta (lenta = rápida * multiplicador).
FastMaShift, SlowMaShift Desplazamientos horizontales en velas aplicados al evaluar los valores de MA.
RsiPeriod Longitud del RSI (usa la vela finalizada anterior).
RsiUpperLevel, RsiLowerLevel Umbrales RSI para confirmaciones largas y cortas.
BuyPreviousFastBelowSlow, BuyCurrentFastAboveSlow, BuyRequiresRsiAboveUpper Activar/desactivar comparaciones para señales largas.
SellPreviousFastAboveSlow, SellCurrentFastBelowSlow, SellRequiresRsiBelowLower Activar/desactivar comparaciones para señales cortas.
StopLossPips, TakeProfitPips Stop protector y objetivo medido en pips (tamaño del pip derivado del paso de precio del instrumento).
TrailingStopPips, TrailingStepPips Distancia del trailing stop y mejora mínima.
MaxPositions Número máximo de entradas simultáneas por dirección (0 = ilimitado).
ProfitClose Objetivo de beneficio en divisa que cierra todas las posiciones al alcanzarse.
CloseOppositePositions Si se debe cerrar el lado opuesto antes de abrir una nueva operación.
TradeVolume Tamaño base de la orden; también se sincroniza con la propiedad Volume de la estrategia.

Notas de implementación

  • Todas las decisiones usan solo velas finalizadas, igualando la lógica de "nueva barra" del experto MT5.
  • El tamaño del pip es igual al paso de precio del instrumento. Si su mercado usa precios de pip fraccionarios, ajuste la configuración del instrumento en consecuencia para que la traducción del pip coincida con la lógica digits_adjust del experto original.
  • Los trailing stops solo comienzan después de que el precio ha avanzado TrailingStopPips + TrailingStepPips; el stop entonces se ancla TrailingStopPips lejos del cierre y solo se mueve cuando mejora al menos TrailingStepPips.
  • ProfitClose calcula el beneficio flotante usando PriceStep y StepPrice del instrumento. Asegúrese de que esos campos estén configurados para resultados de divisa correctos.
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>
/// Two MA one RSI strategy (simplified).
/// EMA crossover filtered by RSI levels.
/// </summary>
public class TwoMaOneRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

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

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

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA", "Indicators");

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

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		decimal prevFast = 0, prevSlow = 0;
		bool hasPrev = false;

		var subscription = SubscribeCandles(CandleType);
		// Use Bind with fast, slow - RSI computed separately via cross-feed
		subscription
			.Bind(fast, slow, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!hasPrev)
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					hasPrev = true;
					return;
				}

				if (!IsFormedAndOnlineAndAllowTrading())
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					return;
				}

				// Golden cross + RSI not overbought
				if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
				{
					BuyMarket();
				}
				// Death cross + RSI not oversold
				else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
				{
					SellMarket();
				}

				prevFast = fastValue;
				prevSlow = slowValue;
			})
			.Start();

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