Die Strategie repliziert den MetaTrader-Expertenberater Exp_AbsolutelyNoLagLwma, indem ein doppelter gewichteter gleitender Durchschnitt (LWMA) auf Kerzendaten angewendet wird. Die Indikatorausgabe ist farbcodiert: Grün (2) für eine aufwärtsgerichtete Steigung, Grau (1) für flach und Magenta (0) für eine abwärtsgerichtete Steigung. Handelsentscheidungen basieren auf Übergängen zwischen diesen Farbzuständen. Die StockSharp-Implementierung verwendet die High-Level-API, abonniert Zeitrahmen-Kerzen und sendet Marktaufträge gemäß der erkannten Trendrichtung.
Handelslogik
Indikator-Pipeline
Die gewünschte Preisserie auswählen, die durch den Parameter Preistyp definiert wird.
Einen gewichteten gleitenden Durchschnitt (LWMA) mit der konfigurierten LWMA-Länge anwenden.
Das Ergebnis mit einem zweiten LWMA gleicher Länge glätten.
Den geglätteten LWMA-Wert mit dem vorherigen Wert vergleichen, um die Steigungsrichtung zu klassifizieren:
2 (Aufwärtstrend) – aktueller Wert ist größer als der vorherige Wert.
1 (neutral) – aktueller Wert entspricht dem vorherigen Wert.
0 (Abwärtstrend) – aktueller Wert ist kleiner als der vorherige Wert.
Signalauswertung
Nur abgeschlossene Kerzen werden verarbeitet. Der Parameter Signalbalken verschiebt die Signalauswertung auf historische Kerzen (1 = vorherige abgeschlossene Kerze, 2 = die Kerze davor, etc.). Die Strategie merkt sich auch die Farbe des Balkens, der der ausgewählten Signalkerze vorausgeht, um doppelte Einstiege zu vermeiden.
Bullischer Übergang: Die ausgewählte Signalkerze ist Farbe 2 und die vorherige Kerze ist nicht 2. Dies öffnet Longs (wenn aktiviert) und schließt bestehende Shorts.
Bärischer Übergang: Die ausgewählte Signalkerze ist Farbe 0 und die vorherige Kerze ist nicht 0. Dies öffnet Shorts (wenn aktiviert) und schließt bestehende Longs.
Positionsverwaltung
Aufträge werden mit Marktaufträgen ausgeführt. Das angeforderte Volumen ist Volume + |Position|, wenn die Richtung umgekehrt wird, sodass die entgegengesetzte Position automatisch geschlossen wird.
Ausstiegssignale können unabhängig von Einstiegen umgeschaltet werden, was nur-Signal- oder nur-Ausstiegs-Verhalten ermöglicht.
StartProtection() wird aktiviert, um die gemeinsame StockSharp-Schutzlogik einzuschalten, sobald die Strategie startet.
Parameter
LWMA-Länge – Länge der zwei für die Glättung verwendeten LWMAs.
Preistyp – Preisquelle, die den LWMA speist (Schluss, Eröffnung, Hoch, Tief, Median, typisch, gewichtet, vereinfacht, Viertel, Trendfolge-Variationen oder Demark-Preis).
Signalbalken – Anzahl der zurückliegenden abgeschlossenen Kerzen für die Signalauswertung.
Long-Einstiege aktivieren – erlaubt das Öffnen von Long-Positionen bei bullischen Übergängen.
Short-Einstiege aktivieren – erlaubt das Öffnen von Short-Positionen bei bärischen Übergängen.
Long-Ausstiege aktivieren – schließt Long-Positionen wenn der Indikator bärisch wird.
Short-Ausstiege aktivieren – schließt Short-Positionen wenn der Indikator bullisch wird.
Kerzentyp – Zeitrahmen des Kerzenabonnements, das vom Indikator verwendet wird.
Volumen (eingebautes Strategy-Property) – Handelsgröße für neue Einstiege.
Hinweise
Der Standard-Zeitrahmen beträgt 4 Stunden, was der ursprünglichen Expertenkonfiguration entspricht, kann aber über den Parameter Kerzentyp angepasst werden.
Es werden keine Take-Profit- oder Stop-Loss-Aufträge automatisch platziert; Benutzer können die Strategie bei Bedarf mit StockSharp-Risikomanagementkomponenten kombinieren.
Der Python-Port wird absichtlich ausgelassen, wie angefordert.
namespace StockSharp.Samples.Strategies;
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Absolutely No Lag LWMA strategy (simplified).
/// Uses two EMAs of different periods to detect trend direction changes.
/// </summary>
public class AbsolutelyNoLagLwmaStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
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 AbsolutelyNoLagLwmaStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Source candles", "General");
_fastPeriod = Param(nameof(FastPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };
decimal prevFast = 0, prevSlow = 0;
bool hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevFast = fastValue;
prevSlow = slowValue;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevFast = fastValue;
prevSlow = slowValue;
return;
}
if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
{
BuyMarket();
}
else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
{
SellMarket();
}
prevFast = fastValue;
prevSlow = slowValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
}