Ver en GitHub

Triple estrategia de cruce SMA

Descripción general

La estrategia Triple SMA Crossover replica el MQL asesor experto 3sma.mq4 original. El sistema analiza tres promedios móviles simples (SMA) calculados sobre el precio de cierre y opera cuando la tendencia a corto plazo se alinea con los promedios a mediano y largo plazo. La conversión mantiene las reglas comerciales originales y las adapta a la StockSharp estrategia de alto nivel API.

Lógica de trading

  1. Calcule tres SMA con períodos configurables.
  2. Salga de las posiciones largas existentes cuando el SMA rápido caiga por debajo del SMA medio.
  3. Salga de las posiciones cortas existentes cuando el SMA rápido supere el SMA medio.
  4. Ingrese una nueva posición larga cuando:
    • El SMA rápido está por encima del SMA medio al menos en el spread configurado.
    • El SMA medio está por encima del SMA lento al menos en el spread configurado.
    • Actualmente no hay ninguna posición larga abierta.
  5. Ingrese una nueva posición corta cuando:
    • El SMA rápido está por debajo del SMA medio al menos en el spread configurado.
    • El SMA medio está por debajo del SMA lento al menos en el margen configurado.
    • Actualmente no hay ninguna posición corta abierta.

Parámetros

  • Tipo de vela: período de tiempo principal utilizado para calcular los promedios móviles.
  • Duración del SMA rápido: período para el SMA rápido (MQL entrada SMA1).
  • Longitud del medio SMA – Período para el medio SMA (MQL entrada SMA2).
  • Duración del SMA lento: período para el SMA lento (MQL entrada SMA3).
  • SMA Pasos de diferencial: filtro adicional que requiere que las SMA diverjan en una cantidad de incrementos de precio (MQL ingrese SMAspread).
  • Volumen comercial: volumen de órdenes utilizado al abrir posiciones (MQL entrada lots).

Notas

  • El manejo de stop loss de la versión MQL se omite porque estaba deshabilitado en el script fuente.
  • Todas las salidas son órdenes de mercado para alinearse con el comportamiento directo del experto original.
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>
/// Triple SMA crossover strategy.
/// Goes long when fast > medium > slow, short when fast less than medium less than slow.
/// Exits when fast crosses medium in opposite direction.
/// </summary>
public class TripleSmaCrossoverStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _mediumPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevMed;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int MediumPeriod { get => _mediumPeriod.Value; set => _mediumPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public TripleSmaCrossoverStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");

		_mediumPeriod = Param(nameof(MediumPeriod), 10)
			.SetDisplay("Medium SMA", "Medium SMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 20)
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0m;
		_prevMed = 0m;
		_hasPrev = false;
	}

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

		_hasPrev = false;

		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var medium = new SimpleMovingAverage { Length = MediumPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, medium, slow, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal med, decimal slow)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevMed = med;
			_hasPrev = true;
			return;
		}

		// Bullish alignment: fast > medium > slow
		if (fast > med && med > slow && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Bearish alignment: fast < medium < slow
		else if (fast < med && med < slow && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
		// Exit long when fast crosses below medium
		else if (Position > 0 && _prevFast >= _prevMed && fast < med)
		{
			SellMarket();
		}
		// Exit short when fast crosses above medium
		else if (Position < 0 && _prevFast <= _prevMed && fast > med)
		{
			BuyMarket();
		}

		_prevFast = fast;
		_prevMed = med;
	}
}