Auf GitHub ansehen

RndTrade-Strategie

Umwandlung des ursprünglichen MQL4 „RndTrade“-Expertenberaters in eine StockSharp-High-Level-Strategie, die völlig zufällige Markteintritte durchführt und diese nach einer festgelegten Haltedauer wieder verlässt.

Kernlogik

  1. Abonnieren Sie den konfigurierten Kerzentyp (standardmäßig 1-Minuten-Kerzen) und warten Sie auf abgeschlossene Balken.
  2. Wenn die Strategie flach ist, generieren Sie eine Zufallszahl. Ein Wert über 0,5 löst einen Marktkauf aus, andernfalls einen Marktverkauf, jeweils unter Verwendung des konfigurierten Handelsvolumens.
  3. Notieren Sie die Kerzenzeit des Einstiegs und halten Sie die Position für die ausgewählte Haltedauer (standardmäßig vier Stunden) offen.
  4. Nach Ablauf der Haltezeit schließen Sie die gesamte Position mit der entsprechenden Marktorder.

Parameter

Name Beschreibung Standard
CandleType Datentyp von Kerzen, die die Zufallsentscheidungslogik auslösen. 1 Minute Kerzen
TradeVolume Für jede zufällige Marktorder verwendetes Volumen. 1
HoldDuration Zeitspanne, um jede geöffnete Zufallsposition aktiv zu halten, bevor sie geschlossen wird. 4 Stunden

Zusätzliche Hinweise

  • Der Zufallsgenerator wird automatisch neu gesetzt, wenn die Strategie beginnt, das MQL4-Verhalten der Verwendung der Ortszeit als Startwert nachzuahmen.
  • Es werden nur Marktaufträge verwendet, die den ursprünglichen Expertenberater widerspiegeln, der Geschäfte ohne ausstehende Aufträge sofort ausführte.
  • Es sind keine zusätzlichen Indikatoren oder historischen Puffer erforderlich; Die Strategie basiert nur auf den Zeitstempeln der eingehenden Kerzen und dem internen Timer.
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;

	}

}