Ver en GitHub

Estrategia RndTrade

Conversión del asesor experto original MQL4 "RndTrade" en una estrategia StockSharp de alto nivel que realiza entradas de mercado totalmente aleatorias y las sale después de un período de tenencia fijo.

Lógica principal

  1. Suscríbase al tipo de vela configurado (velas de 1 minuto por defecto) y espere a que se completen las barras.
  2. Siempre que la estrategia sea plana, genere un número aleatorio. Un valor superior a 0,5 desencadena una compra en el mercado; de lo contrario, una venta en el mercado, ambos utilizando el volumen comercial configurado.
  3. Registre el tiempo de vela de la entrada y mantenga la posición abierta durante el tiempo de tenencia seleccionado (cuatro horas por defecto).
  4. Una vez transcurrido el cronómetro de retención, cierre toda la posición con la orden de mercado correspondiente.

Parámetros

Nombre Descripción Predeterminado
CandleType Tipo de datos de velas que activan la lógica de decisión aleatoria. velas de 1 minuto
TradeVolume Volumen utilizado para cada orden de mercado aleatoria. 1
HoldDuration Lapso de tiempo para mantener activa cualquier posición aleatoria abierta antes de cerrarla. 4 horas

Notas adicionales

  • El generador aleatorio se reinicia automáticamente cuando la estrategia comienza a imitar el comportamiento MQL4 de usar la hora local como semilla.
  • Sólo se utilizan órdenes de mercado, lo que refleja el asesor experto original que ejecutó inmediatamente operaciones sin órdenes pendientes.
  • No se requieren indicadores adicionales ni reservas históricas; la estrategia sólo se basa en las marcas de tiempo de las velas entrantes y el temporizador interno.
using System;



using StockSharp.Algo.Indicators;

using StockSharp.Algo.Strategies;

using StockSharp.BusinessEntities;

using StockSharp.Messages;



namespace StockSharp.Samples.Strategies;



public class RndTradeRandomHoldStrategy : Strategy

{

	private readonly StrategyParam<int> _emaPeriod;

	private readonly StrategyParam<int> _momentumPeriod;

	private readonly StrategyParam<DataType> _candleType;



	private decimal _prevMom; private bool _hasPrev;

	private int _cooldown;



	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }

	public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }

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



	public RndTradeRandomHoldStrategy()

	{

		_emaPeriod = Param(nameof(EmaPeriod), 14).SetDisplay("EMA Period", "EMA filter", "Indicators");

		_momentumPeriod = Param(nameof(MomentumPeriod), 10).SetDisplay("Momentum", "Momentum period", "Indicators");

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

	}



	/// <inheritdoc />

	protected override void OnReseted()

	{

		base.OnReseted();

		_prevMom = default;

		_hasPrev = default;

		_cooldown = default;

	}



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)

	{

		base.OnStarted2(time);

		_hasPrev = false;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		var mom = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(ema, mom, ProcessCandle).Start();

	}



	private void ProcessCandle(ICandleMessage candle, decimal ema, decimal mom)

	{

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

		if (!IsFormedAndOnlineAndAllowTrading()) return;

		var close = candle.ClosePrice;

		if (!_hasPrev) { _prevMom = mom; _hasPrev = true; return; }

		if (_cooldown > 0)

		{

			_cooldown--;

			_prevMom = mom;

			return;

		}



		if (close > ema && _prevMom <= 0 && mom > 0 && Position <= 0)

		{

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

			BuyMarket(volume);

			_cooldown = 2;

		}

		else if (close < ema && _prevMom >= 0 && mom < 0 && Position >= 0)

		{

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

			SellMarket(volume);

			_cooldown = 2;

		}

		_prevMom = mom;

	}

}