Ver en GitHub

LCS MACD Estrategia comercial

Esta estrategia es un puerto StockSharp del asesor experto "LCS-MACD-Trader" MetaTrader 4. Intercambia MACD cruces que ocurren por debajo o por encima de la línea cero y, opcionalmente, requiere una confirmación del oscilador Stochastic. La lógica también refleja los filtros de hora del día originales y la gestión de punto de equilibrio/punto de equilibrio dinámico estilo MetaTrader.

como funciona

  • Las entradas largas se activan cuando la línea MACD cruza por encima de su línea de señal mientras ambas permanecen por debajo de cero. Si el filtro estocástico está habilitado, la línea %D debe haber estado por encima de %K dentro del período retrospectivo especificado y la vela actual debe mostrar que %D vuelve a caer por debajo de %K.
  • Las entradas cortas se activan cuando la línea MACD cruza por debajo de su línea de señal mientras ambas permanecen por encima de cero. Con el filtro estocástico habilitado, la línea %D debe haber estado recientemente por debajo de %K y ahora vuelve a subir por encima de ella.
  • Solo se permite operar dentro de tres ventanas intradiarias configurables que replican la configuración de EA.
  • Las distancias de toma de ganancias, stop-loss, punto de equilibrio y trailing-stop se expresan en pips y se convierten utilizando el tamaño de puntos del instrumento.
  • Sólo se mantiene una posición neta por dirección (StockSharp netting). Se permite el apilamiento de posiciones hasta MaxOrders lotes; las señales opuestas esperan hasta que la gestión de riesgos cierre la posición neta actual.

Parámetros

Nombre Descripción Predeterminado
CandleType Serie de velas utilizadas para los cálculos de indicadores. plazo de 15 minutos
FastEmaPeriod Período EMA rápida en el MACD. 12
SlowEmaPeriod Período EMA lenta en el MACD. 26
SignalPeriod Período de línea de señal en el MACD. 9
UseStochasticFilter Requerir confirmación estocástica antes de las entradas. cierto
BarsToCheckStochastic Barras máximas cerradas desde la relación estocástica opuesta. 5
StochasticKPeriod Longitud retrospectiva de %K. 5
StochasticDPeriod Longitud de suavizado de %D. 3
StochasticSlowing Suavizado adicional aplicado a %K. 3
TradeVolume Tamaño de lote utilizado por entrada. 0.1
TakeProfitPips Distancia de toma de ganancias en pips. 100
StopLossPips Distancia de stop-loss en pips. 100
MaxOrders Entradas apiladas máximas por dirección. 5
EnableTrailing Habilite la lógica de parada dinámica de estilo MetaTrader. falso
TrailingActivationPips Se requiere beneficio antes de que comience el seguimiento. 50
TrailingDistancePips Distancia mantenida por el trailing stop. 25
BreakEvenActivationPips Beneficio necesario para mover el stop al punto de equilibrio. 25
BreakEvenOffsetPips Se agregaron pips adicionales al colocar el tope de equilibrio. 1
Session1Start/End, Session2Start/End, Session3Start/End Ventanas de negociación intradía. 08:15-08:35, 13:45-14:42, 22:15-22:45

Notas

  • La estrategia supone una cuenta de compensación. Cierra posiciones existentes a través de las reglas de riesgo configuradas en lugar de cubrir órdenes opuestas como la versión MT4 original.
  • La conversión de pips utiliza el tamaño de puntos del instrumento. Para símbolos FX de 5 dígitos, la lógica escala automáticamente los valores de pip en 10 para que coincidan con la configuración del multiplicador EA.
  • La lógica de trailing stop y punto de equilibrio se evalúa en velas terminadas y utiliza el máximo/mínimo de cada barra para emular el comportamiento MetaTrader basado en ticks.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// LCS MACD Trader: MACD zero-line cross with RSI filter and ATR stops.
/// </summary>
public class LcsMacdTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevMacd;
	private decimal _entryPrice;

	public LcsMacdTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastEmaLength = Param(nameof(FastEmaLength), 12)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowEmaLength = Param(nameof(SlowEmaLength), 26)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int FastEmaLength
	{
		get => _fastEmaLength.Value;
		set => _fastEmaLength.Value = value;
	}

	public int SlowEmaLength
	{
		get => _slowEmaLength.Value;
		set => _slowEmaLength.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

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

		_prevMacd = 0;
		_entryPrice = 0;
	}

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

		_prevMacd = 0;
		_entryPrice = 0;

		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, rsi, atr, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var macd = fastVal - slowVal;

		if (_prevMacd == 0 || atrVal <= 0)
		{
			_prevMacd = macd;
			return;
		}

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || macd < 0)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || macd > 0)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (macd > 0 && _prevMacd <= 0 && rsiVal > 45)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (macd < 0 && _prevMacd >= 0 && rsiVal < 55)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevMacd = macd;
	}
}