Ver en GitHub

Estrategia Tres Indicadores

Descripción general

Esta estrategia es una conversión de StockSharp del expert original "Three indicators" de MQL5. Evalúa tres osciladores clásicos—MACD, Oscilador Estocástico y RSI—en cada vela terminada del marco temporal seleccionado. Solo cuando todos los filtros se alinean la estrategia entra en una posición, asegurando que cada operación siga una confirmación multi-indicador consistente.

Lógica de trading

  1. Filtro de dirección de vela – compara el precio de apertura de la vela terminada actual con el precio de apertura de la anterior. Una apertura más alta favorece operaciones largas, una apertura más baja favorece cortos.
  2. Filtro de pendiente MACD – observa la pendiente de la línea principal MACD (diferencia entre el valor MACD principal actual y el anterior). Un MACD en caída favorece posiciones largas, un MACD en ascenso favorece cortos, exactamente como en el experto de origen.
  3. Filtro de sesgo estocástico – comprueba si el valor %D está por debajo o por encima del punto medio 50. Valores por debajo de 50 apoyan largos, valores por encima de 50 apoyan cortos.
  4. Filtro de sesgo RSI – usa el valor RSI relativo a 50. Valores por debajo de 50 autorizan largos, valores por encima de 50 autorizan cortos.

Solo si los cuatro filtros apoyan la misma dirección abrirá la estrategia una nueva operación. Si aparece una señal opuesta mientras hay una posición abierta, la estrategia revierte inmediatamente enviando una única orden de mercado que cierra la exposición existente y abre la nueva dirección, reflejando el comportamiento de la lógica MQL original.

Parámetros

Parámetro Descripción
CandleType Marco temporal de las velas suministradas a la estrategia. Predeterminado: 1 minuto.
TradeVolume Volumen usado al abrir una posición o revertir al lado opuesto.
MacdFastPeriod Longitud de la EMA rápida dentro del cálculo MACD.
MacdSlowPeriod Longitud de la EMA lenta dentro del cálculo MACD.
MacdSignalPeriod Longitud de la EMA para la línea de señal MACD.
MacdPriceType Precio aplicado al indicador MACD (Close, Open, High, Low, Median, Typical, Weighted).
StochasticKPeriod Período de retroceso para la línea %K.
StochasticDPeriod Período de suavizado para la línea %D.
StochasticSlowing Suavizado adicional aplicado a %K antes de calcular %D.
RsiPeriod Período de promediado usado por el filtro RSI.
RsiPriceType Precio aplicado al alimentar el indicador RSI.

Indicadores

  • MACD (Convergencia/Divergencia de Medias Móviles) – configurado con los períodos rápido, lento y de señal especificados por el usuario.
  • Oscilador Estocástico – usa la implementación de StockSharp con longitudes %K/%D y suavizado configurables.
  • Índice de Fuerza Relativa (RSI) – proporciona la confirmación de impulso final.

Notas de comportamiento

  • La estrategia procesa solo velas terminadas, mejorando la estabilidad en comparación con el desencadenador basado en ticks del experto original.
  • La pausa de 30 segundos presente en la versión MQL se elimina; las reversiones se emiten inmediatamente con la orden de mercado combinada.
  • El suavizado estocástico usa la implementación de media móvil predeterminada de StockSharp, que corresponde al suavizado estándar basado en SMA del script original.
  • La selección de fuente de precio para MACD y RSI se proporciona a través del enum IndicatorAppliedPrice, coincidiendo con las opciones disponibles en MetaTrader (Close, Open, High, Low, Median, Typical, Weighted).

Gestión de riesgo

No se colocan órdenes de stop-loss o take-profit automáticamente. La gestión de posición está impulsada exclusivamente por la lógica de reversión multi-indicador. Agregar controles de riesgo externos si se requiere.

Consejos de uso

  1. Seleccionar el instrumento y marco temporal deseados a través de CandleType.
  2. Ajustar los parámetros del indicador para adecuarse a la volatilidad del mercado y la frecuencia de señales.
  3. Monitorear los objetos de gráfico añadidos por la estrategia (velas más los tres indicadores) para validar la alineación de señales.
  4. Combinar con gestión de dinero externa si se requieren stops fijos o objetivos de beneficio.
namespace StockSharp.Samples.Strategies;

using System;

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

