Auf GitHub ansehen

Exp XHullTrend Digit Strategie

Überblick

  • Konvertierung des MQL5-Experten Exp_XHullTrend_Digit.mq5 aus MQL/22117.
  • Verwendet die StockSharp High-Level-API mit dem benutzerdefinierten XHullTrendDigitIndicator, der die originale XHullTrend Digit-Logik repliziert.
  • Fokussiert auf mittelfristiges Trendfolgen auf dem konfigurierten Indikator-Zeitrahmen (standardmäßig 8 Stunden).

Indikatorlogik

  1. Der Preis wird aus der ausgewählten Kerzenquelle genommen (standardmäßig Close).
  2. Zwei gleitende Durchschnitte mit den Längen BaseLength und BaseLength / 2 werden mit der gewählten Glättungsmethode berechnet (einfach, exponentiell, geglättet oder gewichtet).
  3. Eine Hull-Projektion 2 * shortMA - longMA wird zweimal geglättet: erst durch SignalLength, dann durch sqrt(BaseLength).
  4. Beide resultierenden Linien werden auf das nächste Vielfache des Instrument-Schritts, skaliert mit 10^RoundingDigits, gerundet, um die Ziffernrundung der MQL5-Version zu imitieren.
  5. Wenn die Rundung gleiche Werte produziert, während sich die Rohwerte unterscheiden, wird die schnellere Linie um einen Schritt in Richtung der Differenz verschoben, damit der Übergang erkennbar bleibt.

Handelsregeln

  • Signale werden nur auf geschlossenen Kerzen ausgewertet.
  • SignalBar definiert, wie viele Bars zurück für die Kreuzerkennung verwendet werden (1 = die vorherige abgeschlossene Bar gegen die Bar davor).
  • Long-Einstieg: Vorherige schnelle Linie über der langsamen und die schnelle Linie der ausgewählten Bar auf oder unter der langsamen (Aufwärtskreuzung). Short-Positionen werden optional gleichzeitig geschlossen.
  • Short-Einstieg: Vorherige schnelle Linie unter der langsamen und die schnelle Linie der ausgewählten Bar auf oder über der langsamen (Abwärtskreuzung). Long-Positionen werden optional gleichzeitig geschlossen.
  • Long-Ausstieg: Wenn die vorherige schnelle Linie unter die langsame fällt.
  • Short-Ausstieg: Wenn die vorherige schnelle Linie über die langsame steigt.
  • Erscheint ein Umkehrsignal bei einer Gegenposition, sendet die Strategie den Schließauftrag gefolgt von einem Auftrag, der die Position in die neue Richtung umdreht.

Parameter

  • OrderVolume – Volumen für Markteinstiege.
  • StopLoss / TakeProfit – optionale Schutzabstände in Preisschritten (konvertiert zu StockSharp UnitTypes.Step).
  • EnableBuyEntry, EnableSellEntry – neue Positionen in jeder Richtung erlauben oder blockieren.
  • EnableBuyExit, EnableSellExit – automatische Ausstiege für Long- und Short-Seiten steuern.
  • CandleType – Zeitrahmen für Indikatorberechnungen (standardmäßig 8-Stunden-Zeitrahmen).
  • BaseLength – Basis-Glättungslänge für den Indikator (entspricht XLength in MQL5).
  • SignalLength – Länge der intermediären Hull-Glättung (HLength in MQL5).
  • PriceSource – für Berechnungen verwendeter Kerzenpreis (Close/Open/High/Low/Typical/Weighted/Median/Average).
  • SmoothMethod – gleitender Durchschnittstyp für alle Glättungsstufen (einfach, exponentiell, geglättet, gewichtet).
  • Phase – für Kompatibilität beibehalten; kein Effekt bei den unterstützten Glättungstypen.
  • RoundingDigits – Anzahl zusätzlicher Ziffernkorrekturen beim Runden.
  • SignalBar – Bar-Offset für Signalauswertung (0 = aktuelle geschlossene Bar, 1 = vorherige Bar, etc.).

Risikomanagement

  • Optionaler Stop-Loss und Take-Profit werden vom eingebauten StartProtection-Helper mit schrittbasierten Abständen verwaltet.
  • Das Volumen kann über OrderVolume angepasst werden, um der Zielinstrumentgröße zu entsprechen.

Hinweise

  • Der benutzerdefinierte Indikator reproduziert das Rundungsverhalten des Originalskripts; stellen Sie sicher, dass Security.PriceStep für genaues Runden konfiguriert ist.
  • Nur SMA, EMA, SMMA (RMA) und LWMA-Glättung sind implementiert, da die StockSharp-Standardbibliothek diese von Haus aus bietet. Andere exotische Glättungsmodi aus der MQL5-Quelle können bei Bedarf später hinzugefügt werden.
  • Funktioniert auf jedem Instrument, das Kerzen für den gewählten Zeitrahmen liefert. Passen Sie Rundungsziffern und Basislänge an, wenn Sie zwischen Assets mit unterschiedlichen Tick-Größen wechseln.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

public class ExpXHullTrendDigitStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private decimal? _prevFast, _prevSlow;

	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 ExpXHullTrendDigitStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 9).SetGreaterThanZero().SetDisplay("Fast WMA", "Fast period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 25).SetGreaterThanZero().SetDisplay("Slow WMA", "Slow period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = null; _prevSlow = null;
		var fast = new WeightedMovingAverage { Length = FastPeriod };
		var slow = new WeightedMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
		if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fast > slow;
		_prevFast = fast; _prevSlow = slow;
		if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
	}
}