Auf GitHub ansehen

Strategie MultiTimeframeEmaAlignmentStrategy

Überblick

Die MultiTimeframeEmaAlignmentStrategy ist ein StockSharp-Port des MetaTrader 4 Expert Advisors 1h-4h-1d.mq4 aus dem Ordner MQL/7713. Der ursprüngliche Roboter gleicht schnelle und langsame exponentielle gleitende Durchschnitte über drei Zeitrahmen an und wendet ein schützendes Geldmanagement über feste Stop-Loss-, Take-Profit- und Trailing-Stop-Levels an. Diese C#-Version folgt der gleichen Grundidee und nutzt dabei die Indikatorbindungen und Ordnungshelfer von StockSharp.

Handelslogik

  • Die Strategie abonniert gleichzeitig drei Kerzenserien: M1 (Signalzeitrahmen), M5 (Mittelfristfilter) und M30 (Trendbestätigung mit höherem Zeitrahmen).
  • Jede Serie speist ein Paar exponentieller gleitender Durchschnitte (EMA) mit konfigurierbaren Längen (Standard 8 und 64).
  • Ein bullisches Setup erfordert, dass der schnelle EMA in allen drei Zeitrahmen über dem langsamen EMA bleibt. Außerdem darf der schnelle EMA nicht an Schwung verlieren (aktueller Wert größer oder gleich dem vorherigen Wert und auch über dem Wert vor ShiftDepth Balken).
  • Ein bärisches Setup erfordert, dass der schnelle EMA in allen drei Zeitrahmen unter dem langsamen EMA bleibt, wobei der schnelle EMA an Dynamik verliert.
  • Aufträge werden beim Schließen der M1-Kerze ausgelöst, wenn die Ausrichtungs- und Momentumprüfungen erfüllt sind. Long-Signale sind nur zulässig, wenn keine Long-Position offen ist (oder ein bestehender Short zuerst geschlossen wird) und umgekehrt.

Diese Interpretation stellt die Absicht der MT4-Bedingungen mit dem übergeordneten API von StockSharp wieder her. Die MQL „MA-Shift“-Vergleiche werden durch den ShiftDepth-Puffer emuliert, der EMA-Werte ein paar Kerzen zurückverfolgt und sicherstellt, dass die Dynamik mit der Einstiegsrichtung übereinstimmt.

Risikomanagement

  • Die Positionsgröße wird durch den Parameter TradeVolume gesteuert (standardmäßig 3 Lots wie beim Original EA).
  • Optionale Stop-Loss- und Take-Profit-Abstände werden in Pips angegeben. Sie werden über den PriceStep des Instruments in Preise umgewandelt (fällt bei Fehlen auf 0.0001 zurück).
  • Der Trailing-Stop reproduziert das Verhalten von EA, indem er den Stop-Preis immer dann näher an den Markt verschiebt, wenn der Handel weit genug voranschreitet.
  • Risikoparameter können unabhängig voneinander umgeschaltet werden und entsprechen den Flags StopLossMode, TakeProfitMode und TrailingStopMode aus dem Skript MQL.

Parameter

Parameter Beschreibung Standard
TradeVolume Bestellvolumen, das von BuyMarket / SellMarket verwendet wird. Spiegelt die Eingabe Lots. 3
FastLength EMA Zeitraum für die Schnellleitung. 8
SlowLength EMA Zeitraum für die langsame Leitung. 64
ShiftDepth Anzahl der historischen Kerzen, die zur Emulation der MQL gleitenden Durchschnittsverschiebungsvergleiche verwendet werden. 3
UseStopLoss Ermöglicht einen festen Stop-Loss. true
StopLossPips Stop-Loss-Distanz, ausgedrückt in Pips. 75
UseTakeProfit Ermöglicht Take-Profit. true
TakeProfitPips Take-Profit-Distanz, ausgedrückt in Pips. 150
UseTrailingStop Aktiviert die Trailing-Stop-Verwaltung. true
TrailingStopPips Nachlaufdistanz in Pips. 30
M1CandleType Kerzentyp für den Signalzeitrahmen (Standard 1 Minute). 1m
M5CandleType Kerzentyp für den Halbzeitfilter (Standard 5 Minuten). 5m
M30CandleType Kerzentyp für den höheren Zeitrahmen (Standard 30 Minuten). 30m

Nutzungshinweise

  1. Hängen Sie die Strategie an ein Instrument an und stellen Sie sicher, dass historische Daten für alle drei Zeitrahmen verfügbar sind, damit die EMA-Puffer gefüllt werden können.
  2. Der Parameter ShiftDepth sollte mindestens 2 betragen, damit die Strategie die kurzfristige Dynamik validieren kann.
  3. Wenn UseTrailingStop ohne UseStopLoss aktiv ist, initialisiert die abschließende Logik immer noch einen Stoppwert, sobald sich der Handel positiv entwickelt.
  4. Da StockSharp bei Kerzenschluss ausgeführt wird, können die Ergebnisse leicht von der Tick-für-Tick-Ausführung der MT4-Version abweichen, insbesondere auf volatilen Märkten. Das zentrale Trendausrichtungsverhalten bleibt erhalten.

Konvertierungshinweise

  • Indikatorberechnungen basieren ausschließlich auf dem Bind-Mechanismus von StockSharp; Es werden keine manuellen Indikatorverlaufssammlungen verwendet.
  • Die Auftragsverwaltung wird mit High-Level-Helfern (BuyMarket, SellMarket) und interner Preisverfolgung anstelle direkter OrderSend-Aufrufe implementiert.
  • E-Mail-Benachrichtigungen und Slippage-Kontrollen aus dem MQL-Skript werden weggelassen, da sie außerhalb des Geltungsbereichs von StockSharp liegen.

Dateien

  • CS/MultiTimeframeEmaAlignmentStrategy.cs – Hauptimplementierung der C#-Strategie.
  • README_ru.md – Russische Dokumentation.
  • README_zh.md – Chinesische Dokumentation.
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>
/// Multi-Timeframe EMA Alignment strategy - fast/slow EMA crossover with trend EMA filter.
/// Buys when fast EMA crosses above slow EMA while close is above trend EMA.
/// Sells when fast EMA crosses below slow EMA while close is below trend EMA.
/// </summary>
public class MultiTimeframeEmaAlignmentStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _trendPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int TrendPeriod { get => _trendPeriod.Value; set => _trendPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public MultiTimeframeEmaAlignmentStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_trendPeriod = Param(nameof(TrendPeriod), 100)
			.SetDisplay("Trend EMA", "Trend EMA period", "Indicators");

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

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

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

		_hasPrev = false;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var trend = new ExponentialMovingAverage { Length = TrendPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, trend, ProcessCandle)
			.Start();
	}

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

		var close = candle.ClosePrice;

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_hasPrev = true;
			return;
		}

		if (_prevFast <= _prevSlow && fast > slow && close > trend && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (_prevFast >= _prevSlow && fast < slow && close < trend && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}