Ver en GitHub

Estrategia heredada de captura de tendencias

La estrategia heredada de captura de tendencias traslada el MetaTrader experto TrendCapture.mq4 al StockSharp API de alto nivel. La versión C# mantiene el conjunto de reglas original basado en la dirección Parabolic SAR, un filtro bajo ADX y una administración simple del dinero para equilibrar los gastos.

Ideas centrales

  • Procese las velas terminadas del período de tiempo seleccionado y envíelas a Parabolic SAR (0.02/0.2) y al índice direccional promedio (14).
  • Ingrese solo cuando ADX esté por debajo de AdxThreshold, lo que indica un mercado tranquilo donde SAR las reversiones son más confiables.
  • Recuerde la dirección y el resultado de la última operación cerrada: repita el mismo lado después de un ganador, gire hacia el lado opuesto después de un perdedor.
  • Aplique niveles de stop-loss y take-profit de distancia fija (configurados en puntos de precio) y mueva el stop al punto de equilibrio una vez que la operación gane BreakEvenGuard puntos.
  • Dimensione el volumen del pedido a partir del valor de la cartera disponible y MaximumRisk; recurrir a la estrategia Volume cuando la información de la cartera no esté disponible.

Parámetros

Nombre Predeterminado Descripción
SarStep 0,02 Paso de aceleración inicial Parabolic SAR.
SarMax 0,2 Aceleración máxima Parabolic SAR.
AdxPeriod 14 ADX período promedio.
AdxThreshold 20 Valor máximo ADX que aún permite una entrada nueva.
TakeProfitPoints 180 Distancia de obtención de beneficios en puntos de precio.
StopLossPoints 50 Distancia de stop-loss en puntos de precio.
BreakEvenGuard 5 Colchón de ganancias (en puntos) requerido antes de mover la parada a la entrada.
MaximumRisk 0,03 Fracción del margen libre utilizada para dimensionar la posición.
CandleType velas de 1 hora Plazo para cálculos de indicadores y señales comerciales.

Gestión de pedidos

  • Las entradas largas requieren un precio de cierre superior a SAR con un precio bajo de ADX; los cortos requieren un precio de cierre inferior a SAR con el mismo filtro ADX.
  • Los niveles de stop-loss y take-profit se recalculan en cada entrada y se evalúan en cada vela completa.
  • La activación del punto de equilibrio simplemente desplaza el tope al precio de entrada. Si no se configura ningún stop-loss (distancia cero o negativa), la guardia se ignora.

Indicadores

  • ParabolicSar para sesgo direccional.
  • AverageDirectionalIndex para el filtro de intensidad (solo se utiliza la línea principal ADX).

Notas

  • La estrategia utiliza BindEx para evitar el acceso directo al buffer, siguiendo las pautas del proyecto.
  • El cálculo del volumen basado en cartera respeta las restricciones de la junta directiva (LotStep, MinVolume, MaxVolume).
  • El historial comercial necesario para el sesgo de dirección se recopila a través de OnNewMyTrade, por lo que se siguen admitiendo rellenos parciales.
using System;



using StockSharp.Algo.Indicators;

using StockSharp.Algo.Strategies;

using StockSharp.BusinessEntities;

using StockSharp.Messages;



namespace StockSharp.Samples.Strategies;



public class TrendCaptureLegacyStrategy : Strategy

{

	private readonly StrategyParam<int> _fastPeriod;

	private readonly StrategyParam<int> _slowPeriod;

	private readonly StrategyParam<DataType> _candleType;



	private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;

	private int _cooldown;



	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }

	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

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



	public TrendCaptureLegacyStrategy()

	{

		_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");

	}



	/// <inheritdoc />

	protected override void OnReseted()

	{

		base.OnReseted();

		_prevFast = default;

		_prevSlow = default;

		_hasPrev = default;

		_cooldown = default;

	}



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)

	{

		base.OnStarted2(time);

		_hasPrev = false;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };

		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(fast, slow, ProcessCandle).Start();

	}



	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)

	{

		if (candle.State != CandleStates.Finished) return;

		if (!IsFormedAndOnlineAndAllowTrading()) return;

		if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }

		if (_cooldown > 0)

		{

			_cooldown--;

			_prevFast = fast; _prevSlow = slow;

			return;

		}



		if (_prevFast <= _prevSlow && fast > slow && Position <= 0)

		{

			var volume = Volume + Math.Abs(Position);

			BuyMarket(volume);

			_cooldown = 2;

		}

		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)

		{

			var volume = Volume + Math.Abs(Position);

			SellMarket(volume);

			_cooldown = 2;

		}

		_prevFast = fast; _prevSlow = slow;

	}

}