Auf GitHub ansehen

XAng Zad C TM MM Rec Strategie

Überblick

Diese Strategie ist ein C#-Port des MetaTrader-Expert-Advisors Exp_XAng_Zad_C_Tm_MMRec. Sie handelt adaptive Preisenvelopes, die vom benutzerdefinierten XAng Zad C-Indikator berechnet werden, und fügt ein zeitbasiertes Handelsfenster zusammen mit einem einfachen Money-Management-Zähler hinzu. Das Ziel ist, Ausbrüche zu erfassen, wenn die adaptiven oberen und unteren Linien sich kreuzen, während die Positionsgröße nach einer konfigurierbaren Anzahl verlierender Trades dynamisch skaliert wird.

Kernlogik

  • Indikator – der XAng Zad C-Indikator erzeugt einen adaptiven oberen und unteren Kanal. Die C#-Version reproduziert die Envelope-Berechnung und unterstützt mehrere Moving-Average-Glätter (SMA, EMA, SMMA, LWMA). Exotische Glätter aus dem ursprünglichen Skript fallen auf EMA zurück.
  • Einstiegssignale – wenn die vorherige Kerze zeigt, dass die obere Linie über der unteren liegt, und die aktuelle Kerze mit der oberen Linie unter der unteren schließt, wird ein bullischer Ausbruch erkannt. Die entgegengesetzte Konfiguration erzeugt einen bärischen Ausbruch. Der Parameter SignalShift definiert, wie viele geschlossene Kerzen zurück verglichen werden sollen.
  • Ausstiegssignale – optionale Flags ermöglichen das Schließen von Long-Positionen, wenn die obere Linie wieder unter die untere fällt, und das Schließen von Short-Positionen bei umgekehrtem Ereignis. Positionen werden auch sofort geschlossen, wenn das konfigurierte Handelsfenster endet.
  • Money-Management – die Strategie führt eine Liste historischer Trade-Ergebnisse. Wenn die jüngsten BuyLossTrigger (oder SellLossTrigger) Verlust-Trades innerhalb der letzten BuyTotalTrigger (oder SellTotalTrigger) Trades erscheinen, verwendet die nächste Position das reduzierte Volumen. Andernfalls wird das normale Volumen wiederhergestellt.
  • Risikokontrolle – statische Stop-Loss- und Take-Profit-Ziele werden in Vielfachen des Instrument-Preis-Schritts angewendet. Wenn ein Niveau während der Kerze erreicht wird, wird die Position zum entsprechenden Preis geglättet.

Parameter

Name Beschreibung
NormalVolume Standard-Ordergröße, die verwendet wird, wenn keine jüngste Verlustserie vorliegt.
ReducedVolume Ordergröße, die nach einer Folge von Verlust-Trades angewendet wird.
BuyTotalTrigger / SellTotalTrigger Anzahl der historischen Trades, die bei der Bewertung des Verlustzählers inspiziert werden.
BuyLossTrigger / SellLossTrigger Erforderliche Verlust-Trades (innerhalb des obigen Fensters), um auf das reduzierte Volumen umzuschalten.
EnableBuyEntries / EnableSellEntries Long- oder Short-Einstiege erlauben.
EnableBuyExit / EnableSellExit Automatische Ausstiegssignale auf Basis von Kanalkreuzungen erlauben.
UseTradingWindow Zeitfilter aktivieren. Außerhalb des Fensters werden alle Positionen geschlossen und keine neuen Orders abgeschickt.
WindowStart / WindowEnd Start- und Endzeiten des täglichen Handelsfensters (UTC). Das Fenster kann Mitternacht überspannen.
StopLoss Stop-Loss-Abstand ausgedrückt in Vielfachen von Security.PriceStep. Auf 0 setzen zum Deaktivieren.
TakeProfit Gewinnziel-Abstand ausgedrückt in Vielfachen von Security.PriceStep. Auf 0 setzen zum Deaktivieren.
SignalShift Anzahl der bereits geschlossenen Kerzen für den Kreuzungsvergleich.
CandleType Kerzendatentyp für den Indikator (Standard: 4-Stunden-Kerzen).
SmoothMethods Moving-Average-Glätter innerhalb des Indikators. Nicht unterstützte Werte verwenden automatisch EMA.
MaLength Glättungslänge für den Indikator.
MaPhase Zusätzlicher Phasenparameter aus dem ursprünglichen Indikator übernommen (derzeit informativ).
Ki Verhältnis, das steuert, wie schnell die adaptiven Envelopes auf Preisänderungen reagieren.
AppliedPrices Preisquelle für den Indikator (Schluss, Eröffnung, Mittelwert usw.).

Hinweise im Vergleich zur MQL5-Version

  • MetaTrader-Money-Management-Helfer stützten sich auf die globale Trade-Historie. Die C#-Version verfolgt abgeschlossene Trades lokal und wendet dieselbe Triggerlogik an.
  • Die Lot-Größe wird direkt als Strategievolumen ausgedrückt. Passen Sie NormalVolume/ReducedVolume an die Zielmenge für Ihre Plattform an.
  • Zeitfenster werden mit TimeSpan-Werten konfiguriert. Wenn WindowStart gleich WindowEnd ist, wird der Handel deaktiviert (entspricht dem Null-Breite-Fenster-Verhalten des ursprünglichen Skripts).
  • Die Strategie geht von vollständigen Positionsumkehrungen aus und behält keine Teilpositionen aus früheren Signalen.
  • Nicht unterstützte Glättungstypen (JJMA, JurX, ParMA, T3, VIDYA, AMA) verwenden standardmäßig EMA. Erwägen Sie, CreateMovingAverage zu erweitern, wenn Sie eine bestimmte Alternative benötigen.

Verwendungstipps

  1. Wählen Sie einen Kerzentyp, der dem Indikator-Zeitrahmen in MetaTrader entspricht (Standard: H4).
  2. Passen Sie Stop-Loss- und Take-Profit-Abstände basierend auf der Instrument-Tick-Größe an, um die punktbasierten Werte des ursprünglichen EA anzunähern.
  3. Optimieren Sie die Money-Management-Trigger, um die Asset-Volatilität und Ihre Risikotoleranz widerzuspiegeln.
  4. Überwachen Sie das Indikatorverhalten auf einem Chart (obere/untere Kanallinien), um zu bestätigen, dass der rekonstruierte Indikator die Erwartungen vor dem Live-Trading erfüllt.
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>
/// XAng Zad strategy using SMA crossover with momentum recovery.
/// </summary>
public class XAngZadCTmMmRecStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal? _prevFast;
	private decimal? _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 XAngZadCTmMmRecStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast SMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow SMA period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(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 ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { 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 fastVal, decimal slowVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		if (_prevFast == null || _prevSlow == null)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fastVal > slowVal;

		_prevFast = fastVal;
		_prevSlow = slowVal;

		if (!prevAbove && currAbove)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		else if (prevAbove && !currAbove)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}
	}
}