Ver en GitHub

MACD Buceador y RSI Estrategia

Descripción general

Esta estrategia es una conversión de C# del asesor experto "Macd diver and rsi" MetaTrader 5. Mantiene la idea original de la señal de dos etapas: el índice de fuerza relativa (RSI) detecta extremos de sobreventa o sobrecompra, mientras que el histograma MACD confirma que el impulso está regresando en la dirección de la operación. Los lados largos y cortos se configuran de forma independiente para que el comportamiento se pueda ajustar para configuraciones alcistas y bajistas por separado.

La estrategia opera con una única suscripción de vela (período de tiempo configurable) y negocia el valor registrado directamente a través de órdenes de mercado. Todo el procesamiento de indicadores utiliza el StockSharp API de alto nivel a través de BindEx, que coincide con las reglas del proyecto.

Lógica de trading

  1. Preparación de indicadores

    • Se crean dos indicadores RSI, uno para el tramo largo y otro para el tramo corto, con longitudes y umbrales individuales.
    • Dos indicadores MovingAverageConvergenceDivergenceSignal reflejan la configuración MACD para operaciones largas y cortas. Su componente de histograma se utiliza para confirmar las inversiones de impulso.
  2. Reglas de entrada

    • Configuración larga: cuando el valor largo de RSI está en o por debajo del umbral de sobreventa y el histograma largo de MACD cruza por encima de cero (cambia de signo de negativo a positivo), se abre una posición alcista. Si una posición corta está activa, se cierra y se revierte en el mismo orden de mercado.
    • Configuración corta: cuando el valor corto de RSI está en o por encima del umbral de sobrecompra y el histograma corto de MACD cruza por debajo de cero, se abre una posición bajista. La exposición larga existente se aplana antes de que se establezca la nueva exposición corta.
  3. Gestión de riesgos

    • Después de cada entrada, la estrategia registra el precio de cierre de la barra de señal como precio de referencia.
    • Los niveles de stop-loss y take-profit se proyectan a partir de ese precio utilizando distancias de pips definidas por separado para operaciones largas y cortas.
    • Los pips se convierten a unidades de precio con el instrumento PriceStep y se escalan automáticamente en 10 para símbolos con 3 o 5 decimales para reflejar el comportamiento de MT5.
    • En cada vela completa, el rango máximo/bajo se compara con estos niveles. Alcanzar cualquiera de los niveles cierra inmediatamente la posición con una orden de mercado.
  4. Gestión comercial

    • El estado de la posición se borra cada vez que el tamaño de la posición vuelve a cero (ya sea porque se alcanzó un stop/take-profit o porque la estrategia fue revertida por una señal opuesta).
    • No se realizan salidas parciales ni ajustes de seguimiento; la posición se gestiona únicamente a través de los niveles estáticos de stop-loss y take-profit.

Parámetros

Parámetro Descripción
CandleType Periodo de suscripción de velas utilizado para las señales.
LongRsiPeriod, ShortRsiPeriod RSI longitudes para detección larga y corta.
LongRsiThreshold, ShortRsiThreshold RSI umbrales que permiten entradas (sobreventa para largos, sobrecompra para cortos).
LongMacdFastLength, LongMacdSlowLength, LongMacdSignalLength MACD EMA longitudes para el tramo alcista.
ShortMacdFastLength, ShortMacdSlowLength, ShortMacdSignalLength MACD EMA longitudes para el tramo bajista.
LongVolume, ShortVolume Volumen comercial por señal. Al revertir, la estrategia agrega el volumen de apertura absoluto para que la orden única realice el cierre y la nueva apertura.
LongStopLossPips, LongTakeProfitPips, ShortStopLossPips, ShortTakeProfitPips Distancia de las órdenes stop-loss y take-profit en pips. Cero desactiva el nivel respectivo.

Notas

  • La estrategia requiere instrumentos con un valor distinto de cero PriceStep. Si falta el paso, el cálculo del pip vuelve a 0,0001 para evitar la división por cero.
  • Dado que ambas partes utilizan instancias de indicadores independientes, es posible ajustar el comportamiento alcista y bajista por separado, por ejemplo, ajustando el umbral de sobrecompra y manteniendo el lado de sobreventa más permisivo.
  • El código agrega documentación y comentarios en inglés para aclarar el proceso comercial y satisfacer las pautas del proyecto.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// MACD Diver And RSI strategy: RSI extremes + MACD histogram crossover.
/// Buys when RSI below 30 and MACD histogram crosses above zero.
/// Sells when RSI above 70 and MACD histogram crosses below zero.
/// </summary>
public class MacdDiverAndRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;

	private decimal _prevHistogram;
	private decimal _prevRsi;
	private bool _hasPrev;

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

	public MacdDiverAndRsiStrategy()
	{
		_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");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevHistogram = 0;
		_prevRsi = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrev = false;
		var macd = new MovingAverageConvergenceDivergenceSignal
		{
			Macd = { ShortMa = { Length = 12 }, LongMa = { Length = 26 } },
			SignalMa = { Length = 9 }
		};
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(macd, rsi, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue, IIndicatorValue rsiValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!macdValue.IsFinal || !rsiValue.IsFinal) return;
		if (macdValue is not MovingAverageConvergenceDivergenceSignalValue typed) return;
		if (typed.Macd is not decimal macdMain || typed.Signal is not decimal signal) return;

		var histogram = macdMain - signal;
		var rsi = rsiValue.ToDecimal();

		if (_hasPrev)
		{
			if (_prevHistogram <= 0 && histogram > 0 && _prevRsi < 35 && Position <= 0)
				BuyMarket();
			else if (_prevHistogram >= 0 && histogram < 0 && _prevRsi > 65 && Position >= 0)
				SellMarket();
		}

		_prevHistogram = histogram;
		_prevRsi = rsi;
		_hasPrev = true;
	}
}