Port des MetaTrader-Experten AddOn_TrailingStop. Die Strategie eröffnet keine eigenständigen Positionen und passt lediglich Trailing Stops für eine bestehende Nettoposition an.
Wie es funktioniert
Abonniert Level1-Daten, um die neuesten besten Geld- und Briefkurse zu überwachen.
Berechnet die Pip-Größe aus den Sicherheitsdezimalstellen, sodass sich die Eingaben wie in MetaTrader verhalten (4/5 Ziffern = 0,0001 Pip, 2/3 Ziffern = 0,01 Pip).
Wenn eine Long-Position offen ist und der Geldkurs um TrailingStartPips Pips steigt, verschiebt die Strategie den internen Trailing Stop auf Bid - TrailingStartPips Pips.
Der Long Stop wird nur dann vorgezogen, wenn das neue Level mindestens TrailingStepPips Pips höher ist als der vorherige Stop.
Wenn eine Short-Position offen ist und der Briefkurs um TrailingStartPips Pips sinkt, verschiebt die Strategie den internen Trailing Stop auf Ask + TrailingStartPips Pips.
Der Short-Stop wird nur dann vorgezogen, wenn das neue Level mindestens TrailingStepPips Pips niedriger ist als der vorherige Stop.
Wenn der aktuelle Kurs den Trailing Stop überschreitet, schließt die Strategie die gesamte Position zum Marktwert und setzt ihren Status zurück.
Parameter
EnableTrailing (Standard true) – aktiviert oder deaktiviert die Trailing-Stop-Verwaltung.
TrailingStartPips (Standard 15) – erforderlicher Gewinn in Pips, bevor das Trailing aktiviert wird.
TrailingStepPips (Standard 5) – zusätzlicher Gewinn in Pips erforderlich, bevor sich der Stop wieder bewegen kann.
MagicNumber (Standard 0) – Bezeichner wird aus Gründen der Parität mit dem MQL-Experten beibehalten. Dies ist informativ, da StockSharp auf der aktuellen Strategieposition arbeitet.
Notizen
Erfordert einen konfigurierten Security-, Portfolio- und Level1-Datenfeed.
Entwickelt, um andere Strategien zu ergänzen, die Einträge verarbeiten.
Verwendet StrategyParam<T>, damit jede Eingabe in der Benutzeroberfläche optimiert oder verfügbar gemacht werden kann.
Sendet BuyMarket/SellMarket Orders, wenn der Trailing Stop erreicht wird, da StockSharp automatisch Schutzorder verwaltet, nachdem die Position verlassen wurde.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// AddOn Trailing Stop strategy: EMA crossover with trailing logic.
/// Buys when fast EMA crosses above slow EMA, sells on cross below.
/// </summary>
public class AddOnTrailingStopStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
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 AddOnTrailingStopStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
BuyMarket();
else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
SellMarket();
}
else
{
if (fastValue > slowValue && Position <= 0)
BuyMarket();
else if (fastValue < slowValue && Position >= 0)
SellMarket();
}
_prevFast = fastValue;
_prevSlow = slowValue;
_hasPrev = true;
}
}