Auf GitHub ansehen

Advanced EA Panel-Strategie

Diese Strategie ist ein StockSharp-Port des Advanced EA Panel-Dienstprogramms aus MQL5. Der ursprüngliche Expertenberater stellte ein manuelles Trading-Dashboard mit Multi-Zeitrahmen-Analysen, Pivot-Verwaltung und Schnellhandelsschaltflächen bereit. Die C#-Implementierung recreiert diese analytischen Fähigkeiten innerhalb einer automatisierten Strategie, damit sie ohne ein On-Chart-Bedienpanel verfügbar bleiben.

Hauptmerkmale

  • Aggregiert neun Zeitrahmen (M1 … MN1) und verfolgt EMA(3/6/9)-, SMA(50/200)-, CCI(14)- und RSI(21)-Stimmen für jeden Horizont.
  • Berechnet Floor-Trader-, Woodie- oder Camarilla-Pivot-Niveaus auf einer konfigurierbaren Kerzenserie.
  • Überwacht die Volatilität mit einem ATR-Feed und protokolliert jede bedeutende Änderung.
  • Führt ein internes Risikopanel durch Berechnung von Stop-Abstand, Reward-Abstand und Live-Risiko/Reward-Verhältnis für die aktive Position.
  • Unterstützt automatische Orderausführung, wenn die Multi-Zeitrahmen-Stimme einen konfigurierbaren Schwellenwert überschreitet. Gegenläufige Trades werden vor der Umkehr geschlossen, genau wie beim Drücken der Panel-Schaltflächen.
  • Nutzt StartProtection, damit Stop-Loss- und Take-Profit-Wächter Neustarts überleben und die Schutzlogik des ursprünglichen Panels widerspiegeln.

Handelslogik

  1. Jedes Zeitrahmen-Abonnement produziert Indikatorwerte für EMA(3/6/9), SMA(50/200), CCI(14) und RSI(21). Eine bullische Stimme wird hinzugefügt, wenn der Schlusskurs über den gleitenden Durchschnitten liegt, CCI über +100 ist und RSI über 60 liegt. Bärische Stimmen werden für entgegengesetzte Bedingungen erzeugt. Neutrale Werte tragen nicht zur Punktzahl bei.
  2. Die Gesamtpunktzahl über bereite Zeitrahmen wird mit DirectionalThreshold verglichen. Punkte ≥ Schwellenwert erzeugen ein Kauf-Signal; Punkte ≤ –Schwellenwert erzeugen ein Verkauf-Signal.
  3. Wenn der automatische Handel aktiviert ist, wird die Strategie:
    • Die entgegengesetzte Position mit ClosePosition() schließen, bevor die Umkehrorder gesendet wird.
    • Eine Marktorder senden, die nach Volume dimensioniert und auf den nächsten Security.VolumeStep gerundet ist.
    • Sich auf StartProtection stützen, um Stop-Loss/Take-Profit-Brackets in Pips anzufügen.
  4. ATR aus der primären Kerzenserie wird protokolliert. Jede Änderung über die Rundungspräzision hinaus gibt einen neuen Volatilitätsbericht aus.
  5. Pivot-Niveaus werden neu berechnet, wenn der Pivot-Zeitrahmen eine abgeschlossene Kerze produziert. Das Protokoll zeigt PP, R1–R4 und S1–S4, damit sie als diskretionäre Niveaus oder für Dashboards verwendet werden können.

Parameter

Name Beschreibung Gruppe Standard
Volume Handelsvolumen in Lots. Vor dem Senden von Orders auf VolumeStep gerundet. Handel 1.0
StopLossPips Abstand vom Einstieg zum Stop-Loss in Preisschritten. 0 deaktiviert den Stop. Risiko 50
TakeProfitPips Abstand vom Einstieg zum Take-Profit in Preisschritten. 0 deaktiviert den Take. Risiko 100
VolatilityPeriod ATR-Lookback-Länge für die Volatilitätsprotokollierung. Volatilität 14
PrimaryCandleType Kerzentyp für ATR-Berechnungen und Chart-Zeichnung. Allgemein 15-Minuten-Kerzen
PivotCandleType Kerzentyp für die Pivot-Neuberechnung. Allgemein 1-Stunden-Kerzen
DirectionalThreshold Absoluter Score zum Auslösen eines Kauf/Verkauf-Signals. Signale 3
AutoTradingEnabled Aktiviert die automatische Ausführung erkannter Signale. Signale true
PivotFormula Pivot-Preset (Classic, Woodie, Camarilla). Allgemein Classic

