Ver en GitHub

Estrategia Expert ADC PL Stoch Strategy

Descripción general

La Estrategia Expert ADC PL Stoch es una estrategia de patrón de velas convertida del MQL5 asesor experto original Expert_ADC_PL_Stoch. Busca formaciones de líneas de perforación alcistas y de nubes oscuras bajistas en velas terminadas y confirma las señales con la línea %D del oscilador Stochastic. El método sigue la tendencia cuando el mercado retrocede hacia un movimiento establecido y requiere que el oscilador esté en zonas extremas antes de abrir posiciones. Las salidas de posiciones se basan en cruces Stochastic de áreas extremas, lo que refleja la lógica de salida basada en votos del sistema fuente.

Lógica de trading

  1. Suscríbase a un tipo de vela configurable (predeterminado: período de 1 hora).
  2. Para cada vela terminada, mantenga las últimas velas necesarias para la evaluación del patrón de velas y los valores recientes de Stochastic %D.
  3. Entrada larga
    • El par de velas anterior debe formar un patrón de Línea Perforante:
      • La vela en la barra t-1 es alcista con un cuerpo mayor que el tamaño promedio del cuerpo.
      • La vela en la barra t-2 es bajista con un cuerpo mayor que el promedio.
      • The bullish candle gaps below the bearish low and closes back inside the bearish body while the overall trend is downward according to the close average.
    • The Stochastic %D value on bar t-1 must be below the long entry threshold (default 30).
  4. Short Entry
    • El par de velas anterior debe formar un patrón de Cobertura de Nubes Oscuras:
      • La vela en la barra t-2 es alcista y tiene un cuerpo grande.
      • La vela en la barra t-1 se abre por encima del máximo anterior y se cierra dentro del cuerpo alcista.
      • The mid-price of the bearish candle is above the moving average of closes, signalling an uptrend prior to the reversal.
    • El Stochastic %D en la barra t-1 debe estar por encima del umbral de entrada corta (predeterminado 70).
  5. Condiciones de salida
    • Las posiciones largas se cierran cuando el Stochastic %D en la barra t-1 cruza por debajo de los umbrales superior (80) o inferior (20) en comparación con la barra t-2.
    • Las posiciones cortas se cierran cuando el Stochastic %D en la barra t-1 cruza por encima de los umbrales inferior (20) o superior (80) en comparación con la barra t-2.
  6. Todos los cálculos se realizan sobre velas terminadas; no intrabar processing is used.

Parámetros

Nombre Descripción Predeterminado
CandleType Marco temporal de velas utilizadas para la detección de patrones. 1 hora
StochasticLength Base length for the Stochastic oscillator. 47
StochasticKPeriod Longitud de suavizado para la línea %K. 9
StochasticDPeriod Longitud de suavizado para la línea %D. 13
StochasticSlow Factor de desaceleración adicional aplicado al oscilador. 3
AverageBodyPeriod Número de velas utilizadas para medir el tamaño del cuerpo de referencia y el promedio de cierre. 5
LongEntryThreshold Valor máximo de %D permitido antes de realizar operaciones largas. 30
ShortEntryThreshold Valor mínimo de %D requerido antes de realizar operaciones cortas. 70
ExitLowerThreshold Lower boundary used for exit crossovers. 20
ExitUpperThreshold Upper boundary used for exit crossovers. 80

Gestión del riesgo

  • La estrategia envía órdenes de mercado utilizando el volumen de la estrategia base (por defecto, 1 contrato/lote).
  • No automatic protective orders are configured; Se puede agregar gestión de riesgos externa o StartProtection si es necesario.
  • Only one position is managed at a time; las señales opuestas cierran la posición activa antes de abrir una nueva.

Notas

  • Average candle bodies and close averages are computed from historical candles to replicate the MQL5 vote logic closely.
  • Los valores Stochastic se almacenan por barra terminada para evaluar las mismas compensaciones utilizadas en el asesor experto original.
  • Las operaciones se abren y cierran solo cuando la estrategia está completamente formada y los controles de clase base permiten la negociación.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Expert ADC PL Stoch strategy: Dark Cloud Cover and Piercing Line patterns
/// with Stochastic oscillator confirmation for entries and exits.
/// </summary>
public class ExpertAdcPlStochStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _stochPeriod;
	private readonly StrategyParam<decimal> _longThreshold;
	private readonly StrategyParam<decimal> _shortThreshold;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private readonly List<ICandleMessage> _candles = new();
	private decimal _prevSignal;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int StochPeriod { get => _stochPeriod.Value; set => _stochPeriod.Value = value; }
	public decimal LongThreshold { get => _longThreshold.Value; set => _longThreshold.Value = value; }
	public decimal ShortThreshold { get => _shortThreshold.Value; set => _shortThreshold.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public ExpertAdcPlStochStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_stochPeriod = Param(nameof(StochPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Stoch Period", "Stochastic period", "Indicators");
		_longThreshold = Param(nameof(LongThreshold), 30m)
			.SetDisplay("Long Threshold", "Stochastic below this for long", "Signals");
		_shortThreshold = Param(nameof(ShortThreshold), 70m)
			.SetDisplay("Short Threshold", "Stochastic above this for short", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candles.Clear();
		_prevSignal = 0m;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candles.Clear();
		_candlesSinceTrade = SignalCooldownCandles;
		var stoch = new StochasticOscillator { K = { Length = StochPeriod }, D = { Length = 3 } };
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(stoch, ProcessCandle).Start();

		StartProtection(
			takeProfit: new Unit(2, UnitTypes.Percent),
			stopLoss: new Unit(1, UnitTypes.Percent)
		);
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue stochValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		var stochTyped = stochValue as StochasticOscillatorValue;
		if (stochTyped?.K is not decimal kValue) return;

		_candles.Add(candle);
		if (_candles.Count > 10)
			_candles.RemoveAt(0);

		if (_candles.Count >= 2)
		{
			var curr = _candles[^1];
			var prev = _candles[^2];

			// Piercing Line: bearish prev + bullish curr that closes above prev midpoint
			var isPiercing = prev.OpenPrice > prev.ClosePrice
				&& curr.ClosePrice > curr.OpenPrice
				&& curr.OpenPrice < prev.LowPrice
				&& curr.ClosePrice > (prev.OpenPrice + prev.ClosePrice) / 2m;

			// Dark Cloud Cover: bullish prev + bearish curr that closes below prev midpoint
			var isDarkCloud = prev.ClosePrice > prev.OpenPrice
				&& curr.OpenPrice > curr.ClosePrice
				&& curr.OpenPrice > prev.HighPrice
				&& curr.ClosePrice < (prev.OpenPrice + prev.ClosePrice) / 2m;

			if (isPiercing && kValue < LongThreshold && Position == 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (isDarkCloud && kValue > ShortThreshold && Position == 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevSignal = kValue;
	}
}