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
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.
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.
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.
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.
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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import MoneyFlowIndex
from StockSharp.Algo.Strategies import Strategy
class expert_aml_mfi_strategy(Strategy):
def __init__(self):
super(expert_aml_mfi_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._mfi_period = self.Param("MfiPeriod", 14)
self._mfi_low = self.Param("MfiLow", 40.0)
self._mfi_high = self.Param("MfiHigh", 60.0)
self._prev_candle = None
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def MfiPeriod(self):
return self._mfi_period.Value
@MfiPeriod.setter
def MfiPeriod(self, value):
self._mfi_period.Value = value
@property
def MfiLow(self):
return self._mfi_low.Value
@MfiLow.setter
def MfiLow(self, value):
self._mfi_low.Value = value
@property
def MfiHigh(self):
return self._mfi_high.Value
@MfiHigh.setter
def MfiHigh(self, value):
self._mfi_high.Value = value
def OnReseted(self):
super(expert_aml_mfi_strategy, self).OnReseted()
self._prev_candle = None
def OnStarted2(self, time):
super(expert_aml_mfi_strategy, self).OnStarted2(time)
self._prev_candle = None
mfi = MoneyFlowIndex()
mfi.Length = self.MfiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(mfi, self._process_candle).Start()
def _process_candle(self, candle, mfi_value):
if candle.State != CandleStates.Finished:
return
mfi_val = float(mfi_value)
if self._prev_candle is not None:
avg_body = (abs(float(candle.ClosePrice) - float(candle.OpenPrice))
+ abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))) / 2.0
if avg_body > 0:
prev_bearish = float(self._prev_candle.OpenPrice) > float(self._prev_candle.ClosePrice)
curr_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
closes_near = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bearish and curr_bullish and closes_near and mfi_val < self.MfiLow and self.Position <= 0:
self.BuyMarket()
prev_bullish = float(self._prev_candle.ClosePrice) > float(self._prev_candle.OpenPrice)
curr_bearish = float(candle.OpenPrice) > float(candle.ClosePrice)
closes_near2 = abs(float(candle.ClosePrice) - float(self._prev_candle.ClosePrice)) < avg_body * 0.3
if prev_bullish and curr_bearish and closes_near2 and mfi_val > self.MfiHigh and self.Position >= 0:
self.SellMarket()
self._prev_candle = candle
def CreateClone(self):
return expert_aml_mfi_strategy()