Risikomanagement

  • StartProtection fügt preisbasierte Brackets an, berechnet aus StopLossPips und TakeProfitPips (in absoluten Preis über PriceStep umgerechnet).
  • _entryPrice, _stopPrice und _takePrice werden bei Fills aktualisiert, damit die Strategie Risiko, Reward und Risiko/Reward-Verhältnis in Pips protokollieren kann.
  • Wenn der automatische Handel deaktiviert ist, arbeitet der Risikomonitor weiterhin für manuell außerhalb der Strategie ausgeführte Eintritte.

Unterschiede zum MQL5-Panel

  • Der ursprüngliche EA zeigte Schaltflächen und ziehbare Linien auf dem Chart; die StockSharp-Version exponiert dieselbe Analyse über Protokolle und Strategieparameter. Alle Kommentare im Code erklären, wie die Ergebnisse in eine UI erweitert oder eingehakt werden können.
  • Das Positionsmanagement ist automatisiert. Klicken auf Kaufen, Verkaufen, Umkehren oder Schließen wird durch RequestExecution, SendOrder und ClosePosition() in Reaktion auf den Multi-Zeitrahmen-Score ersetzt.
  • Points of Interest, manuelle Tab-Bearbeitungen und Chart-Objektmanipulation sind nicht portiert. Stattdessen werden Pivots programmatisch neu berechnet und protokolliert. Trader können das Protokoll nutzen oder die Strategie um Chart-Objekte erweitern.
  • Volatilität, Risikometriken und Pivots bleiben über Neustarts hinaus erhalten, da sie aus Live-Daten statt aus Chart-Objekten neu berechnet werden.

Nutzungshinweise

  1. Hängen Sie die Strategie an ein Symbol und stellen Sie sicher, dass der Connector alle in PanelTimeFrames aufgeführten Kerzentypen liefert. Fehlende Daten verzögern die Signalerstellung, bis mindestens eine Kerze pro Zeitrahmen abgeschlossen ist.
  2. Passen Sie DirectionalThreshold an, um die Empfindlichkeit zu steuern. Höhere Schwellenwerte erfordern mehr Übereinstimmung über Zeitrahmen vor dem Handeln.
  3. Setzen Sie AutoTradingEnabled = false, um das Modul als Informations-Dashboard zu nutzen und Orders manuell von einem anderen Tool zu platzieren.
  4. Die Klasse fügt Standard-Chart-Rendering für primäre Kerzen, ATR und eigene Trades hinzu. Entfernen oder erweitern Sie diese Aufrufe wenn eine benutzerdefinierte Visualisierung erforderlich ist.

Konvertierungszusammenfassung

  • UI-Aktionen → Strategiemethoden. Panel-Button-Handler (EAPanelClickHandler, T0ClickHandler usw.) werden auf Order-Ausführungshelfer abgebildet, die den Kauf/Verkauf/Umkehren/Schließen-Fluss bewahren.
  • Pivot-Formeln. Die MQL5-Spinner erlaubten unabhängige Formeln pro Niveau; dieser Port behält die Preset-Kombinationen (Classic, Woodie, Camarilla) bei, die das Panel über seine Schnellauswahl-Schaltflächen anbot.
  • Indikator-Tracking. Native MQL5-Indikator-Handles werden durch ExponentialMovingAverage, SimpleMovingAverage, CommodityChannelIndex und RelativeStrengthIndex aus StockSharp mit Bind-Callbacks ersetzt.
  • Risikopanel. Alle Risiko/Reward-Berechnungen, die früher in Editfeldern gerendert wurden, werden jetzt protokolliert und können von jeder Überwachungskomponente verbraucht werden.

Die Strategie bewahrt daher die Intention des Advanced EA Panel—zentralisiertes situatives Bewusstsein mit schneller Reaktionslogik—und präsentiert sich als vollständig automatisierte StockSharp-Strategie, die für Optimierung oder diskretionäre Überwachung bereit ist.

using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Advanced EA Panel strategy using EMA crossover.
/// Buys when fast EMA crosses above slow EMA, sells on reverse.
/// </summary>
public class AdvancedEaPanelStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _stopLossPoints;
	private readonly StrategyParam<int> _takeProfitPoints;

	private ExponentialMovingAverage _fast;
	private ExponentialMovingAverage _slow;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;
	private int _cooldown;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
	public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }

	public AdvancedEaPanelStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
		_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_fast = null; _slow = null;
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_fast = new ExponentialMovingAverage { Length = FastPeriod };
		_slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
		subscription.Bind(_fast, _slow, ProcessCandle);
		subscription.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
		if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }

		var close = candle.ClosePrice;
		var step = Security?.PriceStep ?? 1m;

		if (Position > 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}
		else if (Position < 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}

		if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
		{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
		else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
		{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }

		_prevFast = fastValue; _prevSlow = slowValue;
	}
}