Auf GitHub ansehen

Beispiel einer Trailing-Stop-Strategie

Überblick

Die SampleTrailingStopStrategy ist eine direkte C#-Portierung des MetaTrader-Expertenberaters SampleTrailingstop.mq4. Die Strategie generiert keine eigenen Einträge; Stattdessen überwacht es kontinuierlich die aktuelle Position und verwaltet schützende Stop-Loss- und Take-Profit-Orders. Die Logik spiegelt die ursprüngliche EA wider, indem sie die vom Broker auferlegten Stop- und Freeze-Levels respektiert und gleichzeitig einen in Preispunkten gemessenen Trailing Stop anwendet.

Immer wenn eine Long-Position profitabel wird und das beste Gebot weit genug vom Einstiegspreis entfernt ist, verschiebt die Strategie den Stop-Loss zunächst um den minimal zulässigen Abstand knapp unter das Gebot. Nachfolgende Aktualisierungen folgen dem Stopp hinter dem Gebot um die konfigurierte Anzahl von Punkten plus Broker-Puffer. Short-Positionen werden symmetrisch abgewickelt, wobei der Stop über der Briefmarke liegt. Optionale Take-Profit-Ziele werden bei jedem nachfolgenden Ereignis neu berechnet.

Datenfluss

  • Abonniert Level1-Updates, um die besten Geld-/Briefkurse zu erhalten.
  • Verfolgt den aktuellen Positionspreis über die Basis Strategy API.
  • Registriert schützende Stop- und Limit-Orders erneut, wenn neue Preise berechnet werden.

Parameter

Parameter Standard Beschreibung
TrailingStopPoints 200 Abstand zwischen dem Markt und dem Trailing Stop, gemessen in Preispunkten. Dieser Wert wird bei nachlaufenden Berechnungen zu den Brokerpuffern hinzugefügt.
TakeProfitPoints 1000 Optionale Take-Profit-Distanz in Punkten. Auf 0 setzen, um die Take-Profit-Verwaltung zu deaktivieren.
StopLevelPoints 0 Beschränkung des Broker-Stop-Levels, ausgedrückt in Punkten. Es wird zur Trailing-Distanz addiert, um die Gültigkeit der Stop-Orders zu gewährleisten.
FreezeLevelPoints 0 Beschränkung des Broker-Einfrierniveaus, ausgedrückt in Punkten. Beim Trailing wird gewartet, bis sich der Markt über diesen Puffer vom Einstiegspreis hinaus bewegt.

Alle Abstände werden mit der Tick-Größe des Instruments in Preiswerte übersetzt, um das _Point-Verhalten von MetaTrader zu emulieren.

Trailing-Algorithmus

  1. Positionsvalidierung – Die Strategie ignoriert das Trailing, bis eine Position existiert und der beste Geld-/Briefkurs bekannt ist.
  2. Gewinnprüfung – Trailing wird nur aktiviert, wenn die Position profitabel ist (bid > entry für Long-Positionen, ask < entry für Short-Positionen) und der Freeze-Puffer gelöscht wurde.
  3. Anfängliche Stop-Platzierung – Wenn noch kein Trailing-Stop aktiv ist, wird der Stop auf den minimal zulässigen Abstand vom Markt verschoben (Geld minus Puffer für Long-Positionen, Briefkurs plus Puffer für Short-Positionen), sobald der Preis mindestens die Trailing-Distanz vom Einstieg entfernt ist.
  4. Trailing-Updates – Während die Position profitabel bleibt, wird der Stop unter Verwendung der konfigurierten Trailing-Distanz plus Broker-Puffer tiefer gedrückt. Bei Aktivierung werden die Take-Profit-Werte bei jedem Update neu berechnet.
  5. Auftragsverwaltung – Schutzaufträge werden automatisch über hochrangige Hilfsmethoden erstellt, aktualisiert oder storniert, sodass der Broker immer die neuesten Stop-Loss- und Take-Profit-Werte sieht.

Nutzungshinweise

  • Starten Sie die Strategie zusammen mit einer anderen Komponente, die Positionen eröffnet, oder verwenden Sie manuelle Aufträge; Dieses Modul verwaltet nur Exits.
  • Stellen Sie sicher, dass die Metadaten des Instruments die richtigen Preis- und Volumenschritte enthalten. Die Strategie normalisiert jeden generierten Preis und Betrag, um Wechselkursbeschränkungen zu erfüllen.
  • Wenn die Positionsrichtung umgedreht wird, werden alle alten Schutzbefehle aufgehoben, bevor die nachlaufenden Neustarts für die neue Seite erfolgen.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Sample Trailing Stop strategy: Smoothed MA crossover.
/// Buys when close crosses above Smoothed MA, sells when crosses below.
/// </summary>
public class SampleTrailingStopStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;

	private decimal _prevClose;
	private decimal _prevSma;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int Period { get => _period.Value; set => _period.Value = value; }

	public SampleTrailingStopStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_period = Param(nameof(Period), 50)
			.SetGreaterThanZero()
			.SetDisplay("Period", "Smoothed MA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = 0;
		_prevSma = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevSma = 0;
		_hasPrev = false;
		var smma = new ExponentialMovingAverage { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(smma, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevClose <= _prevSma && candle.ClosePrice > smmaValue && Position <= 0)
				BuyMarket();
			else if (_prevClose >= _prevSma && candle.ClosePrice < smmaValue && Position >= 0)
				SellMarket();
		}

		_prevClose = candle.ClosePrice;
		_prevSma = smmaValue;
		_hasPrev = true;
	}
}