/// <summary>
/// Combines MACD, Stochastic Oscillator, and RSI filters.
/// All three indicators must agree on direction to enter a trade.
/// </summary>
public class ThreeIndicatorsStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _macdFastPeriod;
	private readonly StrategyParam<int> _macdSlowPeriod;
	private readonly StrategyParam<int> _macdSignalPeriod;
	private readonly StrategyParam<int> _stochasticKPeriod;
	private readonly StrategyParam<int> _stochasticDPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownBars;

	private decimal? _previousOpen;
	private decimal? _previousMacdMain;
	private int _previousCompositeSignal;
	private int _cooldownRemaining;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int MacdFastPeriod { get => _macdFastPeriod.Value; set => _macdFastPeriod.Value = value; }
	public int MacdSlowPeriod { get => _macdSlowPeriod.Value; set => _macdSlowPeriod.Value = value; }
	public int MacdSignalPeriod { get => _macdSignalPeriod.Value; set => _macdSignalPeriod.Value = value; }
	public int StochasticKPeriod { get => _stochasticKPeriod.Value; set => _stochasticKPeriod.Value = value; }
	public int StochasticDPeriod { get => _stochasticDPeriod.Value; set => _stochasticDPeriod.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int SignalCooldownBars { get => _signalCooldownBars.Value; set => _signalCooldownBars.Value = value; }

	public ThreeIndicatorsStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle type", "Primary timeframe", "General");

		_macdFastPeriod = Param(nameof(MacdFastPeriod), 11)
			.SetDisplay("MACD fast", "Fast EMA length", "MACD");

		_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 53)
			.SetDisplay("MACD slow", "Slow EMA length", "MACD");

		_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 26)
			.SetDisplay("MACD signal", "Signal smoothing", "MACD");

		_stochasticKPeriod = Param(nameof(StochasticKPeriod), 40)
			.SetDisplay("Stochastic %K", "%K length", "Stochastic");

		_stochasticDPeriod = Param(nameof(StochasticDPeriod), 23)
			.SetDisplay("Stochastic %D", "%D smoothing", "Stochastic");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI period", "RSI length", "RSI");

		_signalCooldownBars = Param(nameof(SignalCooldownBars), 2)
			.SetNotNegative()
			.SetDisplay("Signal Cooldown Bars", "Closed candles to wait before a new entry", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_previousOpen = null;
		_previousMacdMain = null;
		_previousCompositeSignal = 0;
		_cooldownRemaining = 0;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_previousOpen = null;
		_previousMacdMain = null;
		_previousCompositeSignal = 0;
		_cooldownRemaining = 0;

		var macd = new MovingAverageConvergenceDivergenceSignal();
		macd.Macd.ShortMa.Length = MacdFastPeriod;
		macd.Macd.LongMa.Length = MacdSlowPeriod;
		macd.SignalMa.Length = MacdSignalPeriod;

		var stochastic = new StochasticOscillator();
		stochastic.K.Length = StochasticKPeriod;
		stochastic.D.Length = StochasticDPeriod;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.BindEx(macd, stochastic, rsi, ProcessCandle)
			.Start();

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

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

		if (!macdValue.IsFinal || !stochValue.IsFinal || !rsiValue.IsFinal)
			return;

		if (_cooldownRemaining > 0)
			_cooldownRemaining--;

		if (!macdValue.IsFormed || !stochValue.IsFormed || !rsiValue.IsFormed)
			return;

		var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
		var macdMain = macdVal.Macd ?? 0m;

		var stoch = (StochasticOscillatorValue)stochValue;
		var stochasticD = stoch.D ?? 50m;

		var rsi = rsiValue.GetValue<decimal>();

		if (_previousOpen == null || _previousMacdMain == null)
		{
			_previousOpen = candle.OpenPrice;
			_previousMacdMain = macdMain;
			return;
		}

		// Candle direction
		var candleSignal = candle.OpenPrice > _previousOpen.Value ? 1 : candle.OpenPrice < _previousOpen.Value ? -1 : 0;

		// MACD direction (difference decreasing = bullish momentum)
		var macdDelta = macdMain - _previousMacdMain.Value;
		var macdSignal = macdDelta < 0m ? 1 : macdDelta > 0m ? -1 : 0;

		// Stochastic direction
		var stochSignal = stochasticD < 50m ? 1 : stochasticD > 50m ? -1 : 0;

		// RSI direction
		var rsiSignal = rsi < 50m ? 1 : rsi > 50m ? -1 : 0;

		var longSignal = candleSignal >= 0 && macdSignal >= 0 && stochSignal >= 0 && rsiSignal >= 0;
		var shortSignal = candleSignal <= 0 && macdSignal <= 0 && stochSignal <= 0 && rsiSignal <= 0;

		var compositeSignal = longSignal ? 1 : shortSignal ? -1 : 0;

		if (_cooldownRemaining == 0 && compositeSignal != 0 && compositeSignal != _previousCompositeSignal)
		{
			if (compositeSignal > 0 && Position <= 0)
			{
				BuyMarket(Volume + (Position < 0 ? -Position : 0m));
				_cooldownRemaining = SignalCooldownBars;
			}
			else if (compositeSignal < 0 && Position >= 0)
			{
				SellMarket(Volume + (Position > 0 ? Position : 0m));
				_cooldownRemaining = SignalCooldownBars;
			}
		}

		_previousOpen = candle.OpenPrice;
		_previousMacdMain = macdMain;
		_previousCompositeSignal = compositeSignal;
	}
}