Auf GitHub ansehen

Trading-Panel-Batch-Strategie

Überblick

TradingPanelBatchStrategy ist ein StockSharp-Port des MetaTrader 4-Expertenberaters EA_TradingPanel. Das ursprüngliche Skript zeigte ein manuelles Panel an, in dem der Händler die Anzahl der gleichzeitigen Trades, die Losgröße und die Schutzabstände konfigurierte, bevor er KAUFEN oder VERKAUFEN drückte. In der StockSharp-Version ist das gleiche Verhalten automatisiert: Sobald der Operator den Parameter Direction setzt, löst die Strategie eine Reihe von Marktaufträgen für die nächste fertige Kerze aus und setzt die Richtung sofort wieder auf None zurück.

Die Logik ist bewusst einfach gehalten, sodass das Modul mit externen Signalen oder manueller Überwachung kombiniert werden kann. Alle Aufträge erben optionale Stop-Loss- und Take-Profit-Distanzen, die in Pips gemessen werden, was die Risikokontrollen widerspiegelt, die in der MQL-Implementierung verfügbar sind.

Arbeitsablauf

  1. Wenn die Strategie startet, berechnet sie die Pip-Größe aus Security.PriceStep. Für 1/3/5-stellige Forex-Symbole wird der Wert mit zehn multipliziert, was der MetaTrader-Umrechnung zwischen Punkten und Pips entspricht.
  2. Wenn Stop-Loss- oder Take-Profit-Offsets ungleich Null sind, ermöglicht die Strategie StartProtection, Exits mit Marktaufträgen zu verwalten.
  3. Die Strategie abonniert die durch CandleType angegebene Kerzenserie. Nach jeder fertigen Kerze prüft es den Parameter Direction.
  4. Wenn eine Richtung angefordert wird und die Engine den Handel zulässt, sendet die Strategie NumberOfOrders Marktaufträge unter Verwendung von OrderVolume für jedes Ticket.
  5. Nachdem der Stapel versandt wurde, protokolliert die Strategie die Aktion und setzt Direction automatisch auf None zurück, bereit für den nächsten manuellen Auslöser.

Dieses Design hält das Modul zwischen den Ausführungen zustandslos. Händler können Direction wiederholt auf Buy oder Sell setzen, wenn sie einen neuen Auftragsstapel benötigen; Die Ausführung erfolgt immer bei der nächsten abgeschlossenen Kerze, um zu vermeiden, dass auf unvollständig gebildete Marktdaten eingegriffen wird.

Parameter

Name Typ Standard Beschreibung
NumberOfOrders int 1 Anzahl der im nächsten Stapel gesendeten Marktaufträge.
OrderVolume decimal 0.01 Auf jede Marktorder angewendetes Volumen.
StopLossPips decimal 2 Stop-Loss-Distanz, umgerechnet von Pips in absoluten Preis unter Verwendung der aktuellen Instrument-Metadaten. Zum Deaktivieren auf 0 setzen.
TakeProfitPips decimal 10 Take-Profit-Distanz in Pips. Zum Deaktivieren auf 0 setzen.
Direction TradeDirection None Angeforderte Anweisung für die nächste Ausführung. Die Strategie setzt den Wert zurück, nachdem die Bestellungen aufgegeben wurden.
CandleType DataType TimeFrameCandle(1m) Kerzenserie, die zum Auslösen der Ausführung verwendet wird.

Notizen

  • Die Strategie erfordert ein gültiges Security mit ordnungsgemäß konfiguriertem PriceStep (und optional Decimals). Ohne diese Metadaten fallen die Pip-Berechnungen auf 1 zurück.
  • StartProtection verwendet Marktaufträge für Exits, um nachzuahmen, wie das MQL-Panel Positionen auf Stop-Loss- oder Take-Profit-Niveau schloss.
  • Da die Ausführung bei abgeschlossenen Kerzen erfolgt, können Händler Auftragsstapel mit benutzerdefinierten Analysen oder externen Signalen synchronisieren, indem sie Direction aktualisieren, bevor die Kerze schließt.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Trading Panel Batch strategy: DEMA crossover.
/// Buys when fast DEMA crosses above slow DEMA, sells on cross below.
/// </summary>
public class TradingPanelBatchStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

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

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public TradingPanelBatchStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast DEMA", "Fast DEMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow DEMA", "Slow DEMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_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 fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}