Ver en GitHub

Estrategia de gestión de pedidos ARD Stochastic

Descripción general

La estrategia Ard Order Management es una StockSharp conversión del MetaTrader experto ARD_ORDER_MANAGEMENT_EA-BETA_1. El guión original se centraba en cerrar repetidamente posiciones existentes antes de realizar nuevos pedidos y ofrecía rutinas de ayuda para actualizaciones manuales de stop-loss y take-profit. La versión StockSharp mantiene esta disciplina al tiempo que agrega automatización basada en indicadores basada en el oscilador Stochastic.

La configuración predeterminada apunta al comercio de divisas intradía en un gráfico de 5 minutos, pero el tipo de vela es completamente configurable. Toda la lógica comercial se ejecuta en velas terminadas para permanecer fiel al estilo de ejecución de final de barra del experto fuente.

Lógica de trading

  • Un oscilador Stochastic con períodos configurables de retrospectiva, señal y desaceleración genera señales direccionales (valor predeterminado: 5/3/3).
  • Cuando %K cierra por encima del umbral de compra (80 de forma predeterminada), la estrategia cancela las órdenes pendientes, cierra cualquier exposición corta abierta y entra en una posición larga con el volumen configurado.
  • Cuando %K cierra por debajo del umbral de venta (20 por defecto), se cancelan todas las órdenes pendientes, se cierra la exposición larga abierta y se abre una nueva venta corta.
  • La estrategia permanece en la nueva posición hasta que se dispara la señal opuesta o se activa una salida protectora.

Gestión de pedidos y riesgos

  • Antes de cada nueva entrada, la estrategia emite órdenes de mercado que aplanan completamente la posición actual, replicando el comportamiento open_order(CLOSE) del EA.
  • StartProtection envía automáticamente órdenes iniciales de stop-loss y take-profit de acuerdo con los parámetros StopLossPips y TakeProfitPips.
  • La lógica de seguimiento opcional emula la rama MODIFY del EA: cada vela terminada puede actualizar un nivel de parada dinámico (ModifyStopLossPips) y un objetivo de ganancias flotante (ModifyTakeProfitPips). Cuando el precio toca cualquiera de los niveles finales, la posición se cierra para asegurar ganancias o limitar el riesgo.
  • La conversión de pips utiliza el PriceStep del instrumento (con un ajuste de 10× para símbolos de divisas de pip fraccionario) para que los parámetros basados en la distancia se mantengan consistentes en todos los mercados.

Parámetros

  • Volumen – volumen de operaciones para nuevas entradas; El tamaño adicional se agrega automáticamente para cerrar posiciones opuestas.
  • TakeProfitPips / StopLossPips – distancias de protección iniciales pasadas al módulo de protección incorporado. Establezca en cero para desactivar cualquier orden.
  • ModifyTakeProfitPips / ModifyStopLossPips: compensaciones finales (en pips) recalculadas después de cada vela. Establezca en cero para deshabilitar las actualizaciones finales.
  • StochasticPeriod / SignalPeriod / SlowingPeriod: configuración del oscilador que refleja la llamada iStochastic del experto original.
  • BuyThreshold / SellThreshold: niveles de sobrecompra/sobreventa que desencadenan reversiones largas/cortas.
  • CandleType: período de tiempo o fuente de datos de velas personalizada que alimenta el indicador.

Cada parámetro expone rangos de optimización sensibles para que pueda probar configuraciones alternativas en el optimizador StockSharp.

Notas de uso

  • Funciona mejor en instrumentos líquidos donde las paradas basadas en pips son significativas (principales pares de divisas, CFD sobre índices, futuros líquidos).
  • Aumente el plazo al operar en mercados más lentos para reducir el ruido y las falsas reversiones.
  • Cuando se ejecuta en cuentas reales, verifique que el volumen configurado respete los mínimos del corredor y los tamaños de paso.
  • La lógica de seguimiento se puede desactivar dejando los parámetros Modify* en cero, reproduciendo efectivamente el mantenimiento del orden estático de la fuente EA.
  • Combínelo con filtros adicionales (tendencia, volatilidad, sesiones) si desea entradas más selectivas: el código expone propiedades que se pueden ampliar.

Detalles de conversión

  • Archivo fuente: MQL/9041/ARD_ORDER_MANAGEMENT_EA-BETA_1.mq4.
  • Se recreó la lógica de activación Stochastic insinuada en la rutina start() comentada.
  • Preservó la disciplina de cierre antes de abrir y la colocación de órdenes de protección a través del alto nivel de StockSharp API.
  • Se agregaron salidas finales opcionales para reflejar el bloque manual MODIFY del EA mientras se mantiene la implementación basada en indicadores y eventos.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Ard Order Management Stochastic: RSI overbought/oversold reversal
/// with EMA trend filter and ATR-based trailing stops.
/// </summary>
public class ArdOrderManagementStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;
	private readonly StrategyParam<decimal> _buyThreshold;
	private readonly StrategyParam<decimal> _sellThreshold;

	private decimal _prevRsi;

	public ArdOrderManagementStochasticStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

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

		_emaLength = Param(nameof(EmaLength), 14)
			.SetDisplay("EMA Length", "EMA trend filter period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 10)
			.SetDisplay("ATR Length", "ATR period for stops.", "Indicators");

		_buyThreshold = Param(nameof(BuyThreshold), 30m)
			.SetDisplay("Buy Threshold", "RSI oversold level for buy.", "Signals");

		_sellThreshold = Param(nameof(SellThreshold), 70m)
			.SetDisplay("Sell Threshold", "RSI overbought level for sell.", "Signals");
	}

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

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

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

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

	public decimal BuyThreshold
	{
		get => _buyThreshold.Value;
		set => _buyThreshold.Value = value;
	}

	public decimal SellThreshold
	{
		get => _sellThreshold.Value;
		set => _sellThreshold.Value = value;
	}

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

		_prevRsi = 0;
	}

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

		_prevRsi = 0;

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var atr = new AverageTrueRange { Length = AtrLength };

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

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

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

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

		if (_prevRsi == 0)
		{
			_prevRsi = rsiVal;
			return;
		}

		// Entry: RSI crosses threshold
		if (Position == 0)
		{
			if (rsiVal < BuyThreshold && _prevRsi >= BuyThreshold)
			{
				BuyMarket();
			}
			else if (rsiVal > SellThreshold && _prevRsi <= SellThreshold)
			{
				SellMarket();
			}
		}

		_prevRsi = rsiVal;
	}
}