Auf GitHub ansehen

ENewsLuckyw-Strategie

Überblick

Die ENewsLuckyw-Strategie ist ein zeitbasiertes Breakout-System, das vom MetaTrader-Expertenberater e-News-Lucky$ abgeleitet wurde. Zu einem geplanten Zeitpunkt übermittelt es Kauf-Stopp- und Verkaufs-Stopp-Aufträge rund um den aktuellen Preis, richtet sie kontinuierlich neu aus, während beide Aufträge aktiv sind, und führt ein Positionsmanagement durch, das die ursprüngliche MQL-Logik nachahmt. Schutzexits, optionales Trailing und eine Bereinigung am Tagesende runden den Workflow ab.

Handelslogik

  • Geplante Straddle-Platzierung. Bei SetOrdersTime storniert die Strategie alle verbleibenden ausstehenden Orders, misst den aktuellen Kerzenschluss und platziert symmetrische Stop-Orders bei DistancePips vom Marktpreis.
  • Kontinuierliche Auftragsaktualisierung. Wenn beide ausstehenden Aufträge aktiv sind, werden sie bei jeder fertigen Kerze neu ausgerichtet, sodass der Straddle auf dem Preis zentriert bleibt, wie es der ursprüngliche Experte bei jedem neuen Balken getan hat.
  • Einstiegsvorbereitung. Stop-Loss- und optionale Take-Profit-Level werden vorberechnet, sodass sie sofort bei Eröffnung einer Position angehängt werden können. Gegenüberliegende ausstehende Aufträge werden entfernt, sobald eine Position erscheint.
  • Trailing-Schutz. Wenn UseTrailing aktiviert ist, verschiebt sich die Stop-Order um TrailingStopPips, wenn die Position um mindestens TrailingStepPips vorgerückt ist. Wenn ProfitTrailing aktiviert ist, beginnt das Trailing erst, wenn der Gewinn die Trailing-Distanz überschreitet, was den MQL-Schalter „ProfitTrailing“ repliziert.
  • Sitzungsbereinigung. Am DeleteOrdersTime werden alle ausstehenden Aufträge storniert und alle offenen Positionen geschlossen, um zu vermeiden, dass das Risiko über Nacht gehalten wird.

Parameter

Name Beschreibung
Volume Ordervolumen in Lots, das für beide Stop-Orders verwendet wird.
StopLossPips Schutzanschlagabstand. Null deaktiviert den Stopp.
TakeProfitPips Optionale Take-Profit-Distanz. Null deaktiviert das Ziel.
DistancePips Offset vom aktuellen Preis für die Breakout-Stop-Orders.
UseTrailing Ermöglicht das Stoppen des Trailings, sobald die Position geöffnet ist.
ProfitTrailing Erfordert, dass der nicht realisierte Gewinn die Trailing-Distanz überschreitet, bevor der Stop verschoben wird.
TrailingStopPips Abstand zwischen Preis und Trailing Stop.
TrailingStepPips Minimale Verbesserung erforderlich, bevor der Trailing Stop erneut aktualisiert wird.
SetOrdersTime Tageszeit, zu der der Straddle platziert wird.
DeleteOrdersTime Tageszeit für die Stornierung von Aufträgen und die Schließung von Positionen.
CandleType Kerzenabonnement zur Zeiterfassung und Auftragsverwaltung.

Nutzungshinweise

  1. Hängen Sie die Strategie an das gewünschte Instrument an und konfigurieren Sie CandleType so, dass es der Balkengröße entspricht, die Sie für die Wartung verwenden möchten (die Standardeinstellung sind 1-Minuten-Kerzen).
  2. Legen Sie die Zeitplanparameter fest, um sie an Ihr Nachrichtenereignis oder Ihre Handelssitzung anzupassen.
  3. Passen Sie Abstände und Risikokontrollen entsprechend der Instrumentenvolatilität an. Stellen Sie bei Forex-Symbolen sicher, dass der Preisschritt richtig konfiguriert ist, sodass StopLossPips, TakeProfitPips und DistancePips in die erwarteten Preisversätze übersetzt werden.
  4. Das Trailing-System verwendet Stop- und Limit-Orders für Exits. Wenn Ihr Veranstaltungsort diese Ordertypen nicht unterstützt, ersetzen Sie sie durch Marktaustritte oder simulierte Orders, bevor Sie live gehen.
  5. Die Strategie führt eine tägliche Zurücksetzung nach Datum durch. Wenn Sie es über Mitternacht in der Zeitzone der Börse ausführen, stellen Sie sicher, dass die Handelssitzung einen einzigen Handelstag umfasst.

Konvertierungshinweise

  • Die Strategie spiegelt den Arbeitsablauf des MQL-Experten wider: geplante Platzierung (SetOrders), stündliche Wartung (ModifyOrders), Entfernung widersprüchlicher ausstehender Bestellungen (DeleteOppositeOrders), nachgestellte Logik (TrailingPositions) und Bereinigung am Ende des Tages.
  • Spread-bewusste Preisberechnungen aus dem MQL-Code werden anhand des letzten Kerzenschlusses angenähert, da StockSharp die Preise auf den PriceStep des Instruments normalisiert.
  • Alle Ton-, Kontonummern- und Farbeinstellungen aus dem ursprünglichen Skript wurden weggelassen, da sie in StockSharps High-Level-API keine Entsprechung haben.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// ENews Lucky strategy - momentum breakout with ATR filter.
/// Buys when close breaks above recent high with strong momentum.
/// Sells when close breaks below recent low with strong momentum.
/// </summary>
public class ENewsLuckywStrategy : Strategy
{
	private readonly StrategyParam<int> _channelPeriod;
	private readonly StrategyParam<int> _momentumPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevMid;
	private bool _hasPrev;

	public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
	public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public ENewsLuckywStrategy()
	{
		_channelPeriod = Param(nameof(ChannelPeriod), 15)
			.SetDisplay("Channel Period", "Highest/Lowest period", "Indicators");

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

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevClose = 0m; _prevMid = 0m; _hasPrev = false; }

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var highest = new Highest { Length = ChannelPeriod };
		var lowest = new Lowest { Length = ChannelPeriod };
		var momentum = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(highest, lowest, momentum, ProcessCandle)
			.Start();
	}

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

		var close = candle.ClosePrice;
		var mid = (highest + lowest) / 2;

		if (!_hasPrev)
		{
			_prevClose = close;
			_prevMid = mid;
			_hasPrev = true;
			return;
		}

		// Breakout above midpoint with positive momentum
		if (_prevClose <= _prevMid && close > mid && momentum > 0 && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Breakout below midpoint with negative momentum
		else if (_prevClose >= _prevMid && close < mid && momentum < 0 && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevClose = close;
		_prevMid = mid;
	}
}