Auf GitHub ansehen

Strategie zur Steuerung des Handelspanels

Überblick

Die Trading Panel Control Strategy repliziert die Funktionalität des „Trading Panel“ MetaTrader 4-Dienstprogramms in StockSharp. Das ursprüngliche MQL-Panel ermöglichte es einem Händler, den aktiven Chart-Zeitrahmen zu wechseln und zwischen Instrumenten zu wechseln, indem er auf UI-Schaltflächen klickte. Die StockSharp-Version stellt dieselben Steuerelemente über Strategieparameter bereit, sodass die Hostanwendung (Designer, Terminal oder benutzerdefiniertes Dashboard) sie im Handumdrehen anpassen kann.

Im Gegensatz zum Quell-Expert Advisor sendet dieser Port keine Handelsaufträge. Sein Ziel besteht darin, das Diagrammabonnement mit dem aktuell ausgewählten Zeitrahmen und Instrument synchron zu halten und die letzten Kerzenschließungen zu protokollieren, um ein Feedback ähnlich den Textbeschriftungen im Originalpanel zu liefern.

Schlüsselkonzepte

  • Dynamische Zeitrahmensteuerung – wählen Sie zwischen M1, M5, M15, M30, H1, H4, D1 oder W1. Durch das Ändern des Parameters wird das Kerzenabonnement sofort neu erstellt.
  • Instrumentensuche – Geben Sie eine Sicherheitskennung an, der gefolgt werden soll. Wenn diese Option aktiviert ist, durchsucht die Strategie das verbundene ISecurityProvider; Andernfalls wird auf die Sicherheit zurückgegriffen, die bereits mit der Strategie verbunden ist.
  • Kerzen-Feedback – jede fertige Kerze wird mit ihrem Schlusskurs protokolliert, sodass der Betreiber die aktive Kombination aus Symbol und Zeitrahmen überprüfen kann.

Parameter

Parameter Beschreibung
TimeFrameName Bevorzugter Zeitrahmencode (M1, M5, M15, M30, H1, H4, D1, W1). Standardmäßig ist M15.
SecurityId Optionaler Bezeichner des zu steuernden Instruments. Lassen Sie das Feld leer, um die Eigenschaft Security der Strategie zu verwenden.
AutoLookupSecurity Bei true löst die Strategie SecurityId bis SecurityProvider auf. Deaktivieren Sie es, um die bereits zugewiesene Sicherheit unverändert zu übernehmen.
DefaultCandleType Fallback DataType wird verwendet, wenn ein unbekannter Zeitrahmen eingegeben wird. Standardmäßig werden Ein-Minuten-Kerzen verwendet.

Arbeitsablauf

  1. Start-up – am OnStarted legt die Strategie das Zielwertpapier und den Zielzeitraum fest und beginnt dann ein Kerzenabonnement für diese Kombination.
  2. Laufzeitanpassungen – Wenn Sie TimeFrameName, SecurityId oder AutoLookupSecurity ändern, während die Strategie ausgeführt wird, wird das Abonnement mit den neuen Einstellungen neu gestartet.
  3. Kerzenverarbeitung – jede fertige Kerze aktualisiert die Eigenschaft LastFinishedCandle und schreibt einen Protokolleintrag mit der Sicherheitskennung, dem Zeitrahmencode und dem Schlusskurs.
  4. Herunterfahren – Abonnements werden während OnStopped oder immer dann gestoppt, wenn die Strategie sie neu erstellen muss, weil sich Parameter geändert haben.

Nutzungstipps

  • Kombinieren Sie die Strategie mit einem Diagramm-Widget in StockSharp Designer, um den MT4-Panel-Workflow zu reproduzieren. Parametereditoren fungieren als Schaltflächen/Kombinationen.
  • Lassen Sie SecurityId leer, wenn der Host der Strategieinstanz bereits ein Security zuweist.
  • Die Protokollausgabe kann mit einem UI-Label oder einer Konsole verbunden werden, um die Informationslabels des Originalskripts zu imitieren.

Unterschiede zur MQL-Version

  • Keine grafischen Schaltflächen; Stattdessen werden Parameteränderungen verwendet.
  • Es werden keine Handelsaktionen gesendet – die Logik beschränkt sich auf die Verwaltung und Protokollierung von Datenabonnements.
  • Die Zeitrahmenliste ist mit der des Originalpanels identisch und sorgt so für ein vertrautes Verhalten für Händler, die von MT4 migrieren.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Trading Panel Control strategy: Williams %R crossover.
/// Buys when Williams %R crosses above -80, sells when crosses below -20.
/// </summary>
public class TradingPanelControlStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _prevWr;
	private int _candlesSinceTrade;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int Period { get => _period.Value; set => _period.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public TradingPanelControlStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_period = Param(nameof(Period), 14)
			.SetGreaterThanZero()
			.SetDisplay("Period", "Williams %R period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevWr = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevWr = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
		var wr = new RelativeStrengthIndex { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(wr, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (_hasPrev)
		{
			if (_prevWr < 35 && wrValue >= 35 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevWr > 65 && wrValue <= 65 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevWr = wrValue;
		_hasPrev = true;
	}
}