Ver en GitHub

Estrategia Sensitive MACD con Trailing

Descripción General

Esta estrategia es una conversión directa a StockSharp del asesor experto MACD "Sensitive" para MetaTrader 5. Combina cruces del MACD con herramientas de gestión de riesgo configurables (stop loss fijo, take profit y trailing stops basados en pips). El algoritmo funciona exclusivamente en velas completadas y usa la API de alto nivel para suscribirse al marco temporal deseado.

Indicadores y Datos

  • MACD (Moving Average Convergence Divergence) – configurado con longitudes de EMA rápida, lenta y de señal independientes.
  • Velas – marco temporal seleccionable por el usuario proporcionado a través del parámetro CandleType.

Condiciones de Entrada

  1. Debe cerrarse una nueva vela para evitar ruido intrabarra.
  2. Los valores del MACD se procesan desde la vinculación del indicador:
    • macd representa la línea principal del MACD.
    • signal es la línea de señal (EMA de la diferencia MACD).
  3. Requisitos de entrada larga:
    • El MACD cruza por encima de la línea de señal (macd > signal mientras los valores anteriores satisfacían macd < signal).
    • El MACD permanece en territorio negativo (macd < 0).
    • La magnitud absoluta del MACD es mayor que MacdOpenLevel * Point, asegurando un desplazamiento significativo.
    • No hay posición larga activa (la posición neta es menor o igual a cero). Los cortos existentes se revierten enviando la cantidad necesaria.
  4. Los requisitos de entrada corta son un espejo de la configuración larga:
    • El MACD cruza por debajo de la línea de señal permaneciendo positivo.
    • La magnitud absoluta del MACD supera el umbral configurado.
    • No existe posición corta abierta (la posición neta es mayor o igual a cero). Los largos existentes se aplanan antes de abrir el corto.

Gestión de Salida

  • Take Profit: Una vez abierta la operación, la estrategia almacena un nivel objetivo definido por TakeProfitPips. Si el máximo de una vela larga o el mínimo de una vela corta alcanza este nivel, la posición se cierra a mercado.
  • Stop Loss: Se calcula un stop de protección a partir de StopLossPips. Para largos, una caída del precio al nivel de stop activa una salida a mercado. Los cortos reaccionan a subidas del precio que alcanzan el stop.
  • Trailing Stop: Cuando TrailingStopPips es distinto de cero, el algoritmo activa una lógica de trailing después de que el precio avanza al menos TrailingStopPips + TrailingStepPips pips desde la entrada. Los movimientos posteriores ajustan el nivel de stop manteniendo siempre la distancia de trailing especificada desde el último cierre. El paso de trailing debe ser positivo siempre que el trailing stop esté habilitado; de lo contrario, la estrategia se detiene con un mensaje de error.
  • Cuando no hay posición activa, las variables de seguimiento internas se restablecen para prepararse para la próxima operación.

Dimensionamiento de Posición

Las cantidades de las órdenes se controlan mediante el parámetro de estrategia integrado Volume (predeterminado: 0.1). Las reversiones añaden automáticamente el valor absoluto de la posición actual al volumen deseado para cambiar de dirección en una sola orden de mercado.

Parámetros

Parámetro Descripción Predeterminado
FastLength Período de EMA rápida utilizado por la línea principal del MACD. 12
SlowLength Período de EMA lenta utilizado por la línea principal del MACD. 26
SignalLength Período de EMA de señal para el MACD. 9
MacdOpenLevel Magnitud mínima del MACD (en puntos de precio) requerida para activar operaciones. 3
StopLossPips Distancia del stop de protección en pips. 35
TakeProfitPips Distancia de take-profit en pips. 75
TrailingStopPips Distancia de trailing stop en pips (0 deshabilita el trailing). 5
TrailingStepPips Distancia adicional que debe moverse el precio antes de que se actualice el trailing stop. 5
CandleType Tipo de vela fuente (marco temporal). Velas de 1 minuto
Volume Volumen de la orden, expresado en lotes/contratos según el instrumento. 0.1

Notas Adicionales

  • Los valores de pips y puntos del MACD se derivan del paso de precio del instrumento y su precisión decimal. El código ajusta los símbolos forex de 3 y 5 dígitos escalando el tamaño del pip en consecuencia.
  • Todos los comentarios dentro del código fuente están escritos en inglés, y la implementación usa solo las APIs de alto nivel de StockSharp de acuerdo con las directrices del proyecto.
  • La estrategia evita intencionalmente la gestión de llenados parciales y asume que las órdenes de mercado se ejecutan inmediatamente al ejecutarse en el simulador o en trading real. Se pueden agregar salvaguardas adicionales si es necesario.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Sensitive MACD Trailing strategy. Uses EMA crossover (5/15).
/// </summary>
public class SensitiveMacdTrailingStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private decimal? _prevFast;
	private decimal? _prevSlow;

	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 SensitiveMacdTrailingStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 5).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 15).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevSlow = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = null; _prevSlow = null;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
		if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fast > slow;
		_prevFast = fast; _prevSlow = slow;
		if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
	}
}