Auf GitHub ansehen

Experten-AML-MFI-Strategie

Überblick

Die Expert AML MFI Strategy repliziert den MetaTrader 5 Expert Advisor „Expert_AML_MFI“ unter Verwendung des StockSharp High-Level API. Es konzentriert sich auf das Kerzenmuster Meeting Lines und validiert jedes Signal mit dem Oszillator Money Flow Index (MFI). Die Strategie verwaltet automatisch die erforderlichen Kerzenstatistiken, identifiziert bullische oder bärische Umkehrungen und verwaltet offene Positionen, wenn der MFI überverkaufte oder überkaufte Schwellenwerte überschreitet.

Handelslogik

  1. Kerzenvorbereitung – die Strategie abonniert den ausgewählten Zeitrahmen (standardmäßig H1) und behält die letzten beiden abgeschlossenen Kerzen zusammen mit dem gleitenden Durchschnitt der Kerzenkörper bei. Die durchschnittliche Körpergröße wird durch Anwendung eines SimpleMovingAverage auf die absolute Kerzenkörpergröße berechnet, was die MT5-Implementierung widerspiegelt.
  2. Mustererkennung – zwei spezialisierte Helfer erkennen Bullish Meeting Lines und Bearish Meeting Lines:
    • Bullisches Setup: eine lange bärische Kerze, gefolgt von einer langen zinsbullischen Kerze, die in der Nähe des vorherigen Schlusskurses schließt (innerhalb von 10 % des durchschnittlichen Körpers).
    • Bärisches Setup: eine lange bullische Kerze, gefolgt von einer langen bärischen Kerze mit ähnlichen Schlusskursen.
  3. MFI-Bestätigung – der vorherige MFI-Wert muss für Long-Trades unter dem bullischen Einstiegsniveau (Standard 40) oder für Short-Trades über dem bärischen Einstiegsniveau (Standard 60) liegen.
  4. Positionsmanagement – die letzten beiden MFI-Messwerte werden verfolgt, um Überschreitungen der überverkauften (30) und überkauften (70) Ebenen zu erkennen:
    • Ein Kreuz über einem der beiden Niveaus führt zum Ausstieg aus Short-Positionen.
    • Ein Cross unter dem überverkauften Niveau oder über dem überkauften Niveau führt zum Ausstieg aus Long-Positionen.
  5. Auftragsausführung – wenn ein gültiges Muster und eine MFI-Bestätigung vorliegen, schließt die Strategie alle gegenteiligen Engagements und eröffnet eine neue Position zum Markt mit dem konfigurierten Basisvolumen.

Parameter

Name Beschreibung Standard
CandleType Für das Kerzenabonnement verwendeter Zeitrahmen. Zeitrahmen 1 Stunde
MfiPeriod Anzahl der Balken für den MFI-Oszillator. 12
BodyAveragePeriod Fensterlänge für die Berechnung der durchschnittlichen Körpergröße. 4
BullishEntryLevel Maximal zulässiger MFI-Wert für bullische Einstiege. 40
BearishEntryLevel Erforderlicher Mindest-MFI-Wert für rückläufige Einstiege. 60
OversoldLevel Überverkaufter Wert, der für Ausstiegssignale verwendet wird. 30
OverboughtLevel Überkaufter Wert, der für Ausstiegssignale verwendet wird. 70
TradeVolume Auf neue Geschäfte angewendetes Basisauftragsvolumen. 1

Dank der StrategyParam-Wrapper können alle Parameter direkt im StockSharp-Designer optimiert werden.

Indikatoren und Visuals

  • Geldflussindex – zur Bestätigung an das Kerzenabonnement gebunden und auf dem Chart angezeigt, wenn ein Chartbereich verfügbar ist.
  • Einfacher gleitender Durchschnitt der Kerzenkörper – nur für den internen Gebrauch, Reproduktion der MT5-Durchschnittskörperberechnung.

Notizen

  • Die Strategie ruft StartProtection() einmal auf, um integrierte Positionsschutzfunktionen zu aktivieren.
  • Handelsbefehle verwenden die Helfer BuyMarket und SellMarket, um die aktuelle Position zu reduzieren, bevor eine neue eröffnet wird, was dem Verhalten des Expertenberaters MetaTrader entspricht.
  • Gemäß den Projektanforderungen wird kein Python-Port bereitgestellt.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Meeting Lines + MFI strategy.
/// Buys on bullish meeting lines with low MFI, sells on bearish meeting lines with high MFI.
/// </summary>
public class ExpertAmlMfiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _mfiPeriod;
	private readonly StrategyParam<decimal> _mfiLow;
	private readonly StrategyParam<decimal> _mfiHigh;

	private ICandleMessage _prevCandle;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int MfiPeriod { get => _mfiPeriod.Value; set => _mfiPeriod.Value = value; }
	public decimal MfiLow { get => _mfiLow.Value; set => _mfiLow.Value = value; }
	public decimal MfiHigh { get => _mfiHigh.Value; set => _mfiHigh.Value = value; }

	public ExpertAmlMfiStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_mfiPeriod = Param(nameof(MfiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("MFI Period", "MFI period", "Indicators");
		_mfiLow = Param(nameof(MfiLow), 40m)
			.SetDisplay("MFI Low", "MFI level for bullish entry", "Signals");
		_mfiHigh = Param(nameof(MfiHigh), 60m)
			.SetDisplay("MFI High", "MFI level for bearish entry", "Signals");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevCandle = null;
		var mfi = new MoneyFlowIndex { Length = MfiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(mfi, ProcessCandle).Start();
	}

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

		if (_prevCandle != null)
		{
			var avgBody = (Math.Abs(candle.ClosePrice - candle.OpenPrice) +
						   Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice)) / 2m;

			if (avgBody > 0)
			{
				var prevBearish = _prevCandle.OpenPrice > _prevCandle.ClosePrice;
				var currBullish = candle.ClosePrice > candle.OpenPrice;
				var closesNear = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;

				if (prevBearish && currBullish && closesNear && mfiValue < MfiLow && Position <= 0)
					BuyMarket();

				var prevBullish = _prevCandle.ClosePrice > _prevCandle.OpenPrice;
				var currBearish = candle.OpenPrice > candle.ClosePrice;
				var closesNear2 = Math.Abs(candle.ClosePrice - _prevCandle.ClosePrice) < avgBody * 0.3m;

				if (prevBullish && currBearish && closesNear2 && mfiValue > MfiHigh && Position >= 0)
					SellMarket();
			}
		}

		_prevCandle = candle;
	}
}