Auf GitHub ansehen

Flat Trend EA-Strategie

Überblick

Flat Trend EA Strategy ist ein StockSharp-Port des MQL5-Expert-Advisors "Flat Trend EA". Der Algorithmus kombiniert den Parabolic SAR-Indikator mit dem Average Directional Index (ADX), um vier Marktzustände zu erkennen: Aufwärtstrend, Abwärtstrend, Ende des Kaufs und Ende des Verkaufs. Die Strategie reagiert nur auf abgeschlossene Kerzen aus dem konfigurierten Zeitrahmen und spiegelt die ursprüngliche Logik wider, entgegengesetzte Positionen zu schließen, bevor eine neue eröffnet wird.

Handelslogik

  • Kaufsignal: der Parabolic SAR-Punkt druckt unter dem Schlusskurs und die ADX +DI-Linie liegt über der -DI-Linie. Jede Short-Exposition wird sofort geschlossen, und ein neues Long wird eröffnet, wenn keine Position aktiv ist.
  • Verkaufssignal: der Parabolic SAR-Punkt druckt über dem Schlusskurs und +DI ist kleiner oder gleich -DI. Jede Long-Exposition wird geschlossen, bevor ein Short-Trade eröffnet wird.
  • Trendende-Filter: wenn der SAR über dem Preis liegt, während +DI größer als -DI ist, markiert die Strategie das Ende eines Short-Trends; wenn SAR unter dem Preis liegt, während +DI kleiner oder gleich -DI ist, markiert es das Ende eines Long-Trends. Beide Ereignisse erzwingen das Schließen bestehender Positionen ohne Eröffnung eines neuen Trades.
  • Handelsfenster: optionale Sitzungsfilter beschränken Einstiege auf das Intervall [StartHour, EndHour). Signale außerhalb der Sitzung können Trades noch schließen, aber neue Einstiege werden übersprungen.

Risikomanagement

  • Stop-Loss und Take-Profit-Abstände werden in Pips gemessen (automatisch für drei- und fünfstellige Instrumente skaliert). Preise werden auf den Wertpapierschritt normalisiert.
  • Der Trailing Stop aktiviert sich, nachdem die Position mehr als TrailingStopPips + TrailingStepPips gewinnt. Long-Positionen trailern unterhalb des letzten Schlusskurses, Shorts darüber. Wenn Trailing deaktiviert ist, bleibt das Stop-Niveau fest.
  • Schutzausstiege: bei jeder abgeschlossenen Kerze prüft die Strategie Tief-/Hochpreise gegen Stop-Loss-, Take-Profit- und Trailing-Niveaus. Jede Verletzung schließt die Position und setzt die Risikoverfolgung zurück.

Parameter

  • StopLossPips – Abstand zum Schutz-Stop in Pips.
  • TakeProfitPips – Abstand zum Ziel in Pips.
  • TrailingStopPips – Trailing-Stop-Abstand in Pips (auf 0 setzen um Trailing zu deaktivieren).
  • TrailingStepPips – zusätzlicher Fortschritt erforderlich bevor der Trailing Stop bewegt wird; muss positiv sein wenn Trailing aktiviert ist.
  • UseTradingHours – aktiviert den Handelsfenster-Filter.
  • StartHour / EndHour – inklusive Startstunde und exklusive Endstunde für Einstiege (Börsenzeit).
  • AdxPeriod – Glättungsperiode für ADX, die die +DI- und -DI-Empfindlichkeit steuert.
  • SarStart, SarIncrement, SarMaximum – Parabolic SAR-Beschleunigungseinstellungen entsprechend dem ursprünglichen Indikator (0.02 / 0.02 / 0.2 standardmäßig).
  • CandleType – Zeitrahmen für Kerzen-Abonnements und Indikatorberechnungen.
  • Volume – von Strategy geerbt, repräsentiert die Ordergröße beim Einstieg in neue Positionen.

Indikatoren

  • Average Directional Index (ADX) liefert die +DI- und -DI-Komponenten zur Bestimmung der aktuellen Trendrichtung.
  • Parabolic SAR definiert ob die Marktstruktur bullisch oder bärisch ist und liefert das Punkt-Niveau für die Trailing-Logik.

Weitere Hinweise

  • Die Pip-Größe wird aus den Wertpapiereinstellungen berechnet: Für drei- und fünfstellige Instrumente wird der Preisschritt mit zehn multipliziert, um die MQL-Definition eines Pips zu entsprechen.
  • Die Strategie schließt immer bestehende Positionen, wenn entgegengesetzte oder Endsignale erscheinen, bevor neue Einstiege ausgewertet werden, und reproduziert den ursprünglichen EA-Workflow.
  • Nur die C#-Implementierung wird bereitgestellt; keine Python-Version oder -Ordner wird wie gewünscht erstellt.
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>
/// Flat Trend EA strategy. Uses DEMA crossover to distinguish flat from trend.
/// </summary>
public class FlatTrendEaStrategy : 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 FlatTrendEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

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

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow DEMA", "Slow DEMA 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 DoubleExponentialMovingAverage { Length = FastPeriod };
		var slow = new DoubleExponentialMovingAverage { 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 && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (prevAbove && !currAbove && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
	}